File size: 5,008 Bytes
5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd 47fea40 5835ecd |
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 |
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 sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
serve(async (req) => {
// Handle CORS preflight requests
if (req.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
try {
const { sentence, targetWord, language } = await req.json();
console.log('Checking for fraud:', { sentence, targetWord, language });
const client = new Mistral({
apiKey: Deno.env.get('MISTRAL_API_KEY'),
});
const maxRetries = 3;
let retryCount = 0;
let lastError = null;
while (retryCount < maxRetries) {
try {
console.log(`Attempt ${retryCount + 1} to check for fraud`);
const response = await client.chat.complete({
model: "mistral-large-latest",
messages: [
{
role: "system",
content: `You are a fraud detection system for a word guessing game.
The game is being played in ${language}.
Your task is to detect if a player is trying to cheat by one of two methods:
1. The Player's description is a misspelling of the target word
2. The Player's description is a sentence without spaces
Examples for cheating:
Target word: hand
Player's description: hnd
Language: en
CORRECT ANSWER: cheating
Target word: barfuß
Player's description: germanwordforbarefoot
Language: de
CORRECT ANSWER: cheating
Synonyms and names of instances of a class are legitimate descriptions.
Target word: laptop
Player's description: notebook
Language: en
CORRECT ANSWER: legitimate
Target word: play
Player's description: children often
Language: en
CORRECT ANSWER: legitimate
Target word: Pfankuchen
Player's description: Berliner
Language: de
CORRECT ANSWER: legitimate
Target word: Burrito
Player's description: Wrap
Language: es
CORRECT ANSWER: legitimate
Respond with ONLY "cheating" or "legitimate" (no punctuation or explanation).`
},
{
role: "user",
content: `Target word: "${targetWord}"
Player's description: "${sentence}"
Language: ${language}
Is this a legitimate description or an attempt to cheat?`
}
],
maxTokens: 20,
temperature: 0.1
});
if (!response?.choices?.[0]?.message?.content) {
throw new Error('Invalid response format from Mistral API');
}
const verdict = response.choices[0].message.content.trim().toLowerCase();
console.log('Fraud detection verdict:', verdict);
return new Response(
JSON.stringify({ verdict }),
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
);
} catch (error) {
console.error(`Attempt ${retryCount + 1} failed:`, error);
lastError = error;
// Check if it's a rate limit or service unavailable error
if (error.message?.includes('rate limit') ||
error.message?.includes('503') ||
error.message?.includes('Service unavailable')) {
const waitTime = Math.pow(2, retryCount) * 1000; // Exponential backoff
console.log(`Service unavailable or rate limited, waiting ${waitTime}ms before retry`);
await sleep(waitTime);
retryCount++;
continue;
}
// If it's not a retryable error, throw immediately
throw error;
}
}
// If we've exhausted all retries
throw new Error(`Failed after ${maxRetries} attempts. Last error: ${lastError?.message}`);
} catch (error) {
console.error('Error in fraud detection:', error);
const errorMessage = error.message?.includes('rate limit') || error.message?.includes('503')
? "The AI service is currently busy. Please try again in a few moments."
: "Sorry, there was an error checking for fraud. Please try again.";
return new Response(
JSON.stringify({
error: errorMessage,
details: error.message
}),
{
status: error.message?.includes('rate limit') || error.message?.includes('503') ? 429 : 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
}
);
}
}); |