diff --git a/packages/server/src/core/gemini-client.ts b/packages/server/src/core/client.ts similarity index 83% rename from packages/server/src/core/gemini-client.ts rename to packages/server/src/core/client.ts index 5829afa8..e65e58a7 100644 --- a/packages/server/src/core/gemini-client.ts +++ b/packages/server/src/core/client.ts @@ -21,7 +21,7 @@ import { getFolderStructure } from '../utils/getFolderStructure.js'; import { Turn, ServerTool, ServerGeminiStreamEvent } from './turn.js'; export class GeminiClient { - private ai: GoogleGenAI; + private client: GoogleGenAI; private model: string; private generateContentConfig: GenerateContentConfig = { temperature: 0, @@ -30,7 +30,7 @@ export class GeminiClient { private readonly MAX_TURNS = 100; constructor(apiKey: string, model: string) { - this.ai = new GoogleGenAI({ apiKey: apiKey }); + this.client = new GoogleGenAI({ apiKey: apiKey }); this.model = model; } @@ -56,14 +56,9 @@ export class GeminiClient { async startChat(toolDeclarations: FunctionDeclaration[]): Promise { const envPart = await this.getEnvironment(); - // const tools: Tool[] = toolDeclarations.map((declaration) => ({ - // functionDeclarations: [declaration], - // })); - // merge all functions into a single tool, as seems to be required for gemini 2.5 series - // can test by asking "what tools do you have?", which lists single function unless merged const tools: Tool[] = [{ functionDeclarations: toolDeclarations }]; try { - const chat = this.ai.chats.create({ + return this.client.chats.create({ model: this.model, config: { systemInstruction: CoreSystemPrompt, @@ -81,7 +76,6 @@ export class GeminiClient { }, ], }); - return chat; } catch (error) { console.error('Error initializing Gemini chat session:', error); const message = error instanceof Error ? error.message : 'Unknown error.'; @@ -111,14 +105,11 @@ export class GeminiClient { } // What do we do when we have both function responses and confirmations? - const fnResponses = turn.getFunctionResponses(); - if (fnResponses.length > 0) { - request = fnResponses; - continue; - } else { - break; + if (fnResponses.length == 0) { + break; // user's turn to respond } + request = fnResponses; } if (turns >= this.MAX_TURNS) { console.warn( @@ -140,7 +131,7 @@ export class GeminiClient { schema: SchemaUnion, ): Promise> { try { - const result = await this.ai.models.generateContent({ + const result = await this.client.models.generateContent({ model: this.model, config: { ...this.generateContentConfig, @@ -150,15 +141,13 @@ export class GeminiClient { }, contents, }); - const responseText = result.text; - if (!responseText) { + if (!result || !result.text) { throw new Error('API returned an empty response.'); } try { - const parsedJson = JSON.parse(responseText); - return parsedJson; + return JSON.parse(result.text); } catch (parseError) { - console.error('Failed to parse JSON response:', responseText); + console.error('Failed to parse JSON response:', result.text); throw new Error( `Failed to parse API response as JSON: ${parseError instanceof Error ? parseError.message : String(parseError)}`, ); diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 2cbfbe6b..998ed584 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -8,7 +8,7 @@ export * from './config/config.js'; // Export Core Logic -export * from './core/gemini-client.js'; +export * from './core/client.js'; export * from './core/prompts.js'; export * from './core/turn.js'; // Potentially export types from turn.ts if needed externally diff --git a/packages/server/src/utils/BackgroundTerminalAnalyzer.ts b/packages/server/src/utils/BackgroundTerminalAnalyzer.ts index 54ad9d50..625b06b6 100644 --- a/packages/server/src/utils/BackgroundTerminalAnalyzer.ts +++ b/packages/server/src/utils/BackgroundTerminalAnalyzer.ts @@ -6,7 +6,7 @@ import { Content, SchemaUnion, Type } from '@google/genai'; import { getErrorMessage, isNodeError } from '../utils/errors.js'; -import { GeminiClient } from '../core/gemini-client.js'; +import { GeminiClient } from '../core/client.js'; import { Config } from '../config/config.js'; import { promises as fs } from 'fs'; import { exec as _exec } from 'child_process';