fix(session): normalize tool call blocks for cross-provider compatibility#4719
Closed
bse-ai wants to merge 1 commit intoopenclaw:mainfrom
Closed
fix(session): normalize tool call blocks for cross-provider compatibility#4719bse-ai wants to merge 1 commit intoopenclaw:mainfrom
bse-ai wants to merge 1 commit intoopenclaw:mainfrom
Conversation
…lity
When users switch providers mid-session (e.g., from Google Antigravity to
Anthropic), the session history may contain tool call blocks in different
formats:
- Anthropic / pi-ai: `{ type: "toolCall", arguments: {} }`
- Google Antigravity: `{ type: "toolUse", input: {} }`
This mismatch causes API validation failures like "input: Field required"
when the new provider's serializer encounters the old format.
This fix adds `normalizeToolCallBlocks()` to the session sanitization
pipeline, which converts all tool call variants (toolCall, toolUse,
functionCall) to the canonical `{ type: "toolCall", arguments: {} }` shape
before sending to any provider.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This was referenced Feb 2, 2026
Comment on lines
+345
to
+350
| // Ensure `arguments` is populated — prefer existing `arguments`, fall back to `input`, default to {}. | ||
| const args = rec.arguments ?? rec.input ?? {}; | ||
| if (type === "toolCall" && rec.arguments !== undefined) return block; // already canonical | ||
|
|
||
| contentChanged = true; | ||
| return { ...rec, type: "toolCall", arguments: args }; |
Contributor
There was a problem hiding this comment.
normalizeToolCallBlocks() rewrites { type: "toolUse", input: ... } / { type: "functionCall", ... } to { type: "toolCall", arguments: ... } but leaves the original provider-specific field (input) in place via { ...rec, ... }. If the goal is cross-provider validation, some serializers will still reject type: "toolCall" blocks that include unknown fields like input.
Consider deleting input when normalizing (and similarly any other variant-only keys) so the resulting block matches the canonical schema exactly.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/google.ts
Line: 345:350
Comment:
`normalizeToolCallBlocks()` rewrites `{ type: "toolUse", input: ... }` / `{ type: "functionCall", ... }` to `{ type: "toolCall", arguments: ... }` but leaves the original provider-specific field (`input`) in place via `{ ...rec, ... }`. If the goal is cross-provider validation, some serializers will still reject `type: "toolCall"` blocks that include unknown fields like `input`.
Consider deleting `input` when normalizing (and similarly any other variant-only keys) so the resulting block matches the canonical schema exactly.
How can I resolve this? If you propose a fix, please make it concise.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
normalizeToolCallBlocks()to convert all tool call variants to canonical formattoolCall,toolUse, andfunctionCallblock typesProblem
When users switch providers mid-session, the session history may contain tool call blocks in different formats:
{ type: "toolCall", arguments: {} }{ type: "toolUse", input: {} }This mismatch causes the new provider's serializer to reject requests with validation errors.
Solution
Added
normalizeToolCallBlocks()to the session sanitization pipeline insanitizeSessionHistory(). It:toolCall,toolUse,functionCall){ type: "toolCall", arguments: {} }shapeTest plan
🤖 Generated with Claude Code
Greptile Overview
Greptile Summary
This PR adds
normalizeToolCallBlocks()tosanitizeSessionHistory()insrc/agents/pi-embedded-runner/google.tsto rewrite provider-specific tool-call content blocks (toolUse,functionCall) into a canonical{ type: "toolCall", arguments: ... }shape. The intent is to prevent cross-provider API validation failures when a session history recorded under one provider is later serialized for another (e.g., switching from Google Antigravity to Anthropic).Confidence Score: 3/5
inputon atoolCall) can still trigger validation errors in the exact scenario this PR targets.(4/5) You can add custom instructions or style guidelines for the agent here!