diff --git a/extensions/google/transport-stream.test.ts b/extensions/google/transport-stream.test.ts index b19f6ca0eb0b..b9bdd9e1a9bf 100644 --- a/extensions/google/transport-stream.test.ts +++ b/extensions/google/transport-stream.test.ts @@ -371,19 +371,14 @@ describe("google transport stream", () => { }); const payload = parseRequestJsonBody(init); - expect(payload.systemInstruction).toEqual({ - parts: [{ text: "Follow policy." }], - }); expect(payload.cachedContent).toBe("cachedContents/request-cache"); + expect(payload.systemInstruction).toBeUndefined(); + expect(payload.tools).toBeUndefined(); + expect(payload.toolConfig).toBeUndefined(); expect((payload.generationConfig as { thinkingConfig?: unknown }).thinkingConfig).toEqual({ includeThoughts: true, thinkingLevel: "HIGH", }); - expect( - (payload.toolConfig as { functionCallingConfig?: unknown }).functionCallingConfig, - ).toEqual({ - mode: "AUTO", - }); expect(result.api).toBe("google-generative-ai"); expect(result.provider).toBe("google"); expect(result.responseId).toBe("resp_1"); @@ -1532,6 +1527,36 @@ describe("google transport stream", () => { expect(params.cachedContent).toBe("cachedContents/prebuilt-context"); }); + it("omits per-request system and tool settings when using cachedContent", () => { + const params = buildGoogleGenerativeAiParams( + buildGeminiModel(), + { + systemPrompt: "Follow policy.", + messages: [{ role: "user", content: "hello", timestamp: 0 }], + tools: [ + { + name: "lookup", + description: "Look up a value", + parameters: { + type: "object", + properties: { q: { type: "string" } }, + required: ["q"], + }, + }, + ], + } as never, + { + cachedContent: " cachedContents/prebuilt-context ", + toolChoice: "auto", + }, + ); + + expect(params.cachedContent).toBe("cachedContents/prebuilt-context"); + expect(params.systemInstruction).toBeUndefined(); + expect(params.tools).toBeUndefined(); + expect(params.toolConfig).toBeUndefined(); + }); + it("uses a non-empty text placeholder for empty user text", () => { const params = buildGoogleGenerativeAiParams(buildGeminiModel(), { messages: [ diff --git a/extensions/google/transport-stream.ts b/extensions/google/transport-stream.ts index e3641cb3521d..f06bf5d97c74 100644 --- a/extensions/google/transport-stream.ts +++ b/extensions/google/transport-stream.ts @@ -202,9 +202,7 @@ function hasGeminiThoughtSignatureTruncationFootprint(value: string): boolean { ); } -function sanitizeGeminiThoughtSignature( - thoughtSignature: string | undefined, -): string | undefined { +function sanitizeGeminiThoughtSignature(thoughtSignature: string | undefined): string | undefined { if (typeof thoughtSignature !== "string") { return undefined; } @@ -552,9 +550,7 @@ function convertGoogleMessages(model: GoogleTransportModel, context: Context) { : undefined; parts.push({ text: sanitizeTransportPayloadText(block.text), - ...(sanitizedTextSignature - ? { thoughtSignature: sanitizedTextSignature } - : {}), + ...(sanitizedTextSignature ? { thoughtSignature: sanitizedTextSignature } : {}), }); continue; } @@ -710,13 +706,15 @@ export function buildGoogleGenerativeAiParams( const params: GoogleGenerateContentRequest = { contents: convertGoogleMessages(model, context), }; - if (typeof options?.cachedContent === "string" && options.cachedContent.trim()) { - params.cachedContent = options.cachedContent.trim(); + const cachedContent = + typeof options?.cachedContent === "string" ? options.cachedContent.trim() : ""; + if (cachedContent) { + params.cachedContent = cachedContent; } if (Object.keys(generationConfig).length > 0) { params.generationConfig = generationConfig; } - if (context.systemPrompt) { + if (!cachedContent && context.systemPrompt) { params.systemInstruction = { parts: [ { @@ -725,7 +723,7 @@ export function buildGoogleGenerativeAiParams( ], }; } - if (context.tools?.length) { + if (!cachedContent && context.tools?.length) { params.tools = convertGoogleTools(context.tools); const toolChoice = mapToolChoice(options?.toolChoice); if (toolChoice) {