fix(google): omit request config with cached content

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Neerav Makwana
2026-05-21 09:36:23 -04:00
parent bde07ddb15
commit f7be167430
2 changed files with 41 additions and 18 deletions
+33 -8
View File
@@ -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: [
+8 -10
View File
@@ -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) {