File size: 5,900 Bytes
55a034a
 
 
 
 
 
 
 
831f7e7
 
8ec33d8
a64b653
 
831f7e7
 
8ec33d8
a64b653
 
831f7e7
 
8ec33d8
a64b653
 
831f7e7
 
8ec33d8
a64b653
 
831f7e7
 
8ec33d8
a64b653
 
831f7e7
 
 
5bd3ab2
 
 
 
 
 
55a034a
5bd3ab2
 
 
 
55a034a
5bd3ab2
55a034a
5bd3ab2
47fea40
5bd3ab2
 
 
a64b653
5bd3ab2
 
 
 
 
 
 
 
 
831f7e7
5bd3ab2
 
8725cc4
5bd3ab2
 
 
8725cc4
5bd3ab2
8725cc4
5bd3ab2
 
 
 
 
 
 
 
 
 
 
 
 
a64b653
5bd3ab2
 
 
 
55a034a
5bd3ab2
 
 
 
 
 
 
55a034a
5bd3ab2
 
 
55a034a
5bd3ab2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a64b653
5bd3ab2
 
 
 
 
 
 
55a034a
 
 
5bd3ab2
a64b653
5bd3ab2
55a034a
 
 
 
5bd3ab2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { Mistral } from "npm:@mistralai/mistralai";

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
};

const languagePrompts = {
  en: {
    systemPrompt: "You are helping in a word guessing game. Given a description, guess what single word is being described. The described word itself was not allowed in the description, so do not expect it to appear.",
    instruction: "Based on this description",
    responseInstruction: "Respond with ONLY the word you think is being described, in uppercase letters. Do not add any explanation or punctuation."
  },
  fr: {
    systemPrompt: "Vous aidez dans un jeu de devinettes. À partir d'une description, devinez le mot unique qui est décrit. Le mot décrit n'était pas autorisé dans la description, ne vous attendez donc pas à le voir apparaître.",
    instruction: "D'après cette description",
    responseInstruction: "Répondez uniquement par le mot que vous pensez être décrit, en lettres majuscules. N'ajoutez aucune explication ni ponctuation."
  },
  de: {
    systemPrompt: "Sie helfen bei einem Worträtsel. Erraten Sie anhand einer Beschreibung, welches einzelne Wort beschrieben wird. Das beschriebene Wort durfte nicht in der Beschreibung verwendet werden, also erwarten Sie es nicht.",
    instruction: "Basierend auf dieser Beschreibung",
    responseInstruction: "Antworten Sie nur mit dem Wort, das Sie für beschrieben halten, in Großbuchstaben. Fügen Sie keine Erklärungen oder Satzzeichen hinzu."
  },
  it: {
    systemPrompt: "Stai aiutando in un gioco di indovinelli. Data una descrizione, indovina quale singola parola viene descritta. La parola descritta non era permessa nella descrizione, quindi non aspettarti di trovarla.",
    instruction: "Basandoti su questa descrizione",
    responseInstruction: "Rispondi solo con la parola che pensi venga descritta, in lettere maiuscole. Non aggiungere spiegazioni o punteggiatura."
  },
  es: {
    systemPrompt: "Estás ayudando en un juego de adivinanzas. Dada una descripción, adivina qué palabra única se está describiendo. La palabra descrita no estaba permitida en la descripción, así que no esperes verla.",
    instruction: "Basándote en esta descripción",
    responseInstruction: "Responde únicamente con la palabra que crees que se está describiendo, en letras mayúsculas. No añadas ninguna explicación ni puntuación."
  }
};

const openRouterModels = [
  'sophosympatheia/rogue-rose-103b-v0.2:free',
  'google/gemini-2.0-flash-exp:free',
  'meta-llama/llama-3.1-70b-instruct:free',
  'microsoft/phi-3-medium-128k-instruct:free'
];

async function tryMistral(sentence: string, language: string) {
  const client = new Mistral({
    apiKey: Deno.env.get('MISTRAL_API_KEY'),
  });

  const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;

  const response = await client.chat.complete({
    model: "mistral-large-latest",
    messages: [
      {
        role: "system",
        content: `${prompts.systemPrompt} ${prompts.responseInstruction}`
      },
      {
        role: "user",
        content: `${prompts.instruction} "${sentence}"`
      }
    ],
    maxTokens: 50,
    temperature: 0.1
  });

  return response.choices[0].message.content.trim().toUpperCase();
}

async function tryOpenRouter(sentence: string, language: string) {
  const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;
  const randomModel = openRouterModels[Math.floor(Math.random() * openRouterModels.length)];

  console.log('Trying OpenRouter with model:', randomModel);

  const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${Deno.env.get('OPENROUTER_API_KEY')}`,
      "HTTP-Referer": "https://think-in-sync.com",
      "X-Title": "Think in Sync",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      model: randomModel,
      messages: [
        {
          role: "system",
          content: `${prompts.systemPrompt} ${prompts.responseInstruction}`
        },
        {
          role: "user",
          content: `${prompts.instruction} "${sentence}"`
        }
      ]
    })
  });

  if (!response.ok) {
    throw new Error(`OpenRouter API error: ${response.status}`);
  }

  const data = await response.json();
  return data.choices[0].message.content.trim().toUpperCase();
}

serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response(null, { headers: corsHeaders });
  }

  try {
    const { sentence, language = 'en' } = await req.json();
    console.log('Trying to guess word from sentence:', sentence, 'language:', language);

    try {
      console.log('Attempting with Mistral...');
      const guess = await tryMistral(sentence, language);
      console.log('Successfully generated guess with Mistral:', guess);
      return new Response(
        JSON.stringify({ guess }),
        { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      );
    } catch (mistralError) {
      console.error('Mistral error:', mistralError);
      console.log('Falling back to OpenRouter...');

      const guess = await tryOpenRouter(sentence, language);
      console.log('Successfully generated guess with OpenRouter:', guess);
      return new Response(
        JSON.stringify({ guess }),
        { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      );
    }
  } catch (error) {
    console.error('Error generating guess:', error);
    return new Response(
      JSON.stringify({ error: error.message }),
      {
        status: 500,
        headers: { ...corsHeaders, 'Content-Type': 'application/json' }
      }
    );
  }
});