From ed0d1a0ba317fdacd71969eb728748f8d5a15a32 Mon Sep 17 00:00:00 2001 From: Victor May Date: Tue, 7 Oct 2025 15:05:33 -0400 Subject: [PATCH] Get around the initial empty response from gemini-2.5-flash. (#10508) --- packages/core/src/core/client.ts | 26 ++++++++++++++++++++------ packages/core/src/core/turn.test.ts | 2 +- packages/core/src/core/turn.ts | 6 +++++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/packages/core/src/core/client.ts b/packages/core/src/core/client.ts index df36d796f3..7f37dd7b60 100644 --- a/packages/core/src/core/client.ts +++ b/packages/core/src/core/client.ts @@ -225,23 +225,37 @@ export class GeminiClient { async startChat(extraHistory?: Content[]): Promise { this.forceFullIdeContext = true; this.hasFailedCompressionAttempt = false; - const envParts = await getEnvironmentContext(this.config); const toolRegistry = this.config.getToolRegistry(); const toolDeclarations = toolRegistry.getFunctionDeclarations(); const tools: Tool[] = [{ functionDeclarations: toolDeclarations }]; + // 1. Get the environment context parts as an array + const envParts = await getEnvironmentContext(this.config); + + // 2. Convert the array of parts into a single string + const envContextString = envParts + .map((part) => part.text || '') + .join('\n\n'); + + // 3. Combine the dynamic context with the static handshake instruction + const allSetupText = ` +${envContextString} + +Reminder: Do not return an empty response when a tool call is required. + +My setup is complete. I will provide my first command in the next turn. + `.trim(); + + // 4. Create the history with a single, comprehensive user turn const history: Content[] = [ { role: 'user', - parts: envParts, - }, - { - role: 'model', - parts: [{ text: 'Got it. Thanks for the context!' }], + parts: [{ text: allSetupText }], }, ...(extraHistory ?? []), ]; + try { const userMemory = this.config.getUserMemory(); const systemInstruction = getCoreSystemPrompt(this.config, userMemory); diff --git a/packages/core/src/core/turn.test.ts b/packages/core/src/core/turn.test.ts index d3451166a9..45f78a26a5 100644 --- a/packages/core/src/core/turn.test.ts +++ b/packages/core/src/core/turn.test.ts @@ -251,7 +251,7 @@ describe('Turn', () => { expect(reportError).toHaveBeenCalledWith( error, 'Error when talking to Gemini API', - [...historyContent, reqParts], + [...historyContent, { role: 'user', parts: reqParts }], 'Turn.run-sendMessageStream', ); }); diff --git a/packages/core/src/core/turn.ts b/packages/core/src/core/turn.ts index aef017c414..9a93209c27 100644 --- a/packages/core/src/core/turn.ts +++ b/packages/core/src/core/turn.ts @@ -28,6 +28,7 @@ import { } from '../utils/errors.js'; import type { GeminiChat } from './geminiChat.js'; import { parseThought, type ThoughtSummary } from '../utils/thoughtUtils.js'; +import { createUserContent } from '@google/genai'; // Define a structure for tools passed to the server export interface ServerTool { @@ -306,7 +307,10 @@ export class Turn { throw error; } - const contextForReport = [...this.chat.getHistory(/*curated*/ true), req]; + const contextForReport = [ + ...this.chat.getHistory(/*curated*/ true), + createUserContent(req), + ]; await reportError( error, 'Error when talking to Gemini API',