@@ -295,30 +295,55 @@ export class MistralProvider implements AIProvider {
295295 ) : Promise < string > {
296296 this . validateRequest ( question , correctAnswers , apiKey ) ;
297297
298+ const prompt = `Question: ${ question } \n\nCorrect answers: ${ correctAnswers . join (
299+ ", " ,
300+ ) } \n\nPlease provide a clear and concise explanation of why these answers are correct. Focus on the key concepts and reasoning.`;
301+
298302 try {
299- const response = await fetch ( "/api/ ai/mistral " , {
303+ const response = await fetch ( "https://api.mistral. ai/v1/chat/completions " , {
300304 method : "POST" ,
301- headers : { "Content-Type" : "application/json" } ,
305+ headers : {
306+ "Authorization" : `Bearer ${ apiKey } ` ,
307+ "Content-Type" : "application/json" ,
308+ } ,
302309 body : JSON . stringify ( {
303- question,
304- correctAnswers,
305- apiKey,
310+ model : "mistral-medium" ,
311+ messages : [
312+ {
313+ role : "user" ,
314+ content : prompt ,
315+ } ,
316+ ] ,
317+ max_tokens : 500 ,
318+ temperature : 0.7 ,
306319 } ) ,
307320 } ) ;
308321
309322 if ( ! response . ok ) {
310- const errorType = response . status === 401 ? 'auth' :
311- response . status === 429 ? 'rate_limit' : 'network' ;
312- throw new AIProviderError ( this . name , errorType , `Mistral API error: ${ response . status } ` ) ;
323+ const errorData = await response . json ( ) . catch ( ( ) => ( { } ) ) ;
324+ const errorMessage = errorData . message || errorData . error ?. message || `HTTP ${ response . status } ` ;
325+
326+ // Mistral-specific error handling
327+ if ( response . status === 401 ) {
328+ throw new AIProviderError ( this . name , 'auth' , `Authentication failed: ${ errorMessage } ` ) ;
329+ } else if ( response . status === 429 ) {
330+ throw new AIProviderError ( this . name , 'rate_limit' , `Rate limit exceeded: ${ errorMessage } ` ) ;
331+ } else if ( response . status === 400 ) {
332+ throw new AIProviderError ( this . name , 'validation' , `Invalid request: ${ errorMessage } ` ) ;
333+ } else if ( response . status >= 500 ) {
334+ throw new AIProviderError ( this . name , 'network' , `Mistral server error: ${ errorMessage } ` ) ;
335+ } else {
336+ throw new AIProviderError ( this . name , 'network' , `Mistral API error: ${ errorMessage } ` ) ;
337+ }
313338 }
314339
315340 const data = await response . json ( ) ;
316341
317- if ( ! data . explanation ) {
318- throw new AIProviderError ( this . name , 'validation' , 'Invalid response from Mistral' ) ;
342+ if ( ! data . choices ?. [ 0 ] ?. message ?. content ) {
343+ throw new AIProviderError ( this . name , 'validation' , 'Invalid response structure from Mistral' ) ;
319344 }
320345
321- return data . explanation ;
346+ return data . choices [ 0 ] . message . content ;
322347 } catch ( error ) {
323348 if ( error instanceof AIProviderError ) throw error ;
324349 const errorMessage = error instanceof Error ? error . message : 'Unknown error' ;
@@ -331,7 +356,8 @@ export class MistralProvider implements AIProvider {
331356 }
332357
333358 validateConfig ( apiKey ?: string ) : boolean {
334- return ! ! ( apiKey && apiKey . length > 10 ) ; // Basic validation for Mistral keys
359+ // Mistral API keys typically start with a specific pattern and have reasonable length
360+ return ! ! ( apiKey && apiKey . length > 20 ) ;
335361 }
336362
337363 private validateRequest ( question : string , correctAnswers : string [ ] , apiKey : string ) : void {
@@ -342,7 +368,7 @@ export class MistralProvider implements AIProvider {
342368 throw new AIProviderError ( this . name , 'validation' , 'At least one correct answer is required' ) ;
343369 }
344370 if ( ! this . validateConfig ( apiKey ) ) {
345- throw new AIProviderError ( this . name , 'auth' , 'Invalid Mistral API key' ) ;
371+ throw new AIProviderError ( this . name , 'auth' , 'Invalid Mistral API key format ' ) ;
346372 }
347373 }
348374}
0 commit comments