fix(providers): populate Function field in ToolCall responses to survive session serialization
ToolCall.Name and ToolCall.Arguments are both json:"-" — they are not written to or read from JSONL session storage. The Function field (json:"function,omitempty") is the only carrier that survives a serialize/deserialize round-trip; NormalizeToolCall already knows how to restore Name and Arguments from it. Three provider parseResponse paths were creating ToolCall without setting Function, so after the first session save every tool call in history was unrecoverable: - pkg/providers/anthropic/provider.go (SDK-based Anthropic provider) - pkg/providers/common/common.go (OpenAI-compat / Azure / etc.) - pkg/providers/codex_provider.go (Codex / o-series) Fix: set Function.Name and Function.Arguments (JSON-encoded) alongside Name and Arguments in each of these parseResponse paths, matching the pattern already used by anthropic_messages, antigravity, and tool_call_extract. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0c940a4d47
commit
c5b947fff3
3 changed files with 24 additions and 0 deletions
|
|
@ -351,10 +351,18 @@ func parseResponse(resp *anthropic.Message) *LLMResponse {
|
||||||
log.Printf("anthropic: failed to decode tool call input for %q: %v", tu.Name, err)
|
log.Printf("anthropic: failed to decode tool call input for %q: %v", tu.Name, err)
|
||||||
args = map[string]any{"raw": string(tu.Input)}
|
args = map[string]any{"raw": string(tu.Input)}
|
||||||
}
|
}
|
||||||
|
argsJSON, _ := json.Marshal(args)
|
||||||
toolCalls = append(toolCalls, ToolCall{
|
toolCalls = append(toolCalls, ToolCall{
|
||||||
ID: tu.ID,
|
ID: tu.ID,
|
||||||
Name: tu.Name,
|
Name: tu.Name,
|
||||||
Arguments: args,
|
Arguments: args,
|
||||||
|
// Function must be populated so Name and Arguments survive
|
||||||
|
// JSON serialization to session storage (both fields are
|
||||||
|
// json:"-" on ToolCall; Function carries them through).
|
||||||
|
Function: &FunctionCall{
|
||||||
|
Name: tu.Name,
|
||||||
|
Arguments: string(argsJSON),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -378,10 +378,18 @@ func parseCodexResponse(resp *responses.Response) *LLMResponse {
|
||||||
if err := json.Unmarshal([]byte(item.Arguments), &args); err != nil {
|
if err := json.Unmarshal([]byte(item.Arguments), &args); err != nil {
|
||||||
args = map[string]any{"raw": item.Arguments}
|
args = map[string]any{"raw": item.Arguments}
|
||||||
}
|
}
|
||||||
|
argsJSON, _ := json.Marshal(args)
|
||||||
toolCalls = append(toolCalls, ToolCall{
|
toolCalls = append(toolCalls, ToolCall{
|
||||||
ID: item.CallID,
|
ID: item.CallID,
|
||||||
Name: item.Name,
|
Name: item.Name,
|
||||||
Arguments: args,
|
Arguments: args,
|
||||||
|
// Function must be populated so Name and Arguments survive
|
||||||
|
// JSON serialization to session storage (both fields are
|
||||||
|
// json:"-" on ToolCall; Function carries them through).
|
||||||
|
Function: &FunctionCall{
|
||||||
|
Name: item.Name,
|
||||||
|
Arguments: string(argsJSON),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -190,11 +190,19 @@ func ParseResponse(body io.Reader) (*LLMResponse, error) {
|
||||||
arguments = DecodeToolCallArguments(tc.Function.Arguments, name)
|
arguments = DecodeToolCallArguments(tc.Function.Arguments, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argsJSON, _ := json.Marshal(arguments)
|
||||||
toolCall := ToolCall{
|
toolCall := ToolCall{
|
||||||
ID: tc.ID,
|
ID: tc.ID,
|
||||||
Name: name,
|
Name: name,
|
||||||
Arguments: arguments,
|
Arguments: arguments,
|
||||||
ThoughtSignature: thoughtSignature,
|
ThoughtSignature: thoughtSignature,
|
||||||
|
// Function must be populated so Name and Arguments survive
|
||||||
|
// JSON serialization to session storage (both fields are
|
||||||
|
// json:"-" on ToolCall; Function carries them through).
|
||||||
|
Function: &FunctionCall{
|
||||||
|
Name: name,
|
||||||
|
Arguments: string(argsJSON),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if thoughtSignature != "" {
|
if thoughtSignature != "" {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue