Preserve #3440 coverage under signature replay

Seed a connection-scoped Gemini thought signature before exercising the Claude-to-Gemini id assertions. This keeps the regression focused on the public-Gemini versus Vertex id contract while honoring the new signature replay behavior.

Constraint: Signature-less historical Claude tool calls are intentionally converted to context text.

Rejected: Emit unsigned functionCall parts in the fixture | Gemini 3+ rejects that production behavior.

Confidence: high

Scope-risk: narrow

Tested: Prettier, repository ESLint hook, vertex-functioncall-id-3440 Node test, git diff --check

Not-tested: Full repository test suite
This commit is contained in:
csoftware-arigpt
2026-07-27 20:18:20 +03:00
parent c30724742d
commit 30cf91e272

View File

@@ -11,15 +11,24 @@
import test from "node:test";
import assert from "node:assert/strict";
const { openaiToGeminiRequest } = await import(
"../../open-sse/translator/request/openai-to-gemini.ts"
);
const { claudeToGeminiRequest } = await import(
"../../open-sse/translator/request/claude-to-gemini.ts"
);
const { openaiToGeminiRequest } =
await import("../../open-sse/translator/request/openai-to-gemini.ts");
const { claudeToGeminiRequest } =
await import("../../open-sse/translator/request/claude-to-gemini.ts");
const { buildGeminiThoughtSignatureKey, storeGeminiThoughtSignature } =
await import("../../open-sse/services/geminiThoughtSignatureStore.ts");
type UnknownRecord = Record<string, unknown>;
const CLAUDE_SIGNATURE_NAMESPACE = "regression-3440";
function seedClaudeThoughtSignature() {
storeGeminiThoughtSignature(
buildGeminiThoughtSignatureKey(CLAUDE_SIGNATURE_NAMESPACE, "tu_weather_1"),
"SIG_3440"
);
}
function findFunctionCall(result: any): UnknownRecord | undefined {
for (const content of result.contents ?? []) {
for (const part of content.parts ?? []) {
@@ -126,10 +135,16 @@ test("#3440 OpenAI->Gemini: no provider hint PRESERVES id (default, non-vertex)"
});
test("#3440 Claude->Gemini: vertex provider omits id from functionCall and functionResponse", () => {
seedClaudeThoughtSignature();
const result = claudeToGeminiRequest("gemini-2.5-pro", CLAUDE_TOOL_BODY, false, {
_provider: "vertex",
_signatureNamespace: CLAUDE_SIGNATURE_NAMESPACE,
});
assert.equal(findFunctionCall(result)?.id, undefined, "functionCall.id must be omitted for Vertex");
assert.equal(
findFunctionCall(result)?.id,
undefined,
"functionCall.id must be omitted for Vertex"
);
assert.equal(
findFunctionResponse(result)?.id,
undefined,
@@ -138,6 +153,9 @@ test("#3440 Claude->Gemini: vertex provider omits id from functionCall and funct
});
test("#3440 Claude->Gemini: no provider hint PRESERVES id (default, non-vertex)", () => {
const result = claudeToGeminiRequest("gemini-2.5-pro", CLAUDE_TOOL_BODY, false);
seedClaudeThoughtSignature();
const result = claudeToGeminiRequest("gemini-2.5-pro", CLAUDE_TOOL_BODY, false, {
_signatureNamespace: CLAUDE_SIGNATURE_NAMESPACE,
});
assert.equal(findFunctionCall(result)?.id, "tu_weather_1");
});