From 08e5ca9eb15f2652cd402db70f7f83a23fb8dd3a Mon Sep 17 00:00:00 2001 From: Baller Date: Sat, 7 Mar 2026 16:58:57 -0500 Subject: [PATCH] feat: fix a tool calling issue with claude and update the oauth version (could change with newer claude code versions) Co-Authored-By: Claude Sonnet 4.6 --- pkg/agent/loop.go | 6 ++++-- pkg/providers/claude_provider.go | 26 +++++++++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index ac8da9ffd..a13d23ec3 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -486,8 +486,10 @@ func (al *AgentLoop) runLLMIteration(ctx context.Context, messages []providers.M for _, tc := range response.ToolCalls { argumentsJSON, _ := json.Marshal(tc.Arguments) assistantMsg.ToolCalls = append(assistantMsg.ToolCalls, providers.ToolCall{ - ID: tc.ID, - Type: "function", + ID: tc.ID, + Type: "function", + Name: tc.Name, + Arguments: tc.Arguments, Function: &providers.FunctionCall{ Name: tc.Name, Arguments: string(argumentsJSON), diff --git a/pkg/providers/claude_provider.go b/pkg/providers/claude_provider.go index ae6aca96d..5ef53f7e2 100644 --- a/pkg/providers/claude_provider.go +++ b/pkg/providers/claude_provider.go @@ -4,22 +4,38 @@ import ( "context" "encoding/json" "fmt" + "strings" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/option" "github.com/sipeed/picoclaw/pkg/auth" ) +// Would change with newer versions +const oauthBetaHeader = "oauth-2025-04-20" + type ClaudeProvider struct { client *anthropic.Client tokenSource func() (string, error) } -func NewClaudeProvider(token string) *ClaudeProvider { - client := anthropic.NewClient( - option.WithAuthToken(token), +func claudeClientOptions(token string) []option.RequestOption { + opts := []option.RequestOption{ option.WithBaseURL("https://api.anthropic.com"), - ) + } + if strings.HasPrefix(strings.TrimSpace(token), "sk-ant-oat") { + opts = append(opts, + option.WithAuthToken(token), + option.WithHeader("anthropic-beta", oauthBetaHeader), + ) + } else { + opts = append(opts, option.WithAPIKey(token)) + } + return opts +} + +func NewClaudeProvider(token string) *ClaudeProvider { + client := anthropic.NewClient(claudeClientOptions(token)...) return &ClaudeProvider{client: &client} } @@ -36,7 +52,7 @@ func (p *ClaudeProvider) Chat(ctx context.Context, messages []Message, tools []T if err != nil { return nil, fmt.Errorf("refreshing token: %w", err) } - opts = append(opts, option.WithAuthToken(tok)) + opts = append(opts, claudeClientOptions(tok)...) } params, err := buildClaudeParams(messages, tools, model, options)