@@ -21,12 +21,20 @@ import (
22type anthropicClient struct {
22type anthropicClient struct {
23 providerOptions providerClientOptions
23 providerOptions providerClientOptions
24 client anthropic.Client
25 client anthropic.Client
27type AnthropicClient ProviderClient
28type AnthropicClient ProviderClient
29func newAnthropicClient(opts providerClientOptions, useBedrock bool) AnthropicClient {
30func newAnthropicClient(opts providerClientOptions, useBedrock bool) AnthropicClient {
31+ return &anthropicClient{
32+ providerOptions: opts,
33+ client: createAnthropicClient(opts, useBedrock),
37+func createAnthropicClient(opts providerClientOptions, useBedrock bool) anthropic.Client {
30 anthropicClientOptions := []option.RequestOption{}
38 anthropicClientOptions := []option.RequestOption{}
31 if opts.apiKey != "" {
39 if opts.apiKey != "" {
32 anthropicClientOptions = append(anthropicClientOptions, option.WithAPIKey(opts.apiKey))
40 anthropicClientOptions = append(anthropicClientOptions, option.WithAPIKey(opts.apiKey))
@@ -34,12 +42,7 @@ func newAnthropicClient(opts providerClientOptions, useBedrock bool) AnthropicCl
34 if useBedrock {
42 if useBedrock {
35 anthropicClientOptions = append(anthropicClientOptions, bedrock.WithLoadDefaultConfig(context.Background()))
43 anthropicClientOptions = append(anthropicClientOptions, bedrock.WithLoadDefaultConfig(context.Background()))
38− client := anthropic.NewClient(anthropicClientOptions...)
45+ return anthropic.NewClient(anthropicClientOptions...)
39− return &anthropicClient{
40− providerOptions: opts,
45func (a *anthropicClient) convertMessages(messages []message.Message) (anthropicMessages []anthropic.MessageParam) {
48func (a *anthropicClient) convertMessages(messages []message.Message) (anthropicMessages []anthropic.MessageParam) {
@@ -385,12 +388,21 @@ func (a *anthropicClient) stream(ctx context.Context, messages []message.Message
387func (a *anthropicClient) shouldRetry(attempts int, err error) (bool, int64, error) {
390func (a *anthropicClient) shouldRetry(attempts int, err error) (bool, int64, error) {
388− var apierr *anthropic.Error
391+ var apiErr *anthropic.Error
389− if !errors.As(err, &apierr) {
392+ if !errors.As(err, &apiErr) {
390 return false, 0, err
393 return false, 0, err
396+ if apiErr.StatusCode == 401 {
397+ a.providerOptions.apiKey, err = config.ResolveAPIKey(a.providerOptions.config.APIKey)
399+ return false, 0, fmt.Errorf("failed to resolve API key: %w", err)
401+ a.client = createAnthropicClient(a.providerOptions, a.useBedrock)
393− if apierr.StatusCode != 429 && apierr.StatusCode != 529 {
405+ if apiErr.StatusCode != 429 && apiErr.StatusCode != 529 {
394 return false, 0, err
406 return false, 0, err
@@ -399,7 +411,7 @@ func (a *anthropicClient) shouldRetry(attempts int, err error) (bool, int64, err
401 retryMs := 0
413 retryMs := 0
402− retryAfterValues := apierr.Response.Header.Values("Retry-After")
414+ retryAfterValues := apiErr.Response.Header.Values("Retry-After")
404 backoffMs := 2000 * (1 << (attempts - 1))
416 backoffMs := 2000 * (1 << (attempts - 1))
405 jitterMs := int(float64(backoffMs) * 0.2)
417 jitterMs := int(float64(backoffMs) * 0.2)