Skip to content

Commit 8594cd1

Browse files
committed
fix(agent): change anthropic client to pointer type
Changed the anthropic client from a value type to a pointer type to better handle client initialization. This change allows for lazy initialization of the client when needed during Run() if not already provided. Added a check to initialize the client at runtime if not already set, which helps prevent nil pointer dereference errors when the agent is created without an API key initially.
1 parent 642d595 commit 8594cd1

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

internal/agent/agent.go

+13-4
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ type Status string
3838

3939
// Agent is a struct that contains the state of the agent.
4040
type Agent struct {
41-
client anthropic.Client
41+
client *anthropic.Client
4242
ctx context.Context
4343
cfg config.Configuration
4444
logger *slog.Logger
@@ -88,7 +88,8 @@ func New(opts ...Option) *Agent {
8888
}
8989

9090
if a.cfg.Anthropic.APIKey != "" {
91-
a.client = anthropic.NewClient(option.WithAPIKey(a.cfg.Anthropic.APIKey))
91+
c := anthropic.NewClient(option.WithAPIKey(a.cfg.Anthropic.APIKey))
92+
a.client = &c
9293
}
9394

9495
a.logger.WithGroup("config").With("max_tokens", a.cfg.Anthropic.MaxTokens).With("model", a.cfg.Anthropic.Model).
@@ -119,7 +120,7 @@ func WithLogger(logger *slog.Logger) Option {
119120
}
120121

121122
// WithClient sets the client for the agent.
122-
func WithClient(client anthropic.Client) Option {
123+
func WithClient(client *anthropic.Client) Option {
123124
return func(a *Agent) {
124125
a.client = client
125126
}
@@ -146,6 +147,15 @@ func (a *Agent) Run(opts *tool.RunOptions, ctx context.Context) ([]tool.Output,
146147
ctx = a.ctx
147148
}
148149

150+
// Initialize client if not already initialized
151+
if a.client == nil {
152+
if a.cfg.Anthropic.APIKey == "" {
153+
return nil, fmt.Errorf("anthropic API key is required but not provided")
154+
}
155+
c := anthropic.NewClient(option.WithAPIKey(a.cfg.Anthropic.APIKey))
156+
a.client = &c
157+
}
158+
149159
prompt, err := assets.RenderAgentSystemPrompt(&assets.AgentSystemPromptData{
150160
Shell: a.cfg.Tools.Exec.Shell,
151161
})
@@ -178,7 +188,6 @@ func (a *Agent) Run(opts *tool.RunOptions, ctx context.Context) ([]tool.Output,
178188
msg.ToolChoice = anthropic.ToolChoiceUnionParam{
179189
OfToolChoiceAuto: &anthropic.ToolChoiceAutoParam{
180190
DisableParallelToolUse: param.NewOpt(true),
181-
Type: msg.ToolChoice.OfToolChoiceAuto.Type,
182191
},
183192
}
184193
}

internal/agent/agent_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestNew(t *testing.T) {
4242
assert.NotNil(t, agent.cfg)
4343
assert.NotNil(t, agent.logger)
4444
assert.NotNil(t, agent.communication)
45-
assert.Equal(t, anthropic.Client{}, agent.client) // Check for zero value instead of nil
45+
assert.Nil(t, agent.client) // Default agent should have nil client
4646
})
4747

4848
t.Run("applies options", func(t *testing.T) {
@@ -65,13 +65,16 @@ func TestNew(t *testing.T) {
6565
assert.Equal(t, ctx, agent.ctx)
6666
assert.Equal(t, cfg, agent.cfg)
6767
assert.Equal(t, comm, agent.communication)
68+
assert.Nil(t, agent.client) // Agent without API key should have nil client
6869
})
6970

7071
t.Run("creates client when API key provided", func(t *testing.T) {
7172
cfg := config.New().GetConfig()
7273
cfg.Anthropic.APIKey = "test-key"
7374
agent := New(WithConfig(cfg))
7475
assert.NotNil(t, agent.client)
76+
// Verify client is properly initialized by checking its type
77+
assert.IsType(t, &anthropic.Client{}, agent.client)
7578
})
7679
}
7780

0 commit comments

Comments
 (0)