diff --git a/pkg/providers/anthropic/provider.go b/pkg/providers/anthropic/provider.go index 242ded175..87beae99a 100644 --- a/pkg/providers/anthropic/provider.go +++ b/pkg/providers/anthropic/provider.go @@ -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) args = map[string]any{"raw": string(tu.Input)} } + argsJSON, _ := json.Marshal(args) toolCalls = append(toolCalls, ToolCall{ ID: tu.ID, Name: tu.Name, 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), + }, }) } } diff --git a/pkg/providers/codex_provider.go b/pkg/providers/codex_provider.go index cf5c2d876..a88535ded 100644 --- a/pkg/providers/codex_provider.go +++ b/pkg/providers/codex_provider.go @@ -378,10 +378,18 @@ func parseCodexResponse(resp *responses.Response) *LLMResponse { if err := json.Unmarshal([]byte(item.Arguments), &args); err != nil { args = map[string]any{"raw": item.Arguments} } + argsJSON, _ := json.Marshal(args) toolCalls = append(toolCalls, ToolCall{ ID: item.CallID, Name: item.Name, 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), + }, }) } } diff --git a/pkg/providers/common/common.go b/pkg/providers/common/common.go index 23680a1bf..04b011cb0 100644 --- a/pkg/providers/common/common.go +++ b/pkg/providers/common/common.go @@ -190,11 +190,19 @@ func ParseResponse(body io.Reader) (*LLMResponse, error) { arguments = DecodeToolCallArguments(tc.Function.Arguments, name) } + argsJSON, _ := json.Marshal(arguments) toolCall := ToolCall{ ID: tc.ID, Name: name, Arguments: arguments, 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 != "" {