@@ -195,30 +195,67 @@ export class GeminiProvider implements AIProvider {
195195 ) : Promise < string > {
196196 this . validateRequest ( question , correctAnswers , apiKey ) ;
197197
198+ const prompt = `Question: ${ question } \n\nCorrect answers: ${ correctAnswers . join (
199+ ", " ,
200+ ) } \n\nPlease provide a clear and concise explanation of why these answers are correct. Focus on the key concepts and reasoning.`;
201+
198202 try {
199- const response = await fetch ( "/api/ai/gemini" , {
200- method : "POST" ,
201- headers : { "Content-Type" : "application/json" } ,
202- body : JSON . stringify ( {
203- question,
204- correctAnswers,
205- apiKey,
206- } ) ,
207- } ) ;
203+ const response = await fetch (
204+ `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${ apiKey } ` ,
205+ {
206+ method : "POST" ,
207+ headers : {
208+ "Content-Type" : "application/json" ,
209+ } ,
210+ body : JSON . stringify ( {
211+ contents : [
212+ {
213+ parts : [
214+ {
215+ text : prompt ,
216+ } ,
217+ ] ,
218+ } ,
219+ ] ,
220+ generationConfig : {
221+ maxOutputTokens : 500 ,
222+ temperature : 0.7 ,
223+ } ,
224+ } ) ,
225+ }
226+ ) ;
208227
209228 if ( ! response . ok ) {
210- const errorType = response . status === 401 ? 'auth' :
211- response . status === 429 ? 'rate_limit' : 'network' ;
212- throw new AIProviderError ( this . name , errorType , `Gemini API error: ${ response . status } ` ) ;
229+ const errorData = await response . json ( ) . catch ( ( ) => ( { } ) ) ;
230+ const errorMessage = errorData . error ?. message || `HTTP ${ response . status } ` ;
231+
232+ // Gemini-specific error handling
233+ if ( response . status === 400 ) {
234+ // Check for specific Gemini error types
235+ if ( errorMessage . includes ( 'API_KEY_INVALID' ) || errorMessage . includes ( 'invalid API key' ) ) {
236+ throw new AIProviderError ( this . name , 'auth' , `Invalid Gemini API key: ${ errorMessage } ` ) ;
237+ } else {
238+ throw new AIProviderError ( this . name , 'validation' , `Invalid request: ${ errorMessage } ` ) ;
239+ }
240+ } else if ( response . status === 403 ) {
241+ throw new AIProviderError ( this . name , 'auth' , `Access denied: ${ errorMessage } ` ) ;
242+ } else if ( response . status === 429 ) {
243+ throw new AIProviderError ( this . name , 'rate_limit' , `Rate limit exceeded: ${ errorMessage } ` ) ;
244+ } else if ( response . status >= 500 ) {
245+ throw new AIProviderError ( this . name , 'network' , `Gemini server error: ${ errorMessage } ` ) ;
246+ } else {
247+ throw new AIProviderError ( this . name , 'network' , `Gemini API error: ${ errorMessage } ` ) ;
248+ }
213249 }
214250
215251 const data = await response . json ( ) ;
216252
217- if ( ! data . explanation ) {
218- throw new AIProviderError ( this . name , 'validation' , 'Invalid response from Gemini' ) ;
253+ // Parse Gemini response structure
254+ if ( ! data . candidates ?. [ 0 ] ?. content ?. parts ?. [ 0 ] ?. text ) {
255+ throw new AIProviderError ( this . name , 'validation' , 'Invalid response structure from Gemini' ) ;
219256 }
220257
221- return data . explanation ;
258+ return data . candidates [ 0 ] . content . parts [ 0 ] . text ;
222259 } catch ( error ) {
223260 if ( error instanceof AIProviderError ) throw error ;
224261 const errorMessage = error instanceof Error ? error . message : 'Unknown error' ;
@@ -231,7 +268,8 @@ export class GeminiProvider implements AIProvider {
231268 }
232269
233270 validateConfig ( apiKey ?: string ) : boolean {
234- return ! ! ( apiKey && apiKey . length > 10 ) ; // Basic validation for Gemini keys
271+ // Gemini API keys are typically 39 characters long and start with "AIza"
272+ return ! ! ( apiKey && apiKey . length > 30 && apiKey . startsWith ( 'AIza' ) ) ;
235273 }
236274
237275 private validateRequest ( question : string , correctAnswers : string [ ] , apiKey : string ) : void {
@@ -242,7 +280,7 @@ export class GeminiProvider implements AIProvider {
242280 throw new AIProviderError ( this . name , 'validation' , 'At least one correct answer is required' ) ;
243281 }
244282 if ( ! this . validateConfig ( apiKey ) ) {
245- throw new AIProviderError ( this . name , 'auth' , 'Invalid Gemini API key' ) ;
283+ throw new AIProviderError ( this . name , 'auth' , 'Invalid Gemini API key format ' ) ;
246284 }
247285 }
248286}
0 commit comments