diff --git a/betafile.go b/betafile.go index 8d09ee06..9b1f6afe 100644 --- a/betafile.go +++ b/betafile.go @@ -12,6 +12,7 @@ import ( "net/http" "net/url" "slices" + "strings" "time" "github.com/anthropics/anthropic-sdk-go/internal/apiform" @@ -47,8 +48,12 @@ func NewBetaFileService(opts ...option.RequestOption) (r BetaFileService) { // List Files func (r *BetaFileService) List(ctx context.Context, params BetaFileListParams, opts ...option.RequestOption) (res *pagination.Page[FileMetadata], err error) { var raw *http.Response - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14"), option.WithResponseInto(&raw)}, opts...) @@ -72,8 +77,12 @@ func (r *BetaFileService) ListAutoPaging(ctx context.Context, params BetaFileLis // Delete File func (r *BetaFileService) Delete(ctx context.Context, fileID string, body BetaFileDeleteParams, opts ...option.RequestOption) (res *DeletedFile, err error) { - for _, v := range body.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(body.Betas) > 0 { + betaStrs := make([]string, len(body.Betas)) + for i, v := range body.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14")}, opts...) @@ -88,8 +97,12 @@ func (r *BetaFileService) Delete(ctx context.Context, fileID string, body BetaFi // Download File func (r *BetaFileService) Download(ctx context.Context, fileID string, query BetaFileDownloadParams, opts ...option.RequestOption) (res *http.Response, err error) { - for _, v := range query.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(query.Betas) > 0 { + betaStrs := make([]string, len(query.Betas)) + for i, v := range query.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14"), option.WithHeader("Accept", "application/binary")}, opts...) @@ -104,8 +117,12 @@ func (r *BetaFileService) Download(ctx context.Context, fileID string, query Bet // Get File Metadata func (r *BetaFileService) GetMetadata(ctx context.Context, fileID string, query BetaFileGetMetadataParams, opts ...option.RequestOption) (res *FileMetadata, err error) { - for _, v := range query.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(query.Betas) > 0 { + betaStrs := make([]string, len(query.Betas)) + for i, v := range query.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14")}, opts...) @@ -120,8 +137,12 @@ func (r *BetaFileService) GetMetadata(ctx context.Context, fileID string, query // Upload File func (r *BetaFileService) Upload(ctx context.Context, params BetaFileUploadParams, opts ...option.RequestOption) (res *FileMetadata, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14")}, opts...) diff --git a/betamessage.go b/betamessage.go index 47bd6ee9..59dee003 100644 --- a/betamessage.go +++ b/betamessage.go @@ -8,6 +8,7 @@ import ( "fmt" "net/http" "slices" + "strings" "time" "github.com/anthropics/anthropic-sdk-go/internal/apijson" @@ -52,8 +53,12 @@ func NewBetaMessageService(opts ...option.RequestOption) (r BetaMessageService) // // Note: If you choose to set a timeout for this request, we recommend 10 minutes. func (r *BetaMessageService) New(ctx context.Context, params BetaMessageNewParams, opts ...option.RequestOption) (res *BetaMessage, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) @@ -85,8 +90,12 @@ func (r *BetaMessageService) NewStreaming(ctx context.Context, params BetaMessag raw *http.Response err error ) - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append(opts, option.WithJSONSet("stream", true)) @@ -103,8 +112,12 @@ func (r *BetaMessageService) NewStreaming(ctx context.Context, params BetaMessag // Learn more about token counting in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/token-counting) func (r *BetaMessageService) CountTokens(ctx context.Context, params BetaMessageCountTokensParams, opts ...option.RequestOption) (res *BetaMessageTokensCount, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) path := "v1/messages/count_tokens?beta=true" diff --git a/betamessage_test.go b/betamessage_test.go index 7800428f..ac5f85a1 100644 --- a/betamessage_test.go +++ b/betamessage_test.go @@ -6,7 +6,9 @@ import ( "context" "encoding/json" "errors" + "net/http" "os" + "strings" "testing" "github.com/anthropics/anthropic-sdk-go" @@ -496,3 +498,51 @@ Therefore, the answer is..."}}`, }) } } + +func TestMultipleBetaHeadersJoinedWithCommas(t *testing.T) { + var capturedHeaders http.Header + middleware := option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) { + capturedHeaders = req.Header.Clone() + return &http.Response{StatusCode: 200, Body: http.NoBody}, nil + }) + client := anthropic.NewClient( + option.WithAPIKey("test-key"), + middleware, + ) + + _, _ = client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{ + MaxTokens: 1024, + Messages: []anthropic.BetaMessageParam{{ + Content: []anthropic.BetaContentBlockParamUnion{{ + OfText: &anthropic.BetaTextBlockParam{Text: "hello"}, + }}, + Role: anthropic.BetaMessageParamRoleUser, + }}, + Model: anthropic.ModelClaudeOpus4_6, + Betas: []anthropic.AnthropicBeta{ + anthropic.AnthropicBetaMessageBatches2024_09_24, + anthropic.AnthropicBetaPromptCaching2024_07_31, + }, + }) + + if capturedHeaders == nil { + t.Fatal("Expected middleware to capture headers") + } + + betaValues := capturedHeaders.Values("Anthropic-Beta") + // The user-specified betas should be joined with commas in a single header entry + // (not sent as multiple separate header entries) + joined := false + for _, v := range betaValues { + if strings.Contains(v, ",") { + joined = true + parts := strings.Split(v, ",") + if len(parts) < 2 { + t.Fatalf("Expected at least 2 comma-separated values, got: %s", v) + } + } + } + if !joined { + t.Fatalf("Expected beta headers to be comma-separated, but got separate entries: %v", betaValues) + } +} diff --git a/betamessagebatch.go b/betamessagebatch.go index b4dc2f4f..b9019ef9 100644 --- a/betamessagebatch.go +++ b/betamessagebatch.go @@ -10,6 +10,7 @@ import ( "net/http" "net/url" "slices" + "strings" "time" "github.com/anthropics/anthropic-sdk-go/internal/apijson" @@ -51,8 +52,12 @@ func NewBetaMessageBatchService(opts ...option.RequestOption) (r BetaMessageBatc // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) New(ctx context.Context, params BetaMessageBatchNewParams, opts ...option.RequestOption) (res *BetaMessageBatch, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) @@ -68,8 +73,12 @@ func (r *BetaMessageBatchService) New(ctx context.Context, params BetaMessageBat // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) Get(ctx context.Context, messageBatchID string, query BetaMessageBatchGetParams, opts ...option.RequestOption) (res *BetaMessageBatch, err error) { - for _, v := range query.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(query.Betas) > 0 { + betaStrs := make([]string, len(query.Betas)) + for i, v := range query.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) @@ -89,8 +98,12 @@ func (r *BetaMessageBatchService) Get(ctx context.Context, messageBatchID string // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) List(ctx context.Context, params BetaMessageBatchListParams, opts ...option.RequestOption) (res *pagination.Page[BetaMessageBatch], err error) { var raw *http.Response - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24"), option.WithResponseInto(&raw)}, opts...) @@ -124,8 +137,12 @@ func (r *BetaMessageBatchService) ListAutoPaging(ctx context.Context, params Bet // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) Delete(ctx context.Context, messageBatchID string, body BetaMessageBatchDeleteParams, opts ...option.RequestOption) (res *BetaDeletedMessageBatch, err error) { - for _, v := range body.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(body.Betas) > 0 { + betaStrs := make([]string, len(body.Betas)) + for i, v := range body.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) @@ -151,8 +168,12 @@ func (r *BetaMessageBatchService) Delete(ctx context.Context, messageBatchID str // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) Cancel(ctx context.Context, messageBatchID string, body BetaMessageBatchCancelParams, opts ...option.RequestOption) (res *BetaMessageBatch, err error) { - for _, v := range body.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(body.Betas) > 0 { + betaStrs := make([]string, len(body.Betas)) + for i, v := range body.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) @@ -178,8 +199,12 @@ func (r *BetaMessageBatchService) ResultsStreaming(ctx context.Context, messageB raw *http.Response err error ) - for _, v := range query.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(query.Betas) > 0 { + betaStrs := make([]string, len(query.Betas)) + for i, v := range query.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24"), option.WithHeader("Accept", "application/x-jsonl")}, opts...) diff --git a/betamodel.go b/betamodel.go index 863a5a04..69cb0ded 100644 --- a/betamodel.go +++ b/betamodel.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" "slices" + "strings" "time" "github.com/anthropics/anthropic-sdk-go/internal/apijson" @@ -45,8 +46,12 @@ func NewBetaModelService(opts ...option.RequestOption) (r BetaModelService) { // The Models API response can be used to determine information about a specific // model or resolve a model alias to a model ID. func (r *BetaModelService) Get(ctx context.Context, modelID string, query BetaModelGetParams, opts ...option.RequestOption) (res *BetaModelInfo, err error) { - for _, v := range query.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(query.Betas) > 0 { + betaStrs := make([]string, len(query.Betas)) + for i, v := range query.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) if modelID == "" { @@ -64,8 +69,12 @@ func (r *BetaModelService) Get(ctx context.Context, modelID string, query BetaMo // use in the API. More recently released models are listed first. func (r *BetaModelService) List(ctx context.Context, params BetaModelListParams, opts ...option.RequestOption) (res *pagination.Page[BetaModelInfo], err error) { var raw *http.Response - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...) diff --git a/betaskill.go b/betaskill.go index 66f3f043..96669833 100644 --- a/betaskill.go +++ b/betaskill.go @@ -12,6 +12,7 @@ import ( "net/http" "net/url" "slices" + "strings" "github.com/anthropics/anthropic-sdk-go/internal/apiform" "github.com/anthropics/anthropic-sdk-go/internal/apijson" @@ -46,8 +47,12 @@ func NewBetaSkillService(opts ...option.RequestOption) (r BetaSkillService) { // Create Skill func (r *BetaSkillService) New(ctx context.Context, params BetaSkillNewParams, opts ...option.RequestOption) (res *BetaSkillNewResponse, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) @@ -58,8 +63,12 @@ func (r *BetaSkillService) New(ctx context.Context, params BetaSkillNewParams, o // Get Skill func (r *BetaSkillService) Get(ctx context.Context, skillID string, query BetaSkillGetParams, opts ...option.RequestOption) (res *BetaSkillGetResponse, err error) { - for _, v := range query.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(query.Betas) > 0 { + betaStrs := make([]string, len(query.Betas)) + for i, v := range query.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) @@ -75,8 +84,12 @@ func (r *BetaSkillService) Get(ctx context.Context, skillID string, query BetaSk // List Skills func (r *BetaSkillService) List(ctx context.Context, params BetaSkillListParams, opts ...option.RequestOption) (res *pagination.PageCursor[BetaSkillListResponse], err error) { var raw *http.Response - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02"), option.WithResponseInto(&raw)}, opts...) @@ -100,8 +113,12 @@ func (r *BetaSkillService) ListAutoPaging(ctx context.Context, params BetaSkillL // Delete Skill func (r *BetaSkillService) Delete(ctx context.Context, skillID string, body BetaSkillDeleteParams, opts ...option.RequestOption) (res *BetaSkillDeleteResponse, err error) { - for _, v := range body.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(body.Betas) > 0 { + betaStrs := make([]string, len(body.Betas)) + for i, v := range body.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) diff --git a/betaskillversion.go b/betaskillversion.go index 26115cc7..199245e8 100644 --- a/betaskillversion.go +++ b/betaskillversion.go @@ -12,6 +12,7 @@ import ( "net/http" "net/url" "slices" + "strings" "github.com/anthropics/anthropic-sdk-go/internal/apiform" "github.com/anthropics/anthropic-sdk-go/internal/apijson" @@ -44,8 +45,12 @@ func NewBetaSkillVersionService(opts ...option.RequestOption) (r BetaSkillVersio // Create Skill Version func (r *BetaSkillVersionService) New(ctx context.Context, skillID string, params BetaSkillVersionNewParams, opts ...option.RequestOption) (res *BetaSkillVersionNewResponse, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) @@ -60,8 +65,12 @@ func (r *BetaSkillVersionService) New(ctx context.Context, skillID string, param // Get Skill Version func (r *BetaSkillVersionService) Get(ctx context.Context, version string, params BetaSkillVersionGetParams, opts ...option.RequestOption) (res *BetaSkillVersionGetResponse, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) @@ -81,8 +90,12 @@ func (r *BetaSkillVersionService) Get(ctx context.Context, version string, param // List Skill Versions func (r *BetaSkillVersionService) List(ctx context.Context, skillID string, params BetaSkillVersionListParams, opts ...option.RequestOption) (res *pagination.PageCursor[BetaSkillVersionListResponse], err error) { var raw *http.Response - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02"), option.WithResponseInto(&raw)}, opts...) @@ -110,8 +123,12 @@ func (r *BetaSkillVersionService) ListAutoPaging(ctx context.Context, skillID st // Delete Skill Version func (r *BetaSkillVersionService) Delete(ctx context.Context, version string, params BetaSkillVersionDeleteParams, opts ...option.RequestOption) (res *BetaSkillVersionDeleteResponse, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) diff --git a/completion.go b/completion.go index beaf526c..614b07ba 100644 --- a/completion.go +++ b/completion.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "slices" + "strings" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" @@ -47,8 +48,12 @@ func NewCompletionService(opts ...option.RequestOption) (r CompletionService) { // // Note: If you choose to set a timeout for this request, we recommend 10 minutes. func (r *CompletionService) New(ctx context.Context, params CompletionNewParams, opts ...option.RequestOption) (res *Completion, err error) { - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) path := "v1/complete" @@ -71,8 +76,12 @@ func (r *CompletionService) NewStreaming(ctx context.Context, params CompletionN raw *http.Response err error ) - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append(opts, option.WithJSONSet("stream", true)) diff --git a/model.go b/model.go index 7552020c..48e1ee30 100644 --- a/model.go +++ b/model.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" "slices" + "strings" "time" "github.com/anthropics/anthropic-sdk-go/internal/apijson" @@ -45,8 +46,12 @@ func NewModelService(opts ...option.RequestOption) (r ModelService) { // The Models API response can be used to determine information about a specific // model or resolve a model alias to a model ID. func (r *ModelService) Get(ctx context.Context, modelID string, query ModelGetParams, opts ...option.RequestOption) (res *ModelInfo, err error) { - for _, v := range query.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(query.Betas) > 0 { + betaStrs := make([]string, len(query.Betas)) + for i, v := range query.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) if modelID == "" { @@ -64,8 +69,12 @@ func (r *ModelService) Get(ctx context.Context, modelID string, query ModelGetPa // use in the API. More recently released models are listed first. func (r *ModelService) List(ctx context.Context, params ModelListParams, opts ...option.RequestOption) (res *pagination.Page[ModelInfo], err error) { var raw *http.Response - for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) + if len(params.Betas) > 0 { + betaStrs := make([]string, len(params.Betas)) + for i, v := range params.Betas { + betaStrs[i] = fmt.Sprintf("%v", v) + } + opts = append(opts, option.WithHeaderAdd("anthropic-beta", strings.Join(betaStrs, ","))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)