fix: sanitize tool call IDs in agent loop for Mistral strict9 format (#23595) (#23698)

* fix: sanitize tool call IDs in agent loop for Mistral strict9 format (#23595)

Mistral requires tool call IDs to be exactly 9 alphanumeric characters
([a-zA-Z0-9]{9}). The existing sanitizeToolCallIdsForCloudCodeAssist
mechanism only ran on historical messages at attempt start via
sanitizeSessionHistory, but the pi-agent-core agent loop's internal
tool call → tool result cycles bypassed that path entirely.

Changes:
- Wrap streamFn (like dropThinkingBlocks) so every outbound request
  sees sanitized tool call IDs when the transcript policy requires it
- Replace call_${Date.now()} in pendingToolCalls with a 9-char hex ID
  generated from crypto.randomBytes
- Add Mistral tool call ID error pattern to ERROR_PATTERNS.format so
  the error is correctly classified for retry/rotation

* Changelog: document Mistral strict9 tool-call ID fix

---------

Co-authored-by: echoVic <AkiraVic@outlook.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
青雲
2026-02-23 02:37:12 +08:00
committed by GitHub
parent 042947b944
commit 3dfee78d72
4 changed files with 31 additions and 1 deletions

View File

@@ -1,3 +1,4 @@
import { randomBytes } from "node:crypto";
import fs from "node:fs/promises";
import type { ThinkLevel } from "../../auto-reply/thinking.js";
import { generateSecureToken } from "../../infra/secure-random.js";
@@ -1122,7 +1123,7 @@ export async function runEmbeddedPiAgent(
pendingToolCalls: attempt.clientToolCall
? [
{
id: `call_${Date.now()}`,
id: randomBytes(5).toString("hex").slice(0, 9),
name: attempt.clientToolCall.name,
arguments: JSON.stringify(attempt.clientToolCall.params),
},