Felix Zieger
commited on
Commit
·
5bd3ab2
1
Parent(s):
bf1b7c7
fallback AI model
Browse files
supabase/functions/detect-fraud/index.ts
CHANGED
@@ -27,7 +27,7 @@ serve(async (req) => {
|
|
27 |
while (retryCount < maxRetries) {
|
28 |
try {
|
29 |
const response = await client.chat.complete({
|
30 |
-
model: "mistral-
|
31 |
messages: [
|
32 |
{
|
33 |
role: "system",
|
|
|
27 |
while (retryCount < maxRetries) {
|
28 |
try {
|
29 |
const response = await client.chat.complete({
|
30 |
+
model: "mistral-medium-latest",
|
31 |
messages: [
|
32 |
{
|
33 |
role: "system",
|
supabase/functions/generate-themed-word/index.ts
CHANGED
@@ -30,56 +30,104 @@ const languagePrompts = {
|
|
30 |
}
|
31 |
};
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
41 |
|
42 |
-
|
43 |
-
apiKey: Deno.env.get('MISTRAL_API_KEY'),
|
44 |
-
});
|
45 |
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
messages: [
|
51 |
{
|
52 |
role: "system",
|
53 |
content: `${prompts.systemPrompt} "${theme}".\n${prompts.requirements} ${usedWords.join(', ')}\n\nRespond with just the word in UPPERCASE, nothing else.`
|
54 |
}
|
55 |
-
]
|
56 |
-
|
57 |
-
|
58 |
-
});
|
59 |
|
60 |
-
|
61 |
-
|
|
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
} catch (error) {
|
73 |
console.error('Error generating themed word:', error);
|
74 |
return new Response(
|
75 |
JSON.stringify({ error: error.message }),
|
76 |
{
|
77 |
status: 500,
|
78 |
-
headers: {
|
79 |
-
...corsHeaders,
|
80 |
-
'Content-Type': 'application/json'
|
81 |
-
}
|
82 |
}
|
83 |
);
|
84 |
}
|
85 |
-
});
|
|
|
30 |
}
|
31 |
};
|
32 |
|
33 |
+
const openRouterModels = [
|
34 |
+
'sophosympatheia/rogue-rose-103b-v0.2:free',
|
35 |
+
'google/gemini-2.0-flash-exp:free',
|
36 |
+
'meta-llama/llama-3.1-70b-instruct:free',
|
37 |
+
'microsoft/phi-3-medium-128k-instruct:free'
|
38 |
+
];
|
39 |
|
40 |
+
async function tryMistral(theme: string, usedWords: string[], language: string) {
|
41 |
+
const client = new Mistral({
|
42 |
+
apiKey: Deno.env.get('MISTRAL_API_KEY'),
|
43 |
+
});
|
44 |
|
45 |
+
const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;
|
|
|
|
|
46 |
|
47 |
+
const response = await client.chat.complete({
|
48 |
+
model: "mistral-medium-latest",
|
49 |
+
messages: [
|
50 |
+
{
|
51 |
+
role: "system",
|
52 |
+
content: `${prompts.systemPrompt} "${theme}".\n${prompts.requirements} ${usedWords.join(', ')}\n\nRespond with just the word in UPPERCASE, nothing else.`
|
53 |
+
}
|
54 |
+
],
|
55 |
+
maxTokens: 300,
|
56 |
+
temperature: 0.99
|
57 |
+
});
|
58 |
+
|
59 |
+
return response.choices[0].message.content.trim();
|
60 |
+
}
|
61 |
+
|
62 |
+
async function tryOpenRouter(theme: string, usedWords: string[], language: string) {
|
63 |
+
const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;
|
64 |
+
const randomModel = openRouterModels[Math.floor(Math.random() * openRouterModels.length)];
|
65 |
+
|
66 |
+
console.log('Trying OpenRouter with model:', randomModel);
|
67 |
|
68 |
+
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
|
69 |
+
method: "POST",
|
70 |
+
headers: {
|
71 |
+
"Authorization": `Bearer ${Deno.env.get('OPENROUTER_API_KEY')}`,
|
72 |
+
"HTTP-Referer": "https://think-in-sync.com",
|
73 |
+
"X-Title": "Think in Sync",
|
74 |
+
"Content-Type": "application/json"
|
75 |
+
},
|
76 |
+
body: JSON.stringify({
|
77 |
+
model: randomModel,
|
78 |
messages: [
|
79 |
{
|
80 |
role: "system",
|
81 |
content: `${prompts.systemPrompt} "${theme}".\n${prompts.requirements} ${usedWords.join(', ')}\n\nRespond with just the word in UPPERCASE, nothing else.`
|
82 |
}
|
83 |
+
]
|
84 |
+
})
|
85 |
+
});
|
|
|
86 |
|
87 |
+
if (!response.ok) {
|
88 |
+
throw new Error(`OpenRouter API error: ${response.status}`);
|
89 |
+
}
|
90 |
|
91 |
+
const data = await response.json();
|
92 |
+
return data.choices[0].message.content.trim();
|
93 |
+
}
|
94 |
+
|
95 |
+
serve(async (req) => {
|
96 |
+
if (req.method === 'OPTIONS') {
|
97 |
+
return new Response(null, { headers: corsHeaders });
|
98 |
+
}
|
99 |
+
|
100 |
+
try {
|
101 |
+
const { theme, usedWords = [], language = 'en' } = await req.json();
|
102 |
+
console.log('Generating word for theme:', theme, 'language:', language, 'excluding:', usedWords);
|
103 |
+
|
104 |
+
try {
|
105 |
+
console.log('Attempting with Mistral...');
|
106 |
+
const word = await tryMistral(theme, usedWords, language);
|
107 |
+
console.log('Successfully generated word with Mistral:', word);
|
108 |
+
return new Response(
|
109 |
+
JSON.stringify({ word }),
|
110 |
+
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
111 |
+
);
|
112 |
+
} catch (mistralError) {
|
113 |
+
console.error('Mistral error:', mistralError);
|
114 |
+
console.log('Falling back to OpenRouter...');
|
115 |
+
|
116 |
+
const word = await tryOpenRouter(theme, usedWords, language);
|
117 |
+
console.log('Successfully generated word with OpenRouter:', word);
|
118 |
+
return new Response(
|
119 |
+
JSON.stringify({ word }),
|
120 |
+
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
121 |
+
);
|
122 |
+
}
|
123 |
} catch (error) {
|
124 |
console.error('Error generating themed word:', error);
|
125 |
return new Response(
|
126 |
JSON.stringify({ error: error.message }),
|
127 |
{
|
128 |
status: 500,
|
129 |
+
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
|
|
|
|
|
|
130 |
}
|
131 |
);
|
132 |
}
|
133 |
+
});
|
supabase/functions/generate-word/index.ts
CHANGED
@@ -34,6 +34,82 @@ const languagePrompts = {
|
|
34 |
}
|
35 |
};
|
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
serve(async (req) => {
|
38 |
if (req.method === 'OPTIONS') {
|
39 |
return new Response(null, { headers: corsHeaders });
|
@@ -44,79 +120,34 @@ serve(async (req) => {
|
|
44 |
console.log('Generating word for:', { currentWord, currentSentence, language });
|
45 |
|
46 |
const existingSentence = currentSentence || '';
|
47 |
-
const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;
|
48 |
-
|
49 |
-
const client = new Mistral({
|
50 |
-
apiKey: Deno.env.get('MISTRAL_API_KEY'),
|
51 |
-
});
|
52 |
-
|
53 |
-
const maxRetries = 3;
|
54 |
-
let retryCount = 0;
|
55 |
-
let lastError = null;
|
56 |
-
|
57 |
-
while (retryCount < maxRetries) {
|
58 |
-
try {
|
59 |
-
const response = await client.chat.complete({
|
60 |
-
model: "mistral-large-latest",
|
61 |
-
messages: [
|
62 |
-
{
|
63 |
-
role: "system",
|
64 |
-
content: `${prompts.systemPrompt} "${currentWord}". ${prompts.task} ${prompts.instruction} "${existingSentence}". Do not add quotes or backticks. Just answer with the sentence.`
|
65 |
-
}
|
66 |
-
],
|
67 |
-
maxTokens: 300,
|
68 |
-
temperature: 0.5
|
69 |
-
});
|
70 |
-
|
71 |
-
const aiResponse = response.choices[0].message.content.trim();
|
72 |
-
console.log('AI full response:', aiResponse);
|
73 |
-
|
74 |
-
const newWord = aiResponse
|
75 |
-
.slice(existingSentence.length)
|
76 |
-
.trim()
|
77 |
-
.split(' ')[0]
|
78 |
-
.replace(/[.,!?]$/, '');
|
79 |
-
|
80 |
-
console.log('Extracted new word:', newWord);
|
81 |
-
|
82 |
-
return new Response(
|
83 |
-
JSON.stringify({ word: newWord }),
|
84 |
-
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
85 |
-
);
|
86 |
-
} catch (error) {
|
87 |
-
console.error(`Attempt ${retryCount + 1} failed:`, error);
|
88 |
-
lastError = error;
|
89 |
-
|
90 |
-
if (error.message?.includes('rate limit') || error.status === 429) {
|
91 |
-
const waitTime = Math.pow(2, retryCount) * 1000;
|
92 |
-
console.log(`Rate limit hit, waiting ${waitTime}ms before retry`);
|
93 |
-
await new Promise(resolve => setTimeout(resolve, waitTime));
|
94 |
-
retryCount++;
|
95 |
-
continue;
|
96 |
-
}
|
97 |
-
|
98 |
-
throw error;
|
99 |
-
}
|
100 |
-
}
|
101 |
-
|
102 |
-
throw new Error(`Failed after ${maxRetries} attempts. Last error: ${lastError?.message}`);
|
103 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
} catch (error) {
|
105 |
console.error('Error generating word:', error);
|
106 |
-
|
107 |
-
const errorMessage = error.message?.includes('rate limit')
|
108 |
-
? "The AI service is currently busy. Please try again in a few moments."
|
109 |
-
: "Sorry, there was an error generating the word. Please try again.";
|
110 |
-
|
111 |
return new Response(
|
112 |
-
JSON.stringify({
|
113 |
-
error: errorMessage,
|
114 |
-
details: error.message
|
115 |
-
}),
|
116 |
{
|
117 |
-
status:
|
118 |
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
119 |
}
|
120 |
);
|
121 |
}
|
122 |
-
});
|
|
|
34 |
}
|
35 |
};
|
36 |
|
37 |
+
const openRouterModels = [
|
38 |
+
'sophosympatheia/rogue-rose-103b-v0.2:free',
|
39 |
+
'google/gemini-2.0-flash-exp:free',
|
40 |
+
'meta-llama/llama-3.1-70b-instruct:free',
|
41 |
+
'microsoft/phi-3-medium-128k-instruct:free'
|
42 |
+
];
|
43 |
+
|
44 |
+
async function tryMistral(currentWord: string, existingSentence: string, language: string) {
|
45 |
+
const client = new Mistral({
|
46 |
+
apiKey: Deno.env.get('MISTRAL_API_KEY'),
|
47 |
+
});
|
48 |
+
|
49 |
+
const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;
|
50 |
+
|
51 |
+
const response = await client.chat.complete({
|
52 |
+
model: "mistral-medium-latest",
|
53 |
+
messages: [
|
54 |
+
{
|
55 |
+
role: "system",
|
56 |
+
content: `${prompts.systemPrompt} "${currentWord}". ${prompts.task} ${prompts.instruction} "${existingSentence}". Do not add quotes or backticks. Just answer with the sentence.`
|
57 |
+
}
|
58 |
+
],
|
59 |
+
maxTokens: 300,
|
60 |
+
temperature: 0.5
|
61 |
+
});
|
62 |
+
|
63 |
+
const aiResponse = response.choices[0].message.content.trim();
|
64 |
+
console.log('Mistral full response:', aiResponse);
|
65 |
+
|
66 |
+
return aiResponse
|
67 |
+
.slice(existingSentence.length)
|
68 |
+
.trim()
|
69 |
+
.split(' ')[0]
|
70 |
+
.replace(/[.,!?]$/, '');
|
71 |
+
}
|
72 |
+
|
73 |
+
async function tryOpenRouter(currentWord: string, existingSentence: string, language: string) {
|
74 |
+
const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;
|
75 |
+
const randomModel = openRouterModels[Math.floor(Math.random() * openRouterModels.length)];
|
76 |
+
|
77 |
+
console.log('Trying OpenRouter with model:', randomModel);
|
78 |
+
|
79 |
+
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
|
80 |
+
method: "POST",
|
81 |
+
headers: {
|
82 |
+
"Authorization": `Bearer ${Deno.env.get('OPENROUTER_API_KEY')}`,
|
83 |
+
"HTTP-Referer": "https://think-in-sync.com",
|
84 |
+
"X-Title": "Think in Sync",
|
85 |
+
"Content-Type": "application/json"
|
86 |
+
},
|
87 |
+
body: JSON.stringify({
|
88 |
+
model: randomModel,
|
89 |
+
messages: [
|
90 |
+
{
|
91 |
+
role: "system",
|
92 |
+
content: `${prompts.systemPrompt} "${currentWord}". ${prompts.task} ${prompts.instruction} "${existingSentence}". Do not add quotes or backticks. Just answer with the sentence.`
|
93 |
+
}
|
94 |
+
]
|
95 |
+
})
|
96 |
+
});
|
97 |
+
|
98 |
+
if (!response.ok) {
|
99 |
+
throw new Error(`OpenRouter API error: ${response.status}`);
|
100 |
+
}
|
101 |
+
|
102 |
+
const data = await response.json();
|
103 |
+
const aiResponse = data.choices[0].message.content.trim();
|
104 |
+
console.log('OpenRouter full response:', aiResponse);
|
105 |
+
|
106 |
+
return aiResponse
|
107 |
+
.slice(existingSentence.length)
|
108 |
+
.trim()
|
109 |
+
.split(' ')[0]
|
110 |
+
.replace(/[.,!?]$/, '');
|
111 |
+
}
|
112 |
+
|
113 |
serve(async (req) => {
|
114 |
if (req.method === 'OPTIONS') {
|
115 |
return new Response(null, { headers: corsHeaders });
|
|
|
120 |
console.log('Generating word for:', { currentWord, currentSentence, language });
|
121 |
|
122 |
const existingSentence = currentSentence || '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
|
124 |
+
try {
|
125 |
+
console.log('Attempting with Mistral...');
|
126 |
+
const word = await tryMistral(currentWord, existingSentence, language);
|
127 |
+
console.log('Successfully generated word with Mistral:', word);
|
128 |
+
return new Response(
|
129 |
+
JSON.stringify({ word }),
|
130 |
+
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
131 |
+
);
|
132 |
+
} catch (mistralError) {
|
133 |
+
console.error('Mistral error:', mistralError);
|
134 |
+
console.log('Falling back to OpenRouter...');
|
135 |
+
|
136 |
+
const word = await tryOpenRouter(currentWord, existingSentence, language);
|
137 |
+
console.log('Successfully generated word with OpenRouter:', word);
|
138 |
+
return new Response(
|
139 |
+
JSON.stringify({ word }),
|
140 |
+
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
141 |
+
);
|
142 |
+
}
|
143 |
} catch (error) {
|
144 |
console.error('Error generating word:', error);
|
|
|
|
|
|
|
|
|
|
|
145 |
return new Response(
|
146 |
+
JSON.stringify({ error: error.message }),
|
|
|
|
|
|
|
147 |
{
|
148 |
+
status: 500,
|
149 |
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
150 |
}
|
151 |
);
|
152 |
}
|
153 |
+
});
|
supabase/functions/guess-word/index.ts
CHANGED
@@ -29,85 +29,112 @@ const languagePrompts = {
|
|
29 |
}
|
30 |
};
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
41 |
|
42 |
-
|
43 |
-
apiKey: Deno.env.get('MISTRAL_API_KEY'),
|
44 |
-
});
|
45 |
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
let lastError = null;
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
model: "mistral-large-latest",
|
56 |
-
messages: [
|
57 |
-
{
|
58 |
-
role: "system",
|
59 |
-
content: `${prompts.systemPrompt} Respond with ONLY the word you think is being described, in uppercase letters. Do not add any explanation or punctuation.`
|
60 |
-
},
|
61 |
-
{
|
62 |
-
role: "user",
|
63 |
-
content: `${prompts.instruction} "${sentence}"`
|
64 |
-
}
|
65 |
-
],
|
66 |
-
maxTokens: 50,
|
67 |
-
temperature: 0.1
|
68 |
-
});
|
69 |
|
70 |
-
|
71 |
-
console.log('AI guess:', guess);
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
|
|
|
|
|
|
|
|
87 |
}
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
|
|
|
|
92 |
|
93 |
-
|
|
|
|
|
94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
} catch (error) {
|
96 |
console.error('Error generating guess:', error);
|
97 |
-
|
98 |
-
const errorMessage = error.message?.includes('rate limit')
|
99 |
-
? "The AI service is currently busy. Please try again in a few moments."
|
100 |
-
: "Sorry, there was an error generating the guess. Please try again.";
|
101 |
-
|
102 |
return new Response(
|
103 |
-
JSON.stringify({
|
104 |
-
error: errorMessage,
|
105 |
-
details: error.message
|
106 |
-
}),
|
107 |
{
|
108 |
-
status:
|
109 |
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
110 |
}
|
111 |
);
|
112 |
}
|
113 |
-
});
|
|
|
29 |
}
|
30 |
};
|
31 |
|
32 |
+
const openRouterModels = [
|
33 |
+
'sophosympatheia/rogue-rose-103b-v0.2:free',
|
34 |
+
'google/gemini-2.0-flash-exp:free',
|
35 |
+
'meta-llama/llama-3.1-70b-instruct:free',
|
36 |
+
'microsoft/phi-3-medium-128k-instruct:free'
|
37 |
+
];
|
38 |
|
39 |
+
async function tryMistral(sentence: string, language: string) {
|
40 |
+
const client = new Mistral({
|
41 |
+
apiKey: Deno.env.get('MISTRAL_API_KEY'),
|
42 |
+
});
|
43 |
|
44 |
+
const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;
|
|
|
|
|
45 |
|
46 |
+
const response = await client.chat.complete({
|
47 |
+
model: "mistral-medium-latest",
|
48 |
+
messages: [
|
49 |
+
{
|
50 |
+
role: "system",
|
51 |
+
content: `${prompts.systemPrompt} Respond with ONLY the word you think is being described, in uppercase letters. Do not add any explanation or punctuation.`
|
52 |
+
},
|
53 |
+
{
|
54 |
+
role: "user",
|
55 |
+
content: `${prompts.instruction} "${sentence}"`
|
56 |
+
}
|
57 |
+
],
|
58 |
+
maxTokens: 50,
|
59 |
+
temperature: 0.1
|
60 |
+
});
|
61 |
|
62 |
+
return response.choices[0].message.content.trim().toUpperCase();
|
63 |
+
}
|
|
|
64 |
|
65 |
+
async function tryOpenRouter(sentence: string, language: string) {
|
66 |
+
const prompts = languagePrompts[language as keyof typeof languagePrompts] || languagePrompts.en;
|
67 |
+
const randomModel = openRouterModels[Math.floor(Math.random() * openRouterModels.length)];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
+
console.log('Trying OpenRouter with model:', randomModel);
|
|
|
70 |
|
71 |
+
const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
|
72 |
+
method: "POST",
|
73 |
+
headers: {
|
74 |
+
"Authorization": `Bearer ${Deno.env.get('OPENROUTER_API_KEY')}`,
|
75 |
+
"HTTP-Referer": "https://think-in-sync.com",
|
76 |
+
"X-Title": "Think in Sync",
|
77 |
+
"Content-Type": "application/json"
|
78 |
+
},
|
79 |
+
body: JSON.stringify({
|
80 |
+
model: randomModel,
|
81 |
+
messages: [
|
82 |
+
{
|
83 |
+
role: "system",
|
84 |
+
content: `${prompts.systemPrompt} Respond with ONLY the word you think is being described, in uppercase letters. Do not add any explanation or punctuation.`
|
85 |
+
},
|
86 |
+
{
|
87 |
+
role: "user",
|
88 |
+
content: `${prompts.instruction} "${sentence}"`
|
89 |
}
|
90 |
+
]
|
91 |
+
})
|
92 |
+
});
|
93 |
+
|
94 |
+
if (!response.ok) {
|
95 |
+
throw new Error(`OpenRouter API error: ${response.status}`);
|
96 |
+
}
|
97 |
|
98 |
+
const data = await response.json();
|
99 |
+
return data.choices[0].message.content.trim().toUpperCase();
|
100 |
+
}
|
101 |
|
102 |
+
serve(async (req) => {
|
103 |
+
if (req.method === 'OPTIONS') {
|
104 |
+
return new Response(null, { headers: corsHeaders });
|
105 |
+
}
|
106 |
+
|
107 |
+
try {
|
108 |
+
const { sentence, language = 'en' } = await req.json();
|
109 |
+
console.log('Trying to guess word from sentence:', sentence, 'language:', language);
|
110 |
+
|
111 |
+
try {
|
112 |
+
console.log('Attempting with Mistral...');
|
113 |
+
const guess = await tryMistral(sentence, language);
|
114 |
+
console.log('Successfully generated guess with Mistral:', guess);
|
115 |
+
return new Response(
|
116 |
+
JSON.stringify({ guess }),
|
117 |
+
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
118 |
+
);
|
119 |
+
} catch (mistralError) {
|
120 |
+
console.error('Mistral error:', mistralError);
|
121 |
+
console.log('Falling back to OpenRouter...');
|
122 |
+
|
123 |
+
const guess = await tryOpenRouter(sentence, language);
|
124 |
+
console.log('Successfully generated guess with OpenRouter:', guess);
|
125 |
+
return new Response(
|
126 |
+
JSON.stringify({ guess }),
|
127 |
+
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
128 |
+
);
|
129 |
+
}
|
130 |
} catch (error) {
|
131 |
console.error('Error generating guess:', error);
|
|
|
|
|
|
|
|
|
|
|
132 |
return new Response(
|
133 |
+
JSON.stringify({ error: error.message }),
|
|
|
|
|
|
|
134 |
{
|
135 |
+
status: 500,
|
136 |
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
137 |
}
|
138 |
);
|
139 |
}
|
140 |
+
});
|
supabase/functions/validate-sentence/index.ts
CHANGED
@@ -20,7 +20,7 @@ serve(async (req) => {
|
|
20 |
});
|
21 |
|
22 |
const response = await client.chat.complete({
|
23 |
-
model: "mistral-
|
24 |
messages: [
|
25 |
{
|
26 |
role: "system",
|
|
|
20 |
});
|
21 |
|
22 |
const response = await client.chat.complete({
|
23 |
+
model: "mistral-medium-latest",
|
24 |
messages: [
|
25 |
{
|
26 |
role: "system",
|