diff --git a/packages/core/src/config/models.ts b/packages/core/src/config/models.ts index 8a8c254541..b8420dd259 100644 --- a/packages/core/src/config/models.ts +++ b/packages/core/src/config/models.ts @@ -54,10 +54,9 @@ export const PREVIEW_GEMINI_MODEL = 'gemini-3-pro-preview'; export const PREVIEW_GEMINI_3_1_MODEL = 'gemini-3.1-pro-preview'; export const PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL = 'gemini-3.1-pro-preview-customtools'; +export const PREVIEW_GEMINI_FLASH_MODEL = 'gemini-3-flash-preview'; export const PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL = 'gemini-3.1-flash-lite-preview'; -export const PREVIEW_GEMINI_3_0_FLASH_MODEL = 'gemini-3-flash-preview'; -export const PREVIEW_GEMINI_FLASH_MODEL = PREVIEW_GEMINI_3_0_FLASH_MODEL; export const DEFAULT_GEMINI_MODEL = 'gemini-2.5-pro'; export const DEFAULT_GEMINI_FLASH_MODEL = 'gemini-2.5-flash'; export const DEFAULT_GEMINI_FLASH_LITE_MODEL = 'gemini-2.5-flash-lite'; @@ -66,7 +65,6 @@ export const VALID_GEMINI_MODELS = new Set([ PREVIEW_GEMINI_MODEL, PREVIEW_GEMINI_3_1_MODEL, PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, - PREVIEW_GEMINI_3_0_FLASH_MODEL, PREVIEW_GEMINI_FLASH_MODEL, PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL, DEFAULT_GEMINI_MODEL, @@ -293,7 +291,6 @@ export function isPreviewModel( model === PREVIEW_GEMINI_MODEL || model === PREVIEW_GEMINI_3_1_MODEL || model === PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL || - model === PREVIEW_GEMINI_3_0_FLASH_MODEL || model === PREVIEW_GEMINI_FLASH_MODEL || model === PREVIEW_GEMINI_MODEL_AUTO || model === GEMINI_MODEL_ALIAS_AUTO || @@ -448,9 +445,6 @@ export function isActiveModel( if (model === PREVIEW_GEMINI_3_1_FLASH_LITE_MODEL) { return useGemini3_1FlashLite; } - if (model === PREVIEW_GEMINI_3_0_FLASH_MODEL) { - return true; - } if (useGemini3_1) { if (model === PREVIEW_GEMINI_MODEL) { return false; diff --git a/packages/core/src/core/geminiChat.ts b/packages/core/src/core/geminiChat.ts index d931baaaea..4b3456332b 100644 --- a/packages/core/src/core/geminiChat.ts +++ b/packages/core/src/core/geminiChat.ts @@ -168,18 +168,20 @@ function extractCuratedHistory(comprehensiveHistory: Content[]): Content[] { const role = entry.role; const rawParts = entry.parts || []; - // Filter parts: keep only non-empty text or non-text parts + // Filter out invalid/empty parts const validParts = rawParts.filter((part) => { if (part === undefined || Object.keys(part).length === 0) { return false; } - // Thought parts should always be kept if present - if (part.thought) { - return true; + // Thought parts must be non-empty strings + if (part.thought !== undefined) { + return typeof part.thought === 'string' && part.thought.trim() !== ''; } - if (part.text !== undefined && part.text.trim() === '') { - return false; + // Text parts must be non-empty strings + if (part.text !== undefined) { + return typeof part.text === 'string' && part.text.trim() !== ''; } + // Keep other parts (functionCall, functionResponse, etc.) return true; }); @@ -188,9 +190,7 @@ function extractCuratedHistory(comprehensiveHistory: Content[]): Content[] { } let lastEntry = curatedHistory[curatedHistory.length - 1]; - if (lastEntry && lastEntry.role === role) { - // Merge into last entry - } else { + if (!lastEntry || lastEntry.role !== role) { // Create new entry lastEntry = { role, @@ -201,19 +201,33 @@ function extractCuratedHistory(comprehensiveHistory: Content[]): Content[] { const lastEntryParts = lastEntry.parts || []; for (const part of validParts) { - if ( - lastEntryParts.length > 0 && - lastEntryParts[lastEntryParts.length - 1].text !== undefined && - part.text !== undefined - ) { - // Coalesce text parts - const lastText = lastEntryParts[lastEntryParts.length - 1].text!; - const separator = lastText.endsWith('\n') ? '' : '\n'; - lastEntryParts[lastEntryParts.length - 1] = { - ...lastEntryParts[lastEntryParts.length - 1], - text: lastText + separator + part.text, - }; + if (part.text !== undefined) { + // Coalesce text into the last text part of this turn + const existingTextPart = lastEntryParts.find( + (p) => p.text !== undefined, + ); + if (existingTextPart) { + const lastText = existingTextPart.text!; + const separator = lastText.endsWith('\n') ? '' : '\n'; + existingTextPart.text = lastText + separator + part.text; + } else { + lastEntryParts.push({ ...part }); + } + } else if (part.thought !== undefined) { + // Coalesce thought into the last thought part of this turn + const existingThoughtPart = lastEntryParts.find( + (p) => p.thought !== undefined, + ); + if (existingThoughtPart) { + const lastThought = existingThoughtPart.thought!; + const separator = lastThought.endsWith('\n') ? '' : '\n'; + existingThoughtPart.thought = lastThought + separator + part.thought; + } else { + // Insert thought at the beginning for model consistency + lastEntryParts.unshift({ ...part }); + } } else { + // Add as is (functionCall, functionResponse) lastEntryParts.push({ ...part }); } }