From 77c38626d92cf6b1e620d6707dc3295c8fcd1358 Mon Sep 17 00:00:00 2001 From: Himanshu Tiwari Date: Thu, 29 Jan 2026 11:27:33 +0800 Subject: [PATCH 1/3] Fix: File ID Format Mismatch When Switching from Gemini to OpenAI #3702 This commit addresses an issue where file IDs (or tool call IDs) originating from Gemini sessions were causing validation errors when switching to OpenAI models. OpenAI's API is stricter with ID formats (alphanumeric only) compared to Gemini. Changes: - Enable 'sanitizeToolCallIds' for OpenAI in src/agents/transcript-policy.ts. - Decouple tool call ID sanitization from the full sanitization mode check in src/agents/pi-embedded-helpers/images.ts to allow ID sanitization in 'images-only' mode. Fixes #3702 https://github.com/moltbot/moltbot/issues/3702 --- src/agents/pi-embedded-helpers/images.ts | 2 +- src/agents/transcript-policy.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/agents/pi-embedded-helpers/images.ts b/src/agents/pi-embedded-helpers/images.ts index 518226ae0..f2382e37e 100644 --- a/src/agents/pi-embedded-helpers/images.ts +++ b/src/agents/pi-embedded-helpers/images.ts @@ -45,7 +45,7 @@ export async function sanitizeSessionMessagesImages( // We sanitize historical session messages because Anthropic can reject a request // if the transcript contains oversized base64 images (see MAX_IMAGE_DIMENSION_PX). const sanitizedIds = - allowNonImageSanitization && options?.sanitizeToolCallIds + options?.sanitizeToolCallIds ? sanitizeToolCallIdsForCloudCodeAssist(messages, options.toolCallIdMode) : messages; const out: AgentMessage[] = []; diff --git a/src/agents/transcript-policy.ts b/src/agents/transcript-policy.ts index 9ae14d38f..78f9e6a37 100644 --- a/src/agents/transcript-policy.ts +++ b/src/agents/transcript-policy.ts @@ -85,7 +85,7 @@ export function resolveTranscriptPolicy(params: { const needsNonImageSanitize = isGoogle || isAnthropic || isMistral || isOpenRouterGemini; - const sanitizeToolCallIds = isGoogle || isMistral; + const sanitizeToolCallIds = isGoogle || isMistral || isOpenAi; const toolCallIdMode: ToolCallIdMode | undefined = isMistral ? "strict9" : sanitizeToolCallIds @@ -99,7 +99,7 @@ export function resolveTranscriptPolicy(params: { return { sanitizeMode: isOpenAi ? "images-only" : needsNonImageSanitize ? "full" : "images-only", - sanitizeToolCallIds: !isOpenAi && sanitizeToolCallIds, + sanitizeToolCallIds, toolCallIdMode, repairToolUseResultPairing: !isOpenAi && repairToolUseResultPairing, preserveSignatures: isAntigravityClaudeModel, From 121efe9f38ba0748fabe15e2a1f250671545b3ed Mon Sep 17 00:00:00 2001 From: Himanshu Tiwari Date: Thu, 29 Jan 2026 11:49:16 +0800 Subject: [PATCH 2/3] Style: Fix formatting in images.ts --- src/agents/pi-embedded-helpers/images.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/agents/pi-embedded-helpers/images.ts b/src/agents/pi-embedded-helpers/images.ts index f2382e37e..56841ee37 100644 --- a/src/agents/pi-embedded-helpers/images.ts +++ b/src/agents/pi-embedded-helpers/images.ts @@ -44,10 +44,9 @@ export async function sanitizeSessionMessagesImages( const allowNonImageSanitization = sanitizeMode === "full"; // We sanitize historical session messages because Anthropic can reject a request // if the transcript contains oversized base64 images (see MAX_IMAGE_DIMENSION_PX). - const sanitizedIds = - options?.sanitizeToolCallIds - ? sanitizeToolCallIdsForCloudCodeAssist(messages, options.toolCallIdMode) - : messages; + const sanitizedIds = options?.sanitizeToolCallIds + ? sanitizeToolCallIdsForCloudCodeAssist(messages, options.toolCallIdMode) + : messages; const out: AgentMessage[] = []; for (const msg of sanitizedIds) { if (!msg || typeof msg !== "object") { From b46ba8e06fb2de554df04a8198e8cea3c50ecd23 Mon Sep 17 00:00:00 2001 From: Himanshu Tiwari Date: Thu, 29 Jan 2026 12:00:12 +0800 Subject: [PATCH 3/3] Test: Update test expectation for OpenAI sanitization --- .../pi-embedded-runner.sanitize-session-history.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agents/pi-embedded-runner.sanitize-session-history.test.ts b/src/agents/pi-embedded-runner.sanitize-session-history.test.ts index b428c3328..e362113d6 100644 --- a/src/agents/pi-embedded-runner.sanitize-session-history.test.ts +++ b/src/agents/pi-embedded-runner.sanitize-session-history.test.ts @@ -94,7 +94,7 @@ describe("sanitizeSessionHistory", () => { ); }); - it("does not sanitize tool call ids for openai-responses", async () => { + it("sanitizes tool call ids for openai-responses", async () => { vi.mocked(helpers.isGoogleModelApi).mockReturnValue(false); await sanitizeSessionHistory({ @@ -108,7 +108,7 @@ describe("sanitizeSessionHistory", () => { expect(helpers.sanitizeSessionMessagesImages).toHaveBeenCalledWith( mockMessages, "session:history", - expect.objectContaining({ sanitizeMode: "images-only", sanitizeToolCallIds: false }), + expect.objectContaining({ sanitizeMode: "images-only", sanitizeToolCallIds: true }), ); });