* 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>
* fix(cache): inject cache_control into system prompt for OpenRouter Anthropic
Add onPayload wrapper that injects cache_control: { type: "ephemeral" }
into the system/developer message content for OpenRouter requests routed
to Anthropic models. The system prompt is typically ~18k tokens and was
being re-processed on every request without caching.
Fixes#15151
* Changelog: add OpenRouter note for #17473
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* OpenRouter: allow any model ID instead of restricting to static catalog
OpenRouter models were restricted to a hardcoded prefix list in the internal model catalog, preventing use of newly added or less common models. This change makes OpenRouter work as the pass-through proxy it is -- any valid OpenRouter model ID now resolves dynamically.
Fixes https://github.com/openclaw/openclaw/issues/5241
Changes:
- Add OpenRouter as an implicit provider in resolveImplicitProviders so models.json is populated when an API key is detected (models-config.providers.ts)
- Add a pass-through fallback in resolveModel that creates OpenRouter models on-the-fly when they aren't pre-registered in the local catalog (
model.ts
)
- Remove the static prefix filter for OpenRouter/opencode in isModernModelRef (live-model-filter.ts)
* Apply requested change for maxTokens
* Agents: remove dead helper in live model filter
* Changelog: note Joly0/main OpenRouter fix
* Changelog: fix OpenRouter entry text
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>