diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42f692c81..6ede0d7c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup go uses: actions/setup-go@v5 @@ -35,7 +35,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/anthropic-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup go uses: actions/setup-go@v5 diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 000000000..79fe05647 --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,50 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. + # prompt: 'Update the pull request description to include a summary of changes.' + + # Optional: Add claude_args to customize behavior and configuration + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + # claude_args: '--allowed-tools Bash(gh pr:*)' + diff --git a/.github/workflows/create-releases.yml b/.github/workflows/create-releases.yml index fd1aaa369..2450ae455 100644 --- a/.github/workflows/create-releases.yml +++ b/.github/workflows/create-releases.yml @@ -14,7 +14,7 @@ jobs: environment: production-release steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: stainless-api/trigger-release-please@v1 id: release diff --git a/.github/workflows/detect-breaking-changes.yml b/.github/workflows/detect-breaking-changes.yml index 4e60e2b60..79db05261 100644 --- a/.github/workflows/detect-breaking-changes.yml +++ b/.github/workflows/detect-breaking-changes.yml @@ -15,7 +15,7 @@ jobs: run: | echo "FETCH_DEPTH=$(expr ${{ github.event.pull_request.commits }} + 1)" >> $GITHUB_ENV - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: # Ensure we can check out the pull request base in the script below. fetch-depth: ${{ env.FETCH_DEPTH }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2ef9a1c2e..f97891a67 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.14.0" + ".": "1.26.0" } diff --git a/.stats.yml b/.stats.yml index 0ada1d296..be9d17c3b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 26 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-c91c0b5257f197335770ca7195d6b56e5808bf90d40580ca833095dfe56d2954.yml -openapi_spec_hash: 592d90505082223899e0638ad56ba162 -config_hash: 24ad78f46908cfe5b81c053facaf4194 +configured_endpoints: 34 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-29a6b7ba51942cd606e5bf4b533e5aac1bef42f6d4b1f7f45f756304cf676782.yml +openapi_spec_hash: 58021ab18daccd5c45a930ffd7d6ab4d +config_hash: 4e204fead5f0af80eb9effa1d1e34dca diff --git a/CHANGELOG.md b/CHANGELOG.md index 79bbfa223..70f89c502 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,183 @@ # Changelog +## 1.26.0 (2026-02-19) + +Full Changelog: [v1.25.1...v1.26.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.25.1...v1.26.0) + +### Features + +* **api:** Add top-level cache control (automatic caching) ([75f9f70](https://github.com/anthropics/anthropic-sdk-go/commit/75f9f70045587c458ec2e3491b4eb88bc3329e9e)) +* **client:** add BetaToolRunner for automatic tool use loops ([#603](https://github.com/anthropics/anthropic-sdk-go/issues/603)) ([e44128a](https://github.com/anthropics/anthropic-sdk-go/commit/e44128a1a3c1d9b4710b4a024ace8121258b32b6)) + + +### Chores + +* **internal:** codegen related update ([6247d2f](https://github.com/anthropics/anthropic-sdk-go/commit/6247d2febe87242ee9d3ba49875ff62a5be9a626)) + +## 1.25.1 (2026-02-19) + +Full Changelog: [v1.25.0...v1.25.1](https://github.com/anthropics/anthropic-sdk-go/compare/v1.25.0...v1.25.1) + +### Bug Fixes + +* **client:** use correct format specifier for header serialization ([9115a61](https://github.com/anthropics/anthropic-sdk-go/commit/9115a6154d0b1ba94370911822986b2ef8584e9a)) + +## 1.25.0 (2026-02-18) + +Full Changelog: [v1.24.0...v1.25.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.24.0...v1.25.0) + +### Features + +* **api:** fix shared UserLocation and error code types ([cb98cd0](https://github.com/anthropics/anthropic-sdk-go/commit/cb98cd00c359c0181d7b39bdb057e7b06015aa33)) + +## 1.24.0 (2026-02-18) + +Full Changelog: [v1.23.0...v1.24.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.23.0...v1.24.0) + +### Features + +* **api:** manual updates ([54d01f5](https://github.com/anthropics/anthropic-sdk-go/commit/54d01f5187ef9ec49f803edfe643bf1bf1e91072)) + +## 1.23.0 (2026-02-17) + +Full Changelog: [v1.22.1...v1.23.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.22.1...v1.23.0) + +### Features + +* **api:** Releasing claude-sonnet-4-6 ([782d5a5](https://github.com/anthropics/anthropic-sdk-go/commit/782d5a5dc4c1f63cfef3afc5d257b08f8cf3fadc)) + + +### Bug Fixes + +* **api:** fix spec errors ([15e6a5a](https://github.com/anthropics/anthropic-sdk-go/commit/15e6a5a0b4fb426f126f7b26b087709ea7ba00ac)) +* remove duplicate ServerToolUseBlock struct declaration ([#595](https://github.com/anthropics/anthropic-sdk-go/issues/595)) ([d4ece8a](https://github.com/anthropics/anthropic-sdk-go/commit/d4ece8ae310dd0369a5ea05671295ae2c23a53d9)) + +## 1.22.1 (2026-02-10) + +Full Changelog: [v1.22.0...v1.22.1](https://github.com/anthropics/anthropic-sdk-go/compare/v1.22.0...v1.22.1) + +### Bug Fixes + +* **encoder:** correctly serialize NullStruct ([1435f8a](https://github.com/anthropics/anthropic-sdk-go/commit/1435f8ac4d272561c7e689cc6bb4e3794414ba57)) + +## 1.22.0 (2026-02-07) + +Full Changelog: [v1.21.0...v1.22.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.21.0...v1.22.0) + +### Features + +* **api:** enabling fast-mode in claude-opus-4-6 ([ebe6433](https://github.com/anthropics/anthropic-sdk-go/commit/ebe6433768cab86dcc02b71159aaa347a8d473ec)) + +## 1.21.0 (2026-02-05) + +Full Changelog: [v1.20.0...v1.21.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.20.0...v1.21.0) + +### Features + +* **api:** Release Claude Opus 4.6, adaptive thinking, and other features ([e899e64](https://github.com/anthropics/anthropic-sdk-go/commit/e899e64cd402eb004909d632e68acc4b0587f53c)) + + +### Chores + +* **ci:** remove claude-code-review workflow ([31db702](https://github.com/anthropics/anthropic-sdk-go/commit/31db70249f691b161f326f550dc26cdcce54dd30)) + +## 1.20.0 (2026-01-29) + +Full Changelog: [v1.19.0...v1.20.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.19.0...v1.20.0) + +### Features + +* **api:** add support for Structured Outputs in the Messages API ([10c3821](https://github.com/anthropics/anthropic-sdk-go/commit/10c382188df98d7b045aec525bdc47f3df25d576)) +* **api:** migrate sending message format in output_config rather than output_format ([f996db4](https://github.com/anthropics/anthropic-sdk-go/commit/f996db402bc1f868b11d877014a6c51d977c557f)) +* **client:** add a convenient param.SetJSON helper ([427514e](https://github.com/anthropics/anthropic-sdk-go/commit/427514ea6dde81f4eb374967577b5a4cf380f627)) +* **encoder:** support bracket encoding form-data object members ([eaaeadf](https://github.com/anthropics/anthropic-sdk-go/commit/eaaeadf6dd67119ca4406f0fb0337c16d9011b8f)) + + +### Bug Fixes + +* **accumulator:** revert to marshal accumulator on stop events ([#563](https://github.com/anthropics/anthropic-sdk-go/issues/563)) ([096a8a8](https://github.com/anthropics/anthropic-sdk-go/commit/096a8a8b20b530359c214e06272938bcf8a98c59)) +* **client:** retain streaming when user sets request body ([6d073fe](https://github.com/anthropics/anthropic-sdk-go/commit/6d073fe49f351c26c7f3fa8337e661c6a3600c68)) +* **docs:** add missing pointer prefix to api.md return types ([23aaf6d](https://github.com/anthropics/anthropic-sdk-go/commit/23aaf6de59f0c13c79dbe4fc1d764b47cfd83834)) +* **mcp:** correct code tool API endpoint ([6c8a083](https://github.com/anthropics/anthropic-sdk-go/commit/6c8a0831e6f084d316179a9288c4fa1c5420ea59)) +* rename param to avoid collision ([6d1cf75](https://github.com/anthropics/anthropic-sdk-go/commit/6d1cf75d5a407d5eb19c70e3778ab82bca74d0d5)) +* streaming endpoints should pass through errors correctly ([e584c87](https://github.com/anthropics/anthropic-sdk-go/commit/e584c87ec001ee8991ca17b8236a6ef3deb78ea7)) +* **to-param:** remove panics and add cases ([#524](https://github.com/anthropics/anthropic-sdk-go/issues/524)) ([f689816](https://github.com/anthropics/anthropic-sdk-go/commit/f6898163047854d39cec7c08ec5ab993bab463fc)) + + +### Chores + +* add float64 to valid types for RegisterFieldValidator ([b6bec73](https://github.com/anthropics/anthropic-sdk-go/commit/b6bec73c5ed18698884b990fc3dc6398a3784177)) +* **ci:** Add Claude Code GitHub Workflow ([a151836](https://github.com/anthropics/anthropic-sdk-go/commit/a151836056343974d15eda64180fc776ba0f169d)) +* **client:** improve example values ([8af69b8](https://github.com/anthropics/anthropic-sdk-go/commit/8af69b851f4a60334ed75542c2eacbe69c01893c)) +* **client:** mark claude-3-5-haiku as deprecated ([dcac65c](https://github.com/anthropics/anthropic-sdk-go/commit/dcac65c8dd82f232c2997456319c16357874f37b)) +* elide duplicate aliases ([c8e2ee1](https://github.com/anthropics/anthropic-sdk-go/commit/c8e2ee14de53b5636eadccb2a890e4464e30b8d4)) +* **internal:** codegen related update ([931c976](https://github.com/anthropics/anthropic-sdk-go/commit/931c9769f1ff0557a8eff333463e1847b15f7953)) +* **internal:** update `actions/checkout` version ([3bd83ec](https://github.com/anthropics/anthropic-sdk-go/commit/3bd83eca53f1ec0b759c2568601286405821dcbc)) +* **internal:** use different example values for some enums ([f2d46b8](https://github.com/anthropics/anthropic-sdk-go/commit/f2d46b87de1a57ed1790cad3134b5e340f22fd73)) + +## 1.19.0 (2025-11-24) + +Full Changelog: [v1.18.1...v1.19.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.18.1...v1.19.0) + +### Features + +* **api:** adds support for Claude Opus 4.5, Effort, Advance Tool Use Features, Autocompaction, and Computer Use v5 ([a03391c](https://github.com/anthropics/anthropic-sdk-go/commit/a03391cb00b8c78c79fd8bfe447f00d78f37db25)) + +## 1.18.1 (2025-11-19) + +Full Changelog: [v1.18.0...v1.18.1](https://github.com/anthropics/anthropic-sdk-go/compare/v1.18.0...v1.18.1) + +### Bug Fixes + +* **structured outputs:** use correct beta header ([09ec0a6](https://github.com/anthropics/anthropic-sdk-go/commit/09ec0a647b1a108bb7c74e4c7b1016502ca781bb)) + +## 1.18.0 (2025-11-14) + +Full Changelog: [v1.17.0...v1.18.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.17.0...v1.18.0) + +### Features + +* **api:** add support for structured outputs beta ([fb9cfb4](https://github.com/anthropics/anthropic-sdk-go/commit/fb9cfb4e4b571d5fec7da9874610aa8820aee80c)) + + +### Chores + +* bump gjson version ([69b5e0e](https://github.com/anthropics/anthropic-sdk-go/commit/69b5e0e40757884bece66397fb6ca769f4e00118)) + +## 1.17.0 (2025-11-05) + +Full Changelog: [v1.16.0...v1.17.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.16.0...v1.17.0) + +### Features + +* **bedrock:** re-route beta headers through request body ([00a2bf3](https://github.com/anthropics/anthropic-sdk-go/commit/00a2bf35b34aa49f1514493cf0638b467c4f4eec)) + + +### Chores + +* **internal:** grammar fix (it's -> its) ([687bc29](https://github.com/anthropics/anthropic-sdk-go/commit/687bc299cacb84349eb2684df46994c06f9ba962)) + +## 1.16.0 (2025-10-29) + +Full Changelog: [v1.15.0...v1.16.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.15.0...v1.16.0) + +### Features + +* **api:** add ability to clear thinking in context management ([6082754](https://github.com/anthropics/anthropic-sdk-go/commit/6082754e9b6a04570a93efdb5339853c71f1fe94)) + +## 1.15.0 (2025-10-28) + +Full Changelog: [v1.14.0...v1.15.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.14.0...v1.15.0) + +### Features + +* **api:** adding support for agent skills ([5660b52](https://github.com/anthropics/anthropic-sdk-go/commit/5660b5252a4de07f3343c9089b148b16cda794d4)) + + +### Chores + +* **api:** mark older sonnet models as deprecated ([f13c5bd](https://github.com/anthropics/anthropic-sdk-go/commit/f13c5bd18ebb169c59913985537ca025634ef7eb)) + ## 1.14.0 (2025-10-15) Full Changelog: [v1.13.0...v1.14.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.13.0...v1.14.0) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b3a9597fc..b34f0dd66 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,8 +49,7 @@ $ go mod edit -replace github.com/anthropics/anthropic-sdk-go=/path/to/anthropic Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. ```sh -# you will need npm installed -$ npx prism mock path/to/your/openapi.yml +$ ./scripts/mock ``` ```sh diff --git a/README.md b/README.md index 7fda99c8b..232bf611c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Or to pin the version: ```sh -go get -u 'github.com/anthropics/anthropic-sdk-go@v1.14.0' +go get -u 'github.com/anthropics/anthropic-sdk-go@v1.26.0' ``` @@ -230,7 +230,7 @@ func main() { case anthropic.ToolUseBlock: print(color("[user (" + block.Name + ")]: ")) - var response interface{} + var response any switch block.Name { case "get_coordinates": var input struct { @@ -302,6 +302,71 @@ func color(s string) string { +
+Tool helpers + +The SDK provides helper functions for defining tools and running automatic conversation loops. Here's a basic example: + +```go +package main + +import ( + "context" + "fmt" + + "github.com/anthropics/anthropic-sdk-go" + "github.com/anthropics/anthropic-sdk-go/toolrunner" +) + +// GetWeatherInput defines the tool input with jsonschema tags for automatic schema generation +type GetWeatherInput struct { + City string `json:"city" jsonschema:"required,description=The city name"` +} + +func main() { + client := anthropic.NewClient() + + // Define a tool - the schema is generated automatically from the struct's jsonschema tags + weatherTool, err := toolrunner.NewBetaToolFromJSONSchema( + "get_weather", + "Get weather for a city", + func(ctx context.Context, input GetWeatherInput) (anthropic.BetaToolResultBlockParamContentUnion, error) { + return anthropic.BetaToolResultBlockParamContentUnion{ + OfText: &anthropic.BetaTextBlockParam{ + Text: fmt.Sprintf("The weather in %s is sunny, 72°F", input.City), + }, + }, nil + }, + ) + if err != nil { + panic(err) + } + + // Create a tool runner that automatically handles the conversation loop + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{weatherTool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaudeSonnet4_20250514, + MaxTokens: 1024, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What's the weather in Paris?")), + }, + }, + MaxIterations: 5, + }) + + // Run until Claude produces a final response + message, err := runner.RunToCompletion(context.Background()) + if err != nil { + panic(err) + } + fmt.Println(message.Content[0].Text) +} +``` + +For more details, see [tools.md](tools.md). + +
+ ### Request fields The anthropic library uses the [`omitzero`](https://tip.golang.org/doc/go1.24#encodingjsonpkgencodingjson) @@ -365,7 +430,7 @@ custom := param.Override[anthropic.FooParams](12) ### Request unions -Unions are represented as a struct with fields prefixed by "Of" for each of it's variants, +Unions are represented as a struct with fields prefixed by "Of" for each of its variants, only one field can be non-zero. The non-zero field will be serialized. Sub-properties of the union can be accessed via methods on the union struct. @@ -571,9 +636,9 @@ _, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, @@ -610,7 +675,9 @@ client.Messages.New( MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfRequestTextBlock: &anthropic.TextBlockParam{Text: "What is a quaternion?"}, + OfText: &anthropic.TextBlockParam{ + Text: "What is a quaternion?", + }, }}, Role: anthropic.MessageParamRoleUser, }}, @@ -680,7 +747,9 @@ client.Messages.New( MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfRequestTextBlock: &anthropic.TextBlockParam{Text: "What is a quaternion?"}, + OfText: &anthropic.TextBlockParam{ + Text: "What is a quaternion?", + }, }}, Role: anthropic.MessageParamRoleUser, }}, @@ -704,9 +773,9 @@ message, err := client.Messages.New( MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, @@ -835,7 +904,56 @@ func main() { If you already have an `aws.Config`, you can also use it directly with `bedrock.WithConfig(cfg)`. -Read more about Anthropic and Amazon Bedrock [here](https://docs.anthropic.com/en/api/claude-on-amazon-bedrock). +### Bearer Token Authentication + +You can also authenticate with Bedrock using bearer tokens instead of AWS credentials. This is useful in corporate environments where teams need access to Bedrock without managing AWS credentials, IAM roles, or account-level permissions. + +The simplest approach is to set the `AWS_BEARER_TOKEN_BEDROCK` environment variable: + +```go +package main + +import ( + "context" + + "github.com/anthropics/anthropic-sdk-go" + "github.com/anthropics/anthropic-sdk-go/bedrock" +) + +func main() { + // Automatically uses AWS_BEARER_TOKEN_BEDROCK from the environment. + // Region defaults to us-east-1 or uses AWS_REGION if set. + client := anthropic.NewClient( + bedrock.WithLoadDefaultConfig(context.Background()), + ) +} +``` + +To provide a token programmatically, use `bedrock.WithConfig` with a `BearerAuthTokenProvider`: + +```go +package main + +import ( + "context" + + "github.com/anthropics/anthropic-sdk-go" + "github.com/anthropics/anthropic-sdk-go/bedrock" + "github.com/aws/aws-sdk-go-v2/aws" +) + +func main() { + cfg := aws.Config{ + Region: "us-west-2", + BearerAuthTokenProvider: bedrock.NewStaticBearerTokenProvider("your-bearer-token"), + } + client := anthropic.NewClient( + bedrock.WithConfig(cfg), + ) +} +``` + +Read more about Anthropic and Amazon Bedrock [here](https://docs.anthropic.com/en/api/claude-on-amazon-bedrock) and about Bedrock API keys [here](https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys-use.html). ## Google Vertex AI diff --git a/aliases.go b/aliases.go index fba352eab..88ebc02cc 100644 --- a/aliases.go +++ b/aliases.go @@ -48,3 +48,25 @@ type PermissionError = shared.PermissionError // This is an alias to an internal type. type RateLimitError = shared.RateLimitError + +// Backward-compatible type aliases for renamed types. +// These ensure existing code continues to compile after +// UserLocation and ErrorCode types were consolidated. + +type WebSearchToolRequestErrorErrorCode = WebSearchToolResultErrorCode +type WebSearchToolResultErrorErrorCode = WebSearchToolResultErrorCode +type WebSearchTool20250305UserLocationParam = UserLocationParam +type WebSearchTool20260209UserLocationParam = UserLocationParam + +const WebSearchToolRequestErrorErrorCodeInvalidToolInput = WebSearchToolResultErrorCodeInvalidToolInput +const WebSearchToolRequestErrorErrorCodeUnavailable = WebSearchToolResultErrorCodeUnavailable +const WebSearchToolRequestErrorErrorCodeMaxUsesExceeded = WebSearchToolResultErrorCodeMaxUsesExceeded +const WebSearchToolRequestErrorErrorCodeTooManyRequests = WebSearchToolResultErrorCodeTooManyRequests +const WebSearchToolRequestErrorErrorCodeQueryTooLong = WebSearchToolResultErrorCodeQueryTooLong +const WebSearchToolRequestErrorErrorCodeRequestTooLarge = WebSearchToolResultErrorCodeRequestTooLarge +const WebSearchToolResultErrorErrorCodeInvalidToolInput = WebSearchToolResultErrorCodeInvalidToolInput +const WebSearchToolResultErrorErrorCodeUnavailable = WebSearchToolResultErrorCodeUnavailable +const WebSearchToolResultErrorErrorCodeMaxUsesExceeded = WebSearchToolResultErrorCodeMaxUsesExceeded +const WebSearchToolResultErrorErrorCodeTooManyRequests = WebSearchToolResultErrorCodeTooManyRequests +const WebSearchToolResultErrorErrorCodeQueryTooLong = WebSearchToolResultErrorCodeQueryTooLong +const WebSearchToolResultErrorErrorCodeRequestTooLarge = WebSearchToolResultErrorCodeRequestTooLarge diff --git a/api.md b/api.md index 970021d1c..4ee4ec972 100644 --- a/api.md +++ b/api.md @@ -18,6 +18,11 @@ Params Types: - anthropic.Base64ImageSourceParam - anthropic.Base64PDFSourceParam +- anthropic.BashCodeExecutionOutputBlockParam +- anthropic.BashCodeExecutionResultBlockParam +- anthropic.BashCodeExecutionToolResultBlockParam +- anthropic.BashCodeExecutionToolResultErrorCode +- anthropic.BashCodeExecutionToolResultErrorParam - anthropic.CacheControlEphemeralParam - anthropic.CitationCharLocationParam - anthropic.CitationContentBlockLocationParam @@ -25,22 +30,46 @@ Params Types: - anthropic.CitationSearchResultLocationParam - anthropic.CitationWebSearchResultLocationParam - anthropic.CitationsConfigParam +- anthropic.CodeExecutionOutputBlockParam +- anthropic.CodeExecutionResultBlockParam +- anthropic.CodeExecutionTool20250522Param +- anthropic.CodeExecutionTool20250825Param +- anthropic.CodeExecutionTool20260120Param +- anthropic.CodeExecutionToolResultBlockParam +- anthropic.CodeExecutionToolResultBlockParamContentUnion +- anthropic.CodeExecutionToolResultErrorCode +- anthropic.CodeExecutionToolResultErrorParam +- anthropic.ContainerUploadBlockParam - anthropic.ContentBlockParamUnion - anthropic.ContentBlockSourceParam - anthropic.ContentBlockSourceContentItemUnionParam +- anthropic.DirectCallerParam - anthropic.DocumentBlockParam +- anthropic.EncryptedCodeExecutionResultBlockParam - anthropic.ImageBlockParam +- anthropic.JSONOutputFormatParam +- anthropic.MemoryTool20250818Param - anthropic.MessageCountTokensToolUnionParam - anthropic.MessageParam - anthropic.MetadataParam - anthropic.Model +- anthropic.OutputConfigParam - anthropic.PlainTextSourceParam - anthropic.RedactedThinkingBlockParam - anthropic.SearchResultBlockParam +- anthropic.ServerToolCallerParam +- anthropic.ServerToolCaller20260120Param - anthropic.ServerToolUseBlockParam - anthropic.TextBlockParam - anthropic.TextCitationParamUnion +- anthropic.TextEditorCodeExecutionCreateResultBlockParam +- anthropic.TextEditorCodeExecutionStrReplaceResultBlockParam +- anthropic.TextEditorCodeExecutionToolResultBlockParam +- anthropic.TextEditorCodeExecutionToolResultErrorCode +- anthropic.TextEditorCodeExecutionToolResultErrorParam +- anthropic.TextEditorCodeExecutionViewResultBlockParam - anthropic.ThinkingBlockParam +- anthropic.ThinkingConfigAdaptiveParam - anthropic.ThinkingConfigDisabledParam - anthropic.ThinkingConfigEnabledParam - anthropic.ThinkingConfigParamUnion @@ -51,7 +80,14 @@ Params Types: - anthropic.ToolChoiceAutoParam - anthropic.ToolChoiceNoneParam - anthropic.ToolChoiceToolParam +- anthropic.ToolReferenceBlockParam - anthropic.ToolResultBlockParam +- anthropic.ToolSearchToolBm25_20251119Param +- anthropic.ToolSearchToolRegex20251119Param +- anthropic.ToolSearchToolResultBlockParam +- anthropic.ToolSearchToolResultErrorCode +- anthropic.ToolSearchToolResultErrorParam +- anthropic.ToolSearchToolSearchResultBlockParam - anthropic.ToolTextEditor20250124Param - anthropic.ToolTextEditor20250429Param - anthropic.ToolTextEditor20250728Param @@ -59,27 +95,55 @@ Params Types: - anthropic.ToolUseBlockParam - anthropic.URLImageSourceParam - anthropic.URLPDFSourceParam +- anthropic.UserLocationParam +- anthropic.WebFetchBlockParam +- anthropic.WebFetchTool20250910Param +- anthropic.WebFetchTool20260209Param +- anthropic.WebFetchToolResultBlockParam +- anthropic.WebFetchToolResultErrorBlockParam +- anthropic.WebFetchToolResultErrorCode - anthropic.WebSearchResultBlockParam - anthropic.WebSearchTool20250305Param +- anthropic.WebSearchTool20260209Param - anthropic.WebSearchToolRequestErrorParam - anthropic.WebSearchToolResultBlockParam - anthropic.WebSearchToolResultBlockParamContentUnion +- anthropic.WebSearchToolResultErrorCode Response Types: +- anthropic.Base64PDFSource +- anthropic.BashCodeExecutionOutputBlock +- anthropic.BashCodeExecutionResultBlock +- anthropic.BashCodeExecutionToolResultBlock +- anthropic.BashCodeExecutionToolResultError +- anthropic.BashCodeExecutionToolResultErrorCode - anthropic.CacheCreation - anthropic.CitationCharLocation - anthropic.CitationContentBlockLocation - anthropic.CitationPageLocation +- anthropic.CitationsConfig - anthropic.CitationsDelta - anthropic.CitationsSearchResultLocation - anthropic.CitationsWebSearchResultLocation +- anthropic.CodeExecutionOutputBlock +- anthropic.CodeExecutionResultBlock +- anthropic.CodeExecutionToolResultBlock +- anthropic.CodeExecutionToolResultBlockContentUnion +- anthropic.CodeExecutionToolResultError +- anthropic.CodeExecutionToolResultErrorCode +- anthropic.Container +- anthropic.ContainerUploadBlock - anthropic.ContentBlockUnion +- anthropic.DirectCaller +- anthropic.DocumentBlock +- anthropic.EncryptedCodeExecutionResultBlock - anthropic.InputJSONDelta - anthropic.Message - anthropic.MessageDeltaUsage - anthropic.MessageTokensCount - anthropic.Model +- anthropic.PlainTextSource - anthropic.RawContentBlockDeltaUnion - anthropic.ContentBlockDeltaEvent - anthropic.ContentBlockStartEvent @@ -89,6 +153,8 @@ Response Types: - anthropic.MessageStopEvent - anthropic.MessageStreamEventUnion - anthropic.RedactedThinkingBlock +- anthropic.ServerToolCaller +- anthropic.ServerToolCaller20260120 - anthropic.ServerToolUsage - anthropic.ServerToolUseBlock - anthropic.SignatureDelta @@ -96,19 +162,35 @@ Response Types: - anthropic.TextBlock - anthropic.TextCitationUnion - anthropic.TextDelta +- anthropic.TextEditorCodeExecutionCreateResultBlock +- anthropic.TextEditorCodeExecutionStrReplaceResultBlock +- anthropic.TextEditorCodeExecutionToolResultBlock +- anthropic.TextEditorCodeExecutionToolResultError +- anthropic.TextEditorCodeExecutionToolResultErrorCode +- anthropic.TextEditorCodeExecutionViewResultBlock - anthropic.ThinkingBlock - anthropic.ThinkingDelta +- anthropic.ToolReferenceBlock +- anthropic.ToolSearchToolResultBlock +- anthropic.ToolSearchToolResultError +- anthropic.ToolSearchToolResultErrorCode +- anthropic.ToolSearchToolSearchResultBlock - anthropic.ToolUseBlock - anthropic.Usage +- anthropic.WebFetchBlock +- anthropic.WebFetchToolResultBlock +- anthropic.WebFetchToolResultErrorBlock +- anthropic.WebFetchToolResultErrorCode - anthropic.WebSearchResultBlock - anthropic.WebSearchToolResultBlock - anthropic.WebSearchToolResultBlockContentUnion - anthropic.WebSearchToolResultError +- anthropic.WebSearchToolResultErrorCode Methods: -- client.Messages.New(ctx context.Context, body anthropic.MessageNewParams) (anthropic.Message, error) -- client.Messages.CountTokens(ctx context.Context, body anthropic.MessageCountTokensParams) (anthropic.MessageTokensCount, error) +- client.Messages.New(ctx context.Context, body anthropic.MessageNewParams) (\*anthropic.Message, error) +- client.Messages.CountTokens(ctx context.Context, body anthropic.MessageCountTokensParams) (\*anthropic.MessageTokensCount, error) ## Batches @@ -126,12 +208,12 @@ Response Types: Methods: -- client.Messages.Batches.New(ctx context.Context, body anthropic.MessageBatchNewParams) (anthropic.MessageBatch, error) -- client.Messages.Batches.Get(ctx context.Context, messageBatchID string) (anthropic.MessageBatch, error) -- client.Messages.Batches.List(ctx context.Context, query anthropic.MessageBatchListParams) (pagination.Page[anthropic.MessageBatch], error) -- client.Messages.Batches.Delete(ctx context.Context, messageBatchID string) (anthropic.DeletedMessageBatch, error) -- client.Messages.Batches.Cancel(ctx context.Context, messageBatchID string) (anthropic.MessageBatch, error) -- client.Messages.Batches.Results(ctx context.Context, messageBatchID string) (anthropic.MessageBatchIndividualResponse, error) +- client.Messages.Batches.New(ctx context.Context, body anthropic.MessageBatchNewParams) (\*anthropic.MessageBatch, error) +- client.Messages.Batches.Get(ctx context.Context, messageBatchID string) (\*anthropic.MessageBatch, error) +- client.Messages.Batches.List(ctx context.Context, query anthropic.MessageBatchListParams) (\*pagination.Page[anthropic.MessageBatch], error) +- client.Messages.Batches.Delete(ctx context.Context, messageBatchID string) (\*anthropic.DeletedMessageBatch, error) +- client.Messages.Batches.Cancel(ctx context.Context, messageBatchID string) (\*anthropic.MessageBatch, error) +- client.Messages.Batches.Results(ctx context.Context, messageBatchID string) (\*anthropic.MessageBatchIndividualResponse, error) # Models @@ -141,8 +223,8 @@ Response Types: Methods: -- client.Models.Get(ctx context.Context, modelID string, query anthropic.ModelGetParams) (anthropic.ModelInfo, error) -- client.Models.List(ctx context.Context, params anthropic.ModelListParams) (pagination.Page[anthropic.ModelInfo], error) +- client.Models.Get(ctx context.Context, modelID string, query anthropic.ModelGetParams) (\*anthropic.ModelInfo, error) +- client.Models.List(ctx context.Context, params anthropic.ModelListParams) (\*pagination.Page[anthropic.ModelInfo], error) # Beta @@ -172,13 +254,14 @@ Response Types: Methods: -- client.Beta.Models.Get(ctx context.Context, modelID string, query anthropic.BetaModelGetParams) (anthropic.BetaModelInfo, error) -- client.Beta.Models.List(ctx context.Context, params anthropic.BetaModelListParams) (pagination.Page[anthropic.BetaModelInfo], error) +- client.Beta.Models.Get(ctx context.Context, modelID string, query anthropic.BetaModelGetParams) (\*anthropic.BetaModelInfo, error) +- client.Beta.Models.List(ctx context.Context, params anthropic.BetaModelListParams) (\*pagination.Page[anthropic.BetaModelInfo], error) ## Messages Params Types: +- anthropic.BetaAllThinkingTurnsParam - anthropic.BetaBase64ImageSourceParam - anthropic.BetaBase64PDFSourceParam - anthropic.BetaBashCodeExecutionOutputBlockParam @@ -192,29 +275,41 @@ Params Types: - anthropic.BetaCitationSearchResultLocationParam - anthropic.BetaCitationWebSearchResultLocationParam - anthropic.BetaCitationsConfigParam +- anthropic.BetaClearThinking20251015EditParam - anthropic.BetaClearToolUses20250919EditParam - anthropic.BetaCodeExecutionOutputBlockParam - anthropic.BetaCodeExecutionResultBlockParam - anthropic.BetaCodeExecutionTool20250522Param - anthropic.BetaCodeExecutionTool20250825Param +- anthropic.BetaCodeExecutionTool20260120Param - anthropic.BetaCodeExecutionToolResultBlockParam - anthropic.BetaCodeExecutionToolResultBlockParamContentUnion - anthropic.BetaCodeExecutionToolResultErrorCode - anthropic.BetaCodeExecutionToolResultErrorParam +- anthropic.BetaCompact20260112EditParam +- anthropic.BetaCompactionBlockParam +- anthropic.BetaContainerParams - anthropic.BetaContainerUploadBlockParam - anthropic.BetaContentBlockParamUnion - anthropic.BetaContentBlockSourceParam - anthropic.BetaContentBlockSourceContentUnionParam - anthropic.BetaContextManagementConfigParam +- anthropic.BetaDirectCallerParam +- anthropic.BetaEncryptedCodeExecutionResultBlockParam - anthropic.BetaFileDocumentSourceParam - anthropic.BetaFileImageSourceParam - anthropic.BetaImageBlockParam - anthropic.BetaInputTokensClearAtLeastParam - anthropic.BetaInputTokensTriggerParam +- anthropic.BetaJSONOutputFormatParam +- anthropic.BetaMCPToolConfigParam +- anthropic.BetaMCPToolDefaultConfigParam - anthropic.BetaMCPToolUseBlockParam +- anthropic.BetaMCPToolsetParam - anthropic.BetaMemoryTool20250818Param - anthropic.BetaMessageParam - anthropic.BetaMetadataParam +- anthropic.BetaOutputConfigParam - anthropic.BetaPlainTextSourceParam - anthropic.BetaRedactedThinkingBlockParam - anthropic.BetaRequestDocumentBlockParam @@ -222,7 +317,10 @@ Params Types: - anthropic.BetaRequestMCPServerURLDefinitionParam - anthropic.BetaRequestMCPToolResultBlockParam - anthropic.BetaSearchResultBlockParam +- anthropic.BetaServerToolCallerParam +- anthropic.BetaServerToolCaller20260120Param - anthropic.BetaServerToolUseBlockParam +- anthropic.BetaSkillParams - anthropic.BetaTextBlockParam - anthropic.BetaTextCitationParamUnion - anthropic.BetaTextEditorCodeExecutionCreateResultBlockParam @@ -231,9 +329,11 @@ Params Types: - anthropic.BetaTextEditorCodeExecutionToolResultErrorParam - anthropic.BetaTextEditorCodeExecutionViewResultBlockParam - anthropic.BetaThinkingBlockParam +- anthropic.BetaThinkingConfigAdaptiveParam - anthropic.BetaThinkingConfigDisabledParam - anthropic.BetaThinkingConfigEnabledParam - anthropic.BetaThinkingConfigParamUnion +- anthropic.BetaThinkingTurnsParam - anthropic.BetaToolParam - anthropic.BetaToolBash20241022Param - anthropic.BetaToolBash20250124Param @@ -244,7 +344,14 @@ Params Types: - anthropic.BetaToolChoiceToolParam - anthropic.BetaToolComputerUse20241022Param - anthropic.BetaToolComputerUse20250124Param +- anthropic.BetaToolComputerUse20251124Param +- anthropic.BetaToolReferenceBlockParam - anthropic.BetaToolResultBlockParam +- anthropic.BetaToolSearchToolBm25_20251119Param +- anthropic.BetaToolSearchToolRegex20251119Param +- anthropic.BetaToolSearchToolResultBlockParam +- anthropic.BetaToolSearchToolResultErrorParam +- anthropic.BetaToolSearchToolSearchResultBlockParam - anthropic.BetaToolTextEditor20241022Param - anthropic.BetaToolTextEditor20250124Param - anthropic.BetaToolTextEditor20250429Param @@ -255,13 +362,16 @@ Params Types: - anthropic.BetaToolUsesTriggerParam - anthropic.BetaURLImageSourceParam - anthropic.BetaURLPDFSourceParam +- anthropic.BetaUserLocationParam - anthropic.BetaWebFetchBlockParam - anthropic.BetaWebFetchTool20250910Param +- anthropic.BetaWebFetchTool20260209Param - anthropic.BetaWebFetchToolResultBlockParam - anthropic.BetaWebFetchToolResultErrorBlockParam - anthropic.BetaWebFetchToolResultErrorCode - anthropic.BetaWebSearchResultBlockParam - anthropic.BetaWebSearchTool20250305Param +- anthropic.BetaWebSearchTool20260209Param - anthropic.BetaWebSearchToolRequestErrorParam - anthropic.BetaWebSearchToolResultBlockParam - anthropic.BetaWebSearchToolResultBlockParamContentUnion @@ -282,6 +392,7 @@ Response Types: - anthropic.BetaCitationSearchResultLocation - anthropic.BetaCitationsDelta - anthropic.BetaCitationsWebSearchResultLocation +- anthropic.BetaClearThinking20251015EditResponse - anthropic.BetaClearToolUses20250919EditResponse - anthropic.BetaCodeExecutionOutputBlock - anthropic.BetaCodeExecutionResultBlock @@ -289,13 +400,19 @@ Response Types: - anthropic.BetaCodeExecutionToolResultBlockContentUnion - anthropic.BetaCodeExecutionToolResultError - anthropic.BetaCodeExecutionToolResultErrorCode +- anthropic.BetaCompactionBlock +- anthropic.BetaCompactionContentBlockDelta +- anthropic.BetaCompactionIterationUsage - anthropic.BetaContainer - anthropic.BetaContainerUploadBlock - anthropic.BetaContentBlockUnion - anthropic.BetaContextManagementResponse - anthropic.BetaCountTokensContextManagementResponse +- anthropic.BetaDirectCaller - anthropic.BetaDocumentBlock +- anthropic.BetaEncryptedCodeExecutionResultBlock - anthropic.BetaInputJSONDelta +- anthropic.BetaIterationsUsage - anthropic.BetaMCPToolResultBlock - anthropic.BetaMCPToolUseBlock - anthropic.BetaMemoryTool20250818CommandUnion @@ -307,6 +424,7 @@ Response Types: - anthropic.BetaMemoryTool20250818ViewCommand - anthropic.BetaMessage - anthropic.BetaMessageDeltaUsage +- anthropic.BetaMessageIterationUsage - anthropic.BetaMessageTokensCount - anthropic.BetaPlainTextSource - anthropic.BetaRawContentBlockDeltaUnion @@ -318,9 +436,12 @@ Response Types: - anthropic.BetaRawMessageStopEvent - anthropic.BetaRawMessageStreamEventUnion - anthropic.BetaRedactedThinkingBlock +- anthropic.BetaServerToolCaller +- anthropic.BetaServerToolCaller20260120 - anthropic.BetaServerToolUsage - anthropic.BetaServerToolUseBlock - anthropic.BetaSignatureDelta +- anthropic.BetaSkill - anthropic.BetaStopReason - anthropic.BetaTextBlock - anthropic.BetaTextCitationUnion @@ -332,6 +453,10 @@ Response Types: - anthropic.BetaTextEditorCodeExecutionViewResultBlock - anthropic.BetaThinkingBlock - anthropic.BetaThinkingDelta +- anthropic.BetaToolReferenceBlock +- anthropic.BetaToolSearchToolResultBlock +- anthropic.BetaToolSearchToolResultError +- anthropic.BetaToolSearchToolSearchResultBlock - anthropic.BetaToolUseBlock - anthropic.BetaUsage - anthropic.BetaWebFetchBlock @@ -346,8 +471,8 @@ Response Types: Methods: -- client.Beta.Messages.New(ctx context.Context, params anthropic.BetaMessageNewParams) (anthropic.BetaMessage, error) -- client.Beta.Messages.CountTokens(ctx context.Context, params anthropic.BetaMessageCountTokensParams) (anthropic.BetaMessageTokensCount, error) +- client.Beta.Messages.New(ctx context.Context, params anthropic.BetaMessageNewParams) (\*anthropic.BetaMessage, error) +- client.Beta.Messages.CountTokens(ctx context.Context, params anthropic.BetaMessageCountTokensParams) (\*anthropic.BetaMessageTokensCount, error) ### Batches @@ -365,12 +490,12 @@ Response Types: Methods: -- client.Beta.Messages.Batches.New(ctx context.Context, params anthropic.BetaMessageBatchNewParams) (anthropic.BetaMessageBatch, error) -- client.Beta.Messages.Batches.Get(ctx context.Context, messageBatchID string, query anthropic.BetaMessageBatchGetParams) (anthropic.BetaMessageBatch, error) -- client.Beta.Messages.Batches.List(ctx context.Context, params anthropic.BetaMessageBatchListParams) (pagination.Page[anthropic.BetaMessageBatch], error) -- client.Beta.Messages.Batches.Delete(ctx context.Context, messageBatchID string, body anthropic.BetaMessageBatchDeleteParams) (anthropic.BetaDeletedMessageBatch, error) -- client.Beta.Messages.Batches.Cancel(ctx context.Context, messageBatchID string, body anthropic.BetaMessageBatchCancelParams) (anthropic.BetaMessageBatch, error) -- client.Beta.Messages.Batches.Results(ctx context.Context, messageBatchID string, query anthropic.BetaMessageBatchResultsParams) (anthropic.BetaMessageBatchIndividualResponse, error) +- client.Beta.Messages.Batches.New(ctx context.Context, params anthropic.BetaMessageBatchNewParams) (\*anthropic.BetaMessageBatch, error) +- client.Beta.Messages.Batches.Get(ctx context.Context, messageBatchID string, query anthropic.BetaMessageBatchGetParams) (\*anthropic.BetaMessageBatch, error) +- client.Beta.Messages.Batches.List(ctx context.Context, params anthropic.BetaMessageBatchListParams) (\*pagination.Page[anthropic.BetaMessageBatch], error) +- client.Beta.Messages.Batches.Delete(ctx context.Context, messageBatchID string, body anthropic.BetaMessageBatchDeleteParams) (\*anthropic.BetaDeletedMessageBatch, error) +- client.Beta.Messages.Batches.Cancel(ctx context.Context, messageBatchID string, body anthropic.BetaMessageBatchCancelParams) (\*anthropic.BetaMessageBatch, error) +- client.Beta.Messages.Batches.Results(ctx context.Context, messageBatchID string, query anthropic.BetaMessageBatchResultsParams) (\*anthropic.BetaMessageBatchIndividualResponse, error) ## Files @@ -381,8 +506,40 @@ Response Types: Methods: -- client.Beta.Files.List(ctx context.Context, params anthropic.BetaFileListParams) (pagination.Page[anthropic.FileMetadata], error) -- client.Beta.Files.Delete(ctx context.Context, fileID string, body anthropic.BetaFileDeleteParams) (anthropic.DeletedFile, error) -- client.Beta.Files.Download(ctx context.Context, fileID string, query anthropic.BetaFileDownloadParams) (http.Response, error) -- client.Beta.Files.GetMetadata(ctx context.Context, fileID string, query anthropic.BetaFileGetMetadataParams) (anthropic.FileMetadata, error) -- client.Beta.Files.Upload(ctx context.Context, params anthropic.BetaFileUploadParams) (anthropic.FileMetadata, error) +- client.Beta.Files.List(ctx context.Context, params anthropic.BetaFileListParams) (\*pagination.Page[anthropic.FileMetadata], error) +- client.Beta.Files.Delete(ctx context.Context, fileID string, body anthropic.BetaFileDeleteParams) (\*anthropic.DeletedFile, error) +- client.Beta.Files.Download(ctx context.Context, fileID string, query anthropic.BetaFileDownloadParams) (\*http.Response, error) +- client.Beta.Files.GetMetadata(ctx context.Context, fileID string, query anthropic.BetaFileGetMetadataParams) (\*anthropic.FileMetadata, error) +- client.Beta.Files.Upload(ctx context.Context, params anthropic.BetaFileUploadParams) (\*anthropic.FileMetadata, error) + +## Skills + +Response Types: + +- anthropic.BetaSkillNewResponse +- anthropic.BetaSkillGetResponse +- anthropic.BetaSkillListResponse +- anthropic.BetaSkillDeleteResponse + +Methods: + +- client.Beta.Skills.New(ctx context.Context, params anthropic.BetaSkillNewParams) (\*anthropic.BetaSkillNewResponse, error) +- client.Beta.Skills.Get(ctx context.Context, skillID string, query anthropic.BetaSkillGetParams) (\*anthropic.BetaSkillGetResponse, error) +- client.Beta.Skills.List(ctx context.Context, params anthropic.BetaSkillListParams) (\*pagination.PageCursor[anthropic.BetaSkillListResponse], error) +- client.Beta.Skills.Delete(ctx context.Context, skillID string, body anthropic.BetaSkillDeleteParams) (\*anthropic.BetaSkillDeleteResponse, error) + +### Versions + +Response Types: + +- anthropic.BetaSkillVersionNewResponse +- anthropic.BetaSkillVersionGetResponse +- anthropic.BetaSkillVersionListResponse +- anthropic.BetaSkillVersionDeleteResponse + +Methods: + +- client.Beta.Skills.Versions.New(ctx context.Context, skillID string, params anthropic.BetaSkillVersionNewParams) (\*anthropic.BetaSkillVersionNewResponse, error) +- client.Beta.Skills.Versions.Get(ctx context.Context, version string, params anthropic.BetaSkillVersionGetParams) (\*anthropic.BetaSkillVersionGetResponse, error) +- client.Beta.Skills.Versions.List(ctx context.Context, skillID string, params anthropic.BetaSkillVersionListParams) (\*pagination.PageCursor[anthropic.BetaSkillVersionListResponse], error) +- client.Beta.Skills.Versions.Delete(ctx context.Context, version string, params anthropic.BetaSkillVersionDeleteParams) (\*anthropic.BetaSkillVersionDeleteResponse, error) diff --git a/bedrock/bedrock.go b/bedrock/bedrock.go index 8724af755..c35ddf143 100644 --- a/bedrock/bedrock.go +++ b/bedrock/bedrock.go @@ -19,6 +19,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/eventstreamapi" v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/smithy-go/auth/bearer" "github.com/tidwall/gjson" "github.com/tidwall/sjson" @@ -34,6 +35,15 @@ var DefaultEndpoints = map[string]bool{ "/v1/messages": true, } +func NewStaticBearerTokenProvider(token string) *bearer.StaticTokenProvider { + return &bearer.StaticTokenProvider{ + Token: bearer.Token{ + Value: token, + CanExpire: false, + }, + } +} + type eventstreamChunk struct { Bytes string `json:"bytes"` P string `json:"p"` @@ -174,13 +184,30 @@ func WithLoadDefaultConfig(ctx context.Context, optFns ...func(*config.LoadOptio return WithConfig(cfg) } -// WithConfig returns a request option which uses the provided config and registers middleware that -// intercepts request to the Messages API so that this SDK can be used with Amazon Bedrock. +// WithConfig returns a request option that uses the provided config and registers middleware to +// intercept requests to the Messages API, enabling this SDK to work with Amazon Bedrock. +// +// Authentication is determined as follows: if the AWS_BEARER_TOKEN_BEDROCK environment variable is +// set, it is used for bearer token authentication. Otherwise, if cfg.BearerAuthTokenProvider is set, +// it is used. If neither is available, cfg.Credentials is used for AWS SigV4 signing and must be set. func WithConfig(cfg aws.Config) option.RequestOption { + var credentialErr error + + if cfg.BearerAuthTokenProvider == nil { + if token := os.Getenv("AWS_BEARER_TOKEN_BEDROCK"); token != "" { + cfg.BearerAuthTokenProvider = NewStaticBearerTokenProvider(token) + } + } else if cfg.BearerAuthTokenProvider == nil && cfg.Credentials == nil { + credentialErr = fmt.Errorf("expected AWS credentials to be set") + } + signer := v4.NewSigner() middleware := bedrockMiddleware(signer, cfg) return requestconfig.RequestOptionFunc(func(rc *requestconfig.RequestConfig) error { + if credentialErr != nil { + return credentialErr + } return rc.Apply( option.WithBaseURL(fmt.Sprintf("https://bedrock-runtime.%s.amazonaws.com", cfg.Region)), option.WithMiddleware(middleware), @@ -202,6 +229,15 @@ func bedrockMiddleware(signer *v4.Signer, cfg aws.Config) option.Middleware { body, _ = sjson.SetBytes(body, "anthropic_version", DefaultVersion) } + // pull the betas off of the header (if set) and put them in the body + if betaHeader := r.Header.Values("anthropic-beta"); len(betaHeader) > 0 { + r.Header.Del("anthropic-beta") + body, err = sjson.SetBytes(body, "anthropic_beta", betaHeader) + if err != nil { + return nil, err + } + } + if r.Method == http.MethodPost && DefaultEndpoints[r.URL.Path] { model := gjson.GetBytes(body, "model").String() stream := gjson.GetBytes(body, "stream").Bool() diff --git a/bedrock/bedrock_test.go b/bedrock/bedrock_test.go index 59b0a0b4d..8c5f2ce22 100644 --- a/bedrock/bedrock_test.go +++ b/bedrock/bedrock_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "io" "net/http" "testing" @@ -74,7 +75,7 @@ func TestBedrockURLEncoding(t *testing.T) { middleware := bedrockMiddleware(signer, cfg) // Create request body - requestBody := map[string]interface{}{ + requestBody := map[string]any{ "model": tc.model, "stream": tc.stream, "messages": []map[string]string{ @@ -125,3 +126,129 @@ func TestBedrockURLEncoding(t *testing.T) { }) } } + +func TestBedrockBetaHeadersReRoutedThroughBody(t *testing.T) { + // Create a mock AWS config + cfg := aws.Config{ + Region: "us-east-1", + Credentials: credentials.StaticCredentialsProvider{ + Value: aws.Credentials{ + AccessKeyID: "test-access-key", + SecretAccessKey: "test-secret-key", + }, + }, + } + + signer := v4.NewSigner() + middleware := bedrockMiddleware(signer, cfg) + + // Create HTTP request with beta headers + type fakeRequest struct { + Model string `json:"model"` + AnthropicBeta []string `json:"anthropic_beta,omitempty"` + Messages []map[string]string `json:"messages"` + } + reqBody := fakeRequest{ + Model: "fake-model", + Messages: []map[string]string{ + {"role": "user", "content": "Hello"}, + }, + } + requestBodyBytes, err := json.Marshal(reqBody) + if err != nil { + t.Fatalf("Failed to marshal request body: %v", err) + } + + req, err := http.NewRequest("POST", "https://bedrock-runtime.us-east-1.amazonaws.com/v1/messages", bytes.NewReader(requestBodyBytes)) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + req.Header.Set("Content-Type", "application/json") + req.Header.Add("anthropic-beta", "beta-feature-1") + req.Header.Add("anthropic-beta", "beta-feature-2") + + // Apply middleware + _, err = middleware(req, func(r *http.Request) (*http.Response, error) { + // Read the modified body + bodyBytes, err := io.ReadAll(r.Body) + if err != nil { + t.Fatalf("Failed to read request body: %v", err) + } + var modifiedBody fakeRequest + err = json.Unmarshal(bodyBytes, &modifiedBody) + if err != nil { + t.Fatalf("Failed to unmarshal modified body: %v", err) + } + + // Verify that the anthropic_beta field is present in the body + expectedBetas := []string{"beta-feature-1", "beta-feature-2"} + if len(modifiedBody.AnthropicBeta) != len(expectedBetas) { + t.Fatalf("Expected %d beta features, got %d", len(expectedBetas), len(modifiedBody.AnthropicBeta)) + } + for i, beta := range expectedBetas { + if modifiedBody.AnthropicBeta[i] != beta { + t.Errorf("Expected beta feature %q, got %q", beta, modifiedBody.AnthropicBeta[i]) + } + } + + // Return a dummy response + return &http.Response{ + StatusCode: 200, + Body: http.NoBody, + }, nil + }) + + if err != nil { + t.Fatalf("Middleware failed: %v", err) + } +} + +func TestBedrockBearerToken(t *testing.T) { + token := "test-bearer-token" + region := "us-west-2" + + cfg := aws.Config{ + Region: region, + BearerAuthTokenProvider: NewStaticBearerTokenProvider(token), + } + middleware := bedrockMiddleware(nil, cfg) + + requestBody := map[string]any{ + "model": "claude-3-sonnet", + "messages": []map[string]string{ + {"role": "user", "content": "Hello"}, + }, + } + + bodyBytes, err := json.Marshal(requestBody) + if err != nil { + t.Fatalf("Failed to marshal request body: %v", err) + } + + req, err := http.NewRequest("POST", "https://bedrock-runtime.us-west-2.amazonaws.com/v1/messages", bytes.NewReader(bodyBytes)) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + req.Header.Set("Content-Type", "application/json") + + _, err = middleware(req, func(r *http.Request) (*http.Response, error) { + authHeader := r.Header.Get("Authorization") + expectedAuth := "Bearer " + token + if authHeader != expectedAuth { + t.Errorf("Expected Authorization header %q, got %q", expectedAuth, authHeader) + } + + if r.Header.Get("X-Amz-Date") != "" { + t.Error("Expected no AWS SigV4 headers when using bearer token") + } + + return &http.Response{ + StatusCode: 200, + Body: http.NoBody, + }, nil + }) + + if err != nil { + t.Fatalf("Middleware failed: %v", err) + } +} diff --git a/beta.go b/beta.go index 01c52b323..c9e4c109e 100644 --- a/beta.go +++ b/beta.go @@ -22,6 +22,7 @@ type BetaService struct { Models BetaModelService Messages BetaMessageService Files BetaFileService + Skills BetaSkillService } // NewBetaService generates a new service that applies the given options to each @@ -33,7 +34,8 @@ func NewBetaService(opts ...option.RequestOption) (r BetaService) { r.Models = NewBetaModelService(opts...) r.Messages = NewBetaMessageService(opts...) r.Files = NewBetaFileService(opts...) - return r + r.Skills = NewBetaSkillService(opts...) + return } type AnthropicBeta = string @@ -49,6 +51,7 @@ const ( AnthropicBetaOutput128k2025_02_19 AnthropicBeta = "output-128k-2025-02-19" AnthropicBetaFilesAPI2025_04_14 AnthropicBeta = "files-api-2025-04-14" AnthropicBetaMCPClient2025_04_04 AnthropicBeta = "mcp-client-2025-04-04" + AnthropicBetaMCPClient2025_11_20 AnthropicBeta = "mcp-client-2025-11-20" AnthropicBetaDevFullThinking2025_05_14 AnthropicBeta = "dev-full-thinking-2025-05-14" AnthropicBetaInterleavedThinking2025_05_14 AnthropicBeta = "interleaved-thinking-2025-05-14" AnthropicBetaCodeExecution2025_05_22 AnthropicBeta = "code-execution-2025-05-22" @@ -56,6 +59,8 @@ const ( AnthropicBetaContext1m2025_08_07 AnthropicBeta = "context-1m-2025-08-07" AnthropicBetaContextManagement2025_06_27 AnthropicBeta = "context-management-2025-06-27" AnthropicBetaModelContextWindowExceeded2025_08_26 AnthropicBeta = "model-context-window-exceeded-2025-08-26" + AnthropicBetaSkills2025_10_02 AnthropicBeta = "skills-2025-10-02" + AnthropicBetaFastMode2026_02_01 AnthropicBeta = "fast-mode-2026-02-01" ) type BetaAPIError struct { @@ -72,7 +77,6 @@ type BetaAPIError struct { // Returns the unmodified JSON received from the API func (r BetaAPIError) RawJSON() string { return r.JSON.raw } - func (r *BetaAPIError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -91,7 +95,6 @@ type BetaAuthenticationError struct { // Returns the unmodified JSON received from the API func (r BetaAuthenticationError) RawJSON() string { return r.JSON.raw } - func (r *BetaAuthenticationError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -110,7 +113,6 @@ type BetaBillingError struct { // Returns the unmodified JSON received from the API func (r BetaBillingError) RawJSON() string { return r.JSON.raw } - func (r *BetaBillingError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -193,47 +195,47 @@ func (u BetaErrorUnion) AsAny() anyBetaError { func (u BetaErrorUnion) AsInvalidRequestError() (v BetaInvalidRequestError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaErrorUnion) AsAuthenticationError() (v BetaAuthenticationError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaErrorUnion) AsBillingError() (v BetaBillingError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaErrorUnion) AsPermissionError() (v BetaPermissionError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaErrorUnion) AsNotFoundError() (v BetaNotFoundError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaErrorUnion) AsRateLimitError() (v BetaRateLimitError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaErrorUnion) AsTimeoutError() (v BetaGatewayTimeoutError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaErrorUnion) AsAPIError() (v BetaAPIError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaErrorUnion) AsOverloadedError() (v BetaOverloadedError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -259,7 +261,6 @@ type BetaErrorResponse struct { // Returns the unmodified JSON received from the API func (r BetaErrorResponse) RawJSON() string { return r.JSON.raw } - func (r *BetaErrorResponse) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -278,7 +279,6 @@ type BetaGatewayTimeoutError struct { // Returns the unmodified JSON received from the API func (r BetaGatewayTimeoutError) RawJSON() string { return r.JSON.raw } - func (r *BetaGatewayTimeoutError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -297,7 +297,6 @@ type BetaInvalidRequestError struct { // Returns the unmodified JSON received from the API func (r BetaInvalidRequestError) RawJSON() string { return r.JSON.raw } - func (r *BetaInvalidRequestError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -316,7 +315,6 @@ type BetaNotFoundError struct { // Returns the unmodified JSON received from the API func (r BetaNotFoundError) RawJSON() string { return r.JSON.raw } - func (r *BetaNotFoundError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -335,7 +333,6 @@ type BetaOverloadedError struct { // Returns the unmodified JSON received from the API func (r BetaOverloadedError) RawJSON() string { return r.JSON.raw } - func (r *BetaOverloadedError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -354,7 +351,6 @@ type BetaPermissionError struct { // Returns the unmodified JSON received from the API func (r BetaPermissionError) RawJSON() string { return r.JSON.raw } - func (r *BetaPermissionError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -373,7 +369,6 @@ type BetaRateLimitError struct { // Returns the unmodified JSON received from the API func (r BetaRateLimitError) RawJSON() string { return r.JSON.raw } - func (r *BetaRateLimitError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } diff --git a/betafile.go b/betafile.go index e9b36439c..fda9e2588 100644 --- a/betafile.go +++ b/betafile.go @@ -48,7 +48,7 @@ func NewBetaFileService(opts ...option.RequestOption) (r BetaFileService) { 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14"), option.WithResponseInto(&raw)}, opts...) @@ -73,7 +73,7 @@ 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14")}, opts...) @@ -89,7 +89,7 @@ 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } 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...) @@ -105,7 +105,7 @@ 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14")}, opts...) @@ -121,7 +121,7 @@ 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } 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 c7897ea97..be4750a3c 100644 --- a/betamessage.go +++ b/betamessage.go @@ -38,7 +38,7 @@ func NewBetaMessageService(opts ...option.RequestOption) (r BetaMessageService) r = BetaMessageService{} r.Options = opts r.Batches = NewBetaMessageBatchService(opts...) - return r + return } // Send a structured list of input messages with text and/or image content, and the @@ -47,12 +47,13 @@ func NewBetaMessageService(opts ...option.RequestOption) (r BetaMessageService) // The Messages API can be used for either single queries or stateless multi-turn // conversations. // -// Learn more about the Messages API in our [user guide](/en/docs/initial-setup) +// Learn more about the Messages API in our +// [user guide](https://docs.claude.com/en/docs/initial-setup) // // 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) @@ -66,7 +67,7 @@ func (r *BetaMessageService) New(ctx context.Context, params BetaMessageNewParam path := "v1/messages?beta=true" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) - return res, err + return } // Send a structured list of input messages with text and/or image content, and the @@ -75,7 +76,8 @@ func (r *BetaMessageService) New(ctx context.Context, params BetaMessageNewParam // The Messages API can be used for either single queries or stateless multi-turn // conversations. // -// Learn more about the Messages API in our [user guide](/en/docs/initial-setup) +// Learn more about the Messages API in our +// [user guide](https://docs.claude.com/en/docs/initial-setup) // // Note: If you choose to set a timeout for this request, we recommend 10 minutes. func (r *BetaMessageService) NewStreaming(ctx context.Context, params BetaMessageNewParams, opts ...option.RequestOption) (stream *ssestream.Stream[BetaRawMessageStreamEventUnion]) { @@ -84,10 +86,10 @@ func (r *BetaMessageService) NewStreaming(ctx context.Context, params BetaMessag err error ) for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) - opts = append([]option.RequestOption{option.WithJSONSet("stream", true)}, opts...) + opts = append(opts, option.WithJSONSet("stream", true)) path := "v1/messages?beta=true" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &raw, opts...) return ssestream.NewStream[BetaRawMessageStreamEventUnion](ssestream.NewDecoder(raw), err) @@ -99,15 +101,36 @@ func (r *BetaMessageService) NewStreaming(ctx context.Context, params BetaMessag // including tools, images, and documents, without creating it. // // Learn more about token counting in our -// [user guide](/en/docs/build-with-claude/token-counting) +// [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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) path := "v1/messages/count_tokens?beta=true" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) - return res, err + return +} + +func NewBetaAllThinkingTurnsParam() BetaAllThinkingTurnsParam { + return BetaAllThinkingTurnsParam{ + Type: "all", + } +} + +// This struct has a constant value, construct it with +// [NewBetaAllThinkingTurnsParam]. +type BetaAllThinkingTurnsParam struct { + Type constant.All `json:"type,required"` + paramObj +} + +func (r BetaAllThinkingTurnsParam) MarshalJSON() (data []byte, err error) { + type shadow BetaAllThinkingTurnsParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaAllThinkingTurnsParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // The properties Data, MediaType, Type are required. @@ -124,7 +147,6 @@ func (r BetaBase64ImageSourceParam) MarshalJSON() (data []byte, err error) { type shadow BetaBase64ImageSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaBase64ImageSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -155,7 +177,6 @@ func (r BetaBase64PDFBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaBase64PDFBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaBase64PDFBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -179,7 +200,6 @@ func (u BetaBase64PDFBlockSourceUnionParam) MarshalJSON() ([]byte, error) { u.OfURL, u.OfFile) } - func (u *BetaBase64PDFBlockSourceUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -270,29 +290,6 @@ func init() { ) } -func init() { - apijson.RegisterUnion[BetaContentBlockParamUnion]( - "type", - apijson.Discriminator[BetaTextBlockParam]("text"), - apijson.Discriminator[BetaImageBlockParam]("image"), - apijson.Discriminator[BetaRequestDocumentBlockParam]("document"), - apijson.Discriminator[BetaSearchResultBlockParam]("search_result"), - apijson.Discriminator[BetaThinkingBlockParam]("thinking"), - apijson.Discriminator[BetaRedactedThinkingBlockParam]("redacted_thinking"), - apijson.Discriminator[BetaToolUseBlockParam]("tool_use"), - apijson.Discriminator[BetaToolResultBlockParam]("tool_result"), - apijson.Discriminator[BetaServerToolUseBlockParam]("server_tool_use"), - apijson.Discriminator[BetaWebSearchToolResultBlockParam]("web_search_tool_result"), - apijson.Discriminator[BetaWebFetchToolResultBlockParam]("web_fetch_tool_result"), - apijson.Discriminator[BetaCodeExecutionToolResultBlockParam]("code_execution_tool_result"), - apijson.Discriminator[BetaBashCodeExecutionToolResultBlockParam]("bash_code_execution_tool_result"), - apijson.Discriminator[BetaTextEditorCodeExecutionToolResultBlockParam]("text_editor_code_execution_tool_result"), - apijson.Discriminator[BetaMCPToolUseBlockParam]("mcp_tool_use"), - apijson.Discriminator[BetaRequestMCPToolResultBlockParam]("mcp_tool_result"), - apijson.Discriminator[BetaContainerUploadBlockParam]("container_upload"), - ) -} - func init() { apijson.RegisterUnion[BetaImageBlockParamSourceUnion]( "type", @@ -342,6 +339,54 @@ func init() { ) } +func init() { + apijson.RegisterUnion[BetaClearToolUses20250919EditTriggerUnionParam]( + "type", + apijson.Discriminator[BetaInputTokensTriggerParam]("input_tokens"), + apijson.Discriminator[BetaToolUsesTriggerParam]("tool_uses"), + ) +} + +func init() { + apijson.RegisterUnion[BetaContentBlockParamUnion]( + "type", + apijson.Discriminator[BetaTextBlockParam]("text"), + apijson.Discriminator[BetaImageBlockParam]("image"), + apijson.Discriminator[BetaRequestDocumentBlockParam]("document"), + apijson.Discriminator[BetaSearchResultBlockParam]("search_result"), + apijson.Discriminator[BetaThinkingBlockParam]("thinking"), + apijson.Discriminator[BetaRedactedThinkingBlockParam]("redacted_thinking"), + apijson.Discriminator[BetaToolUseBlockParam]("tool_use"), + apijson.Discriminator[BetaToolResultBlockParam]("tool_result"), + apijson.Discriminator[BetaServerToolUseBlockParam]("server_tool_use"), + apijson.Discriminator[BetaWebSearchToolResultBlockParam]("web_search_tool_result"), + apijson.Discriminator[BetaWebFetchToolResultBlockParam]("web_fetch_tool_result"), + apijson.Discriminator[BetaCodeExecutionToolResultBlockParam]("code_execution_tool_result"), + apijson.Discriminator[BetaBashCodeExecutionToolResultBlockParam]("bash_code_execution_tool_result"), + apijson.Discriminator[BetaTextEditorCodeExecutionToolResultBlockParam]("text_editor_code_execution_tool_result"), + apijson.Discriminator[BetaToolSearchToolResultBlockParam]("tool_search_tool_result"), + apijson.Discriminator[BetaMCPToolUseBlockParam]("mcp_tool_use"), + apijson.Discriminator[BetaRequestMCPToolResultBlockParam]("mcp_tool_result"), + apijson.Discriminator[BetaContainerUploadBlockParam]("container_upload"), + ) +} + +func init() { + apijson.RegisterUnion[BetaContextManagementConfigEditUnionParam]( + "type", + apijson.Discriminator[BetaClearToolUses20250919EditParam]("clear_tool_uses_20250919"), + apijson.Discriminator[BetaClearThinking20251015EditParam]("clear_thinking_20251015"), + ) +} + +func init() { + apijson.RegisterUnion[BetaServerToolUseBlockParamCallerUnion]( + "type", + apijson.Discriminator[BetaDirectCallerParam]("direct"), + apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), + ) +} + func init() { apijson.RegisterUnion[BetaToolResultBlockParamContentUnion]( "type", @@ -349,6 +394,15 @@ func init() { apijson.Discriminator[BetaImageBlockParam]("image"), apijson.Discriminator[BetaSearchResultBlockParam]("search_result"), apijson.Discriminator[BetaRequestDocumentBlockParam]("document"), + apijson.Discriminator[BetaToolReferenceBlockParam]("tool_reference"), + ) +} + +func init() { + apijson.RegisterUnion[BetaToolUseBlockParamCallerUnion]( + "type", + apijson.Discriminator[BetaDirectCallerParam]("direct"), + apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), ) } @@ -368,7 +422,6 @@ type BetaBase64PDFSource struct { // Returns the unmodified JSON received from the API func (r BetaBase64PDFSource) RawJSON() string { return r.JSON.raw } - func (r *BetaBase64PDFSource) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -396,7 +449,6 @@ func (r BetaBase64PDFSourceParam) MarshalJSON() (data []byte, err error) { type shadow BetaBase64PDFSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaBase64PDFSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -415,7 +467,6 @@ type BetaBashCodeExecutionOutputBlock struct { // Returns the unmodified JSON received from the API func (r BetaBashCodeExecutionOutputBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaBashCodeExecutionOutputBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -433,7 +484,6 @@ func (r BetaBashCodeExecutionOutputBlockParam) MarshalJSON() (data []byte, err e type shadow BetaBashCodeExecutionOutputBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaBashCodeExecutionOutputBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -458,7 +508,6 @@ type BetaBashCodeExecutionResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaBashCodeExecutionResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaBashCodeExecutionResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -479,7 +528,6 @@ func (r BetaBashCodeExecutionResultBlockParam) MarshalJSON() (data []byte, err e type shadow BetaBashCodeExecutionResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaBashCodeExecutionResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -500,7 +548,6 @@ type BetaBashCodeExecutionToolResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaBashCodeExecutionToolResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaBashCodeExecutionToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -535,12 +582,12 @@ type BetaBashCodeExecutionToolResultBlockContentUnion struct { func (u BetaBashCodeExecutionToolResultBlockContentUnion) AsResponseBashCodeExecutionToolResultError() (v BetaBashCodeExecutionToolResultError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaBashCodeExecutionToolResultBlockContentUnion) AsResponseBashCodeExecutionResultBlock() (v BetaBashCodeExecutionResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -566,7 +613,6 @@ func (r BetaBashCodeExecutionToolResultBlockParam) MarshalJSON() (data []byte, e type shadow BetaBashCodeExecutionToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaBashCodeExecutionToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -583,7 +629,6 @@ type BetaBashCodeExecutionToolResultBlockParamContentUnion struct { func (u BetaBashCodeExecutionToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfRequestBashCodeExecutionToolResultError, u.OfRequestBashCodeExecutionResultBlock) } - func (u *BetaBashCodeExecutionToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -663,7 +708,6 @@ type BetaBashCodeExecutionToolResultError struct { // Returns the unmodified JSON received from the API func (r BetaBashCodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } - func (r *BetaBashCodeExecutionToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -693,7 +737,6 @@ func (r BetaBashCodeExecutionToolResultErrorParam) MarshalJSON() (data []byte, e type shadow BetaBashCodeExecutionToolResultErrorParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaBashCodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -736,7 +779,6 @@ func (r BetaCacheControlEphemeralParam) MarshalJSON() (data []byte, err error) { type shadow BetaCacheControlEphemeralParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCacheControlEphemeralParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -772,7 +814,6 @@ type BetaCacheCreation struct { // Returns the unmodified JSON received from the API func (r BetaCacheCreation) RawJSON() string { return r.JSON.raw } - func (r *BetaCacheCreation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -801,7 +842,6 @@ type BetaCitationCharLocation struct { // Returns the unmodified JSON received from the API func (r BetaCitationCharLocation) RawJSON() string { return r.JSON.raw } - func (r *BetaCitationCharLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -823,7 +863,6 @@ func (r BetaCitationCharLocationParam) MarshalJSON() (data []byte, err error) { type shadow BetaCitationCharLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCitationCharLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -840,7 +879,6 @@ type BetaCitationConfig struct { // Returns the unmodified JSON received from the API func (r BetaCitationConfig) RawJSON() string { return r.JSON.raw } - func (r *BetaCitationConfig) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -869,7 +907,6 @@ type BetaCitationContentBlockLocation struct { // Returns the unmodified JSON received from the API func (r BetaCitationContentBlockLocation) RawJSON() string { return r.JSON.raw } - func (r *BetaCitationContentBlockLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -892,7 +929,6 @@ func (r BetaCitationContentBlockLocationParam) MarshalJSON() (data []byte, err e type shadow BetaCitationContentBlockLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCitationContentBlockLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -921,7 +957,6 @@ type BetaCitationPageLocation struct { // Returns the unmodified JSON received from the API func (r BetaCitationPageLocation) RawJSON() string { return r.JSON.raw } - func (r *BetaCitationPageLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -943,7 +978,6 @@ func (r BetaCitationPageLocationParam) MarshalJSON() (data []byte, err error) { type shadow BetaCitationPageLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCitationPageLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -972,7 +1006,6 @@ type BetaCitationSearchResultLocation struct { // Returns the unmodified JSON received from the API func (r BetaCitationSearchResultLocation) RawJSON() string { return r.JSON.raw } - func (r *BetaCitationSearchResultLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -996,7 +1029,6 @@ func (r BetaCitationSearchResultLocationParam) MarshalJSON() (data []byte, err e type shadow BetaCitationSearchResultLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCitationSearchResultLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1017,7 +1049,6 @@ func (r BetaCitationWebSearchResultLocationParam) MarshalJSON() (data []byte, er type shadow BetaCitationWebSearchResultLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCitationWebSearchResultLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1031,7 +1062,6 @@ func (r BetaCitationsConfigParam) MarshalJSON() (data []byte, err error) { type shadow BetaCitationsConfigParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCitationsConfigParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1050,7 +1080,6 @@ type BetaCitationsDelta struct { // Returns the unmodified JSON received from the API func (r BetaCitationsDelta) RawJSON() string { return r.JSON.raw } - func (r *BetaCitationsDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1153,27 +1182,27 @@ func (u BetaCitationsDeltaCitationUnion) AsAny() anyBetaCitationsDeltaCitation { func (u BetaCitationsDeltaCitationUnion) AsCharLocation() (v BetaCitationCharLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaCitationsDeltaCitationUnion) AsPageLocation() (v BetaCitationPageLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaCitationsDeltaCitationUnion) AsContentBlockLocation() (v BetaCitationContentBlockLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaCitationsDeltaCitationUnion) AsWebSearchResultLocation() (v BetaCitationsWebSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaCitationsDeltaCitationUnion) AsSearchResultLocation() (v BetaCitationSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -1203,11 +1232,99 @@ type BetaCitationsWebSearchResultLocation struct { // Returns the unmodified JSON received from the API func (r BetaCitationsWebSearchResultLocation) RawJSON() string { return r.JSON.raw } - func (r *BetaCitationsWebSearchResultLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// The property Type is required. +type BetaClearThinking20251015EditParam struct { + // Number of most recent assistant turns to keep thinking blocks for. Older turns + // will have their thinking blocks removed. + Keep BetaClearThinking20251015EditKeepUnionParam `json:"keep,omitzero"` + // This field can be elided, and will marshal its zero value as + // "clear_thinking_20251015". + Type constant.ClearThinking20251015 `json:"type,required"` + paramObj +} + +func (r BetaClearThinking20251015EditParam) MarshalJSON() (data []byte, err error) { + type shadow BetaClearThinking20251015EditParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaClearThinking20251015EditParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaClearThinking20251015EditKeepUnionParam struct { + OfThinkingTurns *BetaThinkingTurnsParam `json:",omitzero,inline"` + OfAllThinkingTurns *BetaAllThinkingTurnsParam `json:",omitzero,inline"` + // Construct this variant with constant.ValueOf[constant.All]() + OfAll constant.All `json:",omitzero,inline"` + paramUnion +} + +func (u BetaClearThinking20251015EditKeepUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfThinkingTurns, u.OfAllThinkingTurns, u.OfAll) +} +func (u *BetaClearThinking20251015EditKeepUnionParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BetaClearThinking20251015EditKeepUnionParam) asAny() any { + if !param.IsOmitted(u.OfThinkingTurns) { + return u.OfThinkingTurns + } else if !param.IsOmitted(u.OfAllThinkingTurns) { + return u.OfAllThinkingTurns + } else if !param.IsOmitted(u.OfAll) { + return &u.OfAll + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaClearThinking20251015EditKeepUnionParam) GetValue() *int64 { + if vt := u.OfThinkingTurns; vt != nil { + return &vt.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaClearThinking20251015EditKeepUnionParam) GetType() *string { + if vt := u.OfThinkingTurns; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfAllThinkingTurns; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +type BetaClearThinking20251015EditResponse struct { + // Number of input tokens cleared by this edit. + ClearedInputTokens int64 `json:"cleared_input_tokens,required"` + // Number of thinking turns that were cleared. + ClearedThinkingTurns int64 `json:"cleared_thinking_turns,required"` + // The type of context management edit applied. + Type constant.ClearThinking20251015 `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ClearedInputTokens respjson.Field + ClearedThinkingTurns respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaClearThinking20251015EditResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaClearThinking20251015EditResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // The property Type is required. type BetaClearToolUses20250919EditParam struct { // Whether to clear all tool inputs (bool) or specific tool inputs to clear (list) @@ -1231,7 +1348,6 @@ func (r BetaClearToolUses20250919EditParam) MarshalJSON() (data []byte, err erro type shadow BetaClearToolUses20250919EditParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaClearToolUses20250919EditParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1248,7 +1364,6 @@ type BetaClearToolUses20250919EditClearToolInputsUnionParam struct { func (u BetaClearToolUses20250919EditClearToolInputsUnionParam) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfBool, u.OfStringArray) } - func (u *BetaClearToolUses20250919EditClearToolInputsUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -1274,7 +1389,6 @@ type BetaClearToolUses20250919EditTriggerUnionParam struct { func (u BetaClearToolUses20250919EditTriggerUnionParam) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfInputTokens, u.OfToolUses) } - func (u *BetaClearToolUses20250919EditTriggerUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -1308,15 +1422,6 @@ func (u BetaClearToolUses20250919EditTriggerUnionParam) GetValue() *int64 { return nil } -func init() { - apijson.RegisterUnion[BetaClearToolUses20250919EditTriggerUnionParam]( - "type", - apijson.Discriminator[BetaInputTokensTriggerParam]("input_tokens"), - apijson.Discriminator[BetaToolUsesTriggerParam]("tool_uses"), - ) -} - -// Results for clear_tool_uses_20250919 edit. type BetaClearToolUses20250919EditResponse struct { // Number of input tokens cleared by this edit. ClearedInputTokens int64 `json:"cleared_input_tokens,required"` @@ -1336,7 +1441,6 @@ type BetaClearToolUses20250919EditResponse struct { // Returns the unmodified JSON received from the API func (r BetaClearToolUses20250919EditResponse) RawJSON() string { return r.JSON.raw } - func (r *BetaClearToolUses20250919EditResponse) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1355,7 +1459,6 @@ type BetaCodeExecutionOutputBlock struct { // Returns the unmodified JSON received from the API func (r BetaCodeExecutionOutputBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaCodeExecutionOutputBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1373,7 +1476,6 @@ func (r BetaCodeExecutionOutputBlockParam) MarshalJSON() (data []byte, err error type shadow BetaCodeExecutionOutputBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCodeExecutionOutputBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1398,7 +1500,6 @@ type BetaCodeExecutionResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaCodeExecutionResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaCodeExecutionResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1419,13 +1520,19 @@ func (r BetaCodeExecutionResultBlockParam) MarshalJSON() (data []byte, err error type shadow BetaCodeExecutionResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCodeExecutionResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Name, Type are required. type BetaCodeExecutionTool20250522Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` // Name of the tool. @@ -1444,13 +1551,19 @@ func (r BetaCodeExecutionTool20250522Param) MarshalJSON() (data []byte, err erro type shadow BetaCodeExecutionTool20250522Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCodeExecutionTool20250522Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Name, Type are required. type BetaCodeExecutionTool20250825Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` // Name of the tool. @@ -1469,12 +1582,46 @@ func (r BetaCodeExecutionTool20250825Param) MarshalJSON() (data []byte, err erro type shadow BetaCodeExecutionTool20250825Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCodeExecutionTool20250825Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Code execution tool with REPL state persistence (daemon mode + gVisor +// checkpoint). +// +// The properties Name, Type are required. +type BetaCodeExecutionTool20260120Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "code_execution". + Name constant.CodeExecution `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_20260120". + Type constant.CodeExecution20260120 `json:"type,required"` + paramObj +} + +func (r BetaCodeExecutionTool20260120Param) MarshalJSON() (data []byte, err error) { + type shadow BetaCodeExecutionTool20260120Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaCodeExecutionTool20260120Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + type BetaCodeExecutionToolResultBlock struct { + // Code execution result with encrypted stdout for PFC + web_search results. Content BetaCodeExecutionToolResultBlockContentUnion `json:"content,required"` ToolUseID string `json:"tool_use_id,required"` Type constant.CodeExecutionToolResult `json:"type,required"` @@ -1490,47 +1637,51 @@ type BetaCodeExecutionToolResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaCodeExecutionToolResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaCodeExecutionToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaCodeExecutionToolResultBlockContentUnion contains all possible properties // and values from [BetaCodeExecutionToolResultError], -// [BetaCodeExecutionResultBlock]. +// [BetaCodeExecutionResultBlock], [BetaEncryptedCodeExecutionResultBlock]. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaCodeExecutionToolResultBlockContentUnion struct { // This field is from variant [BetaCodeExecutionToolResultError]. - ErrorCode BetaCodeExecutionToolResultErrorCode `json:"error_code"` - Type string `json:"type"` - // This field is from variant [BetaCodeExecutionResultBlock]. - Content []BetaCodeExecutionOutputBlock `json:"content"` - // This field is from variant [BetaCodeExecutionResultBlock]. - ReturnCode int64 `json:"return_code"` - // This field is from variant [BetaCodeExecutionResultBlock]. - Stderr string `json:"stderr"` + ErrorCode BetaCodeExecutionToolResultErrorCode `json:"error_code"` + Type string `json:"type"` + Content []BetaCodeExecutionOutputBlock `json:"content"` + ReturnCode int64 `json:"return_code"` + Stderr string `json:"stderr"` // This field is from variant [BetaCodeExecutionResultBlock]. Stdout string `json:"stdout"` - JSON struct { - ErrorCode respjson.Field - Type respjson.Field - Content respjson.Field - ReturnCode respjson.Field - Stderr respjson.Field - Stdout respjson.Field - raw string + // This field is from variant [BetaEncryptedCodeExecutionResultBlock]. + EncryptedStdout string `json:"encrypted_stdout"` + JSON struct { + ErrorCode respjson.Field + Type respjson.Field + Content respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Stdout respjson.Field + EncryptedStdout respjson.Field + raw string } `json:"-"` } func (u BetaCodeExecutionToolResultBlockContentUnion) AsResponseCodeExecutionToolResultError() (v BetaCodeExecutionToolResultError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaCodeExecutionToolResultBlockContentUnion) AsResponseCodeExecutionResultBlock() (v BetaCodeExecutionResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return +} + +func (u BetaCodeExecutionToolResultBlockContentUnion) AsResponseEncryptedCodeExecutionResultBlock() (v BetaEncryptedCodeExecutionResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } // Returns the unmodified JSON received from the API @@ -1542,6 +1693,7 @@ func (r *BetaCodeExecutionToolResultBlockContentUnion) UnmarshalJSON(data []byte // The properties Content, ToolUseID, Type are required. type BetaCodeExecutionToolResultBlockParam struct { + // Code execution result with encrypted stdout for PFC + web_search results. Content BetaCodeExecutionToolResultBlockParamContentUnion `json:"content,omitzero,required"` ToolUseID string `json:"tool_use_id,required"` // Create a cache control breakpoint at this content block. @@ -1556,7 +1708,6 @@ func (r BetaCodeExecutionToolResultBlockParam) MarshalJSON() (data []byte, err e type shadow BetaCodeExecutionToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCodeExecutionToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1571,15 +1722,15 @@ func BetaNewCodeExecutionToolRequestError(errorCode BetaCodeExecutionToolResultE // // Use [param.IsOmitted] to confirm if a field is set. type BetaCodeExecutionToolResultBlockParamContentUnion struct { - OfError *BetaCodeExecutionToolResultErrorParam `json:",omitzero,inline"` - OfResultBlock *BetaCodeExecutionResultBlockParam `json:",omitzero,inline"` + OfError *BetaCodeExecutionToolResultErrorParam `json:",omitzero,inline"` + OfResultBlock *BetaCodeExecutionResultBlockParam `json:",omitzero,inline"` + OfRequestEncryptedCodeExecutionResultBlock *BetaEncryptedCodeExecutionResultBlockParam `json:",omitzero,inline"` paramUnion } func (u BetaCodeExecutionToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfError, u.OfResultBlock) + return param.MarshalUnion(u, u.OfError, u.OfResultBlock, u.OfRequestEncryptedCodeExecutionResultBlock) } - func (u *BetaCodeExecutionToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -1589,6 +1740,8 @@ func (u *BetaCodeExecutionToolResultBlockParamContentUnion) asAny() any { return u.OfError } else if !param.IsOmitted(u.OfResultBlock) { return u.OfResultBlock + } else if !param.IsOmitted(u.OfRequestEncryptedCodeExecutionResultBlock) { + return u.OfRequestEncryptedCodeExecutionResultBlock } return nil } @@ -1602,43 +1755,59 @@ func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetErrorCode() *strin } // Returns a pointer to the underlying variant's property, if present. -func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetContent() []BetaCodeExecutionOutputBlockParam { +func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetStdout() *string { if vt := u.OfResultBlock; vt != nil { - return vt.Content + return &vt.Stdout } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetReturnCode() *int64 { - if vt := u.OfResultBlock; vt != nil { - return &vt.ReturnCode +func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetEncryptedStdout() *string { + if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return &vt.EncryptedStdout } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetStderr() *string { - if vt := u.OfResultBlock; vt != nil { - return &vt.Stderr +func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetType() *string { + if vt := u.OfError; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfResultBlock; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return (*string)(&vt.Type) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetStdout() *string { +func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetReturnCode() *int64 { if vt := u.OfResultBlock; vt != nil { - return &vt.Stdout + return (*int64)(&vt.ReturnCode) + } else if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return (*int64)(&vt.ReturnCode) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetType() *string { - if vt := u.OfError; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfResultBlock; vt != nil { - return (*string)(&vt.Type) +func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetStderr() *string { + if vt := u.OfResultBlock; vt != nil { + return (*string)(&vt.Stderr) + } else if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return (*string)(&vt.Stderr) + } + return nil +} + +// Returns a pointer to the underlying variant's Content property, if present. +func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetContent() []BetaCodeExecutionOutputBlockParam { + if vt := u.OfResultBlock; vt != nil { + return vt.Content + } else if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return vt.Content } return nil } @@ -1659,7 +1828,6 @@ type BetaCodeExecutionToolResultError struct { // Returns the unmodified JSON received from the API func (r BetaCodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } - func (r *BetaCodeExecutionToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1688,22 +1856,150 @@ func (r BetaCodeExecutionToolResultErrorParam) MarshalJSON() (data []byte, err e type shadow BetaCodeExecutionToolResultErrorParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaCodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Information about the container used in the request (for the code execution -// tool) -type BetaContainer struct { - // Identifier for the container used in this request +// Automatically compact older context when reaching the configured trigger +// threshold. +// +// The property Type is required. +type BetaCompact20260112EditParam struct { + // Additional instructions for summarization. + Instructions param.Opt[string] `json:"instructions,omitzero"` + // Whether to pause after compaction and return the compaction block to the user. + PauseAfterCompaction param.Opt[bool] `json:"pause_after_compaction,omitzero"` + // When to trigger compaction. Defaults to 150000 input tokens. + Trigger BetaInputTokensTriggerParam `json:"trigger,omitzero"` + // This field can be elided, and will marshal its zero value as "compact_20260112". + Type constant.Compact20260112 `json:"type,required"` + paramObj +} + +func (r BetaCompact20260112EditParam) MarshalJSON() (data []byte, err error) { + type shadow BetaCompact20260112EditParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaCompact20260112EditParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// A compaction block returned when autocompact is triggered. +// +// When content is None, it indicates the compaction failed to produce a valid +// summary (e.g., malformed output from the model). Clients may round-trip +// compaction blocks with null content; the server treats them as no-ops. +type BetaCompactionBlock struct { + // Summary of compacted content, or null if compaction failed + Content string `json:"content,required"` + Type constant.Compaction `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaCompactionBlock) RawJSON() string { return r.JSON.raw } +func (r *BetaCompactionBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// A compaction block containing summary of previous context. +// +// Users should round-trip these blocks from responses to subsequent requests to +// maintain context across compaction boundaries. +// +// When content is None, the block represents a failed compaction. The server +// treats these as no-ops. Empty string content is not allowed. +// +// The properties Content, Type are required. +type BetaCompactionBlockParam struct { + // Summary of previously compacted content, or null if compaction failed + Content param.Opt[string] `json:"content,omitzero,required"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as "compaction". + Type constant.Compaction `json:"type,required"` + paramObj +} + +func (r BetaCompactionBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BetaCompactionBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaCompactionBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaCompactionContentBlockDelta struct { + Content string `json:"content,required"` + Type constant.CompactionDelta `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaCompactionContentBlockDelta) RawJSON() string { return r.JSON.raw } +func (r *BetaCompactionContentBlockDelta) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Token usage for a compaction iteration. +type BetaCompactionIterationUsage struct { + // Breakdown of cached tokens by TTL + CacheCreation BetaCacheCreation `json:"cache_creation,required"` + // The number of input tokens used to create the cache entry. + CacheCreationInputTokens int64 `json:"cache_creation_input_tokens,required"` + // The number of input tokens read from the cache. + CacheReadInputTokens int64 `json:"cache_read_input_tokens,required"` + // The number of input tokens which were used. + InputTokens int64 `json:"input_tokens,required"` + // The number of output tokens which were used. + OutputTokens int64 `json:"output_tokens,required"` + // Usage for a compaction iteration + Type constant.Compaction `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + CacheCreation respjson.Field + CacheCreationInputTokens respjson.Field + CacheReadInputTokens respjson.Field + InputTokens respjson.Field + OutputTokens respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaCompactionIterationUsage) RawJSON() string { return r.JSON.raw } +func (r *BetaCompactionIterationUsage) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Information about the container used in the request (for the code execution +// tool) +type BetaContainer struct { + // Identifier for the container used in this request ID string `json:"id,required"` // The time at which the container will expire. ExpiresAt time.Time `json:"expires_at,required" format:"date-time"` + // Skills loaded in the container + Skills []BetaSkill `json:"skills,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field ExpiresAt respjson.Field + Skills respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` @@ -1711,11 +2007,27 @@ type BetaContainer struct { // Returns the unmodified JSON received from the API func (r BetaContainer) RawJSON() string { return r.JSON.raw } - func (r *BetaContainer) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Container parameters with skills to be loaded. +type BetaContainerParams struct { + // Container id + ID param.Opt[string] `json:"id,omitzero"` + // List of skills to load in the container + Skills []BetaSkillParams `json:"skills,omitzero"` + paramObj +} + +func (r BetaContainerParams) MarshalJSON() (data []byte, err error) { + type shadow BetaContainerParams + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaContainerParams) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // Response model for a file uploaded to the container. type BetaContainerUploadBlock struct { FileID string `json:"file_id,required"` @@ -1731,7 +2043,6 @@ type BetaContainerUploadBlock struct { // Returns the unmodified JSON received from the API func (r BetaContainerUploadBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaContainerUploadBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1753,7 +2064,6 @@ func (r BetaContainerUploadBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaContainerUploadBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaContainerUploadBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -1763,8 +2073,9 @@ func (r *BetaContainerUploadBlockParam) UnmarshalJSON(data []byte) error { // [BetaToolUseBlock], [BetaServerToolUseBlock], [BetaWebSearchToolResultBlock], // [BetaWebFetchToolResultBlock], [BetaCodeExecutionToolResultBlock], // [BetaBashCodeExecutionToolResultBlock], -// [BetaTextEditorCodeExecutionToolResultBlock], [BetaMCPToolUseBlock], -// [BetaMCPToolResultBlock], [BetaContainerUploadBlock]. +// [BetaTextEditorCodeExecutionToolResultBlock], [BetaToolSearchToolResultBlock], +// [BetaMCPToolUseBlock], [BetaMCPToolResultBlock], [BetaContainerUploadBlock], +// [BetaCompactionBlock]. // // Use the [BetaContentBlockUnion.AsAny] method to switch on the variant. // @@ -1777,7 +2088,8 @@ type BetaContentBlockUnion struct { // Any of "text", "thinking", "redacted_thinking", "tool_use", "server_tool_use", // "web_search_tool_result", "web_fetch_tool_result", "code_execution_tool_result", // "bash_code_execution_tool_result", "text_editor_code_execution_tool_result", - // "mcp_tool_use", "mcp_tool_result", "container_upload". + // "tool_search_tool_result", "mcp_tool_use", "mcp_tool_result", + // "container_upload", "compaction". Type string `json:"type"` // This field is from variant [BetaThinkingBlock]. Signature string `json:"signature"` @@ -1789,12 +2101,17 @@ type BetaContentBlockUnion struct { // necessary custom code modification Input json.RawMessage `json:"input"` Name string `json:"name"` + // This field is a union of [BetaToolUseBlockCallerUnion], + // [BetaServerToolUseBlockCallerUnion], [BetaWebSearchToolResultBlockCallerUnion], + // [BetaWebFetchToolResultBlockCallerUnion] + Caller BetaContentBlockUnionCaller `json:"caller"` // This field is a union of [BetaWebSearchToolResultBlockContentUnion], // [BetaWebFetchToolResultBlockContentUnion], // [BetaCodeExecutionToolResultBlockContentUnion], // [BetaBashCodeExecutionToolResultBlockContentUnion], // [BetaTextEditorCodeExecutionToolResultBlockContentUnion], - // [BetaMCPToolResultBlockContentUnion] + // [BetaToolSearchToolResultBlockContentUnion], + // [BetaMCPToolResultBlockContentUnion], [string] Content BetaContentBlockUnionContent `json:"content"` ToolUseID string `json:"tool_use_id"` // This field is from variant [BetaMCPToolUseBlock]. @@ -1813,6 +2130,7 @@ type BetaContentBlockUnion struct { ID respjson.Field Input respjson.Field Name respjson.Field + Caller respjson.Field Content respjson.Field ToolUseID respjson.Field ServerName respjson.Field @@ -1822,28 +2140,11 @@ type BetaContentBlockUnion struct { } `json:"-"` } -func (r BetaContentBlockUnion) ToParam() BetaContentBlockParamUnion { - switch variant := r.AsAny().(type) { - case BetaTextBlock: - p := variant.ToParam() - return BetaContentBlockParamUnion{OfText: &p} - case BetaToolUseBlock: - p := variant.ToParam() - return BetaContentBlockParamUnion{OfToolUse: &p} - case BetaThinkingBlock: - p := variant.ToParam() - return BetaContentBlockParamUnion{OfThinking: &p} - case BetaRedactedThinkingBlock: - p := variant.ToParam() - return BetaContentBlockParamUnion{OfRedactedThinking: &p} - } - return BetaContentBlockParamUnion{} -} - // anyBetaContentBlock is implemented by each variant of [BetaContentBlockUnion] to // add type safety for the return type of [BetaContentBlockUnion.AsAny] type anyBetaContentBlock interface { implBetaContentBlockUnion() + toParamUnion() BetaContentBlockParamUnion } func (BetaTextBlock) implBetaContentBlockUnion() {} @@ -1856,9 +2157,11 @@ func (BetaWebFetchToolResultBlock) implBetaContentBlockUnion() {} func (BetaCodeExecutionToolResultBlock) implBetaContentBlockUnion() {} func (BetaBashCodeExecutionToolResultBlock) implBetaContentBlockUnion() {} func (BetaTextEditorCodeExecutionToolResultBlock) implBetaContentBlockUnion() {} +func (BetaToolSearchToolResultBlock) implBetaContentBlockUnion() {} func (BetaMCPToolUseBlock) implBetaContentBlockUnion() {} func (BetaMCPToolResultBlock) implBetaContentBlockUnion() {} func (BetaContainerUploadBlock) implBetaContentBlockUnion() {} +func (BetaCompactionBlock) implBetaContentBlockUnion() {} // Use the following switch statement to find the correct variant // @@ -1873,9 +2176,11 @@ func (BetaContainerUploadBlock) implBetaContentBlockUnion() {} // case anthropic.BetaCodeExecutionToolResultBlock: // case anthropic.BetaBashCodeExecutionToolResultBlock: // case anthropic.BetaTextEditorCodeExecutionToolResultBlock: +// case anthropic.BetaToolSearchToolResultBlock: // case anthropic.BetaMCPToolUseBlock: // case anthropic.BetaMCPToolResultBlock: // case anthropic.BetaContainerUploadBlock: +// case anthropic.BetaCompactionBlock: // default: // fmt.Errorf("no variant present") // } @@ -1901,79 +2206,93 @@ func (u BetaContentBlockUnion) AsAny() anyBetaContentBlock { return u.AsBashCodeExecutionToolResult() case "text_editor_code_execution_tool_result": return u.AsTextEditorCodeExecutionToolResult() + case "tool_search_tool_result": + return u.AsToolSearchToolResult() case "mcp_tool_use": return u.AsMCPToolUse() case "mcp_tool_result": return u.AsMCPToolResult() case "container_upload": return u.AsContainerUpload() + case "compaction": + return u.AsCompaction() } return nil } func (u BetaContentBlockUnion) AsText() (v BetaTextBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsThinking() (v BetaThinkingBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsRedactedThinking() (v BetaRedactedThinkingBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsToolUse() (v BetaToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsServerToolUse() (v BetaServerToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsWebSearchToolResult() (v BetaWebSearchToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsWebFetchToolResult() (v BetaWebFetchToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsCodeExecutionToolResult() (v BetaCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsBashCodeExecutionToolResult() (v BetaBashCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsTextEditorCodeExecutionToolResult() (v BetaTextEditorCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return +} + +func (u BetaContentBlockUnion) AsToolSearchToolResult() (v BetaToolSearchToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } func (u BetaContentBlockUnion) AsMCPToolUse() (v BetaMCPToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsMCPToolResult() (v BetaMCPToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaContentBlockUnion) AsContainerUpload() (v BetaContainerUploadBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return +} + +func (u BetaContentBlockUnion) AsCompaction() (v BetaCompactionBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } // Returns the unmodified JSON received from the API @@ -1983,6 +2302,26 @@ func (r *BetaContentBlockUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// BetaContentBlockUnionCaller is an implicit subunion of [BetaContentBlockUnion]. +// BetaContentBlockUnionCaller provides convenient access to the sub-properties of +// the union. +// +// For type safety it is recommended to directly use a variant of the +// [BetaContentBlockUnion]. +type BetaContentBlockUnionCaller struct { + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +func (r *BetaContentBlockUnionCaller) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // BetaContentBlockUnionContent is an implicit subunion of [BetaContentBlockUnion]. // BetaContentBlockUnionContent provides convenient access to the sub-properties of // the union. @@ -2005,7 +2344,7 @@ type BetaContentBlockUnionContent struct { ErrorCode string `json:"error_code"` Type string `json:"type"` // This field is a union of [BetaDocumentBlock], [[]BetaCodeExecutionOutputBlock], - // [[]BetaBashCodeExecutionOutputBlock], [string] + // [[]BetaCodeExecutionOutputBlock], [[]BetaBashCodeExecutionOutputBlock], [string] Content BetaContentBlockUnionContentContent `json:"content"` // This field is from variant [BetaWebFetchToolResultBlockContentUnion]. RetrievedAt string `json:"retrieved_at"` @@ -2014,9 +2353,9 @@ type BetaContentBlockUnionContent struct { ReturnCode int64 `json:"return_code"` Stderr string `json:"stderr"` Stdout string `json:"stdout"` - // This field is from variant - // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. - ErrorMessage string `json:"error_message"` + // This field is from variant [BetaCodeExecutionToolResultBlockContentUnion]. + EncryptedStdout string `json:"encrypted_stdout"` + ErrorMessage string `json:"error_message"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. FileType BetaTextEditorCodeExecutionViewResultBlockFileType `json:"file_type"` @@ -2047,7 +2386,9 @@ type BetaContentBlockUnionContent struct { // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. OldStart int64 `json:"old_start"` - JSON struct { + // This field is from variant [BetaToolSearchToolResultBlockContentUnion]. + ToolReferences []BetaToolReferenceBlock `json:"tool_references"` + JSON struct { OfBetaWebSearchResultBlockArray respjson.Field OfString respjson.Field OfBetaMCPToolResultBlockContent respjson.Field @@ -2059,6 +2400,7 @@ type BetaContentBlockUnionContent struct { ReturnCode respjson.Field Stderr respjson.Field Stdout respjson.Field + EncryptedStdout respjson.Field ErrorMessage respjson.Field FileType respjson.Field NumLines respjson.Field @@ -2070,6 +2412,7 @@ type BetaContentBlockUnionContent struct { NewStart respjson.Field OldLines respjson.Field OldStart respjson.Field + ToolReferences respjson.Field raw string } `json:"-"` } @@ -2185,10 +2528,14 @@ func NewBetaToolUseBlock(id string, input any, name string) BetaContentBlockPara return BetaContentBlockParamUnion{OfToolUse: &toolUse} } -func NewBetaToolResultBlock(toolUseID string) BetaContentBlockParamUnion { - var toolResult BetaToolResultBlockParam - toolResult.ToolUseID = toolUseID - return BetaContentBlockParamUnion{OfToolResult: &toolResult} +func NewBetaToolResultBlock(toolUseID string, content string, isError bool) BetaContentBlockParamUnion { + var toolBlock BetaToolResultBlockParam + toolBlock.ToolUseID = toolUseID + toolBlock.Content = []BetaToolResultBlockParamContentUnion{ + {OfText: &BetaTextBlockParam{Text: content}}, + } + toolBlock.IsError = Bool(isError) + return BetaContentBlockParamUnion{OfToolResult: &toolBlock} } func NewBetaServerToolUseBlock(id string, input any, name BetaServerToolUseBlockParamName) BetaContentBlockParamUnion { @@ -2228,7 +2575,7 @@ func NewBetaWebFetchToolResultBlock[ } func NewBetaCodeExecutionToolResultBlock[ - T BetaCodeExecutionToolResultErrorParam | BetaCodeExecutionResultBlockParam, + T BetaCodeExecutionToolResultErrorParam | BetaCodeExecutionResultBlockParam | BetaEncryptedCodeExecutionResultBlockParam, ](content T, toolUseID string) BetaContentBlockParamUnion { var codeExecutionToolResult BetaCodeExecutionToolResultBlockParam switch v := any(content).(type) { @@ -2236,6 +2583,8 @@ func NewBetaCodeExecutionToolResultBlock[ codeExecutionToolResult.Content.OfError = &v case BetaCodeExecutionResultBlockParam: codeExecutionToolResult.Content.OfResultBlock = &v + case BetaEncryptedCodeExecutionResultBlockParam: + codeExecutionToolResult.Content.OfRequestEncryptedCodeExecutionResultBlock = &v } codeExecutionToolResult.ToolUseID = toolUseID return BetaContentBlockParamUnion{OfCodeExecutionToolResult: &codeExecutionToolResult} @@ -2273,6 +2622,20 @@ func NewBetaTextEditorCodeExecutionToolResultBlock[ return BetaContentBlockParamUnion{OfTextEditorCodeExecutionToolResult: &textEditorCodeExecutionToolResult} } +func NewBetaToolSearchToolResultBlock[ + T BetaToolSearchToolResultErrorParam | BetaToolSearchToolSearchResultBlockParam, +](content T, toolUseID string) BetaContentBlockParamUnion { + var toolSearchToolResult BetaToolSearchToolResultBlockParam + switch v := any(content).(type) { + case BetaToolSearchToolResultErrorParam: + toolSearchToolResult.Content.OfRequestToolSearchToolResultError = &v + case BetaToolSearchToolSearchResultBlockParam: + toolSearchToolResult.Content.OfRequestToolSearchToolSearchResultBlock = &v + } + toolSearchToolResult.ToolUseID = toolUseID + return BetaContentBlockParamUnion{OfToolSearchToolResult: &toolSearchToolResult} +} + func NewBetaMCPToolResultBlock(toolUseID string) BetaContentBlockParamUnion { var mcpToolResult BetaRequestMCPToolResultBlockParam mcpToolResult.ToolUseID = toolUseID @@ -2285,6 +2648,12 @@ func NewBetaContainerUploadBlock(fileID string) BetaContentBlockParamUnion { return BetaContentBlockParamUnion{OfContainerUpload: &containerUpload} } +func NewBetaCompactionBlock(content string) BetaContentBlockParamUnion { + var compaction BetaCompactionBlockParam + compaction.Content = param.NewOpt(content) + return BetaContentBlockParamUnion{OfCompaction: &compaction} +} + // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. @@ -2303,9 +2672,11 @@ type BetaContentBlockParamUnion struct { OfCodeExecutionToolResult *BetaCodeExecutionToolResultBlockParam `json:",omitzero,inline"` OfBashCodeExecutionToolResult *BetaBashCodeExecutionToolResultBlockParam `json:",omitzero,inline"` OfTextEditorCodeExecutionToolResult *BetaTextEditorCodeExecutionToolResultBlockParam `json:",omitzero,inline"` + OfToolSearchToolResult *BetaToolSearchToolResultBlockParam `json:",omitzero,inline"` OfMCPToolUse *BetaMCPToolUseBlockParam `json:",omitzero,inline"` OfMCPToolResult *BetaRequestMCPToolResultBlockParam `json:",omitzero,inline"` OfContainerUpload *BetaContainerUploadBlockParam `json:",omitzero,inline"` + OfCompaction *BetaCompactionBlockParam `json:",omitzero,inline"` paramUnion } @@ -2324,11 +2695,12 @@ func (u BetaContentBlockParamUnion) MarshalJSON() ([]byte, error) { u.OfCodeExecutionToolResult, u.OfBashCodeExecutionToolResult, u.OfTextEditorCodeExecutionToolResult, + u.OfToolSearchToolResult, u.OfMCPToolUse, u.OfMCPToolResult, - u.OfContainerUpload) + u.OfContainerUpload, + u.OfCompaction) } - func (u *BetaContentBlockParamUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -2362,12 +2734,16 @@ func (u *BetaContentBlockParamUnion) asAny() any { return u.OfBashCodeExecutionToolResult } else if !param.IsOmitted(u.OfTextEditorCodeExecutionToolResult) { return u.OfTextEditorCodeExecutionToolResult + } else if !param.IsOmitted(u.OfToolSearchToolResult) { + return u.OfToolSearchToolResult } else if !param.IsOmitted(u.OfMCPToolUse) { return u.OfMCPToolUse } else if !param.IsOmitted(u.OfMCPToolResult) { return u.OfMCPToolResult } else if !param.IsOmitted(u.OfContainerUpload) { return u.OfContainerUpload + } else if !param.IsOmitted(u.OfCompaction) { + return u.OfCompaction } return nil } @@ -2458,12 +2834,16 @@ func (u BetaContentBlockParamUnion) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfTextEditorCodeExecutionToolResult; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolResult; vt != nil { + return (*string)(&vt.Type) } else if vt := u.OfMCPToolUse; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfMCPToolResult; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfContainerUpload; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfCompaction; vt != nil { + return (*string)(&vt.Type) } return nil } @@ -2516,6 +2896,8 @@ func (u BetaContentBlockParamUnion) GetToolUseID() *string { return (*string)(&vt.ToolUseID) } else if vt := u.OfTextEditorCodeExecutionToolResult; vt != nil { return (*string)(&vt.ToolUseID) + } else if vt := u.OfToolSearchToolResult; vt != nil { + return (*string)(&vt.ToolUseID) } else if vt := u.OfMCPToolResult; vt != nil { return (*string)(&vt.ToolUseID) } @@ -2558,12 +2940,16 @@ func (u BetaContentBlockParamUnion) GetCacheControl() *BetaCacheControlEphemeral return &vt.CacheControl } else if vt := u.OfTextEditorCodeExecutionToolResult; vt != nil { return &vt.CacheControl + } else if vt := u.OfToolSearchToolResult; vt != nil { + return &vt.CacheControl } else if vt := u.OfMCPToolUse; vt != nil { return &vt.CacheControl } else if vt := u.OfMCPToolResult; vt != nil { return &vt.CacheControl } else if vt := u.OfContainerUpload; vt != nil { return &vt.CacheControl + } else if vt := u.OfCompaction; vt != nil { + return &vt.CacheControl } return nil } @@ -2579,7 +2965,7 @@ func (u BetaContentBlockParamUnion) GetCitations() (res betaContentBlockParamUni } else if vt := u.OfSearchResult; vt != nil { res.any = &vt.Citations } - return res + return } // Can have the runtime types [*[]BetaTextCitationParamUnion], @@ -2616,7 +3002,7 @@ func (u BetaContentBlockParamUnion) GetSource() (res betaContentBlockParamUnionS } else if vt := u.OfSearchResult; vt != nil { res.any = &vt.Source } - return res + return } // Can have the runtime types [*BetaBase64ImageSourceParam], @@ -2725,22 +3111,29 @@ func (u BetaContentBlockParamUnion) GetContent() (res betaContentBlockParamUnion res.any = vt.Content.asAny() } else if vt := u.OfTextEditorCodeExecutionToolResult; vt != nil { res.any = vt.Content.asAny() + } else if vt := u.OfToolSearchToolResult; vt != nil { + res.any = vt.Content.asAny() } else if vt := u.OfMCPToolResult; vt != nil { res.any = vt.Content.asAny() + } else if vt := u.OfCompaction; vt != nil && vt.Content.Valid() { + res.any = &vt.Content.Value } - return res + return } // Can have the runtime types [_[]BetaTextBlockParam], // [_[]BetaToolResultBlockParamContentUnion], [*[]BetaWebSearchResultBlockParam], // [*BetaWebFetchToolResultErrorBlockParam], [*BetaWebFetchBlockParam], // [*BetaCodeExecutionToolResultErrorParam], [*BetaCodeExecutionResultBlockParam], +// [*BetaEncryptedCodeExecutionResultBlockParam], // [*BetaBashCodeExecutionToolResultErrorParam], // [*BetaBashCodeExecutionResultBlockParam], // [*BetaTextEditorCodeExecutionToolResultErrorParam], // [*BetaTextEditorCodeExecutionViewResultBlockParam], // [*BetaTextEditorCodeExecutionCreateResultBlockParam], -// [*BetaTextEditorCodeExecutionStrReplaceResultBlockParam], [*string] +// [*BetaTextEditorCodeExecutionStrReplaceResultBlockParam], +// [*BetaToolSearchToolResultErrorParam], +// [*BetaToolSearchToolSearchResultBlockParam], [*string] type betaContentBlockParamUnionContent struct{ any } // Use the following switch statement to get the type of the union: @@ -2753,12 +3146,15 @@ type betaContentBlockParamUnionContent struct{ any } // case *anthropic.BetaWebFetchBlockParam: // case *anthropic.BetaCodeExecutionToolResultErrorParam: // case *anthropic.BetaCodeExecutionResultBlockParam: +// case *anthropic.BetaEncryptedCodeExecutionResultBlockParam: // case *anthropic.BetaBashCodeExecutionToolResultErrorParam: // case *anthropic.BetaBashCodeExecutionResultBlockParam: // case *anthropic.BetaTextEditorCodeExecutionToolResultErrorParam: // case *anthropic.BetaTextEditorCodeExecutionViewResultBlockParam: // case *anthropic.BetaTextEditorCodeExecutionCreateResultBlockParam: // case *anthropic.BetaTextEditorCodeExecutionStrReplaceResultBlockParam: +// case *anthropic.BetaToolSearchToolResultErrorParam: +// case *anthropic.BetaToolSearchToolSearchResultBlockParam: // case *string: // default: // fmt.Errorf("not present") @@ -2783,6 +3179,15 @@ func (u betaContentBlockParamUnionContent) GetRetrievedAt() *string { return nil } +// Returns a pointer to the underlying variant's property, if present. +func (u betaContentBlockParamUnionContent) GetEncryptedStdout() *string { + switch vt := u.any.(type) { + case *BetaCodeExecutionToolResultBlockParamContentUnion: + return vt.GetEncryptedStdout() + } + return nil +} + // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetErrorMessage() *string { switch vt := u.any.(type) { @@ -2882,6 +3287,15 @@ func (u betaContentBlockParamUnionContent) GetOldStart() *int64 { return nil } +// Returns a pointer to the underlying variant's property, if present. +func (u betaContentBlockParamUnionContent) GetToolReferences() []BetaToolReferenceBlockParam { + switch vt := u.any.(type) { + case *BetaToolSearchToolResultBlockParamContentUnion: + return vt.GetToolReferences() + } + return nil +} + // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetErrorCode() *string { switch vt := u.any.(type) { @@ -2897,6 +3311,8 @@ func (u betaContentBlockParamUnionContent) GetErrorCode() *string { return vt.GetErrorCode() case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetErrorCode() + case *BetaToolSearchToolResultBlockParamContentUnion: + return vt.GetErrorCode() } return nil } @@ -2916,6 +3332,8 @@ func (u betaContentBlockParamUnionContent) GetType() *string { return vt.GetType() case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetType() + case *BetaToolSearchToolResultBlockParamContentUnion: + return vt.GetType() } return nil } @@ -2999,6 +3417,68 @@ func (u BetaContentBlockParamUnion) GetInput() *any { return nil } +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u BetaContentBlockParamUnion) GetCaller() (res betaContentBlockParamUnionCaller) { + if vt := u.OfToolUse; vt != nil { + res.any = vt.Caller.asAny() + } else if vt := u.OfServerToolUse; vt != nil { + res.any = vt.Caller.asAny() + } else if vt := u.OfWebSearchToolResult; vt != nil { + res.any = vt.Caller.asAny() + } else if vt := u.OfWebFetchToolResult; vt != nil { + res.any = vt.Caller.asAny() + } + return +} + +// Can have the runtime types [*BetaDirectCallerParam], +// [*BetaServerToolCallerParam], [*BetaServerToolCaller20260120Param] +type betaContentBlockParamUnionCaller struct{ any } + +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *anthropic.BetaDirectCallerParam: +// case *anthropic.BetaServerToolCallerParam: +// case *anthropic.BetaServerToolCaller20260120Param: +// default: +// fmt.Errorf("not present") +// } +func (u betaContentBlockParamUnionCaller) AsAny() any { return u.any } + +// Returns a pointer to the underlying variant's property, if present. +func (u betaContentBlockParamUnionCaller) GetType() *string { + switch vt := u.any.(type) { + case *BetaToolUseBlockParamCallerUnion: + return vt.GetType() + case *BetaServerToolUseBlockParamCallerUnion: + return vt.GetType() + case *BetaWebSearchToolResultBlockParamCallerUnion: + return vt.GetType() + case *BetaWebFetchToolResultBlockParamCallerUnion: + return vt.GetType() + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u betaContentBlockParamUnionCaller) GetToolID() *string { + switch vt := u.any.(type) { + case *BetaToolUseBlockParamCallerUnion: + return vt.GetToolID() + case *BetaServerToolUseBlockParamCallerUnion: + return vt.GetToolID() + case *BetaWebSearchToolResultBlockParamCallerUnion: + return vt.GetToolID() + case *BetaWebFetchToolResultBlockParamCallerUnion: + return vt.GetToolID() + } + return nil +} + + // The properties Content, Type are required. type BetaContentBlockSourceParam struct { Content BetaContentBlockSourceContentUnionParam `json:"content,omitzero,required"` @@ -3011,7 +3491,6 @@ func (r BetaContentBlockSourceParam) MarshalJSON() (data []byte, err error) { type shadow BetaContentBlockSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaContentBlockSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3028,7 +3507,6 @@ type BetaContentBlockSourceContentUnionParam struct { func (u BetaContentBlockSourceContentUnionParam) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfString, u.OfBetaContentBlockSourceContent) } - func (u *BetaContentBlockSourceContentUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -3042,10 +3520,9 @@ func (u *BetaContentBlockSourceContentUnionParam) asAny() any { return nil } -// Configuration for context management operations. type BetaContextManagementConfigParam struct { // List of context management edits to apply - Edits []BetaClearToolUses20250919EditParam `json:"edits,omitzero"` + Edits []BetaContextManagementConfigEditUnionParam `json:"edits,omitzero"` paramObj } @@ -3053,74 +3530,315 @@ func (r BetaContextManagementConfigParam) MarshalJSON() (data []byte, err error) type shadow BetaContextManagementConfigParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaContextManagementConfigParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Information about context management operations applied during the request. -type BetaContextManagementResponse struct { - // List of context management edits that were applied. - AppliedEdits []BetaClearToolUses20250919EditResponse `json:"applied_edits,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - AppliedEdits respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaContextManagementConfigEditUnionParam struct { + OfClearToolUses20250919 *BetaClearToolUses20250919EditParam `json:",omitzero,inline"` + OfClearThinking20251015 *BetaClearThinking20251015EditParam `json:",omitzero,inline"` + OfCompact20260112 *BetaCompact20260112EditParam `json:",omitzero,inline"` + paramUnion } -// Returns the unmodified JSON received from the API -func (r BetaContextManagementResponse) RawJSON() string { return r.JSON.raw } - -func (r *BetaContextManagementResponse) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func (u BetaContextManagementConfigEditUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfClearToolUses20250919, u.OfClearThinking20251015, u.OfCompact20260112) } - -type BetaCountTokensContextManagementResponse struct { - // The original token count before context management was applied - OriginalInputTokens int64 `json:"original_input_tokens,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - OriginalInputTokens respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +func (u *BetaContextManagementConfigEditUnionParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) } -// Returns the unmodified JSON received from the API -func (r BetaCountTokensContextManagementResponse) RawJSON() string { return r.JSON.raw } +func (u *BetaContextManagementConfigEditUnionParam) asAny() any { + if !param.IsOmitted(u.OfClearToolUses20250919) { + return u.OfClearToolUses20250919 + } else if !param.IsOmitted(u.OfClearThinking20251015) { + return u.OfClearThinking20251015 + } else if !param.IsOmitted(u.OfCompact20260112) { + return u.OfCompact20260112 + } + return nil +} -func (r *BetaCountTokensContextManagementResponse) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's property, if present. +func (u BetaContextManagementConfigEditUnionParam) GetClearAtLeast() *BetaInputTokensClearAtLeastParam { + if vt := u.OfClearToolUses20250919; vt != nil { + return &vt.ClearAtLeast + } + return nil } -type BetaDocumentBlock struct { - // Citation configuration for the document - Citations BetaCitationConfig `json:"citations,required"` - Source BetaDocumentBlockSourceUnion `json:"source,required"` - // The title of the document - Title string `json:"title,required"` - Type constant.Document `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Citations respjson.Field - Source respjson.Field - Title respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +// Returns a pointer to the underlying variant's property, if present. +func (u BetaContextManagementConfigEditUnionParam) GetClearToolInputs() *BetaClearToolUses20250919EditClearToolInputsUnionParam { + if vt := u.OfClearToolUses20250919; vt != nil { + return &vt.ClearToolInputs + } + return nil } -// Returns the unmodified JSON received from the API -func (r BetaDocumentBlock) RawJSON() string { return r.JSON.raw } +// Returns a pointer to the underlying variant's property, if present. +func (u BetaContextManagementConfigEditUnionParam) GetExcludeTools() []string { + if vt := u.OfClearToolUses20250919; vt != nil { + return vt.ExcludeTools + } + return nil +} -func (r *BetaDocumentBlock) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's property, if present. +func (u BetaContextManagementConfigEditUnionParam) GetInstructions() *string { + if vt := u.OfCompact20260112; vt != nil && vt.Instructions.Valid() { + return &vt.Instructions.Value + } + return nil } -// BetaDocumentBlockSourceUnion contains all possible properties and values from +// Returns a pointer to the underlying variant's property, if present. +func (u BetaContextManagementConfigEditUnionParam) GetPauseAfterCompaction() *bool { + if vt := u.OfCompact20260112; vt != nil && vt.PauseAfterCompaction.Valid() { + return &vt.PauseAfterCompaction.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaContextManagementConfigEditUnionParam) GetType() *string { + if vt := u.OfClearToolUses20250919; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfClearThinking20251015; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCompact20260112; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u BetaContextManagementConfigEditUnionParam) GetKeep() (res betaContextManagementConfigEditUnionParamKeep) { + if vt := u.OfClearToolUses20250919; vt != nil { + res.any = &vt.Keep + } else if vt := u.OfClearThinking20251015; vt != nil { + res.any = vt.Keep.asAny() + } + return +} + +// Can have the runtime types [*BetaToolUsesKeepParam], [*string] +type betaContextManagementConfigEditUnionParamKeep struct{ any } + +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *anthropic.BetaToolUsesKeepParam: +// case *string: +// default: +// fmt.Errorf("not present") +// } +func (u betaContextManagementConfigEditUnionParamKeep) AsAny() any { return u.any } + +// Returns a pointer to the underlying variant's property, if present. +func (u betaContextManagementConfigEditUnionParamKeep) GetType() *string { + switch vt := u.any.(type) { + case *BetaToolUsesKeepParam: + return (*string)(&vt.Type) + case *BetaClearThinking20251015EditKeepUnionParam: + return vt.GetType() + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u betaContextManagementConfigEditUnionParamKeep) GetValue() *int64 { + switch vt := u.any.(type) { + case *BetaToolUsesKeepParam: + return (*int64)(&vt.Value) + case *BetaClearThinking20251015EditKeepUnionParam: + return vt.GetValue() + } + return nil +} + + +type BetaContextManagementResponse struct { + // List of context management edits that were applied. + AppliedEdits []BetaContextManagementResponseAppliedEditUnion `json:"applied_edits,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + AppliedEdits respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaContextManagementResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaContextManagementResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// BetaContextManagementResponseAppliedEditUnion contains all possible properties +// and values from [BetaClearToolUses20250919EditResponse], +// [BetaClearThinking20251015EditResponse]. +// +// Use the [BetaContextManagementResponseAppliedEditUnion.AsAny] method to switch +// on the variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type BetaContextManagementResponseAppliedEditUnion struct { + ClearedInputTokens int64 `json:"cleared_input_tokens"` + // This field is from variant [BetaClearToolUses20250919EditResponse]. + ClearedToolUses int64 `json:"cleared_tool_uses"` + // Any of "clear_tool_uses_20250919", "clear_thinking_20251015". + Type string `json:"type"` + // This field is from variant [BetaClearThinking20251015EditResponse]. + ClearedThinkingTurns int64 `json:"cleared_thinking_turns"` + JSON struct { + ClearedInputTokens respjson.Field + ClearedToolUses respjson.Field + Type respjson.Field + ClearedThinkingTurns respjson.Field + raw string + } `json:"-"` +} + +// anyBetaContextManagementResponseAppliedEdit is implemented by each variant of +// [BetaContextManagementResponseAppliedEditUnion] to add type safety for the +// return type of [BetaContextManagementResponseAppliedEditUnion.AsAny] +type anyBetaContextManagementResponseAppliedEdit interface { + implBetaContextManagementResponseAppliedEditUnion() +} + +func (BetaClearToolUses20250919EditResponse) implBetaContextManagementResponseAppliedEditUnion() {} +func (BetaClearThinking20251015EditResponse) implBetaContextManagementResponseAppliedEditUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := BetaContextManagementResponseAppliedEditUnion.AsAny().(type) { +// case anthropic.BetaClearToolUses20250919EditResponse: +// case anthropic.BetaClearThinking20251015EditResponse: +// default: +// fmt.Errorf("no variant present") +// } +func (u BetaContextManagementResponseAppliedEditUnion) AsAny() anyBetaContextManagementResponseAppliedEdit { + switch u.Type { + case "clear_tool_uses_20250919": + return u.AsClearToolUses20250919() + case "clear_thinking_20251015": + return u.AsClearThinking20251015() + } + return nil +} + +func (u BetaContextManagementResponseAppliedEditUnion) AsClearToolUses20250919() (v BetaClearToolUses20250919EditResponse) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaContextManagementResponseAppliedEditUnion) AsClearThinking20251015() (v BetaClearThinking20251015EditResponse) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u BetaContextManagementResponseAppliedEditUnion) RawJSON() string { return u.JSON.raw } + +func (r *BetaContextManagementResponseAppliedEditUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaCountTokensContextManagementResponse struct { + // The original token count before context management was applied + OriginalInputTokens int64 `json:"original_input_tokens,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + OriginalInputTokens respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaCountTokensContextManagementResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaCountTokensContextManagementResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Tool invocation directly from the model. +type BetaDirectCaller struct { + Type constant.Direct `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaDirectCaller) RawJSON() string { return r.JSON.raw } +func (r *BetaDirectCaller) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this BetaDirectCaller to a BetaDirectCallerParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// BetaDirectCallerParam.Overrides() +func (r BetaDirectCaller) ToParam() BetaDirectCallerParam { + return param.Override[BetaDirectCallerParam](json.RawMessage(r.RawJSON())) +} + +func NewBetaDirectCallerParam() BetaDirectCallerParam { + return BetaDirectCallerParam{ + Type: "direct", + } +} + +// Tool invocation directly from the model. +// +// This struct has a constant value, construct it with [NewBetaDirectCallerParam]. +type BetaDirectCallerParam struct { + Type constant.Direct `json:"type,required"` + paramObj +} + +func (r BetaDirectCallerParam) MarshalJSON() (data []byte, err error) { + type shadow BetaDirectCallerParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaDirectCallerParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaDocumentBlock struct { + // Citation configuration for the document + Citations BetaCitationConfig `json:"citations,required"` + Source BetaDocumentBlockSourceUnion `json:"source,required"` + // The title of the document + Title string `json:"title,required"` + Type constant.Document `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Citations respjson.Field + Source respjson.Field + Title respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaDocumentBlock) RawJSON() string { return r.JSON.raw } +func (r *BetaDocumentBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// BetaDocumentBlockSourceUnion contains all possible properties and values from // [BetaBase64PDFSource], [BetaPlainTextSource]. // // Use the [BetaDocumentBlockSourceUnion.AsAny] method to switch on the variant. @@ -3169,12 +3887,12 @@ func (u BetaDocumentBlockSourceUnion) AsAny() anyBetaDocumentBlockSource { func (u BetaDocumentBlockSourceUnion) AsBase64() (v BetaBase64PDFSource) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaDocumentBlockSourceUnion) AsText() (v BetaPlainTextSource) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -3184,6 +3902,53 @@ func (r *BetaDocumentBlockSourceUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Code execution result with encrypted stdout for PFC + web_search results. +type BetaEncryptedCodeExecutionResultBlock struct { + Content []BetaCodeExecutionOutputBlock `json:"content,required"` + EncryptedStdout string `json:"encrypted_stdout,required"` + ReturnCode int64 `json:"return_code,required"` + Stderr string `json:"stderr,required"` + Type constant.EncryptedCodeExecutionResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + EncryptedStdout respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaEncryptedCodeExecutionResultBlock) RawJSON() string { return r.JSON.raw } +func (r *BetaEncryptedCodeExecutionResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Code execution result with encrypted stdout for PFC + web_search results. +// +// The properties Content, EncryptedStdout, ReturnCode, Stderr, Type are required. +type BetaEncryptedCodeExecutionResultBlockParam struct { + Content []BetaCodeExecutionOutputBlockParam `json:"content,omitzero,required"` + EncryptedStdout string `json:"encrypted_stdout,required"` + ReturnCode int64 `json:"return_code,required"` + Stderr string `json:"stderr,required"` + // This field can be elided, and will marshal its zero value as + // "encrypted_code_execution_result". + Type constant.EncryptedCodeExecutionResult `json:"type,required"` + paramObj +} + +func (r BetaEncryptedCodeExecutionResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BetaEncryptedCodeExecutionResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaEncryptedCodeExecutionResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // The properties FileID, Type are required. type BetaFileDocumentSourceParam struct { FileID string `json:"file_id,required"` @@ -3196,7 +3961,6 @@ func (r BetaFileDocumentSourceParam) MarshalJSON() (data []byte, err error) { type shadow BetaFileDocumentSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaFileDocumentSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3213,7 +3977,6 @@ func (r BetaFileImageSourceParam) MarshalJSON() (data []byte, err error) { type shadow BetaFileImageSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaFileImageSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3232,7 +3995,6 @@ func (r BetaImageBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaImageBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaImageBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3250,7 +4012,6 @@ type BetaImageBlockParamSourceUnion struct { func (u BetaImageBlockParamSourceUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfBase64, u.OfURL, u.OfFile) } - func (u *BetaImageBlockParamSourceUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -3324,7 +4085,6 @@ type BetaInputJSONDelta struct { // Returns the unmodified JSON received from the API func (r BetaInputJSONDelta) RawJSON() string { return r.JSON.raw } - func (r *BetaInputJSONDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3341,7 +4101,6 @@ func (r BetaInputTokensClearAtLeastParam) MarshalJSON() (data []byte, err error) type shadow BetaInputTokensClearAtLeastParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaInputTokensClearAtLeastParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3358,11 +4117,99 @@ func (r BetaInputTokensTriggerParam) MarshalJSON() (data []byte, err error) { type shadow BetaInputTokensTriggerParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaInputTokensTriggerParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +type BetaIterationsUsage []BetaIterationsUsageItemUnion + +// BetaIterationsUsageItemUnion contains all possible properties and values from +// [BetaMessageIterationUsage], [BetaCompactionIterationUsage]. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type BetaIterationsUsageItemUnion struct { + // This field is from variant [BetaMessageIterationUsage]. + CacheCreation BetaCacheCreation `json:"cache_creation"` + CacheCreationInputTokens int64 `json:"cache_creation_input_tokens"` + CacheReadInputTokens int64 `json:"cache_read_input_tokens"` + InputTokens int64 `json:"input_tokens"` + OutputTokens int64 `json:"output_tokens"` + Type string `json:"type"` + JSON struct { + CacheCreation respjson.Field + CacheCreationInputTokens respjson.Field + CacheReadInputTokens respjson.Field + InputTokens respjson.Field + OutputTokens respjson.Field + Type respjson.Field + raw string + } `json:"-"` +} + +func (u BetaIterationsUsageItemUnion) AsMessageIterationUsage() (v BetaMessageIterationUsage) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaIterationsUsageItemUnion) AsCompactionIterationUsage() (v BetaCompactionIterationUsage) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u BetaIterationsUsageItemUnion) RawJSON() string { return u.JSON.raw } + +func (r *BetaIterationsUsageItemUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Schema, Type are required. +type BetaJSONOutputFormatParam struct { + // The JSON schema of the format + Schema map[string]any `json:"schema,omitzero,required"` + // This field can be elided, and will marshal its zero value as "json_schema". + Type constant.JSONSchema `json:"type,required"` + paramObj +} + +func (r BetaJSONOutputFormatParam) MarshalJSON() (data []byte, err error) { + type shadow BetaJSONOutputFormatParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaJSONOutputFormatParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Configuration for a specific tool in an MCP toolset. +type BetaMCPToolConfigParam struct { + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + Enabled param.Opt[bool] `json:"enabled,omitzero"` + paramObj +} + +func (r BetaMCPToolConfigParam) MarshalJSON() (data []byte, err error) { + type shadow BetaMCPToolConfigParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaMCPToolConfigParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Default configuration for tools in an MCP toolset. +type BetaMCPToolDefaultConfigParam struct { + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + Enabled param.Opt[bool] `json:"enabled,omitzero"` + paramObj +} + +func (r BetaMCPToolDefaultConfigParam) MarshalJSON() (data []byte, err error) { + type shadow BetaMCPToolDefaultConfigParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaMCPToolDefaultConfigParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + type BetaMCPToolResultBlock struct { Content BetaMCPToolResultBlockContentUnion `json:"content,required"` IsError bool `json:"is_error,required"` @@ -3381,7 +4228,6 @@ type BetaMCPToolResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaMCPToolResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaMCPToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3408,12 +4254,12 @@ type BetaMCPToolResultBlockContentUnion struct { func (u BetaMCPToolResultBlockContentUnion) AsString() (v string) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaMCPToolResultBlockContentUnion) AsBetaMCPToolResultBlockContent() (v []BetaTextBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -3445,7 +4291,6 @@ type BetaMCPToolUseBlock struct { // Returns the unmodified JSON received from the API func (r BetaMCPToolUseBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaMCPToolUseBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3468,15 +4313,50 @@ func (r BetaMCPToolUseBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaMCPToolUseBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaMCPToolUseBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Configuration for a group of tools from an MCP server. +// +// Allows configuring enabled status and defer_loading for all tools from an MCP +// server, with optional per-tool overrides. +// +// The properties MCPServerName, Type are required. +type BetaMCPToolsetParam struct { + // Name of the MCP server to configure tools for + MCPServerName string `json:"mcp_server_name,required"` + // Configuration overrides for specific tools, keyed by tool name + Configs map[string]BetaMCPToolConfigParam `json:"configs,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Default configuration applied to all tools from this server + DefaultConfig BetaMCPToolDefaultConfigParam `json:"default_config,omitzero"` + // This field can be elided, and will marshal its zero value as "mcp_toolset". + Type constant.MCPToolset `json:"type,required"` + paramObj +} + +func (r BetaMCPToolsetParam) MarshalJSON() (data []byte, err error) { + type shadow BetaMCPToolsetParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaMCPToolsetParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // The properties Name, Type are required. type BetaMemoryTool20250818Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -3492,7 +4372,6 @@ func (r BetaMemoryTool20250818Param) MarshalJSON() (data []byte, err error) { type shadow BetaMemoryTool20250818Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaMemoryTool20250818Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3588,32 +4467,32 @@ func (u BetaMemoryTool20250818CommandUnion) AsAny() anyBetaMemoryTool20250818Com func (u BetaMemoryTool20250818CommandUnion) AsView() (v BetaMemoryTool20250818ViewCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaMemoryTool20250818CommandUnion) AsCreate() (v BetaMemoryTool20250818CreateCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaMemoryTool20250818CommandUnion) AsStrReplace() (v BetaMemoryTool20250818StrReplaceCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaMemoryTool20250818CommandUnion) AsInsert() (v BetaMemoryTool20250818InsertCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaMemoryTool20250818CommandUnion) AsDelete() (v BetaMemoryTool20250818DeleteCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaMemoryTool20250818CommandUnion) AsRename() (v BetaMemoryTool20250818RenameCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -3642,7 +4521,6 @@ type BetaMemoryTool20250818CreateCommand struct { // Returns the unmodified JSON received from the API func (r BetaMemoryTool20250818CreateCommand) RawJSON() string { return r.JSON.raw } - func (r *BetaMemoryTool20250818CreateCommand) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3663,7 +4541,6 @@ type BetaMemoryTool20250818DeleteCommand struct { // Returns the unmodified JSON received from the API func (r BetaMemoryTool20250818DeleteCommand) RawJSON() string { return r.JSON.raw } - func (r *BetaMemoryTool20250818DeleteCommand) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3690,7 +4567,6 @@ type BetaMemoryTool20250818InsertCommand struct { // Returns the unmodified JSON received from the API func (r BetaMemoryTool20250818InsertCommand) RawJSON() string { return r.JSON.raw } - func (r *BetaMemoryTool20250818InsertCommand) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3714,7 +4590,6 @@ type BetaMemoryTool20250818RenameCommand struct { // Returns the unmodified JSON received from the API func (r BetaMemoryTool20250818RenameCommand) RawJSON() string { return r.JSON.raw } - func (r *BetaMemoryTool20250818RenameCommand) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3741,7 +4616,6 @@ type BetaMemoryTool20250818StrReplaceCommand struct { // Returns the unmodified JSON received from the API func (r BetaMemoryTool20250818StrReplaceCommand) RawJSON() string { return r.JSON.raw } - func (r *BetaMemoryTool20250818StrReplaceCommand) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3765,7 +4639,6 @@ type BetaMemoryTool20250818ViewCommand struct { // Returns the unmodified JSON received from the API func (r BetaMemoryTool20250818ViewCommand) RawJSON() string { return r.JSON.raw } - func (r *BetaMemoryTool20250818ViewCommand) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -3813,7 +4686,9 @@ type BetaMessage struct { // [{ "type": "text", "text": "B)" }] // ``` Content []BetaContentBlockUnion `json:"content,required"` - // Information about context management operations applied during the request. + // Context management response. + // + // Information about context management strategies applied during the request. ContextManagement BetaContextManagementResponse `json:"context_management,required"` // The model that will complete your prompt.\n\nSee // [models](https://docs.anthropic.com/en/docs/models-overview) for additional @@ -3840,7 +4715,7 @@ type BetaMessage struct { // null in the `message_start` event and non-null otherwise. // // Any of "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", - // "refusal", "model_context_window_exceeded". + // "compaction", "refusal", "model_context_window_exceeded". StopReason BetaStopReason `json:"stop_reason,required"` // Which custom stop sequence was generated, if any. // @@ -3886,22 +4761,10 @@ type BetaMessage struct { // Returns the unmodified JSON received from the API func (r BetaMessage) RawJSON() string { return r.JSON.raw } - func (r *BetaMessage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r BetaMessage) ToParam() BetaMessageParam { - var p BetaMessageParam - p.Role = BetaMessageParamRole(r.Role) - p.Content = make([]BetaContentBlockParamUnion, len(r.Content)) - for i, c := range r.Content { - contentParams := c.ToParam() - p.Content[i] = contentParams - } - return p -} - // The reason that we stopped. // // This may be one the following values: @@ -3929,6 +4792,15 @@ type BetaMessageDeltaUsage struct { CacheReadInputTokens int64 `json:"cache_read_input_tokens,required"` // The cumulative number of input tokens which were used. InputTokens int64 `json:"input_tokens,required"` + // Per-iteration token usage breakdown. + // + // Each entry represents one sampling iteration, with its own input/output token + // counts and cache statistics. This allows you to: + // + // - Determine which iterations exceeded long context thresholds (>=200k tokens) + // - Calculate the true context window size from the last iteration + // - Understand token accumulation across server-side tool use loops + Iterations BetaIterationsUsage `json:"iterations,required"` // The cumulative number of output tokens which were used. OutputTokens int64 `json:"output_tokens,required"` // The number of server tool requests. @@ -3938,6 +4810,7 @@ type BetaMessageDeltaUsage struct { CacheCreationInputTokens respjson.Field CacheReadInputTokens respjson.Field InputTokens respjson.Field + Iterations respjson.Field OutputTokens respjson.Field ServerToolUse respjson.Field ExtraFields map[string]respjson.Field @@ -3947,11 +4820,43 @@ type BetaMessageDeltaUsage struct { // Returns the unmodified JSON received from the API func (r BetaMessageDeltaUsage) RawJSON() string { return r.JSON.raw } - func (r *BetaMessageDeltaUsage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Token usage for a sampling iteration. +type BetaMessageIterationUsage struct { + // Breakdown of cached tokens by TTL + CacheCreation BetaCacheCreation `json:"cache_creation,required"` + // The number of input tokens used to create the cache entry. + CacheCreationInputTokens int64 `json:"cache_creation_input_tokens,required"` + // The number of input tokens read from the cache. + CacheReadInputTokens int64 `json:"cache_read_input_tokens,required"` + // The number of input tokens which were used. + InputTokens int64 `json:"input_tokens,required"` + // The number of output tokens which were used. + OutputTokens int64 `json:"output_tokens,required"` + // Usage for a sampling iteration + Type constant.Message `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + CacheCreation respjson.Field + CacheCreationInputTokens respjson.Field + CacheReadInputTokens respjson.Field + InputTokens respjson.Field + OutputTokens respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaMessageIterationUsage) RawJSON() string { return r.JSON.raw } +func (r *BetaMessageIterationUsage) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // The properties Content, Role are required. type BetaMessageParam struct { Content []BetaContentBlockParamUnion `json:"content,omitzero,required"` @@ -3971,7 +4876,6 @@ func (r BetaMessageParam) MarshalJSON() (data []byte, err error) { type shadow BetaMessageParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaMessageParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4000,7 +4904,6 @@ type BetaMessageTokensCount struct { // Returns the unmodified JSON received from the API func (r BetaMessageTokensCount) RawJSON() string { return r.JSON.raw } - func (r *BetaMessageTokensCount) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4019,11 +4922,39 @@ func (r BetaMetadataParam) MarshalJSON() (data []byte, err error) { type shadow BetaMetadataParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaMetadataParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +type BetaOutputConfigParam struct { + // All possible effort levels. + // + // Any of "low", "medium", "high", "max". + Effort BetaOutputConfigEffort `json:"effort,omitzero"` + // A schema to specify Claude's output format in responses. See + // [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + Format BetaJSONOutputFormatParam `json:"format,omitzero"` + paramObj +} + +func (r BetaOutputConfigParam) MarshalJSON() (data []byte, err error) { + type shadow BetaOutputConfigParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaOutputConfigParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// All possible effort levels. +type BetaOutputConfigEffort string + +const ( + BetaOutputConfigEffortLow BetaOutputConfigEffort = "low" + BetaOutputConfigEffortMedium BetaOutputConfigEffort = "medium" + BetaOutputConfigEffortHigh BetaOutputConfigEffort = "high" + BetaOutputConfigEffortMax BetaOutputConfigEffort = "max" +) + type BetaPlainTextSource struct { Data string `json:"data,required"` MediaType constant.TextPlain `json:"media_type,required"` @@ -4040,7 +4971,6 @@ type BetaPlainTextSource struct { // Returns the unmodified JSON received from the API func (r BetaPlainTextSource) RawJSON() string { return r.JSON.raw } - func (r *BetaPlainTextSource) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4068,14 +4998,13 @@ func (r BetaPlainTextSourceParam) MarshalJSON() (data []byte, err error) { type shadow BetaPlainTextSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaPlainTextSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaRawContentBlockDeltaUnion contains all possible properties and values from // [BetaTextDelta], [BetaInputJSONDelta], [BetaCitationsDelta], -// [BetaThinkingDelta], [BetaSignatureDelta]. +// [BetaThinkingDelta], [BetaSignatureDelta], [BetaCompactionContentBlockDelta]. // // Use the [BetaRawContentBlockDeltaUnion.AsAny] method to switch on the variant. // @@ -4084,7 +5013,7 @@ type BetaRawContentBlockDeltaUnion struct { // This field is from variant [BetaTextDelta]. Text string `json:"text"` // Any of "text_delta", "input_json_delta", "citations_delta", "thinking_delta", - // "signature_delta". + // "signature_delta", "compaction_delta". Type string `json:"type"` // This field is from variant [BetaInputJSONDelta]. PartialJSON string `json:"partial_json"` @@ -4094,13 +5023,16 @@ type BetaRawContentBlockDeltaUnion struct { Thinking string `json:"thinking"` // This field is from variant [BetaSignatureDelta]. Signature string `json:"signature"` - JSON struct { + // This field is from variant [BetaCompactionContentBlockDelta]. + Content string `json:"content"` + JSON struct { Text respjson.Field Type respjson.Field PartialJSON respjson.Field Citation respjson.Field Thinking respjson.Field Signature respjson.Field + Content respjson.Field raw string } `json:"-"` } @@ -4112,11 +5044,12 @@ type anyBetaRawContentBlockDelta interface { implBetaRawContentBlockDeltaUnion() } -func (BetaTextDelta) implBetaRawContentBlockDeltaUnion() {} -func (BetaInputJSONDelta) implBetaRawContentBlockDeltaUnion() {} -func (BetaCitationsDelta) implBetaRawContentBlockDeltaUnion() {} -func (BetaThinkingDelta) implBetaRawContentBlockDeltaUnion() {} -func (BetaSignatureDelta) implBetaRawContentBlockDeltaUnion() {} +func (BetaTextDelta) implBetaRawContentBlockDeltaUnion() {} +func (BetaInputJSONDelta) implBetaRawContentBlockDeltaUnion() {} +func (BetaCitationsDelta) implBetaRawContentBlockDeltaUnion() {} +func (BetaThinkingDelta) implBetaRawContentBlockDeltaUnion() {} +func (BetaSignatureDelta) implBetaRawContentBlockDeltaUnion() {} +func (BetaCompactionContentBlockDelta) implBetaRawContentBlockDeltaUnion() {} // Use the following switch statement to find the correct variant // @@ -4126,6 +5059,7 @@ func (BetaSignatureDelta) implBetaRawContentBlockDeltaUnion() {} // case anthropic.BetaCitationsDelta: // case anthropic.BetaThinkingDelta: // case anthropic.BetaSignatureDelta: +// case anthropic.BetaCompactionContentBlockDelta: // default: // fmt.Errorf("no variant present") // } @@ -4141,33 +5075,40 @@ func (u BetaRawContentBlockDeltaUnion) AsAny() anyBetaRawContentBlockDelta { return u.AsThinkingDelta() case "signature_delta": return u.AsSignatureDelta() + case "compaction_delta": + return u.AsCompactionDelta() } return nil } func (u BetaRawContentBlockDeltaUnion) AsTextDelta() (v BetaTextDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockDeltaUnion) AsInputJSONDelta() (v BetaInputJSONDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockDeltaUnion) AsCitationsDelta() (v BetaCitationsDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockDeltaUnion) AsThinkingDelta() (v BetaThinkingDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockDeltaUnion) AsSignatureDelta() (v BetaSignatureDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return +} + +func (u BetaRawContentBlockDeltaUnion) AsCompactionDelta() (v BetaCompactionContentBlockDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } // Returns the unmodified JSON received from the API @@ -4193,7 +5134,6 @@ type BetaRawContentBlockDeltaEvent struct { // Returns the unmodified JSON received from the API func (r BetaRawContentBlockDeltaEvent) RawJSON() string { return r.JSON.raw } - func (r *BetaRawContentBlockDeltaEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4215,7 +5155,6 @@ type BetaRawContentBlockStartEvent struct { // Returns the unmodified JSON received from the API func (r BetaRawContentBlockStartEvent) RawJSON() string { return r.JSON.raw } - func (r *BetaRawContentBlockStartEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4225,8 +5164,9 @@ func (r *BetaRawContentBlockStartEvent) UnmarshalJSON(data []byte) error { // [BetaRedactedThinkingBlock], [BetaToolUseBlock], [BetaServerToolUseBlock], // [BetaWebSearchToolResultBlock], [BetaWebFetchToolResultBlock], // [BetaCodeExecutionToolResultBlock], [BetaBashCodeExecutionToolResultBlock], -// [BetaTextEditorCodeExecutionToolResultBlock], [BetaMCPToolUseBlock], -// [BetaMCPToolResultBlock], [BetaContainerUploadBlock]. +// [BetaTextEditorCodeExecutionToolResultBlock], [BetaToolSearchToolResultBlock], +// [BetaMCPToolUseBlock], [BetaMCPToolResultBlock], [BetaContainerUploadBlock], +// [BetaCompactionBlock]. // // Use the [BetaRawContentBlockStartEventContentBlockUnion.AsAny] method to switch // on the variant. @@ -4240,7 +5180,8 @@ type BetaRawContentBlockStartEventContentBlockUnion struct { // Any of "text", "thinking", "redacted_thinking", "tool_use", "server_tool_use", // "web_search_tool_result", "web_fetch_tool_result", "code_execution_tool_result", // "bash_code_execution_tool_result", "text_editor_code_execution_tool_result", - // "mcp_tool_use", "mcp_tool_result", "container_upload". + // "tool_search_tool_result", "mcp_tool_use", "mcp_tool_result", + // "container_upload", "compaction". Type string `json:"type"` // This field is from variant [BetaThinkingBlock]. Signature string `json:"signature"` @@ -4251,12 +5192,17 @@ type BetaRawContentBlockStartEventContentBlockUnion struct { ID string `json:"id"` Input any `json:"input"` Name string `json:"name"` + // This field is a union of [BetaToolUseBlockCallerUnion], + // [BetaServerToolUseBlockCallerUnion], [BetaWebSearchToolResultBlockCallerUnion], + // [BetaWebFetchToolResultBlockCallerUnion] + Caller BetaRawContentBlockStartEventContentBlockUnionCaller `json:"caller"` // This field is a union of [BetaWebSearchToolResultBlockContentUnion], // [BetaWebFetchToolResultBlockContentUnion], // [BetaCodeExecutionToolResultBlockContentUnion], // [BetaBashCodeExecutionToolResultBlockContentUnion], // [BetaTextEditorCodeExecutionToolResultBlockContentUnion], - // [BetaMCPToolResultBlockContentUnion] + // [BetaToolSearchToolResultBlockContentUnion], + // [BetaMCPToolResultBlockContentUnion], [string] Content BetaRawContentBlockStartEventContentBlockUnionContent `json:"content"` ToolUseID string `json:"tool_use_id"` // This field is from variant [BetaMCPToolUseBlock]. @@ -4275,6 +5221,7 @@ type BetaRawContentBlockStartEventContentBlockUnion struct { ID respjson.Field Input respjson.Field Name respjson.Field + Caller respjson.Field Content respjson.Field ToolUseID respjson.Field ServerName respjson.Field @@ -4302,9 +5249,11 @@ func (BetaCodeExecutionToolResultBlock) implBetaRawContentBlockStartEventContent func (BetaBashCodeExecutionToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaTextEditorCodeExecutionToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() { } -func (BetaMCPToolUseBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} -func (BetaMCPToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} -func (BetaContainerUploadBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} +func (BetaToolSearchToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} +func (BetaMCPToolUseBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} +func (BetaMCPToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} +func (BetaContainerUploadBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} +func (BetaCompactionBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} // Use the following switch statement to find the correct variant // @@ -4319,9 +5268,11 @@ func (BetaContainerUploadBlock) implBetaRawContentBlockStartEventContentBlockUni // case anthropic.BetaCodeExecutionToolResultBlock: // case anthropic.BetaBashCodeExecutionToolResultBlock: // case anthropic.BetaTextEditorCodeExecutionToolResultBlock: +// case anthropic.BetaToolSearchToolResultBlock: // case anthropic.BetaMCPToolUseBlock: // case anthropic.BetaMCPToolResultBlock: // case anthropic.BetaContainerUploadBlock: +// case anthropic.BetaCompactionBlock: // default: // fmt.Errorf("no variant present") // } @@ -4347,79 +5298,93 @@ func (u BetaRawContentBlockStartEventContentBlockUnion) AsAny() anyBetaRawConten return u.AsBashCodeExecutionToolResult() case "text_editor_code_execution_tool_result": return u.AsTextEditorCodeExecutionToolResult() + case "tool_search_tool_result": + return u.AsToolSearchToolResult() case "mcp_tool_use": return u.AsMCPToolUse() case "mcp_tool_result": return u.AsMCPToolResult() case "container_upload": return u.AsContainerUpload() + case "compaction": + return u.AsCompaction() } return nil } func (u BetaRawContentBlockStartEventContentBlockUnion) AsText() (v BetaTextBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsThinking() (v BetaThinkingBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsRedactedThinking() (v BetaRedactedThinkingBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsToolUse() (v BetaToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsServerToolUse() (v BetaServerToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsWebSearchToolResult() (v BetaWebSearchToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsWebFetchToolResult() (v BetaWebFetchToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsCodeExecutionToolResult() (v BetaCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsBashCodeExecutionToolResult() (v BetaBashCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsTextEditorCodeExecutionToolResult() (v BetaTextEditorCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return +} + +func (u BetaRawContentBlockStartEventContentBlockUnion) AsToolSearchToolResult() (v BetaToolSearchToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsMCPToolUse() (v BetaMCPToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsMCPToolResult() (v BetaMCPToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsContainerUpload() (v BetaContainerUploadBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return +} + +func (u BetaRawContentBlockStartEventContentBlockUnion) AsCompaction() (v BetaCompactionBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } // Returns the unmodified JSON received from the API @@ -4429,6 +5394,27 @@ func (r *BetaRawContentBlockStartEventContentBlockUnion) UnmarshalJSON(data []by return apijson.UnmarshalRoot(data, r) } +// BetaRawContentBlockStartEventContentBlockUnionCaller is an implicit subunion of +// [BetaRawContentBlockStartEventContentBlockUnion]. +// BetaRawContentBlockStartEventContentBlockUnionCaller provides convenient access +// to the sub-properties of the union. +// +// For type safety it is recommended to directly use a variant of the +// [BetaRawContentBlockStartEventContentBlockUnion]. +type BetaRawContentBlockStartEventContentBlockUnionCaller struct { + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +func (r *BetaRawContentBlockStartEventContentBlockUnionCaller) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // BetaRawContentBlockStartEventContentBlockUnionContent is an implicit subunion of // [BetaRawContentBlockStartEventContentBlockUnion]. // BetaRawContentBlockStartEventContentBlockUnionContent provides convenient access @@ -4452,7 +5438,7 @@ type BetaRawContentBlockStartEventContentBlockUnionContent struct { ErrorCode string `json:"error_code"` Type string `json:"type"` // This field is a union of [BetaDocumentBlock], [[]BetaCodeExecutionOutputBlock], - // [[]BetaBashCodeExecutionOutputBlock], [string] + // [[]BetaCodeExecutionOutputBlock], [[]BetaBashCodeExecutionOutputBlock], [string] Content BetaRawContentBlockStartEventContentBlockUnionContentContent `json:"content"` // This field is from variant [BetaWebFetchToolResultBlockContentUnion]. RetrievedAt string `json:"retrieved_at"` @@ -4461,9 +5447,9 @@ type BetaRawContentBlockStartEventContentBlockUnionContent struct { ReturnCode int64 `json:"return_code"` Stderr string `json:"stderr"` Stdout string `json:"stdout"` - // This field is from variant - // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. - ErrorMessage string `json:"error_message"` + // This field is from variant [BetaCodeExecutionToolResultBlockContentUnion]. + EncryptedStdout string `json:"encrypted_stdout"` + ErrorMessage string `json:"error_message"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. FileType BetaTextEditorCodeExecutionViewResultBlockFileType `json:"file_type"` @@ -4494,7 +5480,9 @@ type BetaRawContentBlockStartEventContentBlockUnionContent struct { // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. OldStart int64 `json:"old_start"` - JSON struct { + // This field is from variant [BetaToolSearchToolResultBlockContentUnion]. + ToolReferences []BetaToolReferenceBlock `json:"tool_references"` + JSON struct { OfBetaWebSearchResultBlockArray respjson.Field OfString respjson.Field OfBetaMCPToolResultBlockContent respjson.Field @@ -4506,6 +5494,7 @@ type BetaRawContentBlockStartEventContentBlockUnionContent struct { ReturnCode respjson.Field Stderr respjson.Field Stdout respjson.Field + EncryptedStdout respjson.Field ErrorMessage respjson.Field FileType respjson.Field NumLines respjson.Field @@ -4517,6 +5506,7 @@ type BetaRawContentBlockStartEventContentBlockUnionContent struct { NewStart respjson.Field OldLines respjson.Field OldStart respjson.Field + ToolReferences respjson.Field raw string } `json:"-"` } @@ -4578,13 +5568,12 @@ type BetaRawContentBlockStopEvent struct { // Returns the unmodified JSON received from the API func (r BetaRawContentBlockStopEvent) RawJSON() string { return r.JSON.raw } - func (r *BetaRawContentBlockStopEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRawMessageDeltaEvent struct { - // Information about context management operations applied during the request. + // Information about context management strategies applied during the request ContextManagement BetaContextManagementResponse `json:"context_management,required"` Delta BetaRawMessageDeltaEventDelta `json:"delta,required"` Type constant.MessageDelta `json:"type,required"` @@ -4617,7 +5606,6 @@ type BetaRawMessageDeltaEvent struct { // Returns the unmodified JSON received from the API func (r BetaRawMessageDeltaEvent) RawJSON() string { return r.JSON.raw } - func (r *BetaRawMessageDeltaEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4627,7 +5615,7 @@ type BetaRawMessageDeltaEventDelta struct { // tool) Container BetaContainer `json:"container,required"` // Any of "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", - // "refusal", "model_context_window_exceeded". + // "compaction", "refusal", "model_context_window_exceeded". StopReason BetaStopReason `json:"stop_reason,required"` StopSequence string `json:"stop_sequence,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. @@ -4642,7 +5630,6 @@ type BetaRawMessageDeltaEventDelta struct { // Returns the unmodified JSON received from the API func (r BetaRawMessageDeltaEventDelta) RawJSON() string { return r.JSON.raw } - func (r *BetaRawMessageDeltaEventDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4661,7 +5648,6 @@ type BetaRawMessageStartEvent struct { // Returns the unmodified JSON received from the API func (r BetaRawMessageStartEvent) RawJSON() string { return r.JSON.raw } - func (r *BetaRawMessageStartEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4678,7 +5664,6 @@ type BetaRawMessageStopEvent struct { // Returns the unmodified JSON received from the API func (r BetaRawMessageStopEvent) RawJSON() string { return r.JSON.raw } - func (r *BetaRawMessageStopEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4765,32 +5750,32 @@ func (u BetaRawMessageStreamEventUnion) AsAny() anyBetaRawMessageStreamEvent { func (u BetaRawMessageStreamEventUnion) AsMessageStart() (v BetaRawMessageStartEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawMessageStreamEventUnion) AsMessageDelta() (v BetaRawMessageDeltaEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawMessageStreamEventUnion) AsMessageStop() (v BetaRawMessageStopEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawMessageStreamEventUnion) AsContentBlockStart() (v BetaRawContentBlockStartEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawMessageStreamEventUnion) AsContentBlockDelta() (v BetaRawContentBlockDeltaEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaRawMessageStreamEventUnion) AsContentBlockStop() (v BetaRawContentBlockStopEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -4824,7 +5809,9 @@ type BetaRawMessageStreamEventUnionDelta struct { Thinking string `json:"thinking"` // This field is from variant [BetaRawContentBlockDeltaUnion]. Signature string `json:"signature"` - JSON struct { + // This field is from variant [BetaRawContentBlockDeltaUnion]. + Content string `json:"content"` + JSON struct { Container respjson.Field StopReason respjson.Field StopSequence respjson.Field @@ -4834,6 +5821,7 @@ type BetaRawMessageStreamEventUnionDelta struct { Citation respjson.Field Thinking respjson.Field Signature respjson.Field + Content respjson.Field raw string } `json:"-"` } @@ -4842,83 +5830,6 @@ func (r *BetaRawMessageStreamEventUnionDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Accumulate builds up the Message incrementally from a MessageStreamEvent. The Message then can be used as -// any other Message, except with the caveat that the Message.JSON field which normally can be used to inspect -// the JSON sent over the network may not be populated fully. -// -// message := anthropic.Message{} -// for stream.Next() { -// event := stream.Current() -// message.Accumulate(event) -// } -func (acc *BetaMessage) Accumulate(event BetaRawMessageStreamEventUnion) error { - if acc == nil { - return fmt.Errorf("accumulate: cannot accumlate into nil Message") - } - - switch event := event.AsAny().(type) { - case BetaRawMessageStartEvent: - *acc = event.Message - case BetaRawMessageDeltaEvent: - acc.StopReason = event.Delta.StopReason - acc.StopSequence = event.Delta.StopSequence - acc.Usage.OutputTokens = event.Usage.OutputTokens - acc.ContextManagement = event.ContextManagement - case BetaRawMessageStopEvent: - accJson, err := json.Marshal(acc) - if err != nil { - return fmt.Errorf("error converting content block to JSON: %w", err) - } - acc.JSON.raw = string(accJson) - case BetaRawContentBlockStartEvent: - acc.Content = append(acc.Content, BetaContentBlockUnion{}) - err := acc.Content[len(acc.Content)-1].UnmarshalJSON([]byte(event.ContentBlock.RawJSON())) - if err != nil { - return err - } - case BetaRawContentBlockDeltaEvent: - if len(acc.Content) == 0 { - return fmt.Errorf("received event of type %s but there was no content block", event.Type) - } - cb := &acc.Content[len(acc.Content)-1] - switch delta := event.Delta.AsAny().(type) { - case BetaTextDelta: - cb.Text += delta.Text - case BetaInputJSONDelta: - if len(delta.PartialJSON) != 0 { - if string(cb.Input) == "{}" { - cb.Input = []byte(delta.PartialJSON) - } else { - cb.Input = append(cb.Input, []byte(delta.PartialJSON)...) - } - } - case BetaThinkingDelta: - cb.Thinking += delta.Thinking - case BetaSignatureDelta: - cb.Signature += delta.Signature - case BetaCitationsDelta: - citation := BetaTextCitationUnion{} - err := citation.UnmarshalJSON([]byte(delta.Citation.RawJSON())) - if err != nil { - return fmt.Errorf("could not unmarshal citation delta into citation type: %w", err) - } - cb.Citations = append(cb.Citations, citation) - } - case BetaRawContentBlockStopEvent: - if len(acc.Content) == 0 { - return fmt.Errorf("received event of type %s but there was no content block", event.Type) - } - contentBlock := &acc.Content[len(acc.Content)-1] - cbJson, err := json.Marshal(contentBlock) - if err != nil { - return fmt.Errorf("error converting content block to JSON: %w", err) - } - contentBlock.JSON.raw = string(cbJson) - } - - return nil -} - type BetaRedactedThinkingBlock struct { Data string `json:"data,required"` Type constant.RedactedThinking `json:"type,required"` @@ -4933,18 +5844,10 @@ type BetaRedactedThinkingBlock struct { // Returns the unmodified JSON received from the API func (r BetaRedactedThinkingBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaRedactedThinkingBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r BetaRedactedThinkingBlock) ToParam() BetaRedactedThinkingBlockParam { - var p BetaRedactedThinkingBlockParam - p.Type = r.Type - p.Data = r.Data - return p -} - // The properties Data, Type are required. type BetaRedactedThinkingBlockParam struct { Data string `json:"data,required"` @@ -4958,7 +5861,6 @@ func (r BetaRedactedThinkingBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaRedactedThinkingBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaRedactedThinkingBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4980,7 +5882,6 @@ func (r BetaRequestDocumentBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaRequestDocumentBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaRequestDocumentBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5004,7 +5905,6 @@ func (u BetaRequestDocumentBlockSourceUnionParam) MarshalJSON() ([]byte, error) u.OfURL, u.OfFile) } - func (u *BetaRequestDocumentBlockSourceUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -5094,7 +5994,6 @@ func (r BetaRequestMCPServerToolConfigurationParam) MarshalJSON() (data []byte, type shadow BetaRequestMCPServerToolConfigurationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaRequestMCPServerToolConfigurationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5114,7 +6013,6 @@ func (r BetaRequestMCPServerURLDefinitionParam) MarshalJSON() (data []byte, err type shadow BetaRequestMCPServerURLDefinitionParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaRequestMCPServerURLDefinitionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5135,7 +6033,6 @@ func (r BetaRequestMCPToolResultBlockParam) MarshalJSON() (data []byte, err erro type shadow BetaRequestMCPToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaRequestMCPToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5152,7 +6049,6 @@ type BetaRequestMCPToolResultBlockParamContentUnion struct { func (u BetaRequestMCPToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfString, u.OfBetaMCPToolResultBlockContent) } - func (u *BetaRequestMCPToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -5166,25 +6062,116 @@ func (u *BetaRequestMCPToolResultBlockParamContentUnion) asAny() any { return nil } -// The properties Content, Source, Title, Type are required. -type BetaSearchResultBlockParam struct { - Content []BetaTextBlockParam `json:"content,omitzero,required"` - Source string `json:"source,required"` - Title string `json:"title,required"` - // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` - Citations BetaCitationsConfigParam `json:"citations,omitzero"` - // This field can be elided, and will marshal its zero value as "search_result". - Type constant.SearchResult `json:"type,required"` +// The properties Content, Source, Title, Type are required. +type BetaSearchResultBlockParam struct { + Content []BetaTextBlockParam `json:"content,omitzero,required"` + Source string `json:"source,required"` + Title string `json:"title,required"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + Citations BetaCitationsConfigParam `json:"citations,omitzero"` + // This field can be elided, and will marshal its zero value as "search_result". + Type constant.SearchResult `json:"type,required"` + paramObj +} + +func (r BetaSearchResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BetaSearchResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaSearchResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Tool invocation generated by a server-side tool. +type BetaServerToolCaller struct { + ToolID string `json:"tool_id,required"` + Type constant.CodeExecution20250825 `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ToolID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaServerToolCaller) RawJSON() string { return r.JSON.raw } +func (r *BetaServerToolCaller) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this BetaServerToolCaller to a BetaServerToolCallerParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// BetaServerToolCallerParam.Overrides() +func (r BetaServerToolCaller) ToParam() BetaServerToolCallerParam { + return param.Override[BetaServerToolCallerParam](json.RawMessage(r.RawJSON())) +} + +// Tool invocation generated by a server-side tool. +// +// The properties ToolID, Type are required. +type BetaServerToolCallerParam struct { + ToolID string `json:"tool_id,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_20250825". + Type constant.CodeExecution20250825 `json:"type,required"` + paramObj +} + +func (r BetaServerToolCallerParam) MarshalJSON() (data []byte, err error) { + type shadow BetaServerToolCallerParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaServerToolCallerParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaServerToolCaller20260120 struct { + ToolID string `json:"tool_id,required"` + Type constant.CodeExecution20260120 `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ToolID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaServerToolCaller20260120) RawJSON() string { return r.JSON.raw } +func (r *BetaServerToolCaller20260120) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this BetaServerToolCaller20260120 to a +// BetaServerToolCaller20260120Param. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// BetaServerToolCaller20260120Param.Overrides() +func (r BetaServerToolCaller20260120) ToParam() BetaServerToolCaller20260120Param { + return param.Override[BetaServerToolCaller20260120Param](json.RawMessage(r.RawJSON())) +} + +// The properties ToolID, Type are required. +type BetaServerToolCaller20260120Param struct { + ToolID string `json:"tool_id,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_20260120". + Type constant.CodeExecution20260120 `json:"type,required"` paramObj } -func (r BetaSearchResultBlockParam) MarshalJSON() (data []byte, err error) { - type shadow BetaSearchResultBlockParam +func (r BetaServerToolCaller20260120Param) MarshalJSON() (data []byte, err error) { + type shadow BetaServerToolCaller20260120Param return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *BetaSearchResultBlockParam) UnmarshalJSON(data []byte) error { +func (r *BetaServerToolCaller20260120Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5204,7 +6191,6 @@ type BetaServerToolUsage struct { // Returns the unmodified JSON received from the API func (r BetaServerToolUsage) RawJSON() string { return r.JSON.raw } - func (r *BetaServerToolUsage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5213,15 +6199,18 @@ type BetaServerToolUseBlock struct { ID string `json:"id,required"` Input any `json:"input,required"` // Any of "web_search", "web_fetch", "code_execution", "bash_code_execution", - // "text_editor_code_execution". + // "text_editor_code_execution", "tool_search_tool_regex", "tool_search_tool_bm25". Name BetaServerToolUseBlockName `json:"name,required"` Type constant.ServerToolUse `json:"type,required"` + // Tool invocation directly from the model. + Caller BetaServerToolUseBlockCallerUnion `json:"caller"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field Input respjson.Field Name respjson.Field Type respjson.Field + Caller respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` @@ -5229,7 +6218,6 @@ type BetaServerToolUseBlock struct { // Returns the unmodified JSON received from the API func (r BetaServerToolUseBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaServerToolUseBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5242,17 +6230,93 @@ const ( BetaServerToolUseBlockNameCodeExecution BetaServerToolUseBlockName = "code_execution" BetaServerToolUseBlockNameBashCodeExecution BetaServerToolUseBlockName = "bash_code_execution" BetaServerToolUseBlockNameTextEditorCodeExecution BetaServerToolUseBlockName = "text_editor_code_execution" + BetaServerToolUseBlockNameToolSearchToolRegex BetaServerToolUseBlockName = "tool_search_tool_regex" + BetaServerToolUseBlockNameToolSearchToolBm25 BetaServerToolUseBlockName = "tool_search_tool_bm25" ) +// BetaServerToolUseBlockCallerUnion contains all possible properties and values +// from [BetaDirectCaller], [BetaServerToolCaller], [BetaServerToolCaller20260120]. +// +// Use the [BetaServerToolUseBlockCallerUnion.AsAny] method to switch on the +// variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type BetaServerToolUseBlockCallerUnion struct { + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +// anyBetaServerToolUseBlockCaller is implemented by each variant of +// [BetaServerToolUseBlockCallerUnion] to add type safety for the return type of +// [BetaServerToolUseBlockCallerUnion.AsAny] +type anyBetaServerToolUseBlockCaller interface { + implBetaServerToolUseBlockCallerUnion() +} + +func (BetaDirectCaller) implBetaServerToolUseBlockCallerUnion() {} +func (BetaServerToolCaller) implBetaServerToolUseBlockCallerUnion() {} +func (BetaServerToolCaller20260120) implBetaServerToolUseBlockCallerUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := BetaServerToolUseBlockCallerUnion.AsAny().(type) { +// case anthropic.BetaDirectCaller: +// case anthropic.BetaServerToolCaller: +// case anthropic.BetaServerToolCaller20260120: +// default: +// fmt.Errorf("no variant present") +// } +func (u BetaServerToolUseBlockCallerUnion) AsAny() anyBetaServerToolUseBlockCaller { + switch u.Type { + case "direct": + return u.AsDirect() + case "code_execution_20250825": + return u.AsCodeExecution20250825() + case "code_execution_20260120": + return u.AsCodeExecution20260120() + } + return nil +} + +func (u BetaServerToolUseBlockCallerUnion) AsDirect() (v BetaDirectCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaServerToolUseBlockCallerUnion) AsCodeExecution20250825() (v BetaServerToolCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaServerToolUseBlockCallerUnion) AsCodeExecution20260120() (v BetaServerToolCaller20260120) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u BetaServerToolUseBlockCallerUnion) RawJSON() string { return u.JSON.raw } + +func (r *BetaServerToolUseBlockCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // The properties ID, Input, Name, Type are required. type BetaServerToolUseBlockParam struct { ID string `json:"id,required"` Input any `json:"input,omitzero,required"` // Any of "web_search", "web_fetch", "code_execution", "bash_code_execution", - // "text_editor_code_execution". + // "text_editor_code_execution", "tool_search_tool_regex", "tool_search_tool_bm25". Name BetaServerToolUseBlockParamName `json:"name,omitzero,required"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Tool invocation directly from the model. + Caller BetaServerToolUseBlockParamCallerUnion `json:"caller,omitzero"` // This field can be elided, and will marshal its zero value as "server_tool_use". Type constant.ServerToolUse `json:"type,required"` paramObj @@ -5262,7 +6326,6 @@ func (r BetaServerToolUseBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaServerToolUseBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaServerToolUseBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5275,8 +6338,69 @@ const ( BetaServerToolUseBlockParamNameCodeExecution BetaServerToolUseBlockParamName = "code_execution" BetaServerToolUseBlockParamNameBashCodeExecution BetaServerToolUseBlockParamName = "bash_code_execution" BetaServerToolUseBlockParamNameTextEditorCodeExecution BetaServerToolUseBlockParamName = "text_editor_code_execution" + BetaServerToolUseBlockParamNameToolSearchToolRegex BetaServerToolUseBlockParamName = "tool_search_tool_regex" + BetaServerToolUseBlockParamNameToolSearchToolBm25 BetaServerToolUseBlockParamName = "tool_search_tool_bm25" ) +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaServerToolUseBlockParamCallerUnion struct { + OfDirect *BetaDirectCallerParam `json:",omitzero,inline"` + OfCodeExecution20250825 *BetaServerToolCallerParam `json:",omitzero,inline"` + OfCodeExecution20260120 *BetaServerToolCaller20260120Param `json:",omitzero,inline"` + paramUnion +} + +func (u BetaServerToolUseBlockParamCallerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfDirect, u.OfCodeExecution20250825, u.OfCodeExecution20260120) +} +func (u *BetaServerToolUseBlockParamCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BetaServerToolUseBlockParamCallerUnion) asAny() any { + if !param.IsOmitted(u.OfDirect) { + return u.OfDirect + } else if !param.IsOmitted(u.OfCodeExecution20250825) { + return u.OfCodeExecution20250825 + } else if !param.IsOmitted(u.OfCodeExecution20260120) { + return u.OfCodeExecution20260120 + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaServerToolUseBlockParamCallerUnion) GetType() *string { + if vt := u.OfDirect; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaServerToolUseBlockParamCallerUnion) GetToolID() *string { + if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.ToolID) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.ToolID) + } + return nil +} + +func init() { + apijson.RegisterUnion[BetaServerToolUseBlockParamCallerUnion]( + "type", + apijson.Discriminator[BetaDirectCallerParam]("direct"), + apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), + apijson.Discriminator[BetaServerToolCaller20260120Param]("code_execution_20260120"), + ) +} + type BetaSignatureDelta struct { Signature string `json:"signature,required"` Type constant.SignatureDelta `json:"type,required"` @@ -5291,11 +6415,75 @@ type BetaSignatureDelta struct { // Returns the unmodified JSON received from the API func (r BetaSignatureDelta) RawJSON() string { return r.JSON.raw } - func (r *BetaSignatureDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// A skill that was loaded in a container (response model). +type BetaSkill struct { + // Skill ID + SkillID string `json:"skill_id,required"` + // Type of skill - either 'anthropic' (built-in) or 'custom' (user-defined) + // + // Any of "anthropic", "custom". + Type BetaSkillType `json:"type,required"` + // Skill version or 'latest' for most recent version + Version string `json:"version,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + SkillID respjson.Field + Type respjson.Field + Version respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkill) RawJSON() string { return r.JSON.raw } +func (r *BetaSkill) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Type of skill - either 'anthropic' (built-in) or 'custom' (user-defined) +type BetaSkillType string + +const ( + BetaSkillTypeAnthropic BetaSkillType = "anthropic" + BetaSkillTypeCustom BetaSkillType = "custom" +) + +// Specification for a skill to be loaded in a container (request model). +// +// The properties SkillID, Type are required. +type BetaSkillParams struct { + // Skill ID + SkillID string `json:"skill_id,required"` + // Type of skill - either 'anthropic' (built-in) or 'custom' (user-defined) + // + // Any of "anthropic", "custom". + Type BetaSkillParamsType `json:"type,omitzero,required"` + // Skill version or 'latest' for most recent version + Version param.Opt[string] `json:"version,omitzero"` + paramObj +} + +func (r BetaSkillParams) MarshalJSON() (data []byte, err error) { + type shadow BetaSkillParams + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaSkillParams) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Type of skill - either 'anthropic' (built-in) or 'custom' (user-defined) +type BetaSkillParamsType string + +const ( + BetaSkillParamsTypeAnthropic BetaSkillParamsType = "anthropic" + BetaSkillParamsTypeCustom BetaSkillParamsType = "custom" +) + type BetaStopReason string const ( @@ -5304,6 +6492,7 @@ const ( BetaStopReasonStopSequence BetaStopReason = "stop_sequence" BetaStopReasonToolUse BetaStopReason = "tool_use" BetaStopReasonPauseTurn BetaStopReason = "pause_turn" + BetaStopReasonCompaction BetaStopReason = "compaction" BetaStopReasonRefusal BetaStopReason = "refusal" BetaStopReasonModelContextWindowExceeded BetaStopReason = "model_context_window_exceeded" ) @@ -5329,55 +6518,10 @@ type BetaTextBlock struct { // Returns the unmodified JSON received from the API func (r BetaTextBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaTextBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r BetaTextBlock) ToParam() BetaTextBlockParam { - var p BetaTextBlockParam - p.Type = r.Type - p.Text = r.Text - - // Distinguish between a nil and zero length slice, since some compatible - // APIs may not require citations. - if r.Citations != nil { - p.Citations = make([]BetaTextCitationParamUnion, len(r.Citations)) - } - - for i, citation := range r.Citations { - switch citationVariant := citation.AsAny().(type) { - case BetaCitationCharLocation: - var citationParam BetaCitationCharLocationParam - citationParam.Type = citationVariant.Type - citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) - citationParam.CitedText = citationVariant.CitedText - citationParam.DocumentIndex = citationVariant.DocumentIndex - citationParam.EndCharIndex = citationVariant.EndCharIndex - citationParam.StartCharIndex = citationVariant.StartCharIndex - p.Citations[i] = BetaTextCitationParamUnion{OfCharLocation: &citationParam} - case BetaCitationPageLocation: - var citationParam BetaCitationPageLocationParam - citationParam.Type = citationVariant.Type - citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) - citationParam.DocumentIndex = citationVariant.DocumentIndex - citationParam.EndPageNumber = citationVariant.EndPageNumber - citationParam.StartPageNumber = citationVariant.StartPageNumber - p.Citations[i] = BetaTextCitationParamUnion{OfPageLocation: &citationParam} - case BetaCitationContentBlockLocation: - var citationParam BetaCitationContentBlockLocationParam - citationParam.Type = citationVariant.Type - citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) - citationParam.CitedText = citationVariant.CitedText - citationParam.DocumentIndex = citationVariant.DocumentIndex - citationParam.EndBlockIndex = citationVariant.EndBlockIndex - citationParam.StartBlockIndex = citationVariant.StartBlockIndex - p.Citations[i] = BetaTextCitationParamUnion{OfContentBlockLocation: &citationParam} - } - } - return p -} - // The properties Text, Type are required. type BetaTextBlockParam struct { Text string `json:"text,required"` @@ -5393,7 +6537,6 @@ func (r BetaTextBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaTextBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaTextBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5458,6 +6601,7 @@ type BetaTextCitationUnion struct { // add type safety for the return type of [BetaTextCitationUnion.AsAny] type anyBetaTextCitation interface { implBetaTextCitationUnion() + toParamUnion() BetaTextCitationParamUnion } func (BetaCitationCharLocation) implBetaTextCitationUnion() {} @@ -5495,27 +6639,27 @@ func (u BetaTextCitationUnion) AsAny() anyBetaTextCitation { func (u BetaTextCitationUnion) AsCharLocation() (v BetaCitationCharLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaTextCitationUnion) AsPageLocation() (v BetaCitationPageLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaTextCitationUnion) AsContentBlockLocation() (v BetaCitationContentBlockLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaTextCitationUnion) AsWebSearchResultLocation() (v BetaCitationsWebSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaTextCitationUnion) AsSearchResultLocation() (v BetaCitationSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -5544,7 +6688,6 @@ func (u BetaTextCitationParamUnion) MarshalJSON() ([]byte, error) { u.OfWebSearchResultLocation, u.OfSearchResultLocation) } - func (u *BetaTextCitationParamUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -5728,7 +6871,6 @@ type BetaTextDelta struct { // Returns the unmodified JSON received from the API func (r BetaTextDelta) RawJSON() string { return r.JSON.raw } - func (r *BetaTextDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5747,7 +6889,6 @@ type BetaTextEditorCodeExecutionCreateResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaTextEditorCodeExecutionCreateResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaTextEditorCodeExecutionCreateResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5765,7 +6906,6 @@ func (r BetaTextEditorCodeExecutionCreateResultBlockParam) MarshalJSON() (data [ type shadow BetaTextEditorCodeExecutionCreateResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaTextEditorCodeExecutionCreateResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5792,7 +6932,6 @@ type BetaTextEditorCodeExecutionStrReplaceResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaTextEditorCodeExecutionStrReplaceResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaTextEditorCodeExecutionStrReplaceResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5814,7 +6953,6 @@ func (r BetaTextEditorCodeExecutionStrReplaceResultBlockParam) MarshalJSON() (da type shadow BetaTextEditorCodeExecutionStrReplaceResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaTextEditorCodeExecutionStrReplaceResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5835,7 +6973,6 @@ type BetaTextEditorCodeExecutionToolResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaTextEditorCodeExecutionToolResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaTextEditorCodeExecutionToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5896,22 +7033,22 @@ type BetaTextEditorCodeExecutionToolResultBlockContentUnion struct { func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionToolResultError() (v BetaTextEditorCodeExecutionToolResultError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionViewResultBlock() (v BetaTextEditorCodeExecutionViewResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionCreateResultBlock() (v BetaTextEditorCodeExecutionCreateResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionStrReplaceResultBlock() (v BetaTextEditorCodeExecutionStrReplaceResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -5937,7 +7074,6 @@ func (r BetaTextEditorCodeExecutionToolResultBlockParam) MarshalJSON() (data []b type shadow BetaTextEditorCodeExecutionToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaTextEditorCodeExecutionToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5956,7 +7092,6 @@ type BetaTextEditorCodeExecutionToolResultBlockParamContentUnion struct { func (u BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfRequestTextEditorCodeExecutionToolResultError, u.OfRequestTextEditorCodeExecutionViewResultBlock, u.OfRequestTextEditorCodeExecutionCreateResultBlock, u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock) } - func (u *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -6110,7 +7245,6 @@ type BetaTextEditorCodeExecutionToolResultError struct { // Returns the unmodified JSON received from the API func (r BetaTextEditorCodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } - func (r *BetaTextEditorCodeExecutionToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6141,7 +7275,6 @@ func (r BetaTextEditorCodeExecutionToolResultErrorParam) MarshalJSON() (data []b type shadow BetaTextEditorCodeExecutionToolResultErrorParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaTextEditorCodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6179,7 +7312,6 @@ type BetaTextEditorCodeExecutionViewResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaTextEditorCodeExecutionViewResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaTextEditorCodeExecutionViewResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6210,7 +7342,6 @@ func (r BetaTextEditorCodeExecutionViewResultBlockParam) MarshalJSON() (data []b type shadow BetaTextEditorCodeExecutionViewResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaTextEditorCodeExecutionViewResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6239,19 +7370,10 @@ type BetaThinkingBlock struct { // Returns the unmodified JSON received from the API func (r BetaThinkingBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaThinkingBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r BetaThinkingBlock) ToParam() BetaThinkingBlockParam { - var p BetaThinkingBlockParam - p.Type = r.Type - p.Signature = r.Signature - p.Thinking = r.Thinking - return p -} - // The properties Signature, Thinking, Type are required. type BetaThinkingBlockParam struct { Signature string `json:"signature,required"` @@ -6265,11 +7387,31 @@ func (r BetaThinkingBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaThinkingBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaThinkingBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +func NewBetaThinkingConfigAdaptiveParam() BetaThinkingConfigAdaptiveParam { + return BetaThinkingConfigAdaptiveParam{ + Type: "adaptive", + } +} + +// This struct has a constant value, construct it with +// [NewBetaThinkingConfigAdaptiveParam]. +type BetaThinkingConfigAdaptiveParam struct { + Type constant.Adaptive `json:"type,required"` + paramObj +} + +func (r BetaThinkingConfigAdaptiveParam) MarshalJSON() (data []byte, err error) { + type shadow BetaThinkingConfigAdaptiveParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaThinkingConfigAdaptiveParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + func NewBetaThinkingConfigDisabledParam() BetaThinkingConfigDisabledParam { return BetaThinkingConfigDisabledParam{ Type: "disabled", @@ -6287,7 +7429,6 @@ func (r BetaThinkingConfigDisabledParam) MarshalJSON() (data []byte, err error) type shadow BetaThinkingConfigDisabledParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaThinkingConfigDisabledParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6301,7 +7442,7 @@ type BetaThinkingConfigEnabledParam struct { // Must be ≥1024 and less than `max_tokens`. // // See - // [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + // [extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking) // for details. BudgetTokens int64 `json:"budget_tokens,required"` // This field can be elided, and will marshal its zero value as "enabled". @@ -6313,7 +7454,6 @@ func (r BetaThinkingConfigEnabledParam) MarshalJSON() (data []byte, err error) { type shadow BetaThinkingConfigEnabledParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaThinkingConfigEnabledParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6330,13 +7470,13 @@ func BetaThinkingConfigParamOfEnabled(budgetTokens int64) BetaThinkingConfigPara type BetaThinkingConfigParamUnion struct { OfEnabled *BetaThinkingConfigEnabledParam `json:",omitzero,inline"` OfDisabled *BetaThinkingConfigDisabledParam `json:",omitzero,inline"` + OfAdaptive *BetaThinkingConfigAdaptiveParam `json:",omitzero,inline"` paramUnion } func (u BetaThinkingConfigParamUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfEnabled, u.OfDisabled) + return param.MarshalUnion(u, u.OfEnabled, u.OfDisabled, u.OfAdaptive) } - func (u *BetaThinkingConfigParamUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -6346,6 +7486,8 @@ func (u *BetaThinkingConfigParamUnion) asAny() any { return u.OfEnabled } else if !param.IsOmitted(u.OfDisabled) { return u.OfDisabled + } else if !param.IsOmitted(u.OfAdaptive) { + return u.OfAdaptive } return nil } @@ -6364,10 +7506,13 @@ func (u BetaThinkingConfigParamUnion) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfDisabled; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfAdaptive; vt != nil { + return (*string)(&vt.Type) } return nil } + type BetaThinkingDelta struct { Thinking string `json:"thinking,required"` Type constant.ThinkingDelta `json:"type,required"` @@ -6382,11 +7527,26 @@ type BetaThinkingDelta struct { // Returns the unmodified JSON received from the API func (r BetaThinkingDelta) RawJSON() string { return r.JSON.raw } - func (r *BetaThinkingDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// The properties Type, Value are required. +type BetaThinkingTurnsParam struct { + Value int64 `json:"value,required"` + // This field can be elided, and will marshal its zero value as "thinking_turns". + Type constant.ThinkingTurns `json:"type,required"` + paramObj +} + +func (r BetaThinkingTurnsParam) MarshalJSON() (data []byte, err error) { + type shadow BetaThinkingTurnsParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaThinkingTurnsParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // The properties InputSchema, Name are required. type BetaToolParam struct { // [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. @@ -6398,6 +7558,15 @@ type BetaToolParam struct { // // This is how the tool will be called by the model and in `tool_use` blocks. Name string `json:"name,required"` + // Enable eager input streaming for this tool. When true, tool input parameters + // will be streamed incrementally as they are generated, and types will be inferred + // on-the-fly rather than buffering the full JSON output. When false, streaming is + // disabled for this tool even if the fine-grained-tool-streaming beta is active. + // When null (default), uses the default behavior based on beta headers. + EagerInputStreaming param.Opt[bool] `json:"eager_input_streaming,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` // Description of what this tool does. // // Tool descriptions should be as detailed as possible. The more information that @@ -6405,10 +7574,15 @@ type BetaToolParam struct { // perform. You can use natural language descriptions to reinforce important // aspects of the tool input JSON schema. Description param.Opt[string] `json:"description,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` // Any of "custom". Type BetaToolType `json:"type,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` paramObj } @@ -6416,7 +7590,6 @@ func (r BetaToolParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6440,7 +7613,6 @@ func (r BetaToolInputSchemaParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolInputSchemaParam return param.MarshalWithExtras(r, (*shadow)(&r), r.ExtraFields) } - func (r *BetaToolInputSchemaParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6453,8 +7625,16 @@ const ( // The properties Name, Type are required. type BetaToolBash20241022Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -6470,15 +7650,22 @@ func (r BetaToolBash20241022Param) MarshalJSON() (data []byte, err error) { type shadow BetaToolBash20241022Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolBash20241022Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Name, Type are required. type BetaToolBash20250124Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -6494,7 +7681,6 @@ func (r BetaToolBash20250124Param) MarshalJSON() (data []byte, err error) { type shadow BetaToolBash20250124Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolBash20250124Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6519,7 +7705,6 @@ type BetaToolChoiceUnionParam struct { func (u BetaToolChoiceUnionParam) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfAuto, u.OfAny, u.OfTool, u.OfNone) } - func (u *BetaToolChoiceUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -6589,7 +7774,6 @@ func (r BetaToolChoiceAnyParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolChoiceAnyParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolChoiceAnyParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6612,7 +7796,6 @@ func (r BetaToolChoiceAutoParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolChoiceAutoParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolChoiceAutoParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6636,7 +7819,6 @@ func (r BetaToolChoiceNoneParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolChoiceNoneParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolChoiceNoneParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6661,7 +7843,6 @@ func (r BetaToolChoiceToolParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolChoiceToolParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolChoiceToolParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6674,8 +7855,16 @@ type BetaToolComputerUse20241022Param struct { DisplayWidthPx int64 `json:"display_width_px,required"` // The X11 display number (e.g. 0, 1) for the display. DisplayNumber param.Opt[int64] `json:"display_number,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -6692,7 +7881,6 @@ func (r BetaToolComputerUse20241022Param) MarshalJSON() (data []byte, err error) type shadow BetaToolComputerUse20241022Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolComputerUse20241022Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -6705,8 +7893,16 @@ type BetaToolComputerUse20250124Param struct { DisplayWidthPx int64 `json:"display_width_px,required"` // The X11 display number (e.g. 0, 1) for the display. DisplayNumber param.Opt[int64] `json:"display_number,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -6723,11 +7919,88 @@ func (r BetaToolComputerUse20250124Param) MarshalJSON() (data []byte, err error) type shadow BetaToolComputerUse20250124Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolComputerUse20250124Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// The properties DisplayHeightPx, DisplayWidthPx, Name, Type are required. +type BetaToolComputerUse20251124Param struct { + // The height of the display in pixels. + DisplayHeightPx int64 `json:"display_height_px,required"` + // The width of the display in pixels. + DisplayWidthPx int64 `json:"display_width_px,required"` + // The X11 display number (e.g. 0, 1) for the display. + DisplayNumber param.Opt[int64] `json:"display_number,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // Whether to enable an action to take a zoomed-in screenshot of the screen. + EnableZoom param.Opt[bool] `json:"enable_zoom,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "computer". + Name constant.Computer `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "computer_20251124". + Type constant.Computer20251124 `json:"type,required"` + paramObj +} + +func (r BetaToolComputerUse20251124Param) MarshalJSON() (data []byte, err error) { + type shadow BetaToolComputerUse20251124Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaToolComputerUse20251124Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaToolReferenceBlock struct { + ToolName string `json:"tool_name,required"` + Type constant.ToolReference `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ToolName respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaToolReferenceBlock) RawJSON() string { return r.JSON.raw } +func (r *BetaToolReferenceBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Tool reference block that can be included in tool_result content. +// +// The properties ToolName, Type are required. +type BetaToolReferenceBlockParam struct { + ToolName string `json:"tool_name,required"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as "tool_reference". + Type constant.ToolReference `json:"type,required"` + paramObj +} + +func (r BetaToolReferenceBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BetaToolReferenceBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaToolReferenceBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // The properties ToolUseID, Type are required. type BetaToolResultBlockParam struct { ToolUseID string `json:"tool_use_id,required"` @@ -6744,26 +8017,39 @@ func (r BetaToolResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +func NewBetaToolResultTextBlockParam(toolUseID string, text string, isError bool) BetaToolResultBlockParam { + var p BetaToolResultBlockParam + p.ToolUseID = toolUseID + p.IsError = param.Opt[bool]{Value: isError} + p.Content = []BetaToolResultBlockParamContentUnion{ + {OfText: &BetaTextBlockParam{Text: text}}, + } + return p +} + // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaToolResultBlockParamContentUnion struct { - OfText *BetaTextBlockParam `json:",omitzero,inline"` - OfImage *BetaImageBlockParam `json:",omitzero,inline"` - OfSearchResult *BetaSearchResultBlockParam `json:",omitzero,inline"` - OfDocument *BetaRequestDocumentBlockParam `json:",omitzero,inline"` + OfText *BetaTextBlockParam `json:",omitzero,inline"` + OfImage *BetaImageBlockParam `json:",omitzero,inline"` + OfSearchResult *BetaSearchResultBlockParam `json:",omitzero,inline"` + OfDocument *BetaRequestDocumentBlockParam `json:",omitzero,inline"` + OfToolReference *BetaToolReferenceBlockParam `json:",omitzero,inline"` paramUnion } func (u BetaToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfText, u.OfImage, u.OfSearchResult, u.OfDocument) + return param.MarshalUnion(u, u.OfText, + u.OfImage, + u.OfSearchResult, + u.OfDocument, + u.OfToolReference) } - func (u *BetaToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -6777,6 +8063,8 @@ func (u *BetaToolResultBlockParamContentUnion) asAny() any { return u.OfSearchResult } else if !param.IsOmitted(u.OfDocument) { return u.OfDocument + } else if !param.IsOmitted(u.OfToolReference) { + return u.OfToolReference } return nil } @@ -6805,6 +8093,14 @@ func (u BetaToolResultBlockParamContentUnion) GetContext() *string { return nil } +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolResultBlockParamContentUnion) GetToolName() *string { + if vt := u.OfToolReference; vt != nil { + return &vt.ToolName + } + return nil +} + // Returns a pointer to the underlying variant's property, if present. func (u BetaToolResultBlockParamContentUnion) GetType() *string { if vt := u.OfText; vt != nil { @@ -6815,6 +8111,8 @@ func (u BetaToolResultBlockParamContentUnion) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfDocument; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfToolReference; vt != nil { + return (*string)(&vt.Type) } return nil } @@ -6839,6 +8137,8 @@ func (u BetaToolResultBlockParamContentUnion) GetCacheControl() *BetaCacheContro return &vt.CacheControl } else if vt := u.OfDocument; vt != nil { return &vt.CacheControl + } else if vt := u.OfToolReference; vt != nil { + return &vt.CacheControl } return nil } @@ -6854,7 +8154,7 @@ func (u BetaToolResultBlockParamContentUnion) GetCitations() (res betaToolResult } else if vt := u.OfDocument; vt != nil { res.any = &vt.Citations } - return res + return } // Can have the runtime types [*[]BetaTextCitationParamUnion], @@ -6891,7 +8191,7 @@ func (u BetaToolResultBlockParamContentUnion) GetSource() (res betaToolResultBlo } else if vt := u.OfDocument; vt != nil { res.any = vt.Source.asAny() } - return res + return } // Can have the runtime types [*BetaBase64ImageSourceParam], @@ -6983,9 +8283,318 @@ func (u betaToolResultBlockParamContentUnionSource) GetFileID() *string { } // The properties Name, Type are required. -type BetaToolTextEditor20241022Param struct { +type BetaToolSearchToolBm25_20251119Param struct { + // Any of "tool_search_tool_bm25_20251119", "tool_search_tool_bm25". + Type BetaToolSearchToolBm25_20251119Type `json:"type,omitzero,required"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_bm25". + Name constant.ToolSearchToolBm25 `json:"name,required"` + paramObj +} + +func (r BetaToolSearchToolBm25_20251119Param) MarshalJSON() (data []byte, err error) { + type shadow BetaToolSearchToolBm25_20251119Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaToolSearchToolBm25_20251119Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaToolSearchToolBm25_20251119Type string + +const ( + BetaToolSearchToolBm25_20251119TypeToolSearchToolBm25_20251119 BetaToolSearchToolBm25_20251119Type = "tool_search_tool_bm25_20251119" + BetaToolSearchToolBm25_20251119TypeToolSearchToolBm25 BetaToolSearchToolBm25_20251119Type = "tool_search_tool_bm25" +) + +// The properties Name, Type are required. +type BetaToolSearchToolRegex20251119Param struct { + // Any of "tool_search_tool_regex_20251119", "tool_search_tool_regex". + Type BetaToolSearchToolRegex20251119Type `json:"type,omitzero,required"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_regex". + Name constant.ToolSearchToolRegex `json:"name,required"` + paramObj +} + +func (r BetaToolSearchToolRegex20251119Param) MarshalJSON() (data []byte, err error) { + type shadow BetaToolSearchToolRegex20251119Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaToolSearchToolRegex20251119Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaToolSearchToolRegex20251119Type string + +const ( + BetaToolSearchToolRegex20251119TypeToolSearchToolRegex20251119 BetaToolSearchToolRegex20251119Type = "tool_search_tool_regex_20251119" + BetaToolSearchToolRegex20251119TypeToolSearchToolRegex BetaToolSearchToolRegex20251119Type = "tool_search_tool_regex" +) + +type BetaToolSearchToolResultBlock struct { + Content BetaToolSearchToolResultBlockContentUnion `json:"content,required"` + ToolUseID string `json:"tool_use_id,required"` + Type constant.ToolSearchToolResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + ToolUseID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaToolSearchToolResultBlock) RawJSON() string { return r.JSON.raw } +func (r *BetaToolSearchToolResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// BetaToolSearchToolResultBlockContentUnion contains all possible properties and +// values from [BetaToolSearchToolResultError], +// [BetaToolSearchToolSearchResultBlock]. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type BetaToolSearchToolResultBlockContentUnion struct { + // This field is from variant [BetaToolSearchToolResultError]. + ErrorCode BetaToolSearchToolResultErrorErrorCode `json:"error_code"` + // This field is from variant [BetaToolSearchToolResultError]. + ErrorMessage string `json:"error_message"` + Type string `json:"type"` + // This field is from variant [BetaToolSearchToolSearchResultBlock]. + ToolReferences []BetaToolReferenceBlock `json:"tool_references"` + JSON struct { + ErrorCode respjson.Field + ErrorMessage respjson.Field + Type respjson.Field + ToolReferences respjson.Field + raw string + } `json:"-"` +} + +func (u BetaToolSearchToolResultBlockContentUnion) AsResponseToolSearchToolResultError() (v BetaToolSearchToolResultError) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaToolSearchToolResultBlockContentUnion) AsResponseToolSearchToolSearchResultBlock() (v BetaToolSearchToolSearchResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u BetaToolSearchToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } + +func (r *BetaToolSearchToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Content, ToolUseID, Type are required. +type BetaToolSearchToolResultBlockParam struct { + Content BetaToolSearchToolResultBlockParamContentUnion `json:"content,omitzero,required"` + ToolUseID string `json:"tool_use_id,required"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_result". + Type constant.ToolSearchToolResult `json:"type,required"` + paramObj +} + +func (r BetaToolSearchToolResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BetaToolSearchToolResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaToolSearchToolResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaToolSearchToolResultBlockParamContentUnion struct { + OfRequestToolSearchToolResultError *BetaToolSearchToolResultErrorParam `json:",omitzero,inline"` + OfRequestToolSearchToolSearchResultBlock *BetaToolSearchToolSearchResultBlockParam `json:",omitzero,inline"` + paramUnion +} + +func (u BetaToolSearchToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfRequestToolSearchToolResultError, u.OfRequestToolSearchToolSearchResultBlock) +} +func (u *BetaToolSearchToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BetaToolSearchToolResultBlockParamContentUnion) asAny() any { + if !param.IsOmitted(u.OfRequestToolSearchToolResultError) { + return u.OfRequestToolSearchToolResultError + } else if !param.IsOmitted(u.OfRequestToolSearchToolSearchResultBlock) { + return u.OfRequestToolSearchToolSearchResultBlock + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolSearchToolResultBlockParamContentUnion) GetErrorCode() *string { + if vt := u.OfRequestToolSearchToolResultError; vt != nil { + return (*string)(&vt.ErrorCode) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolSearchToolResultBlockParamContentUnion) GetToolReferences() []BetaToolReferenceBlockParam { + if vt := u.OfRequestToolSearchToolSearchResultBlock; vt != nil { + return vt.ToolReferences + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolSearchToolResultBlockParamContentUnion) GetType() *string { + if vt := u.OfRequestToolSearchToolResultError; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRequestToolSearchToolSearchResultBlock; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +type BetaToolSearchToolResultError struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded". + ErrorCode BetaToolSearchToolResultErrorErrorCode `json:"error_code,required"` + ErrorMessage string `json:"error_message,required"` + Type constant.ToolSearchToolResultError `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ErrorCode respjson.Field + ErrorMessage respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaToolSearchToolResultError) RawJSON() string { return r.JSON.raw } +func (r *BetaToolSearchToolResultError) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaToolSearchToolResultErrorErrorCode string + +const ( + BetaToolSearchToolResultErrorErrorCodeInvalidToolInput BetaToolSearchToolResultErrorErrorCode = "invalid_tool_input" + BetaToolSearchToolResultErrorErrorCodeUnavailable BetaToolSearchToolResultErrorErrorCode = "unavailable" + BetaToolSearchToolResultErrorErrorCodeTooManyRequests BetaToolSearchToolResultErrorErrorCode = "too_many_requests" + BetaToolSearchToolResultErrorErrorCodeExecutionTimeExceeded BetaToolSearchToolResultErrorErrorCode = "execution_time_exceeded" +) + +// The properties ErrorCode, Type are required. +type BetaToolSearchToolResultErrorParam struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded". + ErrorCode BetaToolSearchToolResultErrorParamErrorCode `json:"error_code,omitzero,required"` + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_result_error". + Type constant.ToolSearchToolResultError `json:"type,required"` + paramObj +} + +func (r BetaToolSearchToolResultErrorParam) MarshalJSON() (data []byte, err error) { + type shadow BetaToolSearchToolResultErrorParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaToolSearchToolResultErrorParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaToolSearchToolResultErrorParamErrorCode string + +const ( + BetaToolSearchToolResultErrorParamErrorCodeInvalidToolInput BetaToolSearchToolResultErrorParamErrorCode = "invalid_tool_input" + BetaToolSearchToolResultErrorParamErrorCodeUnavailable BetaToolSearchToolResultErrorParamErrorCode = "unavailable" + BetaToolSearchToolResultErrorParamErrorCodeTooManyRequests BetaToolSearchToolResultErrorParamErrorCode = "too_many_requests" + BetaToolSearchToolResultErrorParamErrorCodeExecutionTimeExceeded BetaToolSearchToolResultErrorParamErrorCode = "execution_time_exceeded" +) + +type BetaToolSearchToolSearchResultBlock struct { + ToolReferences []BetaToolReferenceBlock `json:"tool_references,required"` + Type constant.ToolSearchToolSearchResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ToolReferences respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaToolSearchToolSearchResultBlock) RawJSON() string { return r.JSON.raw } +func (r *BetaToolSearchToolSearchResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties ToolReferences, Type are required. +type BetaToolSearchToolSearchResultBlockParam struct { + ToolReferences []BetaToolReferenceBlockParam `json:"tool_references,omitzero,required"` + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_search_result". + Type constant.ToolSearchToolSearchResult `json:"type,required"` + paramObj +} + +func (r BetaToolSearchToolSearchResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BetaToolSearchToolSearchResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaToolSearchToolSearchResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Name, Type are required. +type BetaToolTextEditor20241022Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -7003,15 +8612,22 @@ func (r BetaToolTextEditor20241022Param) MarshalJSON() (data []byte, err error) type shadow BetaToolTextEditor20241022Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolTextEditor20241022Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Name, Type are required. type BetaToolTextEditor20250124Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -7029,15 +8645,22 @@ func (r BetaToolTextEditor20250124Param) MarshalJSON() (data []byte, err error) type shadow BetaToolTextEditor20250124Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolTextEditor20250124Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Name, Type are required. type BetaToolTextEditor20250429Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -7055,7 +8678,6 @@ func (r BetaToolTextEditor20250429Param) MarshalJSON() (data []byte, err error) type shadow BetaToolTextEditor20250429Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolTextEditor20250429Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7065,8 +8687,16 @@ type BetaToolTextEditor20250728Param struct { // Maximum number of characters to display when viewing a file. If not specified, // defaults to displaying the full file. MaxCharacters param.Opt[int64] `json:"max_characters,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -7084,7 +8714,6 @@ func (r BetaToolTextEditor20250728Param) MarshalJSON() (data []byte, err error) type shadow BetaToolTextEditor20250728Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolTextEditor20250728Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7110,24 +8739,56 @@ func BetaToolUnionParamOfComputerUseTool20250124(displayHeightPx int64, displayW return BetaToolUnionParam{OfComputerUseTool20250124: &variant} } +func BetaToolUnionParamOfComputerUseTool20251124(displayHeightPx int64, displayWidthPx int64) BetaToolUnionParam { + var variant BetaToolComputerUse20251124Param + variant.DisplayHeightPx = displayHeightPx + variant.DisplayWidthPx = displayWidthPx + return BetaToolUnionParam{OfComputerUseTool20251124: &variant} +} + +func BetaToolUnionParamOfToolSearchToolBm25_20251119(type_ BetaToolSearchToolBm25_20251119Type) BetaToolUnionParam { + var variant BetaToolSearchToolBm25_20251119Param + variant.Type = type_ + return BetaToolUnionParam{OfToolSearchToolBm25_20251119: &variant} +} + +func BetaToolUnionParamOfToolSearchToolRegex20251119(type_ BetaToolSearchToolRegex20251119Type) BetaToolUnionParam { + var variant BetaToolSearchToolRegex20251119Param + variant.Type = type_ + return BetaToolUnionParam{OfToolSearchToolRegex20251119: &variant} +} + +func BetaToolUnionParamOfMCPToolset(mcpServerName string) BetaToolUnionParam { + var variant BetaMCPToolsetParam + variant.MCPServerName = mcpServerName + return BetaToolUnionParam{OfMCPToolset: &variant} +} + // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaToolUnionParam struct { - OfTool *BetaToolParam `json:",omitzero,inline"` - OfBashTool20241022 *BetaToolBash20241022Param `json:",omitzero,inline"` - OfBashTool20250124 *BetaToolBash20250124Param `json:",omitzero,inline"` - OfCodeExecutionTool20250522 *BetaCodeExecutionTool20250522Param `json:",omitzero,inline"` - OfCodeExecutionTool20250825 *BetaCodeExecutionTool20250825Param `json:",omitzero,inline"` - OfComputerUseTool20241022 *BetaToolComputerUse20241022Param `json:",omitzero,inline"` - OfMemoryTool20250818 *BetaMemoryTool20250818Param `json:",omitzero,inline"` - OfComputerUseTool20250124 *BetaToolComputerUse20250124Param `json:",omitzero,inline"` - OfTextEditor20241022 *BetaToolTextEditor20241022Param `json:",omitzero,inline"` - OfTextEditor20250124 *BetaToolTextEditor20250124Param `json:",omitzero,inline"` - OfTextEditor20250429 *BetaToolTextEditor20250429Param `json:",omitzero,inline"` - OfTextEditor20250728 *BetaToolTextEditor20250728Param `json:",omitzero,inline"` - OfWebSearchTool20250305 *BetaWebSearchTool20250305Param `json:",omitzero,inline"` - OfWebFetchTool20250910 *BetaWebFetchTool20250910Param `json:",omitzero,inline"` + OfTool *BetaToolParam `json:",omitzero,inline"` + OfBashTool20241022 *BetaToolBash20241022Param `json:",omitzero,inline"` + OfBashTool20250124 *BetaToolBash20250124Param `json:",omitzero,inline"` + OfCodeExecutionTool20250522 *BetaCodeExecutionTool20250522Param `json:",omitzero,inline"` + OfCodeExecutionTool20250825 *BetaCodeExecutionTool20250825Param `json:",omitzero,inline"` + OfCodeExecutionTool20260120 *BetaCodeExecutionTool20260120Param `json:",omitzero,inline"` + OfComputerUseTool20241022 *BetaToolComputerUse20241022Param `json:",omitzero,inline"` + OfMemoryTool20250818 *BetaMemoryTool20250818Param `json:",omitzero,inline"` + OfComputerUseTool20250124 *BetaToolComputerUse20250124Param `json:",omitzero,inline"` + OfTextEditor20241022 *BetaToolTextEditor20241022Param `json:",omitzero,inline"` + OfComputerUseTool20251124 *BetaToolComputerUse20251124Param `json:",omitzero,inline"` + OfTextEditor20250124 *BetaToolTextEditor20250124Param `json:",omitzero,inline"` + OfTextEditor20250429 *BetaToolTextEditor20250429Param `json:",omitzero,inline"` + OfTextEditor20250728 *BetaToolTextEditor20250728Param `json:",omitzero,inline"` + OfWebSearchTool20250305 *BetaWebSearchTool20250305Param `json:",omitzero,inline"` + OfWebFetchTool20250910 *BetaWebFetchTool20250910Param `json:",omitzero,inline"` + OfWebSearchTool20260209 *BetaWebSearchTool20260209Param `json:",omitzero,inline"` + OfWebFetchTool20260209 *BetaWebFetchTool20260209Param `json:",omitzero,inline"` + OfToolSearchToolBm25_20251119 *BetaToolSearchToolBm25_20251119Param `json:",omitzero,inline"` + OfToolSearchToolRegex20251119 *BetaToolSearchToolRegex20251119Param `json:",omitzero,inline"` + OfMCPToolset *BetaMCPToolsetParam `json:",omitzero,inline"` paramUnion } @@ -7137,17 +8798,23 @@ func (u BetaToolUnionParam) MarshalJSON() ([]byte, error) { u.OfBashTool20250124, u.OfCodeExecutionTool20250522, u.OfCodeExecutionTool20250825, + u.OfCodeExecutionTool20260120, u.OfComputerUseTool20241022, u.OfMemoryTool20250818, u.OfComputerUseTool20250124, u.OfTextEditor20241022, + u.OfComputerUseTool20251124, u.OfTextEditor20250124, u.OfTextEditor20250429, u.OfTextEditor20250728, u.OfWebSearchTool20250305, - u.OfWebFetchTool20250910) + u.OfWebFetchTool20250910, + u.OfWebSearchTool20260209, + u.OfWebFetchTool20260209, + u.OfToolSearchToolBm25_20251119, + u.OfToolSearchToolRegex20251119, + u.OfMCPToolset) } - func (u *BetaToolUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -7163,6 +8830,8 @@ func (u *BetaToolUnionParam) asAny() any { return u.OfCodeExecutionTool20250522 } else if !param.IsOmitted(u.OfCodeExecutionTool20250825) { return u.OfCodeExecutionTool20250825 + } else if !param.IsOmitted(u.OfCodeExecutionTool20260120) { + return u.OfCodeExecutionTool20260120 } else if !param.IsOmitted(u.OfComputerUseTool20241022) { return u.OfComputerUseTool20241022 } else if !param.IsOmitted(u.OfMemoryTool20250818) { @@ -7171,6 +8840,8 @@ func (u *BetaToolUnionParam) asAny() any { return u.OfComputerUseTool20250124 } else if !param.IsOmitted(u.OfTextEditor20241022) { return u.OfTextEditor20241022 + } else if !param.IsOmitted(u.OfComputerUseTool20251124) { + return u.OfComputerUseTool20251124 } else if !param.IsOmitted(u.OfTextEditor20250124) { return u.OfTextEditor20250124 } else if !param.IsOmitted(u.OfTextEditor20250429) { @@ -7181,6 +8852,16 @@ func (u *BetaToolUnionParam) asAny() any { return u.OfWebSearchTool20250305 } else if !param.IsOmitted(u.OfWebFetchTool20250910) { return u.OfWebFetchTool20250910 + } else if !param.IsOmitted(u.OfWebSearchTool20260209) { + return u.OfWebSearchTool20260209 + } else if !param.IsOmitted(u.OfWebFetchTool20260209) { + return u.OfWebFetchTool20260209 + } else if !param.IsOmitted(u.OfToolSearchToolBm25_20251119) { + return u.OfToolSearchToolBm25_20251119 + } else if !param.IsOmitted(u.OfToolSearchToolRegex20251119) { + return u.OfToolSearchToolRegex20251119 + } else if !param.IsOmitted(u.OfMCPToolset) { + return u.OfMCPToolset } return nil } @@ -7201,6 +8882,22 @@ func (u BetaToolUnionParam) GetDescription() *string { return nil } +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolUnionParam) GetEagerInputStreaming() *bool { + if vt := u.OfTool; vt != nil && vt.EagerInputStreaming.Valid() { + return &vt.EagerInputStreaming.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolUnionParam) GetEnableZoom() *bool { + if vt := u.OfComputerUseTool20251124; vt != nil && vt.EnableZoom.Valid() { + return &vt.EnableZoom.Value + } + return nil +} + // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) GetMaxCharacters() *int64 { if vt := u.OfTextEditor20250728; vt != nil && vt.MaxCharacters.Valid() { @@ -7210,25 +8907,25 @@ func (u BetaToolUnionParam) GetMaxCharacters() *int64 { } // Returns a pointer to the underlying variant's property, if present. -func (u BetaToolUnionParam) GetUserLocation() *BetaWebSearchTool20250305UserLocationParam { - if vt := u.OfWebSearchTool20250305; vt != nil { - return &vt.UserLocation +func (u BetaToolUnionParam) GetMCPServerName() *string { + if vt := u.OfMCPToolset; vt != nil { + return &vt.MCPServerName } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u BetaToolUnionParam) GetCitations() *BetaCitationsConfigParam { - if vt := u.OfWebFetchTool20250910; vt != nil { - return &vt.Citations +func (u BetaToolUnionParam) GetConfigs() map[string]BetaMCPToolConfigParam { + if vt := u.OfMCPToolset; vt != nil { + return vt.Configs } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u BetaToolUnionParam) GetMaxContentTokens() *int64 { - if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxContentTokens.Valid() { - return &vt.MaxContentTokens.Value +func (u BetaToolUnionParam) GetDefaultConfig() *BetaMCPToolDefaultConfigParam { + if vt := u.OfMCPToolset; vt != nil { + return &vt.DefaultConfig } return nil } @@ -7245,6 +8942,8 @@ func (u BetaToolUnionParam) GetName() *string { return (*string)(&vt.Name) } else if vt := u.OfCodeExecutionTool20250825; vt != nil { return (*string)(&vt.Name) + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return (*string)(&vt.Name) } else if vt := u.OfComputerUseTool20241022; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfMemoryTool20250818; vt != nil { @@ -7253,6 +8952,8 @@ func (u BetaToolUnionParam) GetName() *string { return (*string)(&vt.Name) } else if vt := u.OfTextEditor20241022; vt != nil { return (*string)(&vt.Name) + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return (*string)(&vt.Name) } else if vt := u.OfTextEditor20250124; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfTextEditor20250429; vt != nil { @@ -7263,6 +8964,106 @@ func (u BetaToolUnionParam) GetName() *string { return (*string)(&vt.Name) } else if vt := u.OfWebFetchTool20250910; vt != nil { return (*string)(&vt.Name) + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return (*string)(&vt.Name) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolUnionParam) GetDeferLoading() *bool { + if vt := u.OfTool; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfBashTool20241022; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfBashTool20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20250522; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20250825; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20260120; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfComputerUseTool20241022; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfMemoryTool20250818; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfComputerUseTool20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20241022; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfComputerUseTool20251124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250429; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250728; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebSearchTool20250305; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolUnionParam) GetStrict() *bool { + if vt := u.OfTool; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfBashTool20241022; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfBashTool20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20250522; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20250825; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20260120; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfComputerUseTool20241022; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfMemoryTool20250818; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfComputerUseTool20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20241022; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfComputerUseTool20251124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250429; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250728; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebSearchTool20250305; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value } return nil } @@ -7279,6 +9080,8 @@ func (u BetaToolUnionParam) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfCodeExecutionTool20250825; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return (*string)(&vt.Type) } else if vt := u.OfComputerUseTool20241022; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfMemoryTool20250818; vt != nil { @@ -7287,6 +9090,8 @@ func (u BetaToolUnionParam) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfTextEditor20241022; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return (*string)(&vt.Type) } else if vt := u.OfTextEditor20250124; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfTextEditor20250429; vt != nil { @@ -7297,6 +9102,16 @@ func (u BetaToolUnionParam) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfWebFetchTool20250910; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfMCPToolset; vt != nil { + return (*string)(&vt.Type) } return nil } @@ -7307,6 +9122,8 @@ func (u BetaToolUnionParam) GetDisplayHeightPx() *int64 { return (*int64)(&vt.DisplayHeightPx) } else if vt := u.OfComputerUseTool20250124; vt != nil { return (*int64)(&vt.DisplayHeightPx) + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return (*int64)(&vt.DisplayHeightPx) } return nil } @@ -7317,6 +9134,8 @@ func (u BetaToolUnionParam) GetDisplayWidthPx() *int64 { return (*int64)(&vt.DisplayWidthPx) } else if vt := u.OfComputerUseTool20250124; vt != nil { return (*int64)(&vt.DisplayWidthPx) + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return (*int64)(&vt.DisplayWidthPx) } return nil } @@ -7327,6 +9146,8 @@ func (u BetaToolUnionParam) GetDisplayNumber() *int64 { return &vt.DisplayNumber.Value } else if vt := u.OfComputerUseTool20250124; vt != nil && vt.DisplayNumber.Valid() { return &vt.DisplayNumber.Value + } else if vt := u.OfComputerUseTool20251124; vt != nil && vt.DisplayNumber.Valid() { + return &vt.DisplayNumber.Value } return nil } @@ -7337,6 +9158,67 @@ func (u BetaToolUnionParam) GetMaxUses() *int64 { return &vt.MaxUses.Value } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxUses.Valid() { return &vt.MaxUses.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolUnionParam) GetMaxContentTokens() *int64 { + if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxContentTokens.Valid() { + return &vt.MaxContentTokens.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.MaxContentTokens.Valid() { + return &vt.MaxContentTokens.Value + } + return nil +} + +// Returns a pointer to the underlying variant's AllowedCallers property, if +// present. +func (u BetaToolUnionParam) GetAllowedCallers() []string { + if vt := u.OfTool; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfBashTool20241022; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfBashTool20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfComputerUseTool20241022; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfMemoryTool20250818; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfComputerUseTool20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20241022; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250429; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250728; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return vt.AllowedCallers } return nil } @@ -7353,6 +9235,8 @@ func (u BetaToolUnionParam) GetCacheControl() *BetaCacheControlEphemeralParam { return &vt.CacheControl } else if vt := u.OfCodeExecutionTool20250825; vt != nil { return &vt.CacheControl + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return &vt.CacheControl } else if vt := u.OfComputerUseTool20241022; vt != nil { return &vt.CacheControl } else if vt := u.OfMemoryTool20250818; vt != nil { @@ -7361,6 +9245,8 @@ func (u BetaToolUnionParam) GetCacheControl() *BetaCacheControlEphemeralParam { return &vt.CacheControl } else if vt := u.OfTextEditor20241022; vt != nil { return &vt.CacheControl + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return &vt.CacheControl } else if vt := u.OfTextEditor20250124; vt != nil { return &vt.CacheControl } else if vt := u.OfTextEditor20250429; vt != nil { @@ -7371,6 +9257,45 @@ func (u BetaToolUnionParam) GetCacheControl() *BetaCacheControlEphemeralParam { return &vt.CacheControl } else if vt := u.OfWebFetchTool20250910; vt != nil { return &vt.CacheControl + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return &vt.CacheControl + } else if vt := u.OfMCPToolset; vt != nil { + return &vt.CacheControl + } + return nil +} + +// Returns a pointer to the underlying variant's InputExamples property, if +// present. +func (u BetaToolUnionParam) GetInputExamples() []map[string]any { + if vt := u.OfTool; vt != nil { + return vt.InputExamples + } else if vt := u.OfBashTool20241022; vt != nil { + return vt.InputExamples + } else if vt := u.OfBashTool20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfComputerUseTool20241022; vt != nil { + return vt.InputExamples + } else if vt := u.OfMemoryTool20250818; vt != nil { + return vt.InputExamples + } else if vt := u.OfComputerUseTool20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20241022; vt != nil { + return vt.InputExamples + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250429; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250728; vt != nil { + return vt.InputExamples } return nil } @@ -7382,6 +9307,10 @@ func (u BetaToolUnionParam) GetAllowedDomains() []string { return vt.AllowedDomains } else if vt := u.OfWebFetchTool20250910; vt != nil { return vt.AllowedDomains + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.AllowedDomains + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.AllowedDomains } return nil } @@ -7393,6 +9322,30 @@ func (u BetaToolUnionParam) GetBlockedDomains() []string { return vt.BlockedDomains } else if vt := u.OfWebFetchTool20250910; vt != nil { return vt.BlockedDomains + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.BlockedDomains + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.BlockedDomains + } + return nil +} + +// Returns a pointer to the underlying variant's UserLocation property, if present. +func (u BetaToolUnionParam) GetUserLocation() *BetaUserLocationParam { + if vt := u.OfWebSearchTool20250305; vt != nil { + return &vt.UserLocation + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return &vt.UserLocation + } + return nil +} + +// Returns a pointer to the underlying variant's Citations property, if present. +func (u BetaToolUnionParam) GetCitations() *BetaCitationsConfigParam { + if vt := u.OfWebFetchTool20250910; vt != nil { + return &vt.Citations + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return &vt.Citations } return nil } @@ -7402,12 +9355,15 @@ type BetaToolUseBlock struct { Input any `json:"input,required"` Name string `json:"name,required"` Type constant.ToolUse `json:"type,required"` + // Tool invocation directly from the model. + Caller BetaToolUseBlockCallerUnion `json:"caller"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field Input respjson.Field Name respjson.Field Type respjson.Field + Caller respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` @@ -7415,18 +9371,79 @@ type BetaToolUseBlock struct { // Returns the unmodified JSON received from the API func (r BetaToolUseBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaToolUseBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r BetaToolUseBlock) ToParam() BetaToolUseBlockParam { - var p BetaToolUseBlockParam - p.Type = r.Type - p.ID = r.ID - p.Input = r.Input - p.Name = r.Name - return p +// BetaToolUseBlockCallerUnion contains all possible properties and values from +// [BetaDirectCaller], [BetaServerToolCaller], [BetaServerToolCaller20260120]. +// +// Use the [BetaToolUseBlockCallerUnion.AsAny] method to switch on the variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type BetaToolUseBlockCallerUnion struct { + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +// anyBetaToolUseBlockCaller is implemented by each variant of +// [BetaToolUseBlockCallerUnion] to add type safety for the return type of +// [BetaToolUseBlockCallerUnion.AsAny] +type anyBetaToolUseBlockCaller interface { + implBetaToolUseBlockCallerUnion() +} + +func (BetaDirectCaller) implBetaToolUseBlockCallerUnion() {} +func (BetaServerToolCaller) implBetaToolUseBlockCallerUnion() {} +func (BetaServerToolCaller20260120) implBetaToolUseBlockCallerUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := BetaToolUseBlockCallerUnion.AsAny().(type) { +// case anthropic.BetaDirectCaller: +// case anthropic.BetaServerToolCaller: +// case anthropic.BetaServerToolCaller20260120: +// default: +// fmt.Errorf("no variant present") +// } +func (u BetaToolUseBlockCallerUnion) AsAny() anyBetaToolUseBlockCaller { + switch u.Type { + case "direct": + return u.AsDirect() + case "code_execution_20250825": + return u.AsCodeExecution20250825() + case "code_execution_20260120": + return u.AsCodeExecution20260120() + } + return nil +} + +func (u BetaToolUseBlockCallerUnion) AsDirect() (v BetaDirectCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaToolUseBlockCallerUnion) AsCodeExecution20250825() (v BetaServerToolCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaToolUseBlockCallerUnion) AsCodeExecution20260120() (v BetaServerToolCaller20260120) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u BetaToolUseBlockCallerUnion) RawJSON() string { return u.JSON.raw } + +func (r *BetaToolUseBlockCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } // The properties ID, Input, Name, Type are required. @@ -7436,6 +9453,8 @@ type BetaToolUseBlockParam struct { Name string `json:"name,required"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Tool invocation directly from the model. + Caller BetaToolUseBlockParamCallerUnion `json:"caller,omitzero"` // This field can be elided, and will marshal its zero value as "tool_use". Type constant.ToolUse `json:"type,required"` paramObj @@ -7445,11 +9464,69 @@ func (r BetaToolUseBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolUseBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolUseBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaToolUseBlockParamCallerUnion struct { + OfDirect *BetaDirectCallerParam `json:",omitzero,inline"` + OfCodeExecution20250825 *BetaServerToolCallerParam `json:",omitzero,inline"` + OfCodeExecution20260120 *BetaServerToolCaller20260120Param `json:",omitzero,inline"` + paramUnion +} + +func (u BetaToolUseBlockParamCallerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfDirect, u.OfCodeExecution20250825, u.OfCodeExecution20260120) +} +func (u *BetaToolUseBlockParamCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BetaToolUseBlockParamCallerUnion) asAny() any { + if !param.IsOmitted(u.OfDirect) { + return u.OfDirect + } else if !param.IsOmitted(u.OfCodeExecution20250825) { + return u.OfCodeExecution20250825 + } else if !param.IsOmitted(u.OfCodeExecution20260120) { + return u.OfCodeExecution20260120 + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolUseBlockParamCallerUnion) GetType() *string { + if vt := u.OfDirect; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaToolUseBlockParamCallerUnion) GetToolID() *string { + if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.ToolID) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.ToolID) + } + return nil +} + +func init() { + apijson.RegisterUnion[BetaToolUseBlockParamCallerUnion]( + "type", + apijson.Discriminator[BetaDirectCallerParam]("direct"), + apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), + apijson.Discriminator[BetaServerToolCaller20260120Param]("code_execution_20260120"), + ) +} + // The properties Type, Value are required. type BetaToolUsesKeepParam struct { Value int64 `json:"value,required"` @@ -7462,7 +9539,6 @@ func (r BetaToolUsesKeepParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolUsesKeepParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolUsesKeepParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7479,7 +9555,6 @@ func (r BetaToolUsesTriggerParam) MarshalJSON() (data []byte, err error) { type shadow BetaToolUsesTriggerParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaToolUsesTriggerParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7496,7 +9571,6 @@ func (r BetaURLImageSourceParam) MarshalJSON() (data []byte, err error) { type shadow BetaURLImageSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaURLImageSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7513,7 +9587,6 @@ func (r BetaURLPDFSourceParam) MarshalJSON() (data []byte, err error) { type shadow BetaURLPDFSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaURLPDFSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7525,8 +9598,19 @@ type BetaUsage struct { CacheCreationInputTokens int64 `json:"cache_creation_input_tokens,required"` // The number of input tokens read from the cache. CacheReadInputTokens int64 `json:"cache_read_input_tokens,required"` + // The geographic region where inference was performed for this request. + InferenceGeo string `json:"inference_geo,required"` // The number of input tokens which were used. InputTokens int64 `json:"input_tokens,required"` + // Per-iteration token usage breakdown. + // + // Each entry represents one sampling iteration, with its own input/output token + // counts and cache statistics. This allows you to: + // + // - Determine which iterations exceeded long context thresholds (>=200k tokens) + // - Calculate the true context window size from the last iteration + // - Understand token accumulation across server-side tool use loops + Iterations BetaIterationsUsage `json:"iterations,required"` // The number of output tokens which were used. OutputTokens int64 `json:"output_tokens,required"` // The number of server tool requests. @@ -7535,15 +9619,22 @@ type BetaUsage struct { // // Any of "standard", "priority", "batch". ServiceTier BetaUsageServiceTier `json:"service_tier,required"` + // The inference speed mode used for this request. + // + // Any of "standard", "fast". + Speed BetaUsageSpeed `json:"speed,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { CacheCreation respjson.Field CacheCreationInputTokens respjson.Field CacheReadInputTokens respjson.Field + InferenceGeo respjson.Field InputTokens respjson.Field + Iterations respjson.Field OutputTokens respjson.Field ServerToolUse respjson.Field ServiceTier respjson.Field + Speed respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` @@ -7551,7 +9642,6 @@ type BetaUsage struct { // Returns the unmodified JSON received from the API func (r BetaUsage) RawJSON() string { return r.JSON.raw } - func (r *BetaUsage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7565,6 +9655,39 @@ const ( BetaUsageServiceTierBatch BetaUsageServiceTier = "batch" ) +// The inference speed mode used for this request. +type BetaUsageSpeed string + +const ( + BetaUsageSpeedStandard BetaUsageSpeed = "standard" + BetaUsageSpeedFast BetaUsageSpeed = "fast" +) + +// The property Type is required. +type BetaUserLocationParam struct { + // The city of the user. + City param.Opt[string] `json:"city,omitzero"` + // The two letter + // [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the + // user. + Country param.Opt[string] `json:"country,omitzero"` + // The region of the user. + Region param.Opt[string] `json:"region,omitzero"` + // The [IANA timezone](https://nodatime.org/TimeZones) of the user. + Timezone param.Opt[string] `json:"timezone,omitzero"` + // This field can be elided, and will marshal its zero value as "approximate". + Type constant.Approximate `json:"type,required"` + paramObj +} + +func (r BetaUserLocationParam) MarshalJSON() (data []byte, err error) { + type shadow BetaUserLocationParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaUserLocationParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + type BetaWebFetchBlock struct { Content BetaDocumentBlock `json:"content,required"` // ISO 8601 timestamp when the content was retrieved @@ -7585,7 +9708,6 @@ type BetaWebFetchBlock struct { // Returns the unmodified JSON received from the API func (r BetaWebFetchBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaWebFetchBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7606,7 +9728,6 @@ func (r BetaWebFetchBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaWebFetchBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaWebFetchBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7618,10 +9739,17 @@ type BetaWebFetchTool20250910Param struct { MaxContentTokens param.Opt[int64] `json:"max_content_tokens,omitzero"` // Maximum number of times the tool can be used in the API request. MaxUses param.Opt[int64] `json:"max_uses,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` // List of domains to allow fetching from AllowedDomains []string `json:"allowed_domains,omitzero"` // List of domains to block fetching from BlockedDomains []string `json:"blocked_domains,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` // Citations configuration for fetched documents. Citations are disabled by @@ -7643,20 +9771,65 @@ func (r BetaWebFetchTool20250910Param) MarshalJSON() (data []byte, err error) { type shadow BetaWebFetchTool20250910Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaWebFetchTool20250910Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// The properties Name, Type are required. +type BetaWebFetchTool20260209Param struct { + // Maximum number of tokens used by including web page text content in the context. + // The limit is approximate and does not apply to binary content such as PDFs. + MaxContentTokens param.Opt[int64] `json:"max_content_tokens,omitzero"` + // Maximum number of times the tool can be used in the API request. + MaxUses param.Opt[int64] `json:"max_uses,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // List of domains to allow fetching from + AllowedDomains []string `json:"allowed_domains,omitzero"` + // List of domains to block fetching from + BlockedDomains []string `json:"blocked_domains,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Citations configuration for fetched documents. Citations are disabled by + // default. + Citations BetaCitationsConfigParam `json:"citations,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "web_fetch". + Name constant.WebFetch `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "web_fetch_20260209". + Type constant.WebFetch20260209 `json:"type,required"` + paramObj +} + +func (r BetaWebFetchTool20260209Param) MarshalJSON() (data []byte, err error) { + type shadow BetaWebFetchTool20260209Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BetaWebFetchTool20260209Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + type BetaWebFetchToolResultBlock struct { Content BetaWebFetchToolResultBlockContentUnion `json:"content,required"` ToolUseID string `json:"tool_use_id,required"` Type constant.WebFetchToolResult `json:"type,required"` + // Tool invocation directly from the model. + Caller BetaWebFetchToolResultBlockCallerUnion `json:"caller"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Content respjson.Field ToolUseID respjson.Field Type respjson.Field + Caller respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` @@ -7664,7 +9837,6 @@ type BetaWebFetchToolResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaWebFetchToolResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaWebFetchToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7695,12 +9867,12 @@ type BetaWebFetchToolResultBlockContentUnion struct { func (u BetaWebFetchToolResultBlockContentUnion) AsResponseWebFetchToolResultError() (v BetaWebFetchToolResultErrorBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaWebFetchToolResultBlockContentUnion) AsResponseWebFetchResultBlock() (v BetaWebFetchBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -7710,12 +9882,87 @@ func (r *BetaWebFetchToolResultBlockContentUnion) UnmarshalJSON(data []byte) err return apijson.UnmarshalRoot(data, r) } +// BetaWebFetchToolResultBlockCallerUnion contains all possible properties and +// values from [BetaDirectCaller], [BetaServerToolCaller], +// [BetaServerToolCaller20260120]. +// +// Use the [BetaWebFetchToolResultBlockCallerUnion.AsAny] method to switch on the +// variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type BetaWebFetchToolResultBlockCallerUnion struct { + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +// anyBetaWebFetchToolResultBlockCaller is implemented by each variant of +// [BetaWebFetchToolResultBlockCallerUnion] to add type safety for the return type +// of [BetaWebFetchToolResultBlockCallerUnion.AsAny] +type anyBetaWebFetchToolResultBlockCaller interface { + implBetaWebFetchToolResultBlockCallerUnion() +} + +func (BetaDirectCaller) implBetaWebFetchToolResultBlockCallerUnion() {} +func (BetaServerToolCaller) implBetaWebFetchToolResultBlockCallerUnion() {} +func (BetaServerToolCaller20260120) implBetaWebFetchToolResultBlockCallerUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := BetaWebFetchToolResultBlockCallerUnion.AsAny().(type) { +// case anthropic.BetaDirectCaller: +// case anthropic.BetaServerToolCaller: +// case anthropic.BetaServerToolCaller20260120: +// default: +// fmt.Errorf("no variant present") +// } +func (u BetaWebFetchToolResultBlockCallerUnion) AsAny() anyBetaWebFetchToolResultBlockCaller { + switch u.Type { + case "direct": + return u.AsDirect() + case "code_execution_20250825": + return u.AsCodeExecution20250825() + case "code_execution_20260120": + return u.AsCodeExecution20260120() + } + return nil +} + +func (u BetaWebFetchToolResultBlockCallerUnion) AsDirect() (v BetaDirectCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaWebFetchToolResultBlockCallerUnion) AsCodeExecution20250825() (v BetaServerToolCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaWebFetchToolResultBlockCallerUnion) AsCodeExecution20260120() (v BetaServerToolCaller20260120) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u BetaWebFetchToolResultBlockCallerUnion) RawJSON() string { return u.JSON.raw } + +func (r *BetaWebFetchToolResultBlockCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // The properties Content, ToolUseID, Type are required. type BetaWebFetchToolResultBlockParam struct { Content BetaWebFetchToolResultBlockParamContentUnion `json:"content,omitzero,required"` ToolUseID string `json:"tool_use_id,required"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Tool invocation directly from the model. + Caller BetaWebFetchToolResultBlockParamCallerUnion `json:"caller,omitzero"` // This field can be elided, and will marshal its zero value as // "web_fetch_tool_result". Type constant.WebFetchToolResult `json:"type,required"` @@ -7726,7 +9973,6 @@ func (r BetaWebFetchToolResultBlockParam) MarshalJSON() (data []byte, err error) type shadow BetaWebFetchToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaWebFetchToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7743,7 +9989,6 @@ type BetaWebFetchToolResultBlockParamContentUnion struct { func (u BetaWebFetchToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfRequestWebFetchToolResultError, u.OfRequestWebFetchResultBlock) } - func (u *BetaWebFetchToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -7799,6 +10044,65 @@ func (u BetaWebFetchToolResultBlockParamContentUnion) GetType() *string { return nil } +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaWebFetchToolResultBlockParamCallerUnion struct { + OfDirect *BetaDirectCallerParam `json:",omitzero,inline"` + OfCodeExecution20250825 *BetaServerToolCallerParam `json:",omitzero,inline"` + OfCodeExecution20260120 *BetaServerToolCaller20260120Param `json:",omitzero,inline"` + paramUnion +} + +func (u BetaWebFetchToolResultBlockParamCallerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfDirect, u.OfCodeExecution20250825, u.OfCodeExecution20260120) +} +func (u *BetaWebFetchToolResultBlockParamCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BetaWebFetchToolResultBlockParamCallerUnion) asAny() any { + if !param.IsOmitted(u.OfDirect) { + return u.OfDirect + } else if !param.IsOmitted(u.OfCodeExecution20250825) { + return u.OfCodeExecution20250825 + } else if !param.IsOmitted(u.OfCodeExecution20260120) { + return u.OfCodeExecution20260120 + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaWebFetchToolResultBlockParamCallerUnion) GetType() *string { + if vt := u.OfDirect; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaWebFetchToolResultBlockParamCallerUnion) GetToolID() *string { + if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.ToolID) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.ToolID) + } + return nil +} + +func init() { + apijson.RegisterUnion[BetaWebFetchToolResultBlockParamCallerUnion]( + "type", + apijson.Discriminator[BetaDirectCallerParam]("direct"), + apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), + apijson.Discriminator[BetaServerToolCaller20260120Param]("code_execution_20260120"), + ) +} + type BetaWebFetchToolResultErrorBlock struct { // Any of "invalid_tool_input", "url_too_long", "url_not_allowed", // "url_not_accessible", "unsupported_content_type", "too_many_requests", @@ -7816,7 +10120,6 @@ type BetaWebFetchToolResultErrorBlock struct { // Returns the unmodified JSON received from the API func (r BetaWebFetchToolResultErrorBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaWebFetchToolResultErrorBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7837,7 +10140,6 @@ func (r BetaWebFetchToolResultErrorBlockParam) MarshalJSON() (data []byte, err e type shadow BetaWebFetchToolResultErrorBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaWebFetchToolResultErrorBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7875,7 +10177,6 @@ type BetaWebSearchResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaWebSearchResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaWebSearchResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7896,7 +10197,6 @@ func (r BetaWebSearchResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaWebSearchResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaWebSearchResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7905,17 +10205,24 @@ func (r *BetaWebSearchResultBlockParam) UnmarshalJSON(data []byte) error { type BetaWebSearchTool20250305Param struct { // Maximum number of times the tool can be used in the API request. MaxUses param.Opt[int64] `json:"max_uses,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` // If provided, only these domains will be included in results. Cannot be used // alongside `blocked_domains`. AllowedDomains []string `json:"allowed_domains,omitzero"` // If provided, these domains will never appear in results. Cannot be used // alongside `allowed_domains`. BlockedDomains []string `json:"blocked_domains,omitzero"` - // Parameters for the user's location. Used to provide more relevant search - // results. - UserLocation BetaWebSearchTool20250305UserLocationParam `json:"user_location,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Parameters for the user's location. Used to provide more relevant search + // results. + UserLocation BetaUserLocationParam `json:"user_location,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -7932,44 +10239,56 @@ func (r BetaWebSearchTool20250305Param) MarshalJSON() (data []byte, err error) { type shadow BetaWebSearchTool20250305Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaWebSearchTool20250305Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Parameters for the user's location. Used to provide more relevant search -// results. -// -// The property Type is required. -type BetaWebSearchTool20250305UserLocationParam struct { - // The city of the user. - City param.Opt[string] `json:"city,omitzero"` - // The two letter - // [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the - // user. - Country param.Opt[string] `json:"country,omitzero"` - // The region of the user. - Region param.Opt[string] `json:"region,omitzero"` - // The [IANA timezone](https://nodatime.org/TimeZones) of the user. - Timezone param.Opt[string] `json:"timezone,omitzero"` - // This field can be elided, and will marshal its zero value as "approximate". - Type constant.Approximate `json:"type,required"` +// The properties Name, Type are required. +type BetaWebSearchTool20260209Param struct { + // Maximum number of times the tool can be used in the API request. + MaxUses param.Opt[int64] `json:"max_uses,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // If provided, only these domains will be included in results. Cannot be used + // alongside `blocked_domains`. + AllowedDomains []string `json:"allowed_domains,omitzero"` + // If provided, these domains will never appear in results. Cannot be used + // alongside `allowed_domains`. + BlockedDomains []string `json:"blocked_domains,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Parameters for the user's location. Used to provide more relevant search + // results. + UserLocation BetaUserLocationParam `json:"user_location,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "web_search". + Name constant.WebSearch `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "web_search_20260209". + Type constant.WebSearch20260209 `json:"type,required"` paramObj } -func (r BetaWebSearchTool20250305UserLocationParam) MarshalJSON() (data []byte, err error) { - type shadow BetaWebSearchTool20250305UserLocationParam +func (r BetaWebSearchTool20260209Param) MarshalJSON() (data []byte, err error) { + type shadow BetaWebSearchTool20260209Param return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *BetaWebSearchTool20250305UserLocationParam) UnmarshalJSON(data []byte) error { +func (r *BetaWebSearchTool20260209Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties ErrorCode, Type are required. type BetaWebSearchToolRequestErrorParam struct { // Any of "invalid_tool_input", "unavailable", "max_uses_exceeded", - // "too_many_requests", "query_too_long". + // "too_many_requests", "query_too_long", "request_too_large". ErrorCode BetaWebSearchToolResultErrorCode `json:"error_code,omitzero,required"` // This field can be elided, and will marshal its zero value as // "web_search_tool_result_error". @@ -7981,7 +10300,6 @@ func (r BetaWebSearchToolRequestErrorParam) MarshalJSON() (data []byte, err erro type shadow BetaWebSearchToolRequestErrorParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaWebSearchToolRequestErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -7990,11 +10308,14 @@ type BetaWebSearchToolResultBlock struct { Content BetaWebSearchToolResultBlockContentUnion `json:"content,required"` ToolUseID string `json:"tool_use_id,required"` Type constant.WebSearchToolResult `json:"type,required"` + // Tool invocation directly from the model. + Caller BetaWebSearchToolResultBlockCallerUnion `json:"caller"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Content respjson.Field ToolUseID respjson.Field Type respjson.Field + Caller respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` @@ -8002,11 +10323,83 @@ type BetaWebSearchToolResultBlock struct { // Returns the unmodified JSON received from the API func (r BetaWebSearchToolResultBlock) RawJSON() string { return r.JSON.raw } - func (r *BetaWebSearchToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// BetaWebSearchToolResultBlockCallerUnion contains all possible properties and +// values from [BetaDirectCaller], [BetaServerToolCaller], +// [BetaServerToolCaller20260120]. +// +// Use the [BetaWebSearchToolResultBlockCallerUnion.AsAny] method to switch on the +// variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type BetaWebSearchToolResultBlockCallerUnion struct { + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +// anyBetaWebSearchToolResultBlockCaller is implemented by each variant of +// [BetaWebSearchToolResultBlockCallerUnion] to add type safety for the return type +// of [BetaWebSearchToolResultBlockCallerUnion.AsAny] +type anyBetaWebSearchToolResultBlockCaller interface { + implBetaWebSearchToolResultBlockCallerUnion() +} + +func (BetaDirectCaller) implBetaWebSearchToolResultBlockCallerUnion() {} +func (BetaServerToolCaller) implBetaWebSearchToolResultBlockCallerUnion() {} +func (BetaServerToolCaller20260120) implBetaWebSearchToolResultBlockCallerUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := BetaWebSearchToolResultBlockCallerUnion.AsAny().(type) { +// case anthropic.BetaDirectCaller: +// case anthropic.BetaServerToolCaller: +// case anthropic.BetaServerToolCaller20260120: +// default: +// fmt.Errorf("no variant present") +// } +func (u BetaWebSearchToolResultBlockCallerUnion) AsAny() anyBetaWebSearchToolResultBlockCaller { + switch u.Type { + case "direct": + return u.AsDirect() + case "code_execution_20250825": + return u.AsCodeExecution20250825() + case "code_execution_20260120": + return u.AsCodeExecution20260120() + } + return nil +} + +func (u BetaWebSearchToolResultBlockCallerUnion) AsDirect() (v BetaDirectCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaWebSearchToolResultBlockCallerUnion) AsCodeExecution20250825() (v BetaServerToolCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BetaWebSearchToolResultBlockCallerUnion) AsCodeExecution20260120() (v BetaServerToolCaller20260120) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u BetaWebSearchToolResultBlockCallerUnion) RawJSON() string { return u.JSON.raw } + +func (r *BetaWebSearchToolResultBlockCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // BetaWebSearchToolResultBlockContentUnion contains all possible properties and // values from [BetaWebSearchToolResultError], [[]BetaWebSearchResultBlock]. // @@ -8032,12 +10425,12 @@ type BetaWebSearchToolResultBlockContentUnion struct { func (u BetaWebSearchToolResultBlockContentUnion) AsResponseWebSearchToolResultError() (v BetaWebSearchToolResultError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u BetaWebSearchToolResultBlockContentUnion) AsBetaWebSearchResultBlockArray() (v []BetaWebSearchResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -8053,6 +10446,8 @@ type BetaWebSearchToolResultBlockParam struct { ToolUseID string `json:"tool_use_id,required"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Tool invocation directly from the model. + Caller BetaWebSearchToolResultBlockParamCallerUnion `json:"caller,omitzero"` // This field can be elided, and will marshal its zero value as // "web_search_tool_result". Type constant.WebSearchToolResult `json:"type,required"` @@ -8063,11 +10458,69 @@ func (r BetaWebSearchToolResultBlockParam) MarshalJSON() (data []byte, err error type shadow BetaWebSearchToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaWebSearchToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaWebSearchToolResultBlockParamCallerUnion struct { + OfDirect *BetaDirectCallerParam `json:",omitzero,inline"` + OfCodeExecution20250825 *BetaServerToolCallerParam `json:",omitzero,inline"` + OfCodeExecution20260120 *BetaServerToolCaller20260120Param `json:",omitzero,inline"` + paramUnion +} + +func (u BetaWebSearchToolResultBlockParamCallerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfDirect, u.OfCodeExecution20250825, u.OfCodeExecution20260120) +} +func (u *BetaWebSearchToolResultBlockParamCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BetaWebSearchToolResultBlockParamCallerUnion) asAny() any { + if !param.IsOmitted(u.OfDirect) { + return u.OfDirect + } else if !param.IsOmitted(u.OfCodeExecution20250825) { + return u.OfCodeExecution20250825 + } else if !param.IsOmitted(u.OfCodeExecution20260120) { + return u.OfCodeExecution20260120 + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaWebSearchToolResultBlockParamCallerUnion) GetType() *string { + if vt := u.OfDirect; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaWebSearchToolResultBlockParamCallerUnion) GetToolID() *string { + if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.ToolID) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.ToolID) + } + return nil +} + +func init() { + apijson.RegisterUnion[BetaWebSearchToolResultBlockParamCallerUnion]( + "type", + apijson.Discriminator[BetaDirectCallerParam]("direct"), + apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), + apijson.Discriminator[BetaServerToolCaller20260120Param]("code_execution_20260120"), + ) +} + func BetaNewWebSearchToolRequestError(errorCode BetaWebSearchToolResultErrorCode) BetaWebSearchToolResultBlockParamContentUnion { var variant BetaWebSearchToolRequestErrorParam variant.ErrorCode = errorCode @@ -8086,7 +10539,6 @@ type BetaWebSearchToolResultBlockParamContentUnion struct { func (u BetaWebSearchToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfResultBlock, u.OfError) } - func (u *BetaWebSearchToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -8102,7 +10554,7 @@ func (u *BetaWebSearchToolResultBlockParamContentUnion) asAny() any { type BetaWebSearchToolResultError struct { // Any of "invalid_tool_input", "unavailable", "max_uses_exceeded", - // "too_many_requests", "query_too_long". + // "too_many_requests", "query_too_long", "request_too_large". ErrorCode BetaWebSearchToolResultErrorCode `json:"error_code,required"` Type constant.WebSearchToolResultError `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. @@ -8116,7 +10568,6 @@ type BetaWebSearchToolResultError struct { // Returns the unmodified JSON received from the API func (r BetaWebSearchToolResultError) RawJSON() string { return r.JSON.raw } - func (r *BetaWebSearchToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -8129,6 +10580,7 @@ const ( BetaWebSearchToolResultErrorCodeMaxUsesExceeded BetaWebSearchToolResultErrorCode = "max_uses_exceeded" BetaWebSearchToolResultErrorCodeTooManyRequests BetaWebSearchToolResultErrorCode = "too_many_requests" BetaWebSearchToolResultErrorCodeQueryTooLong BetaWebSearchToolResultErrorCode = "query_too_long" + BetaWebSearchToolResultErrorCodeRequestTooLarge BetaWebSearchToolResultErrorCode = "request_too_large" ) type BetaMessageNewParams struct { @@ -8138,7 +10590,7 @@ type BetaMessageNewParams struct { // only specifies the absolute maximum number of tokens to generate. // // Different models have different maximum values for this parameter. See - // [models](https://docs.anthropic.com/en/docs/models-overview) for details. + // [models](https://docs.claude.com/en/docs/models-overview) for details. MaxTokens int64 `json:"max_tokens,required"` // Input messages. // @@ -8201,12 +10653,12 @@ type BetaMessageNewParams struct { // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // - // See [input examples](https://docs.anthropic.com/en/api/messages-examples). + // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a - // [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use - // the top-level `system` parameter — there is no `"system"` role for input - // messages in the Messages API. + // [system prompt](https://docs.claude.com/en/docs/system-prompts), you can use the + // top-level `system` parameter — there is no `"system"` role for input messages in + // the Messages API. // // There is a limit of 100,000 messages in a single request. Messages []BetaMessageParam `json:"messages,omitzero,required"` @@ -8214,8 +10666,9 @@ type BetaMessageNewParams struct { // [models](https://docs.anthropic.com/en/docs/models-overview) for additional // details and options. Model Model `json:"model,omitzero,required"` - // Container identifier for reuse across requests. - Container param.Opt[string] `json:"container,omitzero"` + // Specifies the geographic region for inference processing. If not specified, the + // workspace's `default_inference_geo` is used. + InferenceGeo param.Opt[string] `json:"inference_geo,omitzero"` // Amount of randomness injected into the response. // // Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` @@ -8243,17 +10696,38 @@ type BetaMessageNewParams struct { // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopP param.Opt[float64] `json:"top_p,omitzero"` - // Configuration for context management operations. + // Container identifier for reuse across requests. + Container BetaMessageNewParamsContainerUnion `json:"container,omitzero"` + // The inference speed mode for this request. `"fast"` enables high + // output-tokens-per-second inference. + // + // Any of "standard", "fast". + Speed BetaMessageNewParamsSpeed `json:"speed,omitzero"` + // Top-level cache control automatically applies a cache_control marker to the last + // cacheable block in the request. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Context management configuration. + // + // This allows you to control how Claude manages context across multiple requests, + // such as whether to clear function results or not. ContextManagement BetaContextManagementConfigParam `json:"context_management,omitzero"` // MCP servers to be utilized in this request MCPServers []BetaRequestMCPServerURLDefinitionParam `json:"mcp_servers,omitzero"` // An object describing metadata about the request. Metadata BetaMetadataParam `json:"metadata,omitzero"` + // Configuration options for the model's output, such as the output format. + OutputConfig BetaOutputConfigParam `json:"output_config,omitzero"` + // Deprecated: Use `output_config.format` instead. See + // [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + // + // A schema to specify Claude's output format in responses. This parameter will be + // removed in a future release. + OutputFormat BetaJSONOutputFormatParam `json:"output_format,omitzero"` // Determines whether to use priority capacity (if available) or standard capacity // for this request. // // Anthropic offers different levels of service for your API requests. See - // [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. + // [service-tiers](https://docs.claude.com/en/api/service-tiers) for details. // // Any of "auto", "standard_only". ServiceTier BetaMessageNewParamsServiceTier `json:"service_tier,omitzero"` @@ -8271,7 +10745,7 @@ type BetaMessageNewParams struct { // // A system prompt is a way of providing context and instructions to Claude, such // as specifying a particular goal or role. See our - // [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). + // [guide to system prompts](https://docs.claude.com/en/docs/system-prompts). System []BetaTextBlockParam `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // @@ -8280,7 +10754,7 @@ type BetaMessageNewParams struct { // tokens and counts towards your `max_tokens` limit. // // See - // [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + // [extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking) // for details. Thinking BetaThinkingConfigParamUnion `json:"thinking,omitzero"` // How the model should use the provided tools. The model can use a specific tool, @@ -8295,9 +10769,9 @@ type BetaMessageNewParams struct { // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For - // [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), + // [server tools](https://docs.claude.com/en/docs/agents-and-tools/tool-use/overview#server-tools), // see their individual documentation as each has its own behavior (e.g., the - // [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). + // [web search tool](https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // @@ -8366,7 +10840,7 @@ type BetaMessageNewParams struct { // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // - // See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. + // See our [guide](https://docs.claude.com/en/docs/tool-use) for more details. Tools []BetaToolUnionParam `json:"tools,omitzero"` // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` @@ -8377,16 +10851,40 @@ func (r BetaMessageNewParams) MarshalJSON() (data []byte, err error) { type shadow BetaMessageNewParams return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaMessageNewParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaMessageNewParamsContainerUnion struct { + OfContainers *BetaContainerParams `json:",omitzero,inline"` + OfString param.Opt[string] `json:",omitzero,inline"` + paramUnion +} + +func (u BetaMessageNewParamsContainerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfContainers, u.OfString) +} +func (u *BetaMessageNewParamsContainerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BetaMessageNewParamsContainerUnion) asAny() any { + if !param.IsOmitted(u.OfContainers) { + return u.OfContainers + } else if !param.IsOmitted(u.OfString) { + return &u.OfString.Value + } + return nil +} + // Determines whether to use priority capacity (if available) or standard capacity // for this request. // // Anthropic offers different levels of service for your API requests. See -// [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. +// [service-tiers](https://docs.claude.com/en/api/service-tiers) for details. type BetaMessageNewParamsServiceTier string const ( @@ -8394,6 +10892,15 @@ const ( BetaMessageNewParamsServiceTierStandardOnly BetaMessageNewParamsServiceTier = "standard_only" ) +// The inference speed mode for this request. `"fast"` enables high +// output-tokens-per-second inference. +type BetaMessageNewParamsSpeed string + +const ( + BetaMessageNewParamsSpeedStandard BetaMessageNewParamsSpeed = "standard" + BetaMessageNewParamsSpeedFast BetaMessageNewParamsSpeed = "fast" +) + type BetaMessageCountTokensParams struct { // Input messages. // @@ -8456,12 +10963,12 @@ type BetaMessageCountTokensParams struct { // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // - // See [input examples](https://docs.anthropic.com/en/api/messages-examples). + // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a - // [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use - // the top-level `system` parameter — there is no `"system"` role for input - // messages in the Messages API. + // [system prompt](https://docs.claude.com/en/docs/system-prompts), you can use the + // top-level `system` parameter — there is no `"system"` role for input messages in + // the Messages API. // // There is a limit of 100,000 messages in a single request. Messages []BetaMessageParam `json:"messages,omitzero,required"` @@ -8469,15 +10976,34 @@ type BetaMessageCountTokensParams struct { // [models](https://docs.anthropic.com/en/docs/models-overview) for additional // details and options. Model Model `json:"model,omitzero,required"` - // Configuration for context management operations. + // The inference speed mode for this request. `"fast"` enables high + // output-tokens-per-second inference. + // + // Any of "standard", "fast". + Speed BetaMessageCountTokensParamsSpeed `json:"speed,omitzero"` + // Top-level cache control automatically applies a cache_control marker to the last + // cacheable block in the request. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Context management configuration. + // + // This allows you to control how Claude manages context across multiple requests, + // such as whether to clear function results or not. ContextManagement BetaContextManagementConfigParam `json:"context_management,omitzero"` // MCP servers to be utilized in this request MCPServers []BetaRequestMCPServerURLDefinitionParam `json:"mcp_servers,omitzero"` + // Configuration options for the model's output, such as the output format. + OutputConfig BetaOutputConfigParam `json:"output_config,omitzero"` + // Deprecated: Use `output_config.format` instead. See + // [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + // + // A schema to specify Claude's output format in responses. This parameter will be + // removed in a future release. + OutputFormat BetaJSONOutputFormatParam `json:"output_format,omitzero"` // System prompt. // // A system prompt is a way of providing context and instructions to Claude, such // as specifying a particular goal or role. See our - // [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). + // [guide to system prompts](https://docs.claude.com/en/docs/system-prompts). System BetaMessageCountTokensParamsSystemUnion `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // @@ -8486,7 +11012,7 @@ type BetaMessageCountTokensParams struct { // tokens and counts towards your `max_tokens` limit. // // See - // [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + // [extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking) // for details. Thinking BetaThinkingConfigParamUnion `json:"thinking,omitzero"` // How the model should use the provided tools. The model can use a specific tool, @@ -8501,9 +11027,9 @@ type BetaMessageCountTokensParams struct { // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For - // [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), + // [server tools](https://docs.claude.com/en/docs/agents-and-tools/tool-use/overview#server-tools), // see their individual documentation as each has its own behavior (e.g., the - // [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). + // [web search tool](https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // @@ -8572,7 +11098,7 @@ type BetaMessageCountTokensParams struct { // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // - // See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. + // See our [guide](https://docs.claude.com/en/docs/tool-use) for more details. Tools []BetaMessageCountTokensParamsToolUnion `json:"tools,omitzero"` // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` @@ -8583,11 +11109,19 @@ func (r BetaMessageCountTokensParams) MarshalJSON() (data []byte, err error) { type shadow BetaMessageCountTokensParams return param.MarshalObject(r, (*shadow)(&r)) } - func (r *BetaMessageCountTokensParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// The inference speed mode for this request. `"fast"` enables high +// output-tokens-per-second inference. +type BetaMessageCountTokensParamsSpeed string + +const ( + BetaMessageCountTokensParamsSpeedStandard BetaMessageCountTokensParamsSpeed = "standard" + BetaMessageCountTokensParamsSpeedFast BetaMessageCountTokensParamsSpeed = "fast" +) + // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. @@ -8600,7 +11134,6 @@ type BetaMessageCountTokensParamsSystemUnion struct { func (u BetaMessageCountTokensParamsSystemUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfString, u.OfBetaTextBlockArray) } - func (u *BetaMessageCountTokensParamsSystemUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -8618,20 +11151,27 @@ func (u *BetaMessageCountTokensParamsSystemUnion) asAny() any { // // Use [param.IsOmitted] to confirm if a field is set. type BetaMessageCountTokensParamsToolUnion struct { - OfTool *BetaToolParam `json:",omitzero,inline"` - OfBashTool20241022 *BetaToolBash20241022Param `json:",omitzero,inline"` - OfBashTool20250124 *BetaToolBash20250124Param `json:",omitzero,inline"` - OfCodeExecutionTool20250522 *BetaCodeExecutionTool20250522Param `json:",omitzero,inline"` - OfCodeExecutionTool20250825 *BetaCodeExecutionTool20250825Param `json:",omitzero,inline"` - OfComputerUseTool20241022 *BetaToolComputerUse20241022Param `json:",omitzero,inline"` - OfMemoryTool20250818 *BetaMemoryTool20250818Param `json:",omitzero,inline"` - OfComputerUseTool20250124 *BetaToolComputerUse20250124Param `json:",omitzero,inline"` - OfTextEditor20241022 *BetaToolTextEditor20241022Param `json:",omitzero,inline"` - OfTextEditor20250124 *BetaToolTextEditor20250124Param `json:",omitzero,inline"` - OfTextEditor20250429 *BetaToolTextEditor20250429Param `json:",omitzero,inline"` - OfTextEditor20250728 *BetaToolTextEditor20250728Param `json:",omitzero,inline"` - OfWebSearchTool20250305 *BetaWebSearchTool20250305Param `json:",omitzero,inline"` - OfWebFetchTool20250910 *BetaWebFetchTool20250910Param `json:",omitzero,inline"` + OfTool *BetaToolParam `json:",omitzero,inline"` + OfBashTool20241022 *BetaToolBash20241022Param `json:",omitzero,inline"` + OfBashTool20250124 *BetaToolBash20250124Param `json:",omitzero,inline"` + OfCodeExecutionTool20250522 *BetaCodeExecutionTool20250522Param `json:",omitzero,inline"` + OfCodeExecutionTool20250825 *BetaCodeExecutionTool20250825Param `json:",omitzero,inline"` + OfCodeExecutionTool20260120 *BetaCodeExecutionTool20260120Param `json:",omitzero,inline"` + OfComputerUseTool20241022 *BetaToolComputerUse20241022Param `json:",omitzero,inline"` + OfMemoryTool20250818 *BetaMemoryTool20250818Param `json:",omitzero,inline"` + OfComputerUseTool20250124 *BetaToolComputerUse20250124Param `json:",omitzero,inline"` + OfTextEditor20241022 *BetaToolTextEditor20241022Param `json:",omitzero,inline"` + OfComputerUseTool20251124 *BetaToolComputerUse20251124Param `json:",omitzero,inline"` + OfTextEditor20250124 *BetaToolTextEditor20250124Param `json:",omitzero,inline"` + OfTextEditor20250429 *BetaToolTextEditor20250429Param `json:",omitzero,inline"` + OfTextEditor20250728 *BetaToolTextEditor20250728Param `json:",omitzero,inline"` + OfWebSearchTool20250305 *BetaWebSearchTool20250305Param `json:",omitzero,inline"` + OfWebFetchTool20250910 *BetaWebFetchTool20250910Param `json:",omitzero,inline"` + OfWebSearchTool20260209 *BetaWebSearchTool20260209Param `json:",omitzero,inline"` + OfWebFetchTool20260209 *BetaWebFetchTool20260209Param `json:",omitzero,inline"` + OfToolSearchToolBm25_20251119 *BetaToolSearchToolBm25_20251119Param `json:",omitzero,inline"` + OfToolSearchToolRegex20251119 *BetaToolSearchToolRegex20251119Param `json:",omitzero,inline"` + OfMCPToolset *BetaMCPToolsetParam `json:",omitzero,inline"` paramUnion } @@ -8641,17 +11181,23 @@ func (u BetaMessageCountTokensParamsToolUnion) MarshalJSON() ([]byte, error) { u.OfBashTool20250124, u.OfCodeExecutionTool20250522, u.OfCodeExecutionTool20250825, + u.OfCodeExecutionTool20260120, u.OfComputerUseTool20241022, u.OfMemoryTool20250818, u.OfComputerUseTool20250124, u.OfTextEditor20241022, + u.OfComputerUseTool20251124, u.OfTextEditor20250124, u.OfTextEditor20250429, u.OfTextEditor20250728, u.OfWebSearchTool20250305, - u.OfWebFetchTool20250910) + u.OfWebFetchTool20250910, + u.OfWebSearchTool20260209, + u.OfWebFetchTool20260209, + u.OfToolSearchToolBm25_20251119, + u.OfToolSearchToolRegex20251119, + u.OfMCPToolset) } - func (u *BetaMessageCountTokensParamsToolUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -8667,6 +11213,8 @@ func (u *BetaMessageCountTokensParamsToolUnion) asAny() any { return u.OfCodeExecutionTool20250522 } else if !param.IsOmitted(u.OfCodeExecutionTool20250825) { return u.OfCodeExecutionTool20250825 + } else if !param.IsOmitted(u.OfCodeExecutionTool20260120) { + return u.OfCodeExecutionTool20260120 } else if !param.IsOmitted(u.OfComputerUseTool20241022) { return u.OfComputerUseTool20241022 } else if !param.IsOmitted(u.OfMemoryTool20250818) { @@ -8675,6 +11223,8 @@ func (u *BetaMessageCountTokensParamsToolUnion) asAny() any { return u.OfComputerUseTool20250124 } else if !param.IsOmitted(u.OfTextEditor20241022) { return u.OfTextEditor20241022 + } else if !param.IsOmitted(u.OfComputerUseTool20251124) { + return u.OfComputerUseTool20251124 } else if !param.IsOmitted(u.OfTextEditor20250124) { return u.OfTextEditor20250124 } else if !param.IsOmitted(u.OfTextEditor20250429) { @@ -8685,6 +11235,16 @@ func (u *BetaMessageCountTokensParamsToolUnion) asAny() any { return u.OfWebSearchTool20250305 } else if !param.IsOmitted(u.OfWebFetchTool20250910) { return u.OfWebFetchTool20250910 + } else if !param.IsOmitted(u.OfWebSearchTool20260209) { + return u.OfWebSearchTool20260209 + } else if !param.IsOmitted(u.OfWebFetchTool20260209) { + return u.OfWebFetchTool20260209 + } else if !param.IsOmitted(u.OfToolSearchToolBm25_20251119) { + return u.OfToolSearchToolBm25_20251119 + } else if !param.IsOmitted(u.OfToolSearchToolRegex20251119) { + return u.OfToolSearchToolRegex20251119 + } else if !param.IsOmitted(u.OfMCPToolset) { + return u.OfMCPToolset } return nil } @@ -8705,6 +11265,22 @@ func (u BetaMessageCountTokensParamsToolUnion) GetDescription() *string { return nil } +// Returns a pointer to the underlying variant's property, if present. +func (u BetaMessageCountTokensParamsToolUnion) GetEagerInputStreaming() *bool { + if vt := u.OfTool; vt != nil && vt.EagerInputStreaming.Valid() { + return &vt.EagerInputStreaming.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaMessageCountTokensParamsToolUnion) GetEnableZoom() *bool { + if vt := u.OfComputerUseTool20251124; vt != nil && vt.EnableZoom.Valid() { + return &vt.EnableZoom.Value + } + return nil +} + // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) GetMaxCharacters() *int64 { if vt := u.OfTextEditor20250728; vt != nil && vt.MaxCharacters.Valid() { @@ -8714,25 +11290,25 @@ func (u BetaMessageCountTokensParamsToolUnion) GetMaxCharacters() *int64 { } // Returns a pointer to the underlying variant's property, if present. -func (u BetaMessageCountTokensParamsToolUnion) GetUserLocation() *BetaWebSearchTool20250305UserLocationParam { - if vt := u.OfWebSearchTool20250305; vt != nil { - return &vt.UserLocation +func (u BetaMessageCountTokensParamsToolUnion) GetMCPServerName() *string { + if vt := u.OfMCPToolset; vt != nil { + return &vt.MCPServerName } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u BetaMessageCountTokensParamsToolUnion) GetCitations() *BetaCitationsConfigParam { - if vt := u.OfWebFetchTool20250910; vt != nil { - return &vt.Citations +func (u BetaMessageCountTokensParamsToolUnion) GetConfigs() map[string]BetaMCPToolConfigParam { + if vt := u.OfMCPToolset; vt != nil { + return vt.Configs } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u BetaMessageCountTokensParamsToolUnion) GetMaxContentTokens() *int64 { - if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxContentTokens.Valid() { - return &vt.MaxContentTokens.Value +func (u BetaMessageCountTokensParamsToolUnion) GetDefaultConfig() *BetaMCPToolDefaultConfigParam { + if vt := u.OfMCPToolset; vt != nil { + return &vt.DefaultConfig } return nil } @@ -8749,6 +11325,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetName() *string { return (*string)(&vt.Name) } else if vt := u.OfCodeExecutionTool20250825; vt != nil { return (*string)(&vt.Name) + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return (*string)(&vt.Name) } else if vt := u.OfComputerUseTool20241022; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfMemoryTool20250818; vt != nil { @@ -8757,6 +11335,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetName() *string { return (*string)(&vt.Name) } else if vt := u.OfTextEditor20241022; vt != nil { return (*string)(&vt.Name) + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return (*string)(&vt.Name) } else if vt := u.OfTextEditor20250124; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfTextEditor20250429; vt != nil { @@ -8767,6 +11347,106 @@ func (u BetaMessageCountTokensParamsToolUnion) GetName() *string { return (*string)(&vt.Name) } else if vt := u.OfWebFetchTool20250910; vt != nil { return (*string)(&vt.Name) + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return (*string)(&vt.Name) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaMessageCountTokensParamsToolUnion) GetDeferLoading() *bool { + if vt := u.OfTool; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfBashTool20241022; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfBashTool20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20250522; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20250825; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20260120; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfComputerUseTool20241022; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfMemoryTool20250818; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfComputerUseTool20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20241022; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfComputerUseTool20251124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250429; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250728; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebSearchTool20250305; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaMessageCountTokensParamsToolUnion) GetStrict() *bool { + if vt := u.OfTool; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfBashTool20241022; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfBashTool20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20250522; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20250825; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20260120; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfComputerUseTool20241022; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfMemoryTool20250818; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfComputerUseTool20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20241022; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfComputerUseTool20251124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250429; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250728; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebSearchTool20250305; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value } return nil } @@ -8783,6 +11463,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfCodeExecutionTool20250825; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return (*string)(&vt.Type) } else if vt := u.OfComputerUseTool20241022; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfMemoryTool20250818; vt != nil { @@ -8791,6 +11473,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfTextEditor20241022; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return (*string)(&vt.Type) } else if vt := u.OfTextEditor20250124; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfTextEditor20250429; vt != nil { @@ -8801,6 +11485,16 @@ func (u BetaMessageCountTokensParamsToolUnion) GetType() *string { return (*string)(&vt.Type) } else if vt := u.OfWebFetchTool20250910; vt != nil { return (*string)(&vt.Type) + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfMCPToolset; vt != nil { + return (*string)(&vt.Type) } return nil } @@ -8811,6 +11505,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetDisplayHeightPx() *int64 { return (*int64)(&vt.DisplayHeightPx) } else if vt := u.OfComputerUseTool20250124; vt != nil { return (*int64)(&vt.DisplayHeightPx) + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return (*int64)(&vt.DisplayHeightPx) } return nil } @@ -8821,6 +11517,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetDisplayWidthPx() *int64 { return (*int64)(&vt.DisplayWidthPx) } else if vt := u.OfComputerUseTool20250124; vt != nil { return (*int64)(&vt.DisplayWidthPx) + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return (*int64)(&vt.DisplayWidthPx) } return nil } @@ -8831,6 +11529,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetDisplayNumber() *int64 { return &vt.DisplayNumber.Value } else if vt := u.OfComputerUseTool20250124; vt != nil && vt.DisplayNumber.Valid() { return &vt.DisplayNumber.Value + } else if vt := u.OfComputerUseTool20251124; vt != nil && vt.DisplayNumber.Valid() { + return &vt.DisplayNumber.Value } return nil } @@ -8841,6 +11541,67 @@ func (u BetaMessageCountTokensParamsToolUnion) GetMaxUses() *int64 { return &vt.MaxUses.Value } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxUses.Valid() { return &vt.MaxUses.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BetaMessageCountTokensParamsToolUnion) GetMaxContentTokens() *int64 { + if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxContentTokens.Valid() { + return &vt.MaxContentTokens.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.MaxContentTokens.Valid() { + return &vt.MaxContentTokens.Value + } + return nil +} + +// Returns a pointer to the underlying variant's AllowedCallers property, if +// present. +func (u BetaMessageCountTokensParamsToolUnion) GetAllowedCallers() []string { + if vt := u.OfTool; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfBashTool20241022; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfBashTool20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfComputerUseTool20241022; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfMemoryTool20250818; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfComputerUseTool20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20241022; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250429; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250728; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return vt.AllowedCallers } return nil } @@ -8857,6 +11618,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetCacheControl() *BetaCacheContr return &vt.CacheControl } else if vt := u.OfCodeExecutionTool20250825; vt != nil { return &vt.CacheControl + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return &vt.CacheControl } else if vt := u.OfComputerUseTool20241022; vt != nil { return &vt.CacheControl } else if vt := u.OfMemoryTool20250818; vt != nil { @@ -8865,6 +11628,8 @@ func (u BetaMessageCountTokensParamsToolUnion) GetCacheControl() *BetaCacheContr return &vt.CacheControl } else if vt := u.OfTextEditor20241022; vt != nil { return &vt.CacheControl + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return &vt.CacheControl } else if vt := u.OfTextEditor20250124; vt != nil { return &vt.CacheControl } else if vt := u.OfTextEditor20250429; vt != nil { @@ -8875,6 +11640,45 @@ func (u BetaMessageCountTokensParamsToolUnion) GetCacheControl() *BetaCacheContr return &vt.CacheControl } else if vt := u.OfWebFetchTool20250910; vt != nil { return &vt.CacheControl + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return &vt.CacheControl + } else if vt := u.OfMCPToolset; vt != nil { + return &vt.CacheControl + } + return nil +} + +// Returns a pointer to the underlying variant's InputExamples property, if +// present. +func (u BetaMessageCountTokensParamsToolUnion) GetInputExamples() []map[string]any { + if vt := u.OfTool; vt != nil { + return vt.InputExamples + } else if vt := u.OfBashTool20241022; vt != nil { + return vt.InputExamples + } else if vt := u.OfBashTool20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfComputerUseTool20241022; vt != nil { + return vt.InputExamples + } else if vt := u.OfMemoryTool20250818; vt != nil { + return vt.InputExamples + } else if vt := u.OfComputerUseTool20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20241022; vt != nil { + return vt.InputExamples + } else if vt := u.OfComputerUseTool20251124; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250429; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250728; vt != nil { + return vt.InputExamples } return nil } @@ -8886,6 +11690,10 @@ func (u BetaMessageCountTokensParamsToolUnion) GetAllowedDomains() []string { return vt.AllowedDomains } else if vt := u.OfWebFetchTool20250910; vt != nil { return vt.AllowedDomains + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.AllowedDomains + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.AllowedDomains } return nil } @@ -8897,6 +11705,30 @@ func (u BetaMessageCountTokensParamsToolUnion) GetBlockedDomains() []string { return vt.BlockedDomains } else if vt := u.OfWebFetchTool20250910; vt != nil { return vt.BlockedDomains + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.BlockedDomains + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.BlockedDomains + } + return nil +} + +// Returns a pointer to the underlying variant's UserLocation property, if present. +func (u BetaMessageCountTokensParamsToolUnion) GetUserLocation() *BetaUserLocationParam { + if vt := u.OfWebSearchTool20250305; vt != nil { + return &vt.UserLocation + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return &vt.UserLocation + } + return nil +} + +// Returns a pointer to the underlying variant's Citations property, if present. +func (u BetaMessageCountTokensParamsToolUnion) GetCitations() *BetaCitationsConfigParam { + if vt := u.OfWebFetchTool20250910; vt != nil { + return &vt.Citations + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return &vt.Citations } return nil } diff --git a/betamessage_test.go b/betamessage_test.go index e17ba522d..e5f534bb9 100644 --- a/betamessage_test.go +++ b/betamessage_test.go @@ -31,33 +31,60 @@ func TestBetaMessageNewWithOptionalParams(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.BetaMessageParam{{ Content: []anthropic.BetaContentBlockParamUnion{{ - OfText: &anthropic.BetaTextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.BetaCacheControlEphemeralParam{TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m}, Citations: []anthropic.BetaTextCitationParamUnion{{ - OfCharLocation: &anthropic.BetaCitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.BetaTextBlockParam{ + Text: "x", + CacheControl: anthropic.BetaCacheControlEphemeralParam{ + TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.BetaTextCitationParamUnion{{ + OfCharLocation: &anthropic.BetaCitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }, }}, Role: anthropic.BetaMessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, - Container: anthropic.String("container"), + Model: anthropic.ModelClaudeOpus4_6, + CacheControl: anthropic.BetaCacheControlEphemeralParam{ + TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, + }, + Container: anthropic.BetaMessageNewParamsContainerUnion{ + OfContainers: &anthropic.BetaContainerParams{ + ID: anthropic.String("id"), + Skills: []anthropic.BetaSkillParams{{ + SkillID: "x", + Type: anthropic.BetaSkillParamsTypeAnthropic, + Version: anthropic.String("x"), + }}, + }, + }, ContextManagement: anthropic.BetaContextManagementConfigParam{ - Edits: []anthropic.BetaClearToolUses20250919EditParam{{ - ClearAtLeast: anthropic.BetaInputTokensClearAtLeastParam{ - Value: 0, - }, - ClearToolInputs: anthropic.BetaClearToolUses20250919EditClearToolInputsUnionParam{ - OfBool: anthropic.Bool(true), - }, - ExcludeTools: []string{"string"}, - Keep: anthropic.BetaToolUsesKeepParam{ - Value: 0, - }, - Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{ - OfInputTokens: &anthropic.BetaInputTokensTriggerParam{ - Value: 1, + Edits: []anthropic.BetaContextManagementConfigEditUnionParam{{ + OfClearToolUses20250919: &anthropic.BetaClearToolUses20250919EditParam{ + ClearAtLeast: anthropic.BetaInputTokensClearAtLeastParam{ + Value: 0, + }, + ClearToolInputs: anthropic.BetaClearToolUses20250919EditClearToolInputsUnionParam{ + OfBool: anthropic.Bool(true), + }, + ExcludeTools: []string{"string"}, + Keep: anthropic.BetaToolUsesKeepParam{ + Value: 0, + }, + Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{ + OfInputTokens: &anthropic.BetaInputTokensTriggerParam{ + Value: 1, + }, }, }, }}, }, + InferenceGeo: anthropic.String("inference_geo"), MCPServers: []anthropic.BetaRequestMCPServerURLDefinitionParam{{ Name: "name", URL: "url", @@ -70,11 +97,37 @@ func TestBetaMessageNewWithOptionalParams(t *testing.T) { Metadata: anthropic.BetaMetadataParam{ UserID: anthropic.String("13803d75-b4b5-4c3e-b2a2-6f21399b021b"), }, + OutputConfig: anthropic.BetaOutputConfigParam{ + Effort: anthropic.BetaOutputConfigEffortLow, + Format: anthropic.BetaJSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, + }, + OutputFormat: anthropic.BetaJSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, ServiceTier: anthropic.BetaMessageNewParamsServiceTierAuto, + Speed: anthropic.BetaMessageNewParamsSpeedStandard, StopSequences: []string{"string"}, - System: []anthropic.BetaTextBlockParam{{Text: "x", CacheControl: anthropic.BetaCacheControlEphemeralParam{TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m}, Citations: []anthropic.BetaTextCitationParamUnion{{ - OfCharLocation: &anthropic.BetaCitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}}, + System: []anthropic.BetaTextBlockParam{{ + Text: "Today's date is 2024-06-01.", + CacheControl: anthropic.BetaCacheControlEphemeralParam{ + TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.BetaTextCitationParamUnion{{ + OfCharLocation: &anthropic.BetaCitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }}, Temperature: anthropic.Float(1), Thinking: anthropic.BetaThinkingConfigParamUnion{ OfEnabled: &anthropic.BetaThinkingConfigEnabledParam{ @@ -89,24 +142,25 @@ func TestBetaMessageNewWithOptionalParams(t *testing.T) { Tools: []anthropic.BetaToolUnionParam{{ OfTool: &anthropic.BetaToolParam{ InputSchema: anthropic.BetaToolInputSchemaParam{ - Properties: map[string]interface{}{ - "location": map[string]interface{}{ - "description": "The city and state, e.g. San Francisco, CA", - "type": "string", - }, - "unit": map[string]interface{}{ - "description": "Unit for the output - one of (celsius, fahrenheit)", - "type": "string", - }, + Properties: map[string]any{ + "location": "bar", + "unit": "bar", }, Required: []string{"location"}, }, - Name: "name", + Name: "name", + AllowedCallers: []string{"direct"}, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, - Description: anthropic.String("Get the current weather in a given location"), - Type: anthropic.BetaToolTypeCustom, + DeferLoading: anthropic.Bool(true), + Description: anthropic.String("Get the current weather in a given location"), + EagerInputStreaming: anthropic.Bool(true), + InputExamples: []map[string]any{{ + "foo": "bar", + }}, + Strict: anthropic.Bool(true), + Type: anthropic.BetaToolTypeCustom, }, }}, TopK: anthropic.Int(5), @@ -138,28 +192,45 @@ func TestBetaMessageCountTokensWithOptionalParams(t *testing.T) { _, err := client.Beta.Messages.CountTokens(context.TODO(), anthropic.BetaMessageCountTokensParams{ Messages: []anthropic.BetaMessageParam{{ Content: []anthropic.BetaContentBlockParamUnion{{ - OfText: &anthropic.BetaTextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.BetaCacheControlEphemeralParam{TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m}, Citations: []anthropic.BetaTextCitationParamUnion{{ - OfCharLocation: &anthropic.BetaCitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.BetaTextBlockParam{ + Text: "x", + CacheControl: anthropic.BetaCacheControlEphemeralParam{ + TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.BetaTextCitationParamUnion{{ + OfCharLocation: &anthropic.BetaCitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }, }}, Role: anthropic.BetaMessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeOpus4_6, + CacheControl: anthropic.BetaCacheControlEphemeralParam{ + TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, + }, ContextManagement: anthropic.BetaContextManagementConfigParam{ - Edits: []anthropic.BetaClearToolUses20250919EditParam{{ - ClearAtLeast: anthropic.BetaInputTokensClearAtLeastParam{ - Value: 0, - }, - ClearToolInputs: anthropic.BetaClearToolUses20250919EditClearToolInputsUnionParam{ - OfBool: anthropic.Bool(true), - }, - ExcludeTools: []string{"string"}, - Keep: anthropic.BetaToolUsesKeepParam{ - Value: 0, - }, - Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{ - OfInputTokens: &anthropic.BetaInputTokensTriggerParam{ - Value: 1, + Edits: []anthropic.BetaContextManagementConfigEditUnionParam{{ + OfClearToolUses20250919: &anthropic.BetaClearToolUses20250919EditParam{ + ClearAtLeast: anthropic.BetaInputTokensClearAtLeastParam{ + Value: 0, + }, + ClearToolInputs: anthropic.BetaClearToolUses20250919EditClearToolInputsUnionParam{ + OfBool: anthropic.Bool(true), + }, + ExcludeTools: []string{"string"}, + Keep: anthropic.BetaToolUsesKeepParam{ + Value: 0, + }, + Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{ + OfInputTokens: &anthropic.BetaInputTokensTriggerParam{ + Value: 1, + }, }, }, }}, @@ -173,6 +244,20 @@ func TestBetaMessageCountTokensWithOptionalParams(t *testing.T) { Enabled: anthropic.Bool(true), }, }}, + OutputConfig: anthropic.BetaOutputConfigParam{ + Effort: anthropic.BetaOutputConfigEffortLow, + Format: anthropic.BetaJSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, + }, + OutputFormat: anthropic.BetaJSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, + Speed: anthropic.BetaMessageCountTokensParamsSpeedStandard, System: anthropic.BetaMessageCountTokensParamsSystemUnion{ OfBetaTextBlockArray: []anthropic.BetaTextBlockParam{{ Text: "Today's date is 2024-06-01.", @@ -203,24 +288,25 @@ func TestBetaMessageCountTokensWithOptionalParams(t *testing.T) { Tools: []anthropic.BetaMessageCountTokensParamsToolUnion{{ OfTool: &anthropic.BetaToolParam{ InputSchema: anthropic.BetaToolInputSchemaParam{ - Properties: map[string]interface{}{ - "location": map[string]interface{}{ - "description": "The city and state, e.g. San Francisco, CA", - "type": "string", - }, - "unit": map[string]interface{}{ - "description": "Unit for the output - one of (celsius, fahrenheit)", - "type": "string", - }, + Properties: map[string]any{ + "location": "bar", + "unit": "bar", }, Required: []string{"location"}, }, - Name: "name", + Name: "name", + AllowedCallers: []string{"direct"}, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, - Description: anthropic.String("Get the current weather in a given location"), - Type: anthropic.BetaToolTypeCustom, + DeferLoading: anthropic.Bool(true), + Description: anthropic.String("Get the current weather in a given location"), + EagerInputStreaming: anthropic.Bool(true), + InputExamples: []map[string]any{{ + "foo": "bar", + }}, + Strict: anthropic.Bool(true), + Type: anthropic.BetaToolTypeCustom, }, }}, Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, @@ -345,6 +431,18 @@ Therefore, the answer is..."}}`, {Type: "redacted_thinking", Data: "Redacted"}, }}, }, + "compaction block": { + events: []string{ + `{"type": "message_start", "message": {}}`, + `{"type": "content_block_start", "index": 0, "content_block": {"type": "compaction", "content": ""}}`, + `{"type": "content_block_delta", "index": 0, "delta": {"type": "compaction_delta", "content": "Summary of the conversation so far."}}`, + `{"type": "content_block_stop", "index": 0}`, + `{"type": "message_stop"}`, + }, + expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ + {Type: "compaction", Content: anthropic.BetaContentBlockUnionContent{OfString: "Summary of the conversation so far."}}, + }}, + }, "multiple content blocks": { events: []string{ `{"type": "message_start", "message": {}}`, diff --git a/betamessagebatch.go b/betamessagebatch.go index 91d70c9f5..e6a8b203c 100644 --- a/betamessagebatch.go +++ b/betamessagebatch.go @@ -49,10 +49,10 @@ func NewBetaMessageBatchService(opts ...option.RequestOption) (r BetaMessageBatc // can take up to 24 hours to complete. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) @@ -66,10 +66,10 @@ func (r *BetaMessageBatchService) New(ctx context.Context, params BetaMessageBat // `results_url` field in the response. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) @@ -86,11 +86,11 @@ func (r *BetaMessageBatchService) Get(ctx context.Context, messageBatchID string // returned first. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24"), option.WithResponseInto(&raw)}, opts...) @@ -111,7 +111,7 @@ func (r *BetaMessageBatchService) List(ctx context.Context, params BetaMessageBa // returned first. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) ListAutoPaging(ctx context.Context, params BetaMessageBatchListParams, opts ...option.RequestOption) *pagination.PageAutoPager[BetaMessageBatch] { return pagination.NewPageAutoPager(r.List(ctx, params, opts...)) } @@ -122,10 +122,10 @@ func (r *BetaMessageBatchService) ListAutoPaging(ctx context.Context, params Bet // like to delete an in-progress batch, you must first cancel it. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) @@ -149,10 +149,10 @@ func (r *BetaMessageBatchService) Delete(ctx context.Context, messageBatchID str // non-interruptible. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) @@ -172,14 +172,14 @@ func (r *BetaMessageBatchService) Cancel(ctx context.Context, messageBatchID str // requests. Use the `custom_id` field to match results to requests. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) ResultsStreaming(ctx context.Context, messageBatchID string, query BetaMessageBatchResultsParams, opts ...option.RequestOption) (stream *jsonl.Stream[BetaMessageBatchIndividualResponse]) { var ( raw *http.Response err error ) for _, v := range query.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } 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...) @@ -543,8 +543,8 @@ type BetaMessageBatchNewParamsRequest struct { CustomID string `json:"custom_id,required"` // Messages API creation parameters for the individual request. // - // See the [Messages API reference](/en/api/messages) for full documentation on - // available parameters. + // See the [Messages API reference](https://docs.claude.com/en/api/messages) for + // full documentation on available parameters. Params BetaMessageBatchNewParamsRequestParams `json:"params,omitzero,required"` paramObj } @@ -560,8 +560,8 @@ func (r *BetaMessageBatchNewParamsRequest) UnmarshalJSON(data []byte) error { // Messages API creation parameters for the individual request. // -// See the [Messages API reference](/en/api/messages) for full documentation on -// available parameters. +// See the [Messages API reference](https://docs.claude.com/en/api/messages) for +// full documentation on available parameters. // // The properties MaxTokens, Messages, Model are required. type BetaMessageBatchNewParamsRequestParams struct { @@ -571,7 +571,7 @@ type BetaMessageBatchNewParamsRequestParams struct { // only specifies the absolute maximum number of tokens to generate. // // Different models have different maximum values for this parameter. See - // [models](https://docs.anthropic.com/en/docs/models-overview) for details. + // [models](https://docs.claude.com/en/docs/models-overview) for details. MaxTokens int64 `json:"max_tokens,required"` // Input messages. // @@ -634,12 +634,12 @@ type BetaMessageBatchNewParamsRequestParams struct { // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // - // See [input examples](https://docs.anthropic.com/en/api/messages-examples). + // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a - // [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use - // the top-level `system` parameter — there is no `"system"` role for input - // messages in the Messages API. + // [system prompt](https://docs.claude.com/en/docs/system-prompts), you can use the + // top-level `system` parameter — there is no `"system"` role for input messages in + // the Messages API. // // There is a limit of 100,000 messages in a single request. Messages []BetaMessageParam `json:"messages,omitzero,required"` @@ -647,12 +647,12 @@ type BetaMessageBatchNewParamsRequestParams struct { // [models](https://docs.anthropic.com/en/docs/models-overview) for additional // details and options. Model Model `json:"model,omitzero,required"` - // Container identifier for reuse across requests. - Container param.Opt[string] `json:"container,omitzero"` + // Specifies the geographic region for inference processing. If not specified, the + // workspace's `default_inference_geo` is used. + InferenceGeo param.Opt[string] `json:"inference_geo,omitzero"` // Whether to incrementally stream the response using server-sent events. // - // See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for - // details. + // See [streaming](https://docs.claude.com/en/api/messages-streaming) for details. Stream param.Opt[bool] `json:"stream,omitzero"` // Amount of randomness injected into the response. // @@ -681,17 +681,40 @@ type BetaMessageBatchNewParamsRequestParams struct { // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopP param.Opt[float64] `json:"top_p,omitzero"` - // Configuration for context management operations. + // Container identifier for reuse across requests. + Container BetaMessageBatchNewParamsRequestParamsContainerUnion `json:"container,omitzero"` + // The inference speed mode for this request. `"fast"` enables high + // output-tokens-per-second inference. + // + // Any of "standard", "fast". + Speed string `json:"speed,omitzero"` + // Top-level cache control automatically applies a cache_control marker to the last + // cacheable block in the request. + CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` + // Context management configuration. + // + // This allows you to control how Claude manages context across multiple requests, + // such as whether to clear function results or not. ContextManagement BetaContextManagementConfigParam `json:"context_management,omitzero"` // MCP servers to be utilized in this request MCPServers []BetaRequestMCPServerURLDefinitionParam `json:"mcp_servers,omitzero"` // An object describing metadata about the request. Metadata BetaMetadataParam `json:"metadata,omitzero"` + // Configuration options for the model's output, such as the output format. + OutputConfig BetaOutputConfigParam `json:"output_config,omitzero"` + // Deprecated: Use `output_config.format` instead. See + // [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + // + // A schema to specify Claude's output format in responses. This parameter will be + // removed in a future release. + // + // Deprecated: deprecated + OutputFormat BetaJSONOutputFormatParam `json:"output_format,omitzero"` // Determines whether to use priority capacity (if available) or standard capacity // for this request. // // Anthropic offers different levels of service for your API requests. See - // [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. + // [service-tiers](https://docs.claude.com/en/api/service-tiers) for details. // // Any of "auto", "standard_only". ServiceTier string `json:"service_tier,omitzero"` @@ -709,7 +732,7 @@ type BetaMessageBatchNewParamsRequestParams struct { // // A system prompt is a way of providing context and instructions to Claude, such // as specifying a particular goal or role. See our - // [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). + // [guide to system prompts](https://docs.claude.com/en/docs/system-prompts). System []BetaTextBlockParam `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // @@ -718,7 +741,7 @@ type BetaMessageBatchNewParamsRequestParams struct { // tokens and counts towards your `max_tokens` limit. // // See - // [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + // [extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking) // for details. Thinking BetaThinkingConfigParamUnion `json:"thinking,omitzero"` // How the model should use the provided tools. The model can use a specific tool, @@ -733,9 +756,9 @@ type BetaMessageBatchNewParamsRequestParams struct { // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For - // [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), + // [server tools](https://docs.claude.com/en/docs/agents-and-tools/tool-use/overview#server-tools), // see their individual documentation as each has its own behavior (e.g., the - // [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). + // [web search tool](https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // @@ -804,7 +827,7 @@ type BetaMessageBatchNewParamsRequestParams struct { // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // - // See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. + // See our [guide](https://docs.claude.com/en/docs/tool-use) for more details. Tools []BetaToolUnionParam `json:"tools,omitzero"` paramObj } @@ -822,6 +845,34 @@ func init() { apijson.RegisterFieldValidator[BetaMessageBatchNewParamsRequestParams]( "service_tier", "auto", "standard_only", ) + apijson.RegisterFieldValidator[BetaMessageBatchNewParamsRequestParams]( + "speed", "standard", "fast", + ) +} + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BetaMessageBatchNewParamsRequestParamsContainerUnion struct { + OfContainers *BetaContainerParams `json:",omitzero,inline"` + OfString param.Opt[string] `json:",omitzero,inline"` + paramUnion +} + +func (u BetaMessageBatchNewParamsRequestParamsContainerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfContainers, u.OfString) +} +func (u *BetaMessageBatchNewParamsRequestParamsContainerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BetaMessageBatchNewParamsRequestParamsContainerUnion) asAny() any { + if !param.IsOmitted(u.OfContainers) { + return u.OfContainers + } else if !param.IsOmitted(u.OfString) { + return &u.OfString.Value + } + return nil } type BetaMessageBatchGetParams struct { diff --git a/betamessagebatch_test.go b/betamessagebatch_test.go index 1ef1d1674..6e037d2bd 100644 --- a/betamessagebatch_test.go +++ b/betamessagebatch_test.go @@ -33,33 +33,60 @@ func TestBetaMessageBatchNewWithOptionalParams(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.BetaMessageParam{{ Content: []anthropic.BetaContentBlockParamUnion{{ - OfText: &anthropic.BetaTextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.BetaCacheControlEphemeralParam{TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m}, Citations: []anthropic.BetaTextCitationParamUnion{{ - OfCharLocation: &anthropic.BetaCitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.BetaTextBlockParam{ + Text: "x", + CacheControl: anthropic.BetaCacheControlEphemeralParam{ + TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.BetaTextCitationParamUnion{{ + OfCharLocation: &anthropic.BetaCitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }, }}, Role: anthropic.BetaMessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, - Container: anthropic.String("container"), + Model: anthropic.ModelClaudeOpus4_6, + CacheControl: anthropic.BetaCacheControlEphemeralParam{ + TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, + }, + Container: anthropic.BetaMessageBatchNewParamsRequestParamsContainerUnion{ + OfContainers: &anthropic.BetaContainerParams{ + ID: anthropic.String("id"), + Skills: []anthropic.BetaSkillParams{{ + SkillID: "x", + Type: anthropic.BetaSkillParamsTypeAnthropic, + Version: anthropic.String("x"), + }}, + }, + }, ContextManagement: anthropic.BetaContextManagementConfigParam{ - Edits: []anthropic.BetaClearToolUses20250919EditParam{{ - ClearAtLeast: anthropic.BetaInputTokensClearAtLeastParam{ - Value: 0, - }, - ClearToolInputs: anthropic.BetaClearToolUses20250919EditClearToolInputsUnionParam{ - OfBool: anthropic.Bool(true), - }, - ExcludeTools: []string{"string"}, - Keep: anthropic.BetaToolUsesKeepParam{ - Value: 0, - }, - Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{ - OfInputTokens: &anthropic.BetaInputTokensTriggerParam{ - Value: 1, + Edits: []anthropic.BetaContextManagementConfigEditUnionParam{{ + OfClearToolUses20250919: &anthropic.BetaClearToolUses20250919EditParam{ + ClearAtLeast: anthropic.BetaInputTokensClearAtLeastParam{ + Value: 0, + }, + ClearToolInputs: anthropic.BetaClearToolUses20250919EditClearToolInputsUnionParam{ + OfBool: anthropic.Bool(true), + }, + ExcludeTools: []string{"string"}, + Keep: anthropic.BetaToolUsesKeepParam{ + Value: 0, + }, + Trigger: anthropic.BetaClearToolUses20250919EditTriggerUnionParam{ + OfInputTokens: &anthropic.BetaInputTokensTriggerParam{ + Value: 1, + }, }, }, }}, }, + InferenceGeo: anthropic.String("inference_geo"), MCPServers: []anthropic.BetaRequestMCPServerURLDefinitionParam{{ Name: "name", URL: "url", @@ -72,12 +99,38 @@ func TestBetaMessageBatchNewWithOptionalParams(t *testing.T) { Metadata: anthropic.BetaMetadataParam{ UserID: anthropic.String("13803d75-b4b5-4c3e-b2a2-6f21399b021b"), }, + OutputConfig: anthropic.BetaOutputConfigParam{ + Effort: anthropic.BetaOutputConfigEffortLow, + Format: anthropic.BetaJSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, + }, + OutputFormat: anthropic.BetaJSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, ServiceTier: "auto", + Speed: "standard", StopSequences: []string{"string"}, Stream: anthropic.Bool(true), - System: []anthropic.BetaTextBlockParam{{Text: "x", CacheControl: anthropic.BetaCacheControlEphemeralParam{TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m}, Citations: []anthropic.BetaTextCitationParamUnion{{ - OfCharLocation: &anthropic.BetaCitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}}, + System: []anthropic.BetaTextBlockParam{{ + Text: "Today's date is 2024-06-01.", + CacheControl: anthropic.BetaCacheControlEphemeralParam{ + TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.BetaTextCitationParamUnion{{ + OfCharLocation: &anthropic.BetaCitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }}, Temperature: anthropic.Float(1), Thinking: anthropic.BetaThinkingConfigParamUnion{ OfEnabled: &anthropic.BetaThinkingConfigEnabledParam{ @@ -92,24 +145,25 @@ func TestBetaMessageBatchNewWithOptionalParams(t *testing.T) { Tools: []anthropic.BetaToolUnionParam{{ OfTool: &anthropic.BetaToolParam{ InputSchema: anthropic.BetaToolInputSchemaParam{ - Properties: map[string]interface{}{ - "location": map[string]interface{}{ - "description": "The city and state, e.g. San Francisco, CA", - "type": "string", - }, - "unit": map[string]interface{}{ - "description": "Unit for the output - one of (celsius, fahrenheit)", - "type": "string", - }, + Properties: map[string]any{ + "location": "bar", + "unit": "bar", }, Required: []string{"location"}, }, - Name: "name", + Name: "name", + AllowedCallers: []string{"direct"}, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, - Description: anthropic.String("Get the current weather in a given location"), - Type: anthropic.BetaToolTypeCustom, + DeferLoading: anthropic.Bool(true), + Description: anthropic.String("Get the current weather in a given location"), + EagerInputStreaming: anthropic.Bool(true), + InputExamples: []map[string]any{{ + "foo": "bar", + }}, + Strict: anthropic.Bool(true), + Type: anthropic.BetaToolTypeCustom, }, }}, TopK: anthropic.Int(5), diff --git a/betamessageutil.go b/betamessageutil.go new file mode 100644 index 000000000..2d9f41e67 --- /dev/null +++ b/betamessageutil.go @@ -0,0 +1,459 @@ +package anthropic + +import ( + "encoding/json" + "fmt" + + "github.com/charmbracelet/anthropic-sdk-go/internal/paramutil" + "github.com/charmbracelet/anthropic-sdk-go/packages/param" +) + +// Accumulate builds up the Message incrementally from a MessageStreamEvent. The Message then can be used as +// any other Message, except with the caveat that the Message.JSON field which normally can be used to inspect +// the JSON sent over the network may not be populated fully. +// +// message := anthropic.Message{} +// for stream.Next() { +// event := stream.Current() +// message.Accumulate(event) +// } +func (acc *BetaMessage) Accumulate(event BetaRawMessageStreamEventUnion) error { + if acc == nil { + return fmt.Errorf("accumulate: cannot accumulate into nil Message") + } + + switch event := event.AsAny().(type) { + case BetaRawMessageStartEvent: + *acc = event.Message + case BetaRawMessageDeltaEvent: + acc.StopReason = event.Delta.StopReason + acc.StopSequence = event.Delta.StopSequence + acc.Usage.OutputTokens = event.Usage.OutputTokens + acc.Usage.Iterations = event.Usage.Iterations + acc.ContextManagement = event.ContextManagement + case BetaRawContentBlockStartEvent: + acc.Content = append(acc.Content, BetaContentBlockUnion{}) + err := acc.Content[len(acc.Content)-1].UnmarshalJSON([]byte(event.ContentBlock.RawJSON())) + if err != nil { + return err + } + case BetaRawContentBlockDeltaEvent: + if len(acc.Content) == 0 { + return fmt.Errorf("received event of type %s but there was no content block", event.Type) + } + cb := &acc.Content[len(acc.Content)-1] + switch delta := event.Delta.AsAny().(type) { + case BetaTextDelta: + cb.Text += delta.Text + case BetaInputJSONDelta: + if len(delta.PartialJSON) != 0 { + if string(cb.Input) == "{}" { + cb.Input = []byte(delta.PartialJSON) + } else { + cb.Input = append(cb.Input, []byte(delta.PartialJSON)...) + } + } + case BetaThinkingDelta: + cb.Thinking += delta.Thinking + case BetaSignatureDelta: + cb.Signature += delta.Signature + case BetaCitationsDelta: + citation := BetaTextCitationUnion{} + err := citation.UnmarshalJSON([]byte(delta.Citation.RawJSON())) + if err != nil { + return fmt.Errorf("could not unmarshal citation delta into citation type: %w", err) + } + cb.Citations = append(cb.Citations, citation) + case BetaCompactionContentBlockDelta: + cb.Content.OfString = delta.Content + } + case BetaRawMessageStopEvent: + // Re-marshal the accumulated message to update JSON.raw so that AsAny() + // returns the accumulated data rather than the original stream data + accJSON, err := json.Marshal(acc) + if err != nil { + return fmt.Errorf("error converting accumulated message to JSON: %w", err) + } + acc.JSON.raw = string(accJSON) + case BetaRawContentBlockStopEvent: + // Re-marshal the content block to update JSON.raw so that AsAny() + // returns the accumulated data rather than the original stream data + if len(acc.Content) == 0 { + return fmt.Errorf("received event of type %s but there was no content block", event.Type) + } + contentBlock := &acc.Content[len(acc.Content)-1] + cbJSON, err := json.Marshal(contentBlock) + if err != nil { + return fmt.Errorf("error converting content block to JSON: %w", err) + } + contentBlock.JSON.raw = string(cbJSON) + } + + return nil +} + +// Param converters + +func (r BetaContentBlockUnion) ToParam() BetaContentBlockParamUnion { + return r.AsAny().toParamUnion() +} + +func (variant BetaTextBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfText: &p} +} + +func (variant BetaToolUseBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfToolUse: &p} +} + +func (variant BetaThinkingBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfThinking: &p} +} + +func (variant BetaRedactedThinkingBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfRedactedThinking: &p} +} + +func (variant BetaWebSearchToolResultBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfWebSearchToolResult: &p} +} + +func (variant BetaBashCodeExecutionToolResultBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfBashCodeExecutionToolResult: &p} +} + +func (variant BetaCodeExecutionToolResultBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfCodeExecutionToolResult: &p} +} + +func (variant BetaContainerUploadBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfContainerUpload: &p} +} + +func (variant BetaMCPToolResultBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfMCPToolResult: &p} +} + +func (variant BetaMCPToolUseBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfMCPToolUse: &p} +} + +func (variant BetaServerToolUseBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfServerToolUse: &p} +} + +func (variant BetaTextEditorCodeExecutionToolResultBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfTextEditorCodeExecutionToolResult: &p} +} + +func (variant BetaWebFetchToolResultBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfWebFetchToolResult: &p} +} + +func (variant BetaToolSearchToolResultBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfToolSearchToolResult: &p} +} + +func (variant BetaCompactionBlock) toParamUnion() BetaContentBlockParamUnion { + p := variant.ToParam() + return BetaContentBlockParamUnion{OfCompaction: &p} +} + +func (r BetaMessage) ToParam() BetaMessageParam { + var p BetaMessageParam + p.Role = BetaMessageParamRole(r.Role) + p.Content = make([]BetaContentBlockParamUnion, len(r.Content)) + for i, c := range r.Content { + contentParams := c.ToParam() + p.Content[i] = contentParams + } + return p +} + +func (r BetaRedactedThinkingBlock) ToParam() BetaRedactedThinkingBlockParam { + var p BetaRedactedThinkingBlockParam + p.Type = r.Type + p.Data = r.Data + return p +} + +func (r BetaTextBlock) ToParam() BetaTextBlockParam { + var p BetaTextBlockParam + p.Type = r.Type + p.Text = r.Text + + // Distinguish between a nil and zero length slice, since some compatible + // APIs may not require citations. + if r.Citations != nil { + p.Citations = make([]BetaTextCitationParamUnion, 0, len(r.Citations)) + } + for _, citation := range r.Citations { + p.Citations = append(p.Citations, citation.AsAny().toParamUnion()) + } + return p +} + +func (r BetaCitationCharLocation) toParamUnion() BetaTextCitationParamUnion { + var citationParam BetaCitationCharLocationParam + citationParam.Type = r.Type + citationParam.DocumentTitle = paramutil.ToOpt(r.DocumentTitle, r.JSON.DocumentTitle) + citationParam.CitedText = r.CitedText + citationParam.DocumentIndex = r.DocumentIndex + citationParam.EndCharIndex = r.EndCharIndex + citationParam.StartCharIndex = r.StartCharIndex + return BetaTextCitationParamUnion{OfCharLocation: &citationParam} +} + +func (citationVariant BetaCitationPageLocation) toParamUnion() BetaTextCitationParamUnion { + var citationParam BetaCitationPageLocationParam + citationParam.Type = citationVariant.Type + citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) + citationParam.DocumentIndex = citationVariant.DocumentIndex + citationParam.EndPageNumber = citationVariant.EndPageNumber + citationParam.StartPageNumber = citationVariant.StartPageNumber + return BetaTextCitationParamUnion{OfPageLocation: &citationParam} +} + +func (citationVariant BetaCitationContentBlockLocation) toParamUnion() BetaTextCitationParamUnion { + var citationParam BetaCitationContentBlockLocationParam + citationParam.Type = citationVariant.Type + citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) + citationParam.CitedText = citationVariant.CitedText + citationParam.DocumentIndex = citationVariant.DocumentIndex + citationParam.EndBlockIndex = citationVariant.EndBlockIndex + citationParam.StartBlockIndex = citationVariant.StartBlockIndex + return BetaTextCitationParamUnion{OfContentBlockLocation: &citationParam} +} + +func (citationVariant BetaCitationsWebSearchResultLocation) toParamUnion() BetaTextCitationParamUnion { + var citationParam BetaCitationWebSearchResultLocationParam + citationParam.Type = citationVariant.Type + citationParam.CitedText = citationVariant.CitedText + citationParam.Title = paramutil.ToOpt(citationVariant.Title, citationVariant.JSON.Title) + return BetaTextCitationParamUnion{OfWebSearchResultLocation: &citationParam} +} + +func (citationVariant BetaCitationSearchResultLocation) toParamUnion() BetaTextCitationParamUnion { + var citationParam BetaCitationSearchResultLocationParam + citationParam.Type = citationVariant.Type + citationParam.CitedText = citationVariant.CitedText + citationParam.Title = paramutil.ToOpt(citationVariant.Title, citationVariant.JSON.Title) + citationParam.EndBlockIndex = citationVariant.EndBlockIndex + citationParam.StartBlockIndex = citationVariant.StartBlockIndex + citationParam.Source = citationVariant.Source + return BetaTextCitationParamUnion{OfSearchResultLocation: &citationParam} +} + +func (r BetaThinkingBlock) ToParam() BetaThinkingBlockParam { + var p BetaThinkingBlockParam + p.Type = r.Type + p.Signature = r.Signature + p.Thinking = r.Thinking + return p +} + +func (r BetaToolUseBlock) ToParam() BetaToolUseBlockParam { + var p BetaToolUseBlockParam + p.Type = r.Type + p.ID = r.ID + p.Input = r.Input + p.Name = r.Name + return p +} + +func (r BetaWebSearchResultBlock) ToParam() BetaWebSearchResultBlockParam { + var p BetaWebSearchResultBlockParam + p.Type = r.Type + p.EncryptedContent = r.EncryptedContent + p.Title = r.Title + p.URL = r.URL + p.PageAge = paramutil.ToOpt(r.PageAge, r.JSON.PageAge) + return p +} + +func (r BetaWebSearchToolResultBlock) ToParam() BetaWebSearchToolResultBlockParam { + var p BetaWebSearchToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + + if len(r.Content.OfBetaWebSearchResultBlockArray) > 0 { + for _, block := range r.Content.OfBetaWebSearchResultBlockArray { + p.Content.OfResultBlock = append(p.Content.OfResultBlock, block.ToParam()) + } + } else { + p.Content.OfError = &BetaWebSearchToolRequestErrorParam{ + Type: r.Content.Type, + ErrorCode: r.Content.ErrorCode, + } + } + return p +} + +func (r BetaWebFetchToolResultBlock) ToParam() BetaWebFetchToolResultBlockParam { + var p BetaWebFetchToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + return p +} + +func (r BetaMCPToolUseBlock) ToParam() BetaMCPToolUseBlockParam { + var p BetaMCPToolUseBlockParam + p.Type = r.Type + p.ID = r.ID + p.Input = r.Input + p.Name = r.Name + p.ServerName = r.ServerName + return p +} + +func (r BetaContainerUploadBlock) ToParam() BetaContainerUploadBlockParam { + var p BetaContainerUploadBlockParam + p.Type = r.Type + p.FileID = r.FileID + return p +} + +func (r BetaServerToolUseBlock) ToParam() BetaServerToolUseBlockParam { + var p BetaServerToolUseBlockParam + p.Type = r.Type + p.ID = r.ID + p.Input = r.Input + p.Name = BetaServerToolUseBlockParamName(r.Name) + return p +} + +func (r BetaTextEditorCodeExecutionToolResultBlock) ToParam() BetaTextEditorCodeExecutionToolResultBlockParam { + var p BetaTextEditorCodeExecutionToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + if r.Content.JSON.ErrorCode.Valid() { + p.Content.OfRequestTextEditorCodeExecutionToolResultError = &BetaTextEditorCodeExecutionToolResultErrorParam{ + ErrorCode: BetaTextEditorCodeExecutionToolResultErrorParamErrorCode(r.Content.ErrorCode), + ErrorMessage: paramutil.ToOpt(r.Content.ErrorMessage, r.Content.JSON.ErrorMessage), + } + } else { + p.Content = param.Override[BetaTextEditorCodeExecutionToolResultBlockParamContentUnion](r.Content.RawJSON()) + } + return p +} + +func (r BetaMCPToolResultBlock) ToParam() BetaRequestMCPToolResultBlockParam { + var p BetaRequestMCPToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + if r.Content.JSON.OfString.Valid() { + p.Content.OfString = paramutil.ToOpt(r.Content.OfString, r.Content.JSON.OfString) + } else { + for _, block := range r.Content.OfBetaMCPToolResultBlockContent { + p.Content.OfBetaMCPToolResultBlockContent = append(p.Content.OfBetaMCPToolResultBlockContent, block.ToParam()) + } + } + return p +} + +func (r BetaBashCodeExecutionToolResultBlock) ToParam() BetaBashCodeExecutionToolResultBlockParam { + var p BetaBashCodeExecutionToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + + if r.Content.JSON.ErrorCode.Valid() { + p.Content.OfRequestBashCodeExecutionToolResultError = &BetaBashCodeExecutionToolResultErrorParam{ + ErrorCode: BetaBashCodeExecutionToolResultErrorParamErrorCode(r.Content.ErrorCode), + } + } else { + requestBashContentResult := &BetaBashCodeExecutionResultBlockParam{ + ReturnCode: r.Content.ReturnCode, + Stderr: r.Content.Stderr, + Stdout: r.Content.Stdout, + } + for _, block := range r.Content.Content { + requestBashContentResult.Content = append(requestBashContentResult.Content, block.ToParam()) + } + p.Content.OfRequestBashCodeExecutionResultBlock = requestBashContentResult + } + + return p +} + +func (r BetaBashCodeExecutionOutputBlock) ToParam() BetaBashCodeExecutionOutputBlockParam { + var p BetaBashCodeExecutionOutputBlockParam + p.Type = r.Type + p.FileID = r.FileID + return p +} + +func (r BetaCodeExecutionToolResultBlock) ToParam() BetaCodeExecutionToolResultBlockParam { + var p BetaCodeExecutionToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + if r.Content.JSON.ErrorCode.Valid() { + p.Content.OfError = &BetaCodeExecutionToolResultErrorParam{ + ErrorCode: r.Content.ErrorCode, + } + } else { + p.Content.OfResultBlock = &BetaCodeExecutionResultBlockParam{ + ReturnCode: r.Content.ReturnCode, + Stderr: r.Content.Stderr, + Stdout: r.Content.Stdout, + } + for _, block := range r.Content.Content { + p.Content.OfResultBlock.Content = append(p.Content.OfResultBlock.Content, block.ToParam()) + } + } + return p +} + +func (r BetaCodeExecutionOutputBlock) ToParam() BetaCodeExecutionOutputBlockParam { + var p BetaCodeExecutionOutputBlockParam + p.Type = r.Type + p.FileID = r.FileID + return p +} + +func (r BetaToolSearchToolResultBlock) ToParam() BetaToolSearchToolResultBlockParam { + var p BetaToolSearchToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + if r.Content.JSON.ErrorCode.Valid() { + p.Content.OfRequestToolSearchToolResultError = &BetaToolSearchToolResultErrorParam{ + ErrorCode: BetaToolSearchToolResultErrorParamErrorCode(r.Content.ErrorCode), + } + } else { + p.Content.OfRequestToolSearchToolSearchResultBlock = &BetaToolSearchToolSearchResultBlockParam{} + for _, block := range r.Content.ToolReferences { + p.Content.OfRequestToolSearchToolSearchResultBlock.ToolReferences = append( + p.Content.OfRequestToolSearchToolSearchResultBlock.ToolReferences, + block.ToParam(), + ) + } + } + return p +} + +func (r BetaToolReferenceBlock) ToParam() BetaToolReferenceBlockParam { + var p BetaToolReferenceBlockParam + p.Type = r.Type + p.ToolName = r.ToolName + return p +} + +func (r BetaCompactionBlock) ToParam() BetaCompactionBlockParam { + var p BetaCompactionBlockParam + p.Type = r.Type + p.Content = param.NewOpt(r.Content) + return p +} diff --git a/betamodel.go b/betamodel.go index 7669d4be4..783872344 100644 --- a/betamodel.go +++ b/betamodel.go @@ -46,7 +46,7 @@ func NewBetaModelService(opts ...option.RequestOption) (r BetaModelService) { // 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) if modelID == "" { @@ -65,7 +65,7 @@ func (r *BetaModelService) Get(ctx context.Context, modelID string, query BetaMo 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...) diff --git a/betaskill.go b/betaskill.go new file mode 100644 index 000000000..d2c15b3fc --- /dev/null +++ b/betaskill.go @@ -0,0 +1,362 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package anthropic + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/url" + "slices" + + "github.com/charmbracelet/anthropic-sdk-go/internal/apiform" + "github.com/charmbracelet/anthropic-sdk-go/internal/apijson" + "github.com/charmbracelet/anthropic-sdk-go/internal/apiquery" + "github.com/charmbracelet/anthropic-sdk-go/internal/requestconfig" + "github.com/charmbracelet/anthropic-sdk-go/option" + "github.com/charmbracelet/anthropic-sdk-go/packages/pagination" + "github.com/charmbracelet/anthropic-sdk-go/packages/param" + "github.com/charmbracelet/anthropic-sdk-go/packages/respjson" +) + +// BetaSkillService contains methods and other services that help with interacting +// with the anthropic API. +// +// Note, unlike clients, this service does not read variables from the environment +// automatically. You should not instantiate this service directly, and instead use +// the [NewBetaSkillService] method instead. +type BetaSkillService struct { + Options []option.RequestOption + Versions BetaSkillVersionService +} + +// NewBetaSkillService generates a new service that applies the given options to +// each request. These options are applied after the parent client's options (if +// there is one), and before any request-specific options. +func NewBetaSkillService(opts ...option.RequestOption) (r BetaSkillService) { + r = BetaSkillService{} + r.Options = opts + r.Versions = NewBetaSkillVersionService(opts...) + return +} + +// 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))) + } + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) + path := "v1/skills?beta=true" + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) + return +} + +// 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))) + } + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) + if skillID == "" { + err = errors.New("missing required skill_id parameter") + return + } + path := fmt.Sprintf("v1/skills/%s?beta=true", skillID) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + return +} + +// 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))) + } + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02"), option.WithResponseInto(&raw)}, opts...) + path := "v1/skills?beta=true" + cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, params, &res, opts...) + if err != nil { + return nil, err + } + err = cfg.Execute() + if err != nil { + return nil, err + } + res.SetPageConfig(cfg, raw) + return res, nil +} + +// List Skills +func (r *BetaSkillService) ListAutoPaging(ctx context.Context, params BetaSkillListParams, opts ...option.RequestOption) *pagination.PageCursorAutoPager[BetaSkillListResponse] { + return pagination.NewPageCursorAutoPager(r.List(ctx, params, opts...)) +} + +// 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))) + } + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) + if skillID == "" { + err = errors.New("missing required skill_id parameter") + return + } + path := fmt.Sprintf("v1/skills/%s?beta=true", skillID) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) + return +} + +type BetaSkillNewResponse struct { + // Unique identifier for the skill. + // + // The format and length of IDs may change over time. + ID string `json:"id,required"` + // ISO 8601 timestamp of when the skill was created. + CreatedAt string `json:"created_at,required"` + // Display title for the skill. + // + // This is a human-readable label that is not included in the prompt sent to the + // model. + DisplayTitle string `json:"display_title,required"` + // The latest version identifier for the skill. + // + // This represents the most recent version of the skill that has been created. + LatestVersion string `json:"latest_version,required"` + // Source of the skill. + // + // This may be one of the following values: + // + // - `"custom"`: the skill was created by a user + // - `"anthropic"`: the skill was created by Anthropic + Source string `json:"source,required"` + // Object type. + // + // For Skills, this is always `"skill"`. + Type string `json:"type,required"` + // ISO 8601 timestamp of when the skill was last updated. + UpdatedAt string `json:"updated_at,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + CreatedAt respjson.Field + DisplayTitle respjson.Field + LatestVersion respjson.Field + Source respjson.Field + Type respjson.Field + UpdatedAt respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkillNewResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaSkillNewResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaSkillGetResponse struct { + // Unique identifier for the skill. + // + // The format and length of IDs may change over time. + ID string `json:"id,required"` + // ISO 8601 timestamp of when the skill was created. + CreatedAt string `json:"created_at,required"` + // Display title for the skill. + // + // This is a human-readable label that is not included in the prompt sent to the + // model. + DisplayTitle string `json:"display_title,required"` + // The latest version identifier for the skill. + // + // This represents the most recent version of the skill that has been created. + LatestVersion string `json:"latest_version,required"` + // Source of the skill. + // + // This may be one of the following values: + // + // - `"custom"`: the skill was created by a user + // - `"anthropic"`: the skill was created by Anthropic + Source string `json:"source,required"` + // Object type. + // + // For Skills, this is always `"skill"`. + Type string `json:"type,required"` + // ISO 8601 timestamp of when the skill was last updated. + UpdatedAt string `json:"updated_at,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + CreatedAt respjson.Field + DisplayTitle respjson.Field + LatestVersion respjson.Field + Source respjson.Field + Type respjson.Field + UpdatedAt respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkillGetResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaSkillGetResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaSkillListResponse struct { + // Unique identifier for the skill. + // + // The format and length of IDs may change over time. + ID string `json:"id,required"` + // ISO 8601 timestamp of when the skill was created. + CreatedAt string `json:"created_at,required"` + // Display title for the skill. + // + // This is a human-readable label that is not included in the prompt sent to the + // model. + DisplayTitle string `json:"display_title,required"` + // The latest version identifier for the skill. + // + // This represents the most recent version of the skill that has been created. + LatestVersion string `json:"latest_version,required"` + // Source of the skill. + // + // This may be one of the following values: + // + // - `"custom"`: the skill was created by a user + // - `"anthropic"`: the skill was created by Anthropic + Source string `json:"source,required"` + // Object type. + // + // For Skills, this is always `"skill"`. + Type string `json:"type,required"` + // ISO 8601 timestamp of when the skill was last updated. + UpdatedAt string `json:"updated_at,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + CreatedAt respjson.Field + DisplayTitle respjson.Field + LatestVersion respjson.Field + Source respjson.Field + Type respjson.Field + UpdatedAt respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkillListResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaSkillListResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaSkillDeleteResponse struct { + // Unique identifier for the skill. + // + // The format and length of IDs may change over time. + ID string `json:"id,required"` + // Deleted object type. + // + // For Skills, this is always `"skill_deleted"`. + Type string `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkillDeleteResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaSkillDeleteResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaSkillNewParams struct { + // Display title for the skill. + // + // This is a human-readable label that is not included in the prompt sent to the + // model. + DisplayTitle param.Opt[string] `json:"display_title,omitzero"` + // Files to upload for the skill. + // + // All files must be in the same top-level directory and must include a SKILL.md + // file at the root of that directory. + Files []io.Reader `json:"files,omitzero" format:"binary"` + // Optional header to specify the beta version(s) you want to use. + Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` + paramObj +} + +func (r BetaSkillNewParams) MarshalMultipart() (data []byte, contentType string, err error) { + buf := bytes.NewBuffer(nil) + writer := multipart.NewWriter(buf) + err = apiform.MarshalRoot(r, writer) + if err == nil { + err = apiform.WriteExtras(writer, r.ExtraFields()) + } + if err != nil { + writer.Close() + return nil, "", err + } + err = writer.Close() + if err != nil { + return nil, "", err + } + return buf.Bytes(), writer.FormDataContentType(), nil +} + +type BetaSkillGetParams struct { + // Optional header to specify the beta version(s) you want to use. + Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` + paramObj +} + +type BetaSkillListParams struct { + // Pagination token for fetching a specific page of results. + // + // Pass the value from a previous response's `next_page` field to get the next page + // of results. + Page param.Opt[string] `query:"page,omitzero" json:"-"` + // Filter skills by source. + // + // If provided, only skills from the specified source will be returned: + // + // - `"custom"`: only return user-created skills + // - `"anthropic"`: only return Anthropic-created skills + Source param.Opt[string] `query:"source,omitzero" json:"-"` + // Number of results to return per page. + // + // Maximum value is 100. Defaults to 20. + Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Optional header to specify the beta version(s) you want to use. + Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` + paramObj +} + +// URLQuery serializes [BetaSkillListParams]'s query parameters as `url.Values`. +func (r BetaSkillListParams) URLQuery() (v url.Values, err error) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type BetaSkillDeleteParams struct { + // Optional header to specify the beta version(s) you want to use. + Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` + paramObj +} diff --git a/betaskill_test.go b/betaskill_test.go new file mode 100644 index 000000000..de043fcba --- /dev/null +++ b/betaskill_test.go @@ -0,0 +1,126 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package anthropic_test + +import ( + "bytes" + "context" + "errors" + "io" + "os" + "testing" + + "github.com/charmbracelet/anthropic-sdk-go" + "github.com/charmbracelet/anthropic-sdk-go/internal/testutil" + "github.com/charmbracelet/anthropic-sdk-go/option" +) + +func TestBetaSkillNewWithOptionalParams(t *testing.T) { + t.Skip("prism binary unsupported") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := anthropic.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("my-anthropic-api-key"), + ) + _, err := client.Beta.Skills.New(context.TODO(), anthropic.BetaSkillNewParams{ + DisplayTitle: anthropic.String("display_title"), + Files: []io.Reader{io.Reader(bytes.NewBuffer([]byte("some file contents")))}, + Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, + }) + if err != nil { + var apierr *anthropic.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestBetaSkillGetWithOptionalParams(t *testing.T) { + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := anthropic.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("my-anthropic-api-key"), + ) + _, err := client.Beta.Skills.Get( + context.TODO(), + "skill_id", + anthropic.BetaSkillGetParams{ + Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, + }, + ) + if err != nil { + var apierr *anthropic.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestBetaSkillListWithOptionalParams(t *testing.T) { + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := anthropic.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("my-anthropic-api-key"), + ) + _, err := client.Beta.Skills.List(context.TODO(), anthropic.BetaSkillListParams{ + Limit: anthropic.Int(0), + Page: anthropic.String("page"), + Source: anthropic.String("source"), + Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, + }) + if err != nil { + var apierr *anthropic.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestBetaSkillDeleteWithOptionalParams(t *testing.T) { + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := anthropic.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("my-anthropic-api-key"), + ) + _, err := client.Beta.Skills.Delete( + context.TODO(), + "skill_id", + anthropic.BetaSkillDeleteParams{ + Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, + }, + ) + if err != nil { + var apierr *anthropic.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} diff --git a/betaskillversion.go b/betaskillversion.go new file mode 100644 index 000000000..2fe31c25e --- /dev/null +++ b/betaskillversion.go @@ -0,0 +1,373 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package anthropic + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/url" + "slices" + + "github.com/charmbracelet/anthropic-sdk-go/internal/apiform" + "github.com/charmbracelet/anthropic-sdk-go/internal/apijson" + "github.com/charmbracelet/anthropic-sdk-go/internal/apiquery" + "github.com/charmbracelet/anthropic-sdk-go/internal/requestconfig" + "github.com/charmbracelet/anthropic-sdk-go/option" + "github.com/charmbracelet/anthropic-sdk-go/packages/pagination" + "github.com/charmbracelet/anthropic-sdk-go/packages/param" + "github.com/charmbracelet/anthropic-sdk-go/packages/respjson" +) + +// BetaSkillVersionService contains methods and other services that help with +// interacting with the anthropic API. +// +// Note, unlike clients, this service does not read variables from the environment +// automatically. You should not instantiate this service directly, and instead use +// the [NewBetaSkillVersionService] method instead. +type BetaSkillVersionService struct { + Options []option.RequestOption +} + +// NewBetaSkillVersionService generates a new service that applies the given +// options to each request. These options are applied after the parent client's +// options (if there is one), and before any request-specific options. +func NewBetaSkillVersionService(opts ...option.RequestOption) (r BetaSkillVersionService) { + r = BetaSkillVersionService{} + r.Options = opts + return +} + +// 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))) + } + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) + if skillID == "" { + err = errors.New("missing required skill_id parameter") + return + } + path := fmt.Sprintf("v1/skills/%s/versions?beta=true", skillID) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) + return +} + +// 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))) + } + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) + if params.SkillID == "" { + err = errors.New("missing required skill_id parameter") + return + } + if version == "" { + err = errors.New("missing required version parameter") + return + } + path := fmt.Sprintf("v1/skills/%s/versions/%s?beta=true", params.SkillID, version) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + return +} + +// 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))) + } + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02"), option.WithResponseInto(&raw)}, opts...) + if skillID == "" { + err = errors.New("missing required skill_id parameter") + return + } + path := fmt.Sprintf("v1/skills/%s/versions?beta=true", skillID) + cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, params, &res, opts...) + if err != nil { + return nil, err + } + err = cfg.Execute() + if err != nil { + return nil, err + } + res.SetPageConfig(cfg, raw) + return res, nil +} + +// List Skill Versions +func (r *BetaSkillVersionService) ListAutoPaging(ctx context.Context, skillID string, params BetaSkillVersionListParams, opts ...option.RequestOption) *pagination.PageCursorAutoPager[BetaSkillVersionListResponse] { + return pagination.NewPageCursorAutoPager(r.List(ctx, skillID, params, opts...)) +} + +// 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))) + } + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "skills-2025-10-02")}, opts...) + if params.SkillID == "" { + err = errors.New("missing required skill_id parameter") + return + } + if version == "" { + err = errors.New("missing required version parameter") + return + } + path := fmt.Sprintf("v1/skills/%s/versions/%s?beta=true", params.SkillID, version) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) + return +} + +type BetaSkillVersionNewResponse struct { + // Unique identifier for the skill version. + // + // The format and length of IDs may change over time. + ID string `json:"id,required"` + // ISO 8601 timestamp of when the skill version was created. + CreatedAt string `json:"created_at,required"` + // Description of the skill version. + // + // This is extracted from the SKILL.md file in the skill upload. + Description string `json:"description,required"` + // Directory name of the skill version. + // + // This is the top-level directory name that was extracted from the uploaded files. + Directory string `json:"directory,required"` + // Human-readable name of the skill version. + // + // This is extracted from the SKILL.md file in the skill upload. + Name string `json:"name,required"` + // Identifier for the skill that this version belongs to. + SkillID string `json:"skill_id,required"` + // Object type. + // + // For Skill Versions, this is always `"skill_version"`. + Type string `json:"type,required"` + // Version identifier for the skill. + // + // Each version is identified by a Unix epoch timestamp (e.g., "1759178010641129"). + Version string `json:"version,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + CreatedAt respjson.Field + Description respjson.Field + Directory respjson.Field + Name respjson.Field + SkillID respjson.Field + Type respjson.Field + Version respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkillVersionNewResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaSkillVersionNewResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaSkillVersionGetResponse struct { + // Unique identifier for the skill version. + // + // The format and length of IDs may change over time. + ID string `json:"id,required"` + // ISO 8601 timestamp of when the skill version was created. + CreatedAt string `json:"created_at,required"` + // Description of the skill version. + // + // This is extracted from the SKILL.md file in the skill upload. + Description string `json:"description,required"` + // Directory name of the skill version. + // + // This is the top-level directory name that was extracted from the uploaded files. + Directory string `json:"directory,required"` + // Human-readable name of the skill version. + // + // This is extracted from the SKILL.md file in the skill upload. + Name string `json:"name,required"` + // Identifier for the skill that this version belongs to. + SkillID string `json:"skill_id,required"` + // Object type. + // + // For Skill Versions, this is always `"skill_version"`. + Type string `json:"type,required"` + // Version identifier for the skill. + // + // Each version is identified by a Unix epoch timestamp (e.g., "1759178010641129"). + Version string `json:"version,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + CreatedAt respjson.Field + Description respjson.Field + Directory respjson.Field + Name respjson.Field + SkillID respjson.Field + Type respjson.Field + Version respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkillVersionGetResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaSkillVersionGetResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaSkillVersionListResponse struct { + // Unique identifier for the skill version. + // + // The format and length of IDs may change over time. + ID string `json:"id,required"` + // ISO 8601 timestamp of when the skill version was created. + CreatedAt string `json:"created_at,required"` + // Description of the skill version. + // + // This is extracted from the SKILL.md file in the skill upload. + Description string `json:"description,required"` + // Directory name of the skill version. + // + // This is the top-level directory name that was extracted from the uploaded files. + Directory string `json:"directory,required"` + // Human-readable name of the skill version. + // + // This is extracted from the SKILL.md file in the skill upload. + Name string `json:"name,required"` + // Identifier for the skill that this version belongs to. + SkillID string `json:"skill_id,required"` + // Object type. + // + // For Skill Versions, this is always `"skill_version"`. + Type string `json:"type,required"` + // Version identifier for the skill. + // + // Each version is identified by a Unix epoch timestamp (e.g., "1759178010641129"). + Version string `json:"version,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + CreatedAt respjson.Field + Description respjson.Field + Directory respjson.Field + Name respjson.Field + SkillID respjson.Field + Type respjson.Field + Version respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkillVersionListResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaSkillVersionListResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaSkillVersionDeleteResponse struct { + // Version identifier for the skill. + // + // Each version is identified by a Unix epoch timestamp (e.g., "1759178010641129"). + ID string `json:"id,required"` + // Deleted object type. + // + // For Skill Versions, this is always `"skill_version_deleted"`. + Type string `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BetaSkillVersionDeleteResponse) RawJSON() string { return r.JSON.raw } +func (r *BetaSkillVersionDeleteResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BetaSkillVersionNewParams struct { + // Files to upload for the skill. + // + // All files must be in the same top-level directory and must include a SKILL.md + // file at the root of that directory. + Files []io.Reader `json:"files,omitzero" format:"binary"` + // Optional header to specify the beta version(s) you want to use. + Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` + paramObj +} + +func (r BetaSkillVersionNewParams) MarshalMultipart() (data []byte, contentType string, err error) { + buf := bytes.NewBuffer(nil) + writer := multipart.NewWriter(buf) + err = apiform.MarshalRoot(r, writer) + if err == nil { + err = apiform.WriteExtras(writer, r.ExtraFields()) + } + if err != nil { + writer.Close() + return nil, "", err + } + err = writer.Close() + if err != nil { + return nil, "", err + } + return buf.Bytes(), writer.FormDataContentType(), nil +} + +type BetaSkillVersionGetParams struct { + // Unique identifier for the skill. + // + // The format and length of IDs may change over time. + SkillID string `path:"skill_id,required" json:"-"` + // Optional header to specify the beta version(s) you want to use. + Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` + paramObj +} + +type BetaSkillVersionListParams struct { + // Number of items to return per page. + // + // Defaults to `20`. Ranges from `1` to `1000`. + Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Optionally set to the `next_page` token from the previous response. + Page param.Opt[string] `query:"page,omitzero" json:"-"` + // Optional header to specify the beta version(s) you want to use. + Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` + paramObj +} + +// URLQuery serializes [BetaSkillVersionListParams]'s query parameters as +// `url.Values`. +func (r BetaSkillVersionListParams) URLQuery() (v url.Values, err error) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} + +type BetaSkillVersionDeleteParams struct { + // Unique identifier for the skill. + // + // The format and length of IDs may change over time. + SkillID string `path:"skill_id,required" json:"-"` + // Optional header to specify the beta version(s) you want to use. + Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` + paramObj +} diff --git a/betaskillversion_test.go b/betaskillversion_test.go new file mode 100644 index 000000000..f4f007dc1 --- /dev/null +++ b/betaskillversion_test.go @@ -0,0 +1,134 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package anthropic_test + +import ( + "bytes" + "context" + "errors" + "io" + "os" + "testing" + + "github.com/charmbracelet/anthropic-sdk-go" + "github.com/charmbracelet/anthropic-sdk-go/internal/testutil" + "github.com/charmbracelet/anthropic-sdk-go/option" +) + +func TestBetaSkillVersionNewWithOptionalParams(t *testing.T) { + t.Skip("prism binary unsupported") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := anthropic.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("my-anthropic-api-key"), + ) + _, err := client.Beta.Skills.Versions.New( + context.TODO(), + "skill_id", + anthropic.BetaSkillVersionNewParams{ + Files: []io.Reader{io.Reader(bytes.NewBuffer([]byte("some file contents")))}, + Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, + }, + ) + if err != nil { + var apierr *anthropic.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestBetaSkillVersionGetWithOptionalParams(t *testing.T) { + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := anthropic.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("my-anthropic-api-key"), + ) + _, err := client.Beta.Skills.Versions.Get( + context.TODO(), + "version", + anthropic.BetaSkillVersionGetParams{ + SkillID: "skill_id", + Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, + }, + ) + if err != nil { + var apierr *anthropic.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestBetaSkillVersionListWithOptionalParams(t *testing.T) { + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := anthropic.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("my-anthropic-api-key"), + ) + _, err := client.Beta.Skills.Versions.List( + context.TODO(), + "skill_id", + anthropic.BetaSkillVersionListParams{ + Limit: anthropic.Int(0), + Page: anthropic.String("page"), + Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, + }, + ) + if err != nil { + var apierr *anthropic.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestBetaSkillVersionDeleteWithOptionalParams(t *testing.T) { + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := anthropic.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("my-anthropic-api-key"), + ) + _, err := client.Beta.Skills.Versions.Delete( + context.TODO(), + "version", + anthropic.BetaSkillVersionDeleteParams{ + SkillID: "skill_id", + Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaMessageBatches2024_09_24}, + }, + ) + if err != nil { + var apierr *anthropic.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} diff --git a/betatoolrunner.go b/betatoolrunner.go new file mode 100644 index 000000000..2ed295567 --- /dev/null +++ b/betatoolrunner.go @@ -0,0 +1,435 @@ +package anthropic + +import ( + "context" + "encoding/json" + "fmt" + "iter" + + "github.com/charmbracelet/anthropic-sdk-go/option" + "golang.org/x/sync/errgroup" +) + +// BetaTool represents a tool that can be executed by the BetaToolRunner. +type BetaTool interface { + // Name returns the tool's name + Name() string + // Description returns the tool's description + Description() string + // InputSchema returns the JSON schema for the tool's input + InputSchema() BetaToolInputSchemaParam + // Execute runs the tool with raw JSON input and returns the result + Execute(ctx context.Context, input json.RawMessage) (BetaToolResultBlockParamContentUnion, error) +} + +// BetaToolRunnerParams contains parameters for creating a BetaToolRunner or BetaToolRunnerStreaming. +type BetaToolRunnerParams struct { + BetaMessageNewParams + // MaxIterations limits the number of API calls. When set to 0 (the default), + // there is no limit and the runner continues until the model stops using tools. + MaxIterations int +} + +// betaToolRunnerBase holds state and logic shared by BetaToolRunner and BetaToolRunnerStreaming. +type betaToolRunnerBase struct { + messageService *BetaMessageService + // Params contains the configuration for the tool runner. + // This field is exported so users can modify parameters directly. + Params BetaToolRunnerParams + toolMap map[string]BetaTool + iterationCount int + lastMessage *BetaMessage + completed bool + opts []option.RequestOption + err error +} + +func newBetaToolRunnerBase(messageService *BetaMessageService, tools []BetaTool, params BetaToolRunnerParams, opts []option.RequestOption) betaToolRunnerBase { + toolMap := make(map[string]BetaTool) + apiTools := make([]BetaToolUnionParam, len(tools)) + + for i, tool := range tools { + toolMap[tool.Name()] = tool + apiTools[i] = BetaToolUnionParam{ + OfTool: &BetaToolParam{ + Name: tool.Name(), + Description: String(tool.Description()), + InputSchema: tool.InputSchema(), + }, + } + } + + // Add tools to the API params + params.BetaMessageNewParams.Tools = apiTools + params.Messages = append([]BetaMessageParam{}, params.Messages...) + + return betaToolRunnerBase{ + messageService: messageService, + Params: params, + toolMap: toolMap, + opts: opts, + } +} + +// LastMessage returns the most recent assistant message, or nil if no messages have been received yet. +func (b *betaToolRunnerBase) LastMessage() *BetaMessage { + return b.lastMessage +} + +// AppendMessages adds messages to the conversation history. +// This is a convenience method equivalent to: +// +// runner.Params.Messages = append(runner.Params.Messages, messages...) +func (b *betaToolRunnerBase) AppendMessages(messages ...BetaMessageParam) { + b.Params.Messages = append(b.Params.Messages, messages...) +} + +// Messages returns a copy of the current conversation history. +// The returned slice can be safely modified without affecting the runner's state. +func (b *betaToolRunnerBase) Messages() []BetaMessageParam { + result := make([]BetaMessageParam, len(b.Params.Messages)) + copy(result, b.Params.Messages) + return result +} + +// IterationCount returns the number of API calls made so far. +// This is incremented each time a turn makes an API call. +func (b *betaToolRunnerBase) IterationCount() int { + return b.iterationCount +} + +// IsCompleted returns true if the conversation has finished, either because +// the model stopped using tools or the maximum iteration limit was reached. +func (b *betaToolRunnerBase) IsCompleted() bool { + return b.completed +} + +// Err returns the last error that occurred during iteration, if any. +// This is useful when using All() or AllStreaming() to check for errors +// after the iteration completes. +func (b *betaToolRunnerBase) Err() error { + return b.err +} + +// executeTools processes any tool use blocks in the given message and returns a tool result message. +// Returns: +// - (result, nil) if tools executed successfully +// - (nil, nil) if no tools to execute +// - (nil, ctx.Err()) if context was cancelled +func (b *betaToolRunnerBase) executeTools(ctx context.Context, message *BetaMessage) (*BetaMessageParam, error) { + var toolUseBlocks []BetaToolUseBlock + + // Find all tool use blocks in the message + for _, block := range message.Content { + if block.Type == "tool_use" { + toolUseBlocks = append(toolUseBlocks, block.AsToolUse()) + } + } + + if len(toolUseBlocks) == 0 { + return nil, nil + } + + // Execute all tools in parallel using errgroup for proper cancellation handling + results := make([]BetaContentBlockParamUnion, len(toolUseBlocks)) + + g, gctx := errgroup.WithContext(ctx) + for i, toolUse := range toolUseBlocks { + g.Go(func() error { + // Check for cancellation before executing tool + select { + case <-gctx.Done(): + return gctx.Err() + default: + } + result := b.executeToolUse(gctx, toolUse) + results[i] = BetaContentBlockParamUnion{OfToolResult: &result} + return nil // tool errors become result content, not Go errors + }) + } + + if err := g.Wait(); err != nil { + return nil, err + } + + // Create user message with tool results + userMessage := NewBetaUserMessage(results...) + return &userMessage, nil +} + +func newBetaToolResultErrorBlockParam(toolUseID string, errorText string) BetaToolResultBlockParam { + return NewBetaToolResultTextBlockParam(toolUseID, errorText, true) +} + +// executeToolUse executes a single tool use block and returns the result. +func (b *betaToolRunnerBase) executeToolUse(ctx context.Context, toolUse BetaToolUseBlock) BetaToolResultBlockParam { + tool, exists := b.toolMap[toolUse.Name] + if !exists { + return newBetaToolResultErrorBlockParam( + toolUse.ID, + fmt.Sprintf("Error: Tool '%s' not found", toolUse.Name), + ) + } + + // Parse and execute the tool + inputBytes, err := json.Marshal(toolUse.Input) + if err != nil { + return newBetaToolResultErrorBlockParam( + toolUse.ID, + fmt.Sprintf("Error: Failed to marshal tool input: %v", err), + ) + } + + result, err := tool.Execute(ctx, inputBytes) + if err != nil { + return newBetaToolResultErrorBlockParam( + toolUse.ID, + fmt.Sprintf("Error: %v", err), + ) + } + + return BetaToolResultBlockParam{ + ToolUseID: toolUse.ID, + Content: []BetaToolResultBlockParamContentUnion{result}, + } +} + +// BetaToolRunner manages the automatic conversation loop between the assistant and tools +// using non-streaming API calls. It implements an iterator pattern for processing +// conversation turns. +// +// A BetaToolRunner is NOT safe for concurrent use. All methods must be called +// from a single goroutine. However, tool handlers ARE called concurrently +// when multiple tools are invoked in a single turn - ensure your handlers +// are thread-safe. +type BetaToolRunner struct { + betaToolRunnerBase +} + +// NewToolRunner creates a BetaToolRunner that automatically handles the loop between +// the model generating tool calls, executing those tool calls, and sending the +// results back to the model until a final answer is produced or the maximum +// number of iterations is reached. +func (r *BetaMessageService) NewToolRunner(tools []BetaTool, params BetaToolRunnerParams, opts ...option.RequestOption) *BetaToolRunner { + return &BetaToolRunner{ + betaToolRunnerBase: newBetaToolRunnerBase(r, tools, params, opts), + } +} + +// NextMessage advances the conversation by one turn. It executes any pending tool calls +// from the previous message, then makes an API call to get the model's next response. +// +// Returns: +// - (message, nil) on success with the assistant's response +// - (nil, nil) when the conversation is complete (no more tool calls or max iterations reached) +// - (nil, error) if an error occurred during tool execution or API call +func (r *BetaToolRunner) NextMessage(ctx context.Context) (*BetaMessage, error) { + if r.completed { + return nil, nil + } + + // Check iteration limit + if r.Params.MaxIterations > 0 && r.iterationCount >= r.Params.MaxIterations { + r.completed = true + return r.lastMessage, nil + } + + // Execute any pending tool calls from the last message + if r.lastMessage != nil { + toolMessage, err := r.executeTools(ctx, r.lastMessage) + if err != nil { + r.err = err + return nil, err + } + if toolMessage == nil { + // No tools to execute, conversation is complete + r.completed = true + return r.lastMessage, nil + } + r.Params.Messages = append(r.Params.Messages, *toolMessage) + } + + // Make API call + r.iterationCount++ + messageParams := r.Params.BetaMessageNewParams + messageParams.Messages = r.Params.Messages + + message, err := r.messageService.New(ctx, messageParams, r.opts...) + if err != nil { + r.err = err + return nil, fmt.Errorf("failed to get next message: %w", err) + } + + r.lastMessage = message + r.Params.Messages = append(r.Params.Messages, message.ToParam()) + + return message, nil +} + +// RunToCompletion repeatedly calls NextMessage until the conversation is complete, +// either because the model stopped using tools or the maximum iteration limit was reached. +// +// Returns the final assistant message and any error that occurred. +func (r *BetaToolRunner) RunToCompletion(ctx context.Context) (*BetaMessage, error) { + for { + message, err := r.NextMessage(ctx) + if err != nil { + return nil, err + } + if message == nil { + return r.lastMessage, nil + } + } +} + +// All returns an iterator that yields all messages until the conversation completes. +// This is a convenience method for iterating over the entire conversation. +// +// Example usage: +// +// for message, err := range runner.All(ctx) { +// if err != nil { +// return err +// } +// // process message +// } +func (r *BetaToolRunner) All(ctx context.Context) iter.Seq2[*BetaMessage, error] { + return func(yield func(*BetaMessage, error) bool) { + for { + message, err := r.NextMessage(ctx) + r.err = err + if message == nil { + if err != nil { + yield(nil, err) + } + return + } + if !yield(message, err) { + return + } + } + } +} + +// BetaToolRunnerStreaming manages the automatic conversation loop between the assistant +// and tools using streaming API calls. It implements an iterator pattern for processing +// streaming events across conversation turns. +// +// A BetaToolRunnerStreaming is NOT safe for concurrent use. All methods must be called +// from a single goroutine. However, tool handlers ARE called concurrently +// when multiple tools are invoked in a single turn - ensure your handlers +// are thread-safe. +type BetaToolRunnerStreaming struct { + betaToolRunnerBase +} + +// NewToolRunnerStreaming creates a BetaToolRunnerStreaming that automatically handles +// the loop between the model generating tool calls, executing those tool calls, and +// sending the results back to the model using streaming API calls until a final answer +// is produced or the maximum number of iterations is reached. +func (r *BetaMessageService) NewToolRunnerStreaming(tools []BetaTool, params BetaToolRunnerParams, opts ...option.RequestOption) *BetaToolRunnerStreaming { + return &BetaToolRunnerStreaming{ + betaToolRunnerBase: newBetaToolRunnerBase(r, tools, params, opts), + } +} + +// NextStreaming advances the conversation by one turn with streaming. It executes any +// pending tool calls from the previous message, then makes a streaming API call. +// +// Returns an iterator that yields streaming events as they arrive. The iterator should +// be fully consumed to ensure the message is properly accumulated for subsequent turns. +// +// If an error occurs, it will be yielded as the second value in the iterator pair. +// Check IsCompleted() after consuming the iterator to determine if the conversation +// has finished. +func (r *BetaToolRunnerStreaming) NextStreaming(ctx context.Context) iter.Seq2[BetaRawMessageStreamEventUnion, error] { + return func(yield func(BetaRawMessageStreamEventUnion, error) bool) { + if r.completed { + return + } + + // Check iteration limit + if r.Params.MaxIterations > 0 && r.iterationCount >= r.Params.MaxIterations { + r.completed = true + return + } + + // Execute any pending tool calls from the last message + if r.lastMessage != nil { + toolMessage, err := r.executeTools(ctx, r.lastMessage) + if err != nil { + r.err = err + yield(BetaRawMessageStreamEventUnion{}, err) + return + } + if toolMessage == nil { + // No tools to execute, conversation is complete + r.completed = true + return + } + r.Params.Messages = append(r.Params.Messages, *toolMessage) + } + + // Make streaming API call + r.iterationCount++ + streamParams := r.Params.BetaMessageNewParams + streamParams.Messages = r.Params.Messages + + stream := r.messageService.NewStreaming(ctx, streamParams, r.opts...) + defer stream.Close() + + // We need to collect the final message from the stream for the next iteration + finalMessage := &BetaMessage{} + for stream.Next() { + event := stream.Current() + err := finalMessage.Accumulate(event) + if err != nil { + r.err = fmt.Errorf("failed to accumulate streaming event: %w", err) + yield(BetaRawMessageStreamEventUnion{}, r.err) + return + } + + if !yield(event, nil) { + return + } + } + + // Check for stream errors after the loop exits + if stream.Err() != nil { + r.err = stream.Err() + yield(BetaRawMessageStreamEventUnion{}, r.err) + return + } + + r.lastMessage = finalMessage + r.Params.Messages = append(r.Params.Messages, finalMessage.ToParam()) + } +} + +// AllStreaming returns an iterator of iterators, where each inner iterator yields +// streaming events for a single turn of the conversation. The outer iterator continues +// until the conversation completes. +// +// Example usage: +// +// for events, err := range runner.AllStreaming(ctx) { +// if err != nil { +// return err +// } +// for event, err := range events { +// if err != nil { +// return err +// } +// // process streaming event +// } +// } +func (r *BetaToolRunnerStreaming) AllStreaming(ctx context.Context) iter.Seq2[iter.Seq2[BetaRawMessageStreamEventUnion, error], error] { + return func(yield func(iter.Seq2[BetaRawMessageStreamEventUnion, error], error) bool) { + for !r.completed { + eventSeq := r.NextStreaming(ctx) + if !yield(eventSeq, nil) { + return + } + } + } +} diff --git a/client.go b/client.go index a88b9d44b..9e6db59ad 100644 --- a/client.go +++ b/client.go @@ -4,12 +4,15 @@ package anthropic import ( "context" + "fmt" "net/http" "os" "slices" + "time" "github.com/charmbracelet/anthropic-sdk-go/internal/requestconfig" "github.com/charmbracelet/anthropic-sdk-go/option" + "github.com/charmbracelet/anthropic-sdk-go/shared/constant" ) // Client creates a struct with services and top level methods that help with @@ -54,7 +57,7 @@ func NewClient(opts ...option.RequestOption) (r Client) { r.Models = NewModelService(opts...) r.Beta = NewBetaService(opts...) - return r + return } // Execute makes a request with the given context, method, URL, request params, @@ -125,3 +128,30 @@ func (r *Client) Patch(ctx context.Context, path string, params any, res any, op func (r *Client) Delete(ctx context.Context, path string, params any, res any, opts ...option.RequestOption) error { return r.Execute(ctx, http.MethodDelete, path, params, res, opts...) } + +// CalculateNonStreamingTimeout calculates the appropriate timeout for a non-streaming request +// based on the maximum number of tokens and the model's non-streaming token limit +func CalculateNonStreamingTimeout(maxTokens int, model Model, opts []option.RequestOption) (time.Duration, error) { + preCfg, err := requestconfig.PreRequestOptions(opts...) + if err != nil { + return 0, fmt.Errorf("error applying request options: %w", err) + } + // if the user has set a specific request timeout, use that + if preCfg.RequestTimeout != 0 { + return preCfg.RequestTimeout, nil + } + + maximumTime := time.Hour // 1 hour + defaultTime := 10 * time.Minute + + expectedTime := time.Duration(float64(maximumTime) * float64(maxTokens) / 128000.0) + + // If the model has a non-streaming token limit and max_tokens exceeds it, + // or if the expected time exceeds default time, require streaming + maxNonStreamingTokens, hasLimit := constant.ModelNonStreamingTokens[string(model)] + if expectedTime > defaultTime || (hasLimit && maxTokens > maxNonStreamingTokens) { + return 0, fmt.Errorf("streaming is required for operations that may take longer than 10 minutes") + } + + return defaultTime, nil +} diff --git a/client_test.go b/client_test.go index eb27ec2cc..7eadc5ec5 100644 --- a/client_test.go +++ b/client_test.go @@ -43,13 +43,13 @@ func TestUserAgentHeader(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if userAgent != fmt.Sprintf("Anthropic/Go %s", internal.PackageVersion) { t.Errorf("Expected User-Agent to be correct, but got: %#v", userAgent) @@ -78,13 +78,13 @@ func TestRetryAfter(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -124,13 +124,13 @@ func TestDeleteRetryCountHeader(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -165,13 +165,13 @@ func TestOverwriteRetryCountHeader(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -205,13 +205,13 @@ func TestRetryAfterMs(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -239,13 +239,13 @@ func TestContextCancel(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") @@ -270,13 +270,13 @@ func TestContextCancelDelay(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("expected there to be a cancel error") @@ -307,13 +307,13 @@ func TestContextDeadline(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("expected there to be a deadline error") @@ -363,13 +363,13 @@ func TestContextDeadlineStreaming(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeOpus4_6, }) for stream.Next() { _ = stream.Current() @@ -421,13 +421,13 @@ func TestContextDeadlineStreamingWithRequestTimeout(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeOpus4_6, }, option.WithRequestTimeout((100 * time.Millisecond)), ) diff --git a/completion.go b/completion.go index 119e35a5e..046960a2a 100644 --- a/completion.go +++ b/completion.go @@ -39,16 +39,16 @@ func NewCompletionService(opts ...option.RequestOption) (r CompletionService) { // [Legacy] Create a Text Completion. // // The Text Completions API is a legacy API. We recommend using the -// [Messages API](https://docs.anthropic.com/en/api/messages) going forward. +// [Messages API](https://docs.claude.com/en/api/messages) going forward. // // Future models and features will not be compatible with Text Completions. See our -// [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) +// [migration guide](https://docs.claude.com/en/api/migrating-from-text-completions-to-messages) // for guidance in migrating from Text Completions to Messages. // // 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) path := "v1/complete" @@ -59,10 +59,10 @@ func (r *CompletionService) New(ctx context.Context, params CompletionNewParams, // [Legacy] Create a Text Completion. // // The Text Completions API is a legacy API. We recommend using the -// [Messages API](https://docs.anthropic.com/en/api/messages) going forward. +// [Messages API](https://docs.claude.com/en/api/messages) going forward. // // Future models and features will not be compatible with Text Completions. See our -// [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) +// [migration guide](https://docs.claude.com/en/api/migrating-from-text-completions-to-messages) // for guidance in migrating from Text Completions to Messages. // // Note: If you choose to set a timeout for this request, we recommend 10 minutes. @@ -72,10 +72,10 @@ func (r *CompletionService) NewStreaming(ctx context.Context, params CompletionN err error ) for _, v := range params.Betas { - opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) - opts = append([]option.RequestOption{option.WithJSONSet("stream", true)}, opts...) + opts = append(opts, option.WithJSONSet("stream", true)) path := "v1/complete" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &raw, opts...) return ssestream.NewStream[Completion](ssestream.NewDecoder(raw), err) @@ -142,10 +142,9 @@ type CompletionNewParams struct { // "\n\nHuman: {userQuestion}\n\nAssistant:" // ``` // - // See [prompt validation](https://docs.anthropic.com/en/api/prompt-validation) and - // our guide to - // [prompt design](https://docs.anthropic.com/en/docs/intro-to-prompting) for more - // details. + // See [prompt validation](https://docs.claude.com/en/api/prompt-validation) and + // our guide to [prompt design](https://docs.claude.com/en/docs/intro-to-prompting) + // for more details. Prompt string `json:"prompt,required"` // Amount of randomness injected into the response. // diff --git a/completion_test.go b/completion_test.go index be0b9aafc..1c083888c 100644 --- a/completion_test.go +++ b/completion_test.go @@ -27,7 +27,7 @@ func TestCompletionNewWithOptionalParams(t *testing.T) { ) _, err := client.Completions.New(context.TODO(), anthropic.CompletionNewParams{ MaxTokensToSample: 256, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeOpus4_6, Prompt: "\n\nHuman: Hello, world!\n\nAssistant:", Metadata: anthropic.MetadataParam{ UserID: anthropic.String("13803d75-b4b5-4c3e-b2a2-6f21399b021b"), diff --git a/examples/bedrock-bearer-token/main.go b/examples/bedrock-bearer-token/main.go new file mode 100644 index 000000000..5cdfb6508 --- /dev/null +++ b/examples/bedrock-bearer-token/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + + "github.com/charmbracelet/anthropic-sdk-go" + "github.com/charmbracelet/anthropic-sdk-go/bedrock" +) + +func main() { + // bedrock.WithLoadDefaultConfig automatically configures using the AWS_BEARER_TOKEN_BEDROCK + // environment variable. Region defaults to us-east-1 or uses AWS_REGION if set. + // + // To provide a token programmatically: + // + // cfg := aws.Config{ + // Region: "us-west-2", + // BearerAuthTokenProvider: bedrock.NewStaticBearerTokenProvider("my-bearer-token"), + // } + // client := anthropic.NewClient( + // bedrock.WithConfig(cfg), + // ) + client := anthropic.NewClient( + bedrock.WithLoadDefaultConfig(context.TODO()), + ) + + content := "Write me a function to call the Anthropic message API in Node.js using the Anthropic Typescript SDK." + + println("[user]: " + content) + + message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{ + MaxTokens: 1024, + Messages: []anthropic.MessageParam{ + anthropic.NewUserMessage(anthropic.NewTextBlock(content)), + }, + Model: "us.anthropic.claude-sonnet-4-20250514-v1:0", + StopSequences: []string{"```\n"}, + }) + if err != nil { + panic(err) + } + + println("[assistant]: " + message.Content[0].Text + message.StopSequence) +} diff --git a/examples/go.mod b/examples/go.mod index 8420e5e44..353f9ba5e 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -8,7 +8,7 @@ toolchain go1.24.3 require ( github.com/anthropics/anthropic-sdk-go v0.0.0-00010101000000-000000000000 - github.com/invopop/jsonschema v0.12.0 + github.com/invopop/jsonschema v0.13.0 ) require ( diff --git a/examples/go.sum b/examples/go.sum index 3c6903b02..9d1116859 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -84,8 +84,8 @@ github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= -github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= diff --git a/examples/structured-outputs/main.go b/examples/structured-outputs/main.go new file mode 100644 index 000000000..ad15753a2 --- /dev/null +++ b/examples/structured-outputs/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/charmbracelet/anthropic-sdk-go" + "github.com/invopop/jsonschema" +) + +// Example struct with various field types and constraints +type WeatherQuery struct { + Location string `json:"location" jsonschema:"title=Location,description=The city and state e.g. San Francisco CA"` + Units string `json:"units,omitempty" jsonschema:"enum=celsius,enum=fahrenheit,default=fahrenheit"` + Days int `json:"days" jsonschema:"minimum=1,maximum=7,description=Number of days to forecast"` + IncludeWind bool `json:"include_wind,omitempty"` + Details []string `json:"details,omitempty" jsonschema:"minItems=1,maxItems=5"` +} + +func main() { + schemaMap := generateJSONSchema(&WeatherQuery{}) + + fmt.Println("schema generated by invopop/jsonschema:") + printJSON(schemaMap) + + client := anthropic.NewClient() + + messages := []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What's the weather like in San Francisco for the next 3 days? Include wind information.")), + } + + msg, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{ + Model: anthropic.Model("claude-sonnet-4-5"), + MaxTokens: 1024, + Messages: messages, + OutputFormat: anthropic.BetaJSONSchemaOutputFormat(schemaMap), + Betas: []anthropic.AnthropicBeta{"structured-outputs-2025-11-13"}, + }) + + if err != nil { + fmt.Printf("Error calling API: %v\n", err) + return + } + + fmt.Println("\nAPI Response:") + for _, block := range msg.Content { + switch v := block.AsAny().(type) { + case anthropic.BetaTextBlock: + fmt.Printf("Text: %s\n", v.Text) + case anthropic.BetaToolUseBlock: + fmt.Printf("Tool use: %s\n", v.Name) + fmt.Printf("Input: %s\n", v.JSON.Input.Raw()) + } + } + +} + +func generateJSONSchema(t any) map[string]any { + reflector := jsonschema.Reflector{ + AllowAdditionalProperties: false, + DoNotReference: true, + } + schema := reflector.Reflect(t) + schemaBytes, err := json.Marshal(schema) + if err != nil { + panic(err) + } + var schemaMap map[string]any + if err := json.Unmarshal(schemaBytes, &schemaMap); err != nil { + panic(err) + } + return schemaMap + +} + +func printJSON(v any) { + b, err := json.MarshalIndent(v, "", " ") + if err != nil { + fmt.Printf("Error: %v\n", err) + return + } + fmt.Println(string(b)) +} diff --git a/examples/tool-runner-streaming/main.go b/examples/tool-runner-streaming/main.go new file mode 100644 index 000000000..d4fcbf67a --- /dev/null +++ b/examples/tool-runner-streaming/main.go @@ -0,0 +1,108 @@ +// Example demonstrating the Tool Runner framework with streaming +package main + +import ( + "context" + "fmt" + + "github.com/charmbracelet/anthropic-sdk-go" + "github.com/charmbracelet/anthropic-sdk-go/toolrunner" +) + +type WeatherRequest struct { + City string `json:"city" jsonschema:"required,description=The city to get weather for"` + Units string `json:"units,omitempty" jsonschema:"description=Temperature units,enum=celsius,fahrenheit"` + Include string `json:"include,omitempty" jsonschema:"description=Additional data to include,enum=forecast,historical"` +} + +func colorWith(code string, s string) string { return fmt.Sprintf("\033[1;%sm%s\033[0m", code, s) } +func colorUser(s string) string { return colorWith("36", s) } // cyan +func colorAssistant(s string) string { return colorWith("32", s) } // green +func colorTool(s string) string { return colorWith("33", s) } // yellow +func colorThinking(s string) string { return colorWith("90", s) } // grey + +func getWeather(ctx context.Context, req WeatherRequest) (anthropic.BetaToolResultBlockParamContentUnion, error) { + fmt.Printf("%s%s %+v\n", colorTool("[tool get_weather]: "), "called with", req) + + temp := 22 + if req.Units == "fahrenheit" { + temp = 72 + } + + return anthropic.BetaToolResultBlockParamContentUnion{ + OfText: &anthropic.BetaTextBlockParam{ + Text: fmt.Sprintf("The current weather in %s is %d degrees %s. Tomorrow's weather will be cloudy and colder.", req.City, temp, req.Units), + }, + }, nil +} + +func main() { + client := anthropic.NewClient() + ctx := context.Background() + + weatherTool, err := toolrunner.NewBetaToolFromJSONSchema("get_weather", "Get current weather information for a city", getWeather) + if err != nil { + fmt.Printf("Error creating weather tool: %v\n", err) + return + } + + userQuestion := "What's the weather like in San Francisco? Please use Fahrenheit and include the forecast." + fmt.Println(colorUser("[user]: ") + userQuestion) + + tools := []anthropic.BetaTool{weatherTool} + + runner := client.Beta.Messages.NewToolRunnerStreaming(tools, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaudeSonnet4_20250514, + MaxTokens: 1000, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage( + anthropic.NewBetaTextBlock(userQuestion), + ), + }, + }, + MaxIterations: 5, + }) + + for eventsIterator := range runner.AllStreaming(ctx) { + _ = runner.IterationCount() + for event, err := range eventsIterator { + if err != nil { + fmt.Printf("%s %+v\n", colorWith("31", "[error]: "+err.Error()), event) + return + } + switch eventVariant := event.AsAny().(type) { + case anthropic.BetaRawMessageStartEvent: + fmt.Print(colorAssistant("[assistant]: ")) + case anthropic.BetaRawContentBlockStartEvent: + switch cb := eventVariant.ContentBlock.AsAny().(type) { + case anthropic.BetaToolUseBlock: + // Assistant is initiating a tool call; stream its JSON input deltas next + label := fmt.Sprintf("[tool call %s]: ", cb.Name) + fmt.Print(colorTool(label)) + case anthropic.BetaTextBlock: + // nothing, normal assistant text will follow via deltas + case anthropic.BetaThinkingBlock: + fmt.Print(colorThinking("[assistant thinking]: ")) + } + case anthropic.BetaRawContentBlockDeltaEvent: + switch deltaVariant := eventVariant.Delta.AsAny().(type) { + case anthropic.BetaTextDelta: + fmt.Print(colorAssistant(deltaVariant.Text)) + case anthropic.BetaInputJSONDelta: + if deltaVariant.PartialJSON != "" { + fmt.Print(colorTool(deltaVariant.PartialJSON)) + } + case anthropic.BetaThinkingDelta: + fmt.Print(colorThinking(deltaVariant.Thinking)) + } + case anthropic.BetaRawContentBlockStopEvent: + fmt.Println() + case anthropic.BetaRawMessageDeltaEvent: + // No visible text here; keep for completeness + case anthropic.BetaRawMessageStopEvent: + fmt.Println() + } + } + } +} diff --git a/examples/tool-runner/main.go b/examples/tool-runner/main.go new file mode 100644 index 000000000..51dc277e2 --- /dev/null +++ b/examples/tool-runner/main.go @@ -0,0 +1,78 @@ +// Example demonstrating the Tool Runner framework +package main + +import ( + "context" + "fmt" + "strconv" + + "github.com/charmbracelet/anthropic-sdk-go" + "github.com/charmbracelet/anthropic-sdk-go/toolrunner" +) + +type CalculatorInput struct { + Operation string `json:"operation" jsonschema:"required,description=The arithmetic operation to perform,enum=add,subtract,multiply,divide"` + A float64 `json:"a" jsonschema:"required,description=The first number"` + B float64 `json:"b" jsonschema:"required,description=The second number"` +} + +func calculate(ctx context.Context, calc CalculatorInput) (anthropic.BetaToolResultBlockParamContentUnion, error) { + var floatResult float64 + fmt.Printf("🔧 Calculator tool called with: %+v\n", calc) + switch calc.Operation { + case "add": + floatResult = calc.A + calc.B + case "subtract": + floatResult = calc.A - calc.B + case "multiply": + floatResult = calc.A * calc.B + case "divide": + if calc.B == 0 { + return anthropic.BetaToolResultBlockParamContentUnion{}, fmt.Errorf("division by zero") + } + floatResult = calc.A / calc.B + default: + return anthropic.BetaToolResultBlockParamContentUnion{}, fmt.Errorf("unknown operation: %s", calc.Operation) + } + + return anthropic.BetaToolResultBlockParamContentUnion{ + OfText: &anthropic.BetaTextBlockParam{Text: strconv.FormatFloat(floatResult, 'g', -1, 64)}, + }, nil +} + +func main() { + client := anthropic.NewClient() + ctx := context.Background() + + calculatorTool, err := toolrunner.NewBetaToolFromJSONSchema("calculator", "Perform basic arithmetic operations", calculate) + if err != nil { + fmt.Printf("Error creating calculator tool: %v\n", err) + return + } + + fmt.Printf("Starting tool runner with calculator tool: %+v\n", calculatorTool) + + tools := []anthropic.BetaTool{calculatorTool} + + runner := client.Beta.Messages.NewToolRunner(tools, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaudeSonnet4_20250514, + MaxTokens: 1000, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage( + anthropic.NewBetaTextBlock("Calculate 15 * 23, then add 10 to the result"), + ), + }, + }, + MaxIterations: 5, + }) + + finalMessage, err := runner.RunToCompletion(ctx) + if err != nil { + fmt.Printf("Error running tools: %v\n", err) + return + } + + fmt.Printf("Final message content:\n") + fmt.Printf("%+v\n", finalMessage) +} diff --git a/examples/tools-streaming-jsonschema/main.go b/examples/tools-streaming-jsonschema/main.go index 8d7e1f1ab..f7ff5355d 100644 --- a/examples/tools-streaming-jsonschema/main.go +++ b/examples/tools-streaming-jsonschema/main.go @@ -87,7 +87,7 @@ func main() { case anthropic.ToolUseBlock: print(color("[user (" + block.Name + ")]: ")) - var response interface{} + var response any switch block.Name { case "get_coordinates": input := GetCoordinatesInput{} diff --git a/examples/tools-streaming/main.go b/examples/tools-streaming/main.go index 9c3ab4c9a..74f3d24c8 100644 --- a/examples/tools-streaming/main.go +++ b/examples/tools-streaming/main.go @@ -24,8 +24,8 @@ func main() { Name: "get_coordinates", Description: anthropic.String("Accepts a place as an address, then returns the latitude and longitude coordinates."), InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "location": map[string]interface{}{ + Properties: map[string]any{ + "location": map[string]any{ "type": "string", "description": "The location to look up.", }, @@ -35,8 +35,8 @@ func main() { { Name: "get_temperature_unit", InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "country": map[string]interface{}{ + Properties: map[string]any{ + "country": map[string]any{ "type": "string", "description": "The country", }, @@ -47,16 +47,16 @@ func main() { Name: "get_weather", Description: anthropic.String("Get the weather at a specific location"), InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "lat": map[string]interface{}{ + Properties: map[string]any{ + "lat": map[string]any{ "type": "number", "description": "The lattitude of the location to check weather.", }, - "long": map[string]interface{}{ + "long": map[string]any{ "type": "number", "description": "The longitude of the location to check weather.", }, - "unit": map[string]interface{}{ + "unit": map[string]any{ "type": "string", "enum": []string{"celsius", "fahrenheit"}, "description": "Unit for the output", @@ -116,7 +116,7 @@ func main() { case anthropic.ToolUseBlock: print(color("[user (" + block.Name + ")]: ")) - var response interface{} + var response any switch block.Name { case "get_coordinates": var input struct { diff --git a/examples/tools/main.go b/examples/tools/main.go index 8076ad543..19c9e5b2f 100644 --- a/examples/tools/main.go +++ b/examples/tools/main.go @@ -24,8 +24,8 @@ func main() { Name: "get_coordinates", Description: anthropic.String("Accepts a place as an address, then returns the latitude and longitude coordinates."), InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "location": map[string]interface{}{ + Properties: map[string]any{ + "location": map[string]any{ "type": "string", "description": "The location to look up.", }, @@ -35,8 +35,8 @@ func main() { { Name: "get_temperature_unit", InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "country": map[string]interface{}{ + Properties: map[string]any{ + "country": map[string]any{ "type": "string", "description": "The country", }, @@ -47,16 +47,16 @@ func main() { Name: "get_weather", Description: anthropic.String("Get the weather at a specific location"), InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "lat": map[string]interface{}{ + Properties: map[string]any{ + "lat": map[string]any{ "type": "number", "description": "The lattitude of the location to check weather.", }, - "long": map[string]interface{}{ + "long": map[string]any{ "type": "number", "description": "The longitude of the location to check weather.", }, - "unit": map[string]interface{}{ + "unit": map[string]any{ "type": "string", "enum": []string{"celsius", "fahrenheit"}, "description": "Unit for the output", @@ -104,7 +104,7 @@ func main() { case anthropic.ToolUseBlock: print(color("[user (" + block.Name + ")]: ")) - var response interface{} + var response any switch block.Name { case "get_coordinates": var input struct { diff --git a/go.mod b/go.mod index 5c0ef8e26..b6dcd4d84 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,14 @@ require ( github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 github.com/aws/aws-sdk-go-v2/config v1.27.27 github.com/aws/aws-sdk-go-v2/credentials v1.17.27 + github.com/aws/smithy-go v1.20.3 + github.com/dnaeon/go-vcr v1.2.0 + github.com/invopop/jsonschema v0.13.0 github.com/stretchr/testify v1.8.4 github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 golang.org/x/oauth2 v0.30.0 + golang.org/x/sync v0.16.0 google.golang.org/api v0.189.0 ) @@ -29,7 +33,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect - github.com/aws/smithy-go v1.20.3 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -38,9 +43,11 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect @@ -49,12 +56,12 @@ require ( go.opentelemetry.io/otel/trace v1.24.0 // indirect golang.org/x/crypto v0.40.0 // indirect golang.org/x/net v0.41.0 // indirect - golang.org/x/sync v0.16.0 // indirect golang.org/x/sys v0.34.0 // indirect golang.org/x/text v0.27.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade // indirect google.golang.org/grpc v1.64.1 // indirect google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v2 v2.2.8 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b3522cae0..15da904cf 100644 --- a/go.sum +++ b/go.sum @@ -34,12 +34,18 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudr github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -80,6 +86,12 @@ github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -101,6 +113,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= @@ -184,6 +198,8 @@ google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6h google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/apiform/encoder.go b/internal/apiform/encoder.go index 3fbfaa49f..25ca49a80 100644 --- a/internal/apiform/encoder.go +++ b/internal/apiform/encoder.go @@ -60,6 +60,7 @@ type encoderField struct { type encoderEntry struct { reflect.Type dateFormat string + arrayFmt string root bool } @@ -77,6 +78,7 @@ func (e *encoder) typeEncoder(t reflect.Type) encoderFunc { entry := encoderEntry{ Type: t, dateFormat: e.dateFormat, + arrayFmt: e.arrayFmt, root: e.root, } @@ -178,34 +180,9 @@ func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc { } } -func arrayKeyEncoder(arrayFmt string) func(string, int) string { - var keyFn func(string, int) string - switch arrayFmt { - case "comma", "repeat": - keyFn = func(k string, _ int) string { return k } - case "brackets": - keyFn = func(key string, _ int) string { return key + "[]" } - case "indices:dots": - keyFn = func(k string, i int) string { - if k == "" { - return strconv.Itoa(i) - } - return k + "." + strconv.Itoa(i) - } - case "indices:brackets": - keyFn = func(k string, i int) string { - if k == "" { - return strconv.Itoa(i) - } - return k + "[" + strconv.Itoa(i) + "]" - } - } - return keyFn -} - func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc { itemEncoder := e.typeEncoder(t.Elem()) - keyFn := arrayKeyEncoder(e.arrayFmt) + keyFn := e.arrayKeyEncoder() return func(key string, v reflect.Value, writer *multipart.Writer) error { if keyFn == nil { return fmt.Errorf("apiform: unsupported array format") @@ -303,13 +280,10 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc { }) return func(key string, value reflect.Value, writer *multipart.Writer) error { - if key != "" { - key = key + "." - } - + keyFn := e.objKeyEncoder(key) for _, ef := range encoderFields { field := value.FieldByIndex(ef.idx) - err := ef.fn(key+ef.tag.name, field, writer) + err := ef.fn(keyFn(ef.tag.name), field, writer) if err != nil { return err } @@ -405,6 +379,43 @@ func (e *encoder) newReaderTypeEncoder() encoderFunc { } } +func (e encoder) arrayKeyEncoder() func(string, int) string { + var keyFn func(string, int) string + switch e.arrayFmt { + case "comma", "repeat": + keyFn = func(k string, _ int) string { return k } + case "brackets": + keyFn = func(key string, _ int) string { return key + "[]" } + case "indices:dots": + keyFn = func(k string, i int) string { + if k == "" { + return strconv.Itoa(i) + } + return k + "." + strconv.Itoa(i) + } + case "indices:brackets": + keyFn = func(k string, i int) string { + if k == "" { + return strconv.Itoa(i) + } + return k + "[" + strconv.Itoa(i) + "]" + } + } + return keyFn +} + +func (e encoder) objKeyEncoder(parent string) func(string) string { + if parent == "" { + return func(child string) string { return child } + } + switch e.arrayFmt { + case "brackets": + return func(child string) string { return parent + "[" + child + "]" } + default: + return func(child string) string { return parent + "." + child } + } +} + // Given a []byte of json (may either be an empty object or an object that already contains entries) // encode all of the entries in the map to the json byte array. func (e *encoder) encodeMapEntries(key string, v reflect.Value, writer *multipart.Writer) error { @@ -413,10 +424,6 @@ func (e *encoder) encodeMapEntries(key string, v reflect.Value, writer *multipar value reflect.Value } - if key != "" { - key = key + "." - } - pairs := []mapPair{} iter := v.MapRange() @@ -434,8 +441,9 @@ func (e *encoder) encodeMapEntries(key string, v reflect.Value, writer *multipar }) elementEncoder := e.typeEncoder(v.Type().Elem()) + keyFn := e.objKeyEncoder(key) for _, p := range pairs { - err := elementEncoder(key+string(p.key), p.value, writer) + err := elementEncoder(keyFn(p.key), p.value, writer) if err != nil { return err } diff --git a/internal/apiform/form_test.go b/internal/apiform/form_test.go index 5f27069cc..070fb6378 100644 --- a/internal/apiform/form_test.go +++ b/internal/apiform/form_test.go @@ -126,6 +126,18 @@ type StructUnion struct { param.APIUnion } +type MultipartMarshalerParent struct { + Middle MultipartMarshalerMiddleNext `form:"middle"` +} + +type MultipartMarshalerMiddleNext struct { + MiddleNext MultipartMarshalerMiddle `form:"middleNext"` +} + +type MultipartMarshalerMiddle struct { + Child int `form:"child"` +} + var tests = map[string]struct { buf string val any @@ -369,6 +381,19 @@ true }, }, }, + "recursive_struct,brackets": { + `--xxx +Content-Disposition: form-data; name="child[name]" + +Alex +--xxx +Content-Disposition: form-data; name="name" + +Robert +--xxx-- +`, + Recursive{Name: "Robert", Child: &Recursive{Name: "Alex"}}, + }, "recursive_struct": { `--xxx @@ -532,6 +557,30 @@ Content-Disposition: form-data; name="union" Union: UnionTime(time.Date(2010, 0o5, 23, 0, 0, 0, 0, time.UTC)), }, }, + "deeply-nested-struct,brackets": { + `--xxx +Content-Disposition: form-data; name="middle[middleNext][child]" + +10 +--xxx-- +`, + MultipartMarshalerParent{ + Middle: MultipartMarshalerMiddleNext{ + MiddleNext: MultipartMarshalerMiddle{ + Child: 10, + }, + }, + }, + }, + "deeply-nested-map,brackets": { + `--xxx +Content-Disposition: form-data; name="middle[middleNext][child]" + +10 +--xxx-- +`, + map[string]any{"middle": map[string]any{"middleNext": map[string]any{"child": 10}}}, + }, } func TestEncode(t *testing.T) { @@ -556,7 +605,7 @@ func TestEncode(t *testing.T) { } raw := buf.Bytes() if string(raw) != strings.ReplaceAll(test.buf, "\n", "\r\n") { - t.Errorf("expected %+#v to serialize to '%s' but got '%s'", test.val, test.buf, string(raw)) + t.Errorf("expected %+#v to serialize to '%s' but got '%s' (with format %s)", test.val, test.buf, string(raw), arrayFmt) } }) } diff --git a/internal/apijson/enum.go b/internal/apijson/enum.go index 18b218a8e..5bef11c3d 100644 --- a/internal/apijson/enum.go +++ b/internal/apijson/enum.go @@ -29,7 +29,7 @@ type validatorFunc func(reflect.Value) exactness var validators sync.Map var validationRegistry = map[reflect.Type][]validationEntry{} -func RegisterFieldValidator[T any, V string | bool | int](fieldName string, values ...V) { +func RegisterFieldValidator[T any, V string | bool | int | float64](fieldName string, values ...V) { var t T parentType := reflect.TypeOf(t) diff --git a/internal/testutil/golden.go b/internal/testutil/golden.go new file mode 100644 index 000000000..2af1baea5 --- /dev/null +++ b/internal/testutil/golden.go @@ -0,0 +1,32 @@ +package testutil + +import ( + "os" + "path/filepath" + "testing" +) + +// CompareGolden compares the given string with the golden file at path. +// If UPDATE_GOLDEN=1, it overwrites the file with the provided contents. +func CompareGolden(t *testing.T, goldenRelPath string, got []byte) { + t.Helper() + goldenPath := filepath.FromSlash(goldenRelPath) + + if os.Getenv("UPDATE_GOLDEN") == "1" { + if err := os.MkdirAll(filepath.Dir(goldenPath), 0o755); err != nil { + t.Fatalf("creating golden dir: %v", err) + } + if err := os.WriteFile(goldenPath, got, 0o644); err != nil { + t.Fatalf("writing golden: %v", err) + } + return + } + + want, err := os.ReadFile(goldenPath) + if err != nil { + t.Fatalf("reading golden: %v", err) + } + if string(want) != string(got) { + t.Fatalf("golden mismatch for %s\nwant:\n%s\n----\ngot:\n%s", goldenRelPath, string(want), string(got)) + } +} diff --git a/internal/testutil/testutil.go b/internal/testutil/testutil.go index 826d266f2..31103e9ed 100644 --- a/internal/testutil/testutil.go +++ b/internal/testutil/testutil.go @@ -16,10 +16,10 @@ func CheckTestServer(t *testing.T, url string) bool { t.Fatalf("strconv.ParseBool(os.LookupEnv(%s)) failed: %s", SKIP_MOCK_TESTS, err) } if skip { - t.Skip("The test will not run without a mock Prism server running against your OpenAPI spec") + t.Skip("The test will not run without a mock server running against your OpenAPI spec") return false } - t.Errorf("The test will not run without a mock Prism server running against your OpenAPI spec. You can set the environment variable %s to true to skip running any tests that require the mock server", SKIP_MOCK_TESTS) + t.Errorf("The test will not run without a mock server running against your OpenAPI spec. You can set the environment variable %s to true to skip running any tests that require the mock server", SKIP_MOCK_TESTS) return false } } diff --git a/internal/testutil/vcr.go b/internal/testutil/vcr.go new file mode 100644 index 000000000..fc645cdc7 --- /dev/null +++ b/internal/testutil/vcr.go @@ -0,0 +1,36 @@ +package testutil + +import ( + "net/http" + "os" + "path/filepath" + "testing" + + "github.com/dnaeon/go-vcr/recorder" +) + +// NewVCRHTTPClient creates an *http.Client wired to a go-vcr recorder. +// Cassette files are stored under testdata/cassettes. +// If ANTHROPIC_LIVE=1, the recorder runs in recording mode; otherwise replay-only. +func NewVCRHTTPClient(t *testing.T, cassetteName string) (*http.Client, *recorder.Recorder) { + t.Helper() + + mode := recorder.ModeReplaying + if os.Getenv("ANTHROPIC_LIVE") == "1" { + mode = recorder.ModeRecording + } + + // Let go-vcr handle the .yaml extension to avoid accidental double suffixes + cassettePath := filepath.Join("testdata", "cassettes", cassetteName) + r, err := recorder.NewAsMode(cassettePath, mode, nil) + if err != nil { + t.Fatalf("failed to create recorder: %v", err) + } + + t.Cleanup(func() { + _ = r.Stop() + }) + + httpClient := &http.Client{Transport: r} + return httpClient, r +} diff --git a/internal/version.go b/internal/version.go index f2e4266ca..abcd67729 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "1.14.0" // x-release-please-version +const PackageVersion = "1.26.0" // x-release-please-version diff --git a/message.go b/message.go index caaebfce6..0307947b8 100644 --- a/message.go +++ b/message.go @@ -5,7 +5,6 @@ package anthropic import ( "context" "encoding/json" - "fmt" "net/http" "reflect" "slices" @@ -40,7 +39,7 @@ func NewMessageService(opts ...option.RequestOption) (r MessageService) { r = MessageService{} r.Options = opts r.Batches = NewMessageBatchService(opts...) - return r + return } // Send a structured list of input messages with text and/or image content, and the @@ -49,7 +48,8 @@ func NewMessageService(opts ...option.RequestOption) (r MessageService) { // The Messages API can be used for either single queries or stateless multi-turn // conversations. // -// Learn more about the Messages API in our [user guide](/en/docs/initial-setup) +// Learn more about the Messages API in our +// [user guide](https://docs.claude.com/en/docs/initial-setup) // // Note: If you choose to set a timeout for this request, we recommend 10 minutes. func (r *MessageService) New(ctx context.Context, body MessageNewParams, opts ...option.RequestOption) (res *Message, err error) { @@ -65,7 +65,7 @@ func (r *MessageService) New(ctx context.Context, body MessageNewParams, opts .. path := "v1/messages" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) - return res, err + return } // Send a structured list of input messages with text and/or image content, and the @@ -74,7 +74,8 @@ func (r *MessageService) New(ctx context.Context, body MessageNewParams, opts .. // The Messages API can be used for either single queries or stateless multi-turn // conversations. // -// Learn more about the Messages API in our [user guide](/en/docs/initial-setup) +// Learn more about the Messages API in our +// [user guide](https://docs.claude.com/en/docs/initial-setup) // // Note: If you choose to set a timeout for this request, we recommend 10 minutes. func (r *MessageService) NewStreaming(ctx context.Context, body MessageNewParams, opts ...option.RequestOption) (stream *ssestream.Stream[MessageStreamEventUnion]) { @@ -83,7 +84,7 @@ func (r *MessageService) NewStreaming(ctx context.Context, body MessageNewParams err error ) opts = slices.Concat(r.Options, opts) - opts = append([]option.RequestOption{option.WithJSONSet("stream", true)}, opts...) + opts = append(opts, option.WithJSONSet("stream", true)) path := "v1/messages" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &raw, opts...) return ssestream.NewStream[MessageStreamEventUnion](ssestream.NewDecoder(raw), err) @@ -95,12 +96,12 @@ func (r *MessageService) NewStreaming(ctx context.Context, body MessageNewParams // including tools, images, and documents, without creating it. // // Learn more about token counting in our -// [user guide](/en/docs/build-with-claude/token-counting) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/token-counting) func (r *MessageService) CountTokens(ctx context.Context, body MessageCountTokensParams, opts ...option.RequestOption) (res *MessageTokensCount, err error) { opts = slices.Concat(r.Options, opts) path := "v1/messages/count_tokens" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) - return res, err + return } // The properties Data, MediaType, Type are required. @@ -117,7 +118,6 @@ func (r Base64ImageSourceParam) MarshalJSON() (data []byte, err error) { type shadow Base64ImageSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *Base64ImageSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -131,6 +131,35 @@ const ( Base64ImageSourceMediaTypeImageWebP Base64ImageSourceMediaType = "image/webp" ) +type Base64PDFSource struct { + Data string `json:"data,required" format:"byte"` + MediaType constant.ApplicationPDF `json:"media_type,required"` + Type constant.Base64 `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Data respjson.Field + MediaType respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r Base64PDFSource) RawJSON() string { return r.JSON.raw } +func (r *Base64PDFSource) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this Base64PDFSource to a Base64PDFSourceParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// Base64PDFSourceParam.Overrides() +func (r Base64PDFSource) ToParam() Base64PDFSourceParam { + return param.Override[Base64PDFSourceParam](json.RawMessage(r.RawJSON())) +} + // The properties Data, MediaType, Type are required. type Base64PDFSourceParam struct { Data string `json:"data,required" format:"byte"` @@ -145,11 +174,298 @@ func (r Base64PDFSourceParam) MarshalJSON() (data []byte, err error) { type shadow Base64PDFSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *Base64PDFSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +type BashCodeExecutionOutputBlock struct { + FileID string `json:"file_id,required"` + Type constant.BashCodeExecutionOutput `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + FileID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BashCodeExecutionOutputBlock) RawJSON() string { return r.JSON.raw } +func (r *BashCodeExecutionOutputBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties FileID, Type are required. +type BashCodeExecutionOutputBlockParam struct { + FileID string `json:"file_id,required"` + // This field can be elided, and will marshal its zero value as + // "bash_code_execution_output". + Type constant.BashCodeExecutionOutput `json:"type,required"` + paramObj +} + +func (r BashCodeExecutionOutputBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BashCodeExecutionOutputBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BashCodeExecutionOutputBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BashCodeExecutionResultBlock struct { + Content []BashCodeExecutionOutputBlock `json:"content,required"` + ReturnCode int64 `json:"return_code,required"` + Stderr string `json:"stderr,required"` + Stdout string `json:"stdout,required"` + Type constant.BashCodeExecutionResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Stdout respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BashCodeExecutionResultBlock) RawJSON() string { return r.JSON.raw } +func (r *BashCodeExecutionResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Content, ReturnCode, Stderr, Stdout, Type are required. +type BashCodeExecutionResultBlockParam struct { + Content []BashCodeExecutionOutputBlockParam `json:"content,omitzero,required"` + ReturnCode int64 `json:"return_code,required"` + Stderr string `json:"stderr,required"` + Stdout string `json:"stdout,required"` + // This field can be elided, and will marshal its zero value as + // "bash_code_execution_result". + Type constant.BashCodeExecutionResult `json:"type,required"` + paramObj +} + +func (r BashCodeExecutionResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BashCodeExecutionResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BashCodeExecutionResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BashCodeExecutionToolResultBlock struct { + Content BashCodeExecutionToolResultBlockContentUnion `json:"content,required"` + ToolUseID string `json:"tool_use_id,required"` + Type constant.BashCodeExecutionToolResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + ToolUseID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BashCodeExecutionToolResultBlock) RawJSON() string { return r.JSON.raw } +func (r *BashCodeExecutionToolResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// BashCodeExecutionToolResultBlockContentUnion contains all possible properties +// and values from [BashCodeExecutionToolResultError], +// [BashCodeExecutionResultBlock]. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type BashCodeExecutionToolResultBlockContentUnion struct { + // This field is from variant [BashCodeExecutionToolResultError]. + ErrorCode BashCodeExecutionToolResultErrorCode `json:"error_code"` + Type string `json:"type"` + // This field is from variant [BashCodeExecutionResultBlock]. + Content []BashCodeExecutionOutputBlock `json:"content"` + // This field is from variant [BashCodeExecutionResultBlock]. + ReturnCode int64 `json:"return_code"` + // This field is from variant [BashCodeExecutionResultBlock]. + Stderr string `json:"stderr"` + // This field is from variant [BashCodeExecutionResultBlock]. + Stdout string `json:"stdout"` + JSON struct { + ErrorCode respjson.Field + Type respjson.Field + Content respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Stdout respjson.Field + raw string + } `json:"-"` +} + +func (u BashCodeExecutionToolResultBlockContentUnion) AsResponseBashCodeExecutionToolResultError() (v BashCodeExecutionToolResultError) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u BashCodeExecutionToolResultBlockContentUnion) AsResponseBashCodeExecutionResultBlock() (v BashCodeExecutionResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u BashCodeExecutionToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } + +func (r *BashCodeExecutionToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Content, ToolUseID, Type are required. +type BashCodeExecutionToolResultBlockParam struct { + Content BashCodeExecutionToolResultBlockParamContentUnion `json:"content,omitzero,required"` + ToolUseID string `json:"tool_use_id,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as + // "bash_code_execution_tool_result". + Type constant.BashCodeExecutionToolResult `json:"type,required"` + paramObj +} + +func (r BashCodeExecutionToolResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow BashCodeExecutionToolResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BashCodeExecutionToolResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type BashCodeExecutionToolResultBlockParamContentUnion struct { + OfRequestBashCodeExecutionToolResultError *BashCodeExecutionToolResultErrorParam `json:",omitzero,inline"` + OfRequestBashCodeExecutionResultBlock *BashCodeExecutionResultBlockParam `json:",omitzero,inline"` + paramUnion +} + +func (u BashCodeExecutionToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfRequestBashCodeExecutionToolResultError, u.OfRequestBashCodeExecutionResultBlock) +} +func (u *BashCodeExecutionToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *BashCodeExecutionToolResultBlockParamContentUnion) asAny() any { + if !param.IsOmitted(u.OfRequestBashCodeExecutionToolResultError) { + return u.OfRequestBashCodeExecutionToolResultError + } else if !param.IsOmitted(u.OfRequestBashCodeExecutionResultBlock) { + return u.OfRequestBashCodeExecutionResultBlock + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BashCodeExecutionToolResultBlockParamContentUnion) GetErrorCode() *string { + if vt := u.OfRequestBashCodeExecutionToolResultError; vt != nil { + return (*string)(&vt.ErrorCode) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BashCodeExecutionToolResultBlockParamContentUnion) GetContent() []BashCodeExecutionOutputBlockParam { + if vt := u.OfRequestBashCodeExecutionResultBlock; vt != nil { + return vt.Content + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BashCodeExecutionToolResultBlockParamContentUnion) GetReturnCode() *int64 { + if vt := u.OfRequestBashCodeExecutionResultBlock; vt != nil { + return &vt.ReturnCode + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BashCodeExecutionToolResultBlockParamContentUnion) GetStderr() *string { + if vt := u.OfRequestBashCodeExecutionResultBlock; vt != nil { + return &vt.Stderr + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BashCodeExecutionToolResultBlockParamContentUnion) GetStdout() *string { + if vt := u.OfRequestBashCodeExecutionResultBlock; vt != nil { + return &vt.Stdout + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u BashCodeExecutionToolResultBlockParamContentUnion) GetType() *string { + if vt := u.OfRequestBashCodeExecutionToolResultError; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRequestBashCodeExecutionResultBlock; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +type BashCodeExecutionToolResultError struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded", "output_file_too_large". + ErrorCode BashCodeExecutionToolResultErrorCode `json:"error_code,required"` + Type constant.BashCodeExecutionToolResultError `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ErrorCode respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r BashCodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } +func (r *BashCodeExecutionToolResultError) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type BashCodeExecutionToolResultErrorCode string + +const ( + BashCodeExecutionToolResultErrorCodeInvalidToolInput BashCodeExecutionToolResultErrorCode = "invalid_tool_input" + BashCodeExecutionToolResultErrorCodeUnavailable BashCodeExecutionToolResultErrorCode = "unavailable" + BashCodeExecutionToolResultErrorCodeTooManyRequests BashCodeExecutionToolResultErrorCode = "too_many_requests" + BashCodeExecutionToolResultErrorCodeExecutionTimeExceeded BashCodeExecutionToolResultErrorCode = "execution_time_exceeded" + BashCodeExecutionToolResultErrorCodeOutputFileTooLarge BashCodeExecutionToolResultErrorCode = "output_file_too_large" +) + +// The properties ErrorCode, Type are required. +type BashCodeExecutionToolResultErrorParam struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded", "output_file_too_large". + ErrorCode BashCodeExecutionToolResultErrorCode `json:"error_code,omitzero,required"` + // This field can be elided, and will marshal its zero value as + // "bash_code_execution_tool_result_error". + Type constant.BashCodeExecutionToolResultError `json:"type,required"` + paramObj +} + +func (r BashCodeExecutionToolResultErrorParam) MarshalJSON() (data []byte, err error) { + type shadow BashCodeExecutionToolResultErrorParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *BashCodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + func NewCacheControlEphemeralParam() CacheControlEphemeralParam { return CacheControlEphemeralParam{ Type: "ephemeral", @@ -178,7 +494,6 @@ func (r CacheControlEphemeralParam) MarshalJSON() (data []byte, err error) { type shadow CacheControlEphemeralParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *CacheControlEphemeralParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -214,7 +529,6 @@ type CacheCreation struct { // Returns the unmodified JSON received from the API func (r CacheCreation) RawJSON() string { return r.JSON.raw } - func (r *CacheCreation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -243,7 +557,6 @@ type CitationCharLocation struct { // Returns the unmodified JSON received from the API func (r CitationCharLocation) RawJSON() string { return r.JSON.raw } - func (r *CitationCharLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -265,7 +578,6 @@ func (r CitationCharLocationParam) MarshalJSON() (data []byte, err error) { type shadow CitationCharLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *CitationCharLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -294,7 +606,6 @@ type CitationContentBlockLocation struct { // Returns the unmodified JSON received from the API func (r CitationContentBlockLocation) RawJSON() string { return r.JSON.raw } - func (r *CitationContentBlockLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -317,7 +628,6 @@ func (r CitationContentBlockLocationParam) MarshalJSON() (data []byte, err error type shadow CitationContentBlockLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *CitationContentBlockLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -346,7 +656,6 @@ type CitationPageLocation struct { // Returns the unmodified JSON received from the API func (r CitationPageLocation) RawJSON() string { return r.JSON.raw } - func (r *CitationPageLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -368,7 +677,6 @@ func (r CitationPageLocationParam) MarshalJSON() (data []byte, err error) { type shadow CitationPageLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *CitationPageLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -392,7 +700,6 @@ func (r CitationSearchResultLocationParam) MarshalJSON() (data []byte, err error type shadow CitationSearchResultLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *CitationSearchResultLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -413,11 +720,26 @@ func (r CitationWebSearchResultLocationParam) MarshalJSON() (data []byte, err er type shadow CitationWebSearchResultLocationParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *CitationWebSearchResultLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +type CitationsConfig struct { + Enabled bool `json:"enabled,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Enabled respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r CitationsConfig) RawJSON() string { return r.JSON.raw } +func (r *CitationsConfig) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + type CitationsConfigParam struct { Enabled param.Opt[bool] `json:"enabled,omitzero"` paramObj @@ -427,7 +749,6 @@ func (r CitationsConfigParam) MarshalJSON() (data []byte, err error) { type shadow CitationsConfigParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *CitationsConfigParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -446,7 +767,6 @@ type CitationsDelta struct { // Returns the unmodified JSON received from the API func (r CitationsDelta) RawJSON() string { return r.JSON.raw } - func (r *CitationsDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -548,27 +868,27 @@ func (u CitationsDeltaCitationUnion) AsAny() anyCitationsDeltaCitation { func (u CitationsDeltaCitationUnion) AsCharLocation() (v CitationCharLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u CitationsDeltaCitationUnion) AsPageLocation() (v CitationPageLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u CitationsDeltaCitationUnion) AsContentBlockLocation() (v CitationContentBlockLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u CitationsDeltaCitationUnion) AsWebSearchResultLocation() (v CitationsWebSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u CitationsDeltaCitationUnion) AsSearchResultLocation() (v CitationsSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -602,7 +922,6 @@ type CitationsSearchResultLocation struct { // Returns the unmodified JSON received from the API func (r CitationsSearchResultLocation) RawJSON() string { return r.JSON.raw } - func (r *CitationsSearchResultLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -627,791 +946,820 @@ type CitationsWebSearchResultLocation struct { // Returns the unmodified JSON received from the API func (r CitationsWebSearchResultLocation) RawJSON() string { return r.JSON.raw } - func (r *CitationsWebSearchResultLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// ContentBlockUnion contains all possible properties and values from [TextBlock], -// [ThinkingBlock], [RedactedThinkingBlock], [ToolUseBlock], [ServerToolUseBlock], -// [WebSearchToolResultBlock]. -// -// Use the [ContentBlockUnion.AsAny] method to switch on the variant. -// -// Use the methods beginning with 'As' to cast the union to one of its variants. -type ContentBlockUnion struct { - // This field is from variant [TextBlock]. - Citations []TextCitationUnion `json:"citations"` - // This field is from variant [TextBlock]. - Text string `json:"text"` - // Any of "text", "thinking", "redacted_thinking", "tool_use", "server_tool_use", - // "web_search_tool_result". - Type string `json:"type"` - // This field is from variant [ThinkingBlock]. - Signature string `json:"signature"` - // This field is from variant [ThinkingBlock]. - Thinking string `json:"thinking"` - // This field is from variant [RedactedThinkingBlock]. - Data string `json:"data"` - ID string `json:"id"` - // necessary custom code modification - Input json.RawMessage `json:"input"` - Name string `json:"name"` - // This field is from variant [WebSearchToolResultBlock]. - Content WebSearchToolResultBlockContentUnion `json:"content"` - // This field is from variant [WebSearchToolResultBlock]. - ToolUseID string `json:"tool_use_id"` - JSON struct { - Citations respjson.Field - Text respjson.Field - Type respjson.Field - Signature respjson.Field - Thinking respjson.Field - Data respjson.Field - ID respjson.Field - Input respjson.Field - Name respjson.Field - Content respjson.Field - ToolUseID respjson.Field - raw string +type CodeExecutionOutputBlock struct { + FileID string `json:"file_id,required"` + Type constant.CodeExecutionOutput `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + FileID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string } `json:"-"` } -func (r ContentBlockUnion) ToParam() ContentBlockParamUnion { - switch variant := r.AsAny().(type) { - case TextBlock: - p := variant.ToParam() - return ContentBlockParamUnion{OfText: &p} - case ToolUseBlock: - p := variant.ToParam() - return ContentBlockParamUnion{OfToolUse: &p} - case ThinkingBlock: - p := variant.ToParam() - return ContentBlockParamUnion{OfThinking: &p} - case RedactedThinkingBlock: - p := variant.ToParam() - return ContentBlockParamUnion{OfRedactedThinking: &p} - } - return ContentBlockParamUnion{} +// Returns the unmodified JSON received from the API +func (r CodeExecutionOutputBlock) RawJSON() string { return r.JSON.raw } +func (r *CodeExecutionOutputBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// anyContentBlock is implemented by each variant of [ContentBlockUnion] to add -// type safety for the return type of [ContentBlockUnion.AsAny] -type anyContentBlock interface { - implContentBlockUnion() +// The properties FileID, Type are required. +type CodeExecutionOutputBlockParam struct { + FileID string `json:"file_id,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_output". + Type constant.CodeExecutionOutput `json:"type,required"` + paramObj } -func (TextBlock) implContentBlockUnion() {} -func (ThinkingBlock) implContentBlockUnion() {} -func (RedactedThinkingBlock) implContentBlockUnion() {} -func (ToolUseBlock) implContentBlockUnion() {} -func (ServerToolUseBlock) implContentBlockUnion() {} -func (WebSearchToolResultBlock) implContentBlockUnion() {} - -// Use the following switch statement to find the correct variant -// -// switch variant := ContentBlockUnion.AsAny().(type) { -// case anthropic.TextBlock: -// case anthropic.ThinkingBlock: -// case anthropic.RedactedThinkingBlock: -// case anthropic.ToolUseBlock: -// case anthropic.ServerToolUseBlock: -// case anthropic.WebSearchToolResultBlock: -// default: -// fmt.Errorf("no variant present") -// } -func (u ContentBlockUnion) AsAny() anyContentBlock { - switch u.Type { - case "text": - return u.AsText() - case "thinking": - return u.AsThinking() - case "redacted_thinking": - return u.AsRedactedThinking() - case "tool_use": - return u.AsToolUse() - case "server_tool_use": - return u.AsServerToolUse() - case "web_search_tool_result": - return u.AsWebSearchToolResult() - } - return nil +func (r CodeExecutionOutputBlockParam) MarshalJSON() (data []byte, err error) { + type shadow CodeExecutionOutputBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *CodeExecutionOutputBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u ContentBlockUnion) AsText() (v TextBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +type CodeExecutionResultBlock struct { + Content []CodeExecutionOutputBlock `json:"content,required"` + ReturnCode int64 `json:"return_code,required"` + Stderr string `json:"stderr,required"` + Stdout string `json:"stdout,required"` + Type constant.CodeExecutionResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Stdout respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -func (u ContentBlockUnion) AsThinking() (v ThinkingBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// Returns the unmodified JSON received from the API +func (r CodeExecutionResultBlock) RawJSON() string { return r.JSON.raw } +func (r *CodeExecutionResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u ContentBlockUnion) AsRedactedThinking() (v RedactedThinkingBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// The properties Content, ReturnCode, Stderr, Stdout, Type are required. +type CodeExecutionResultBlockParam struct { + Content []CodeExecutionOutputBlockParam `json:"content,omitzero,required"` + ReturnCode int64 `json:"return_code,required"` + Stderr string `json:"stderr,required"` + Stdout string `json:"stdout,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_result". + Type constant.CodeExecutionResult `json:"type,required"` + paramObj } -func (u ContentBlockUnion) AsToolUse() (v ToolUseBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (r CodeExecutionResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow CodeExecutionResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *CodeExecutionResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u ContentBlockUnion) AsServerToolUse() (v ServerToolUseBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// The properties Name, Type are required. +type CodeExecutionTool20250522Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "code_execution". + Name constant.CodeExecution `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_20250522". + Type constant.CodeExecution20250522 `json:"type,required"` + paramObj } -func (u ContentBlockUnion) AsWebSearchToolResult() (v WebSearchToolResultBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (r CodeExecutionTool20250522Param) MarshalJSON() (data []byte, err error) { + type shadow CodeExecutionTool20250522Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *CodeExecutionTool20250522Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns the unmodified JSON received from the API -func (u ContentBlockUnion) RawJSON() string { return u.JSON.raw } +// The properties Name, Type are required. +type CodeExecutionTool20250825Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "code_execution". + Name constant.CodeExecution `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_20250825". + Type constant.CodeExecution20250825 `json:"type,required"` + paramObj +} -func (r *ContentBlockUnion) UnmarshalJSON(data []byte) error { +func (r CodeExecutionTool20250825Param) MarshalJSON() (data []byte, err error) { + type shadow CodeExecutionTool20250825Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *CodeExecutionTool20250825Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func NewTextBlock(text string) ContentBlockParamUnion { - var variant TextBlockParam - variant.Text = text - return ContentBlockParamUnion{OfText: &variant} +// Code execution tool with REPL state persistence (daemon mode + gVisor +// checkpoint). +// +// The properties Name, Type are required. +type CodeExecutionTool20260120Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "code_execution". + Name constant.CodeExecution `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_20260120". + Type constant.CodeExecution20260120 `json:"type,required"` + paramObj } -func NewImageBlock[T Base64ImageSourceParam | URLImageSourceParam](source T) ContentBlockParamUnion { - var image ImageBlockParam - switch v := any(source).(type) { - case Base64ImageSourceParam: - image.Source.OfBase64 = &v - case URLImageSourceParam: - image.Source.OfURL = &v - } - return ContentBlockParamUnion{OfImage: &image} +func (r CodeExecutionTool20260120Param) MarshalJSON() (data []byte, err error) { + type shadow CodeExecutionTool20260120Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *CodeExecutionTool20260120Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func NewImageBlockBase64(mediaType string, encodedData string) ContentBlockParamUnion { - return ContentBlockParamUnion{ - OfImage: &ImageBlockParam{ - Source: ImageBlockParamSourceUnion{ - OfBase64: &Base64ImageSourceParam{ - Data: encodedData, - MediaType: Base64ImageSourceMediaType(mediaType), - }, - }, - }, - } +type CodeExecutionToolResultBlock struct { + // Code execution result with encrypted stdout for PFC + web_search results. + Content CodeExecutionToolResultBlockContentUnion `json:"content,required"` + ToolUseID string `json:"tool_use_id,required"` + Type constant.CodeExecutionToolResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + ToolUseID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -func NewDocumentBlock[ - T Base64PDFSourceParam | PlainTextSourceParam | ContentBlockSourceParam | URLPDFSourceParam, -](source T) ContentBlockParamUnion { - var document DocumentBlockParam - switch v := any(source).(type) { - case Base64PDFSourceParam: - document.Source.OfBase64 = &v - case PlainTextSourceParam: - document.Source.OfText = &v - case ContentBlockSourceParam: - document.Source.OfContent = &v - case URLPDFSourceParam: - document.Source.OfURL = &v - } - return ContentBlockParamUnion{OfDocument: &document} +// Returns the unmodified JSON received from the API +func (r CodeExecutionToolResultBlock) RawJSON() string { return r.JSON.raw } +func (r *CodeExecutionToolResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func NewSearchResultBlock(content []TextBlockParam, source string, title string) ContentBlockParamUnion { - var searchResult SearchResultBlockParam - searchResult.Content = content - searchResult.Source = source - searchResult.Title = title - return ContentBlockParamUnion{OfSearchResult: &searchResult} +// CodeExecutionToolResultBlockContentUnion contains all possible properties and +// values from [CodeExecutionToolResultError], [CodeExecutionResultBlock], +// [EncryptedCodeExecutionResultBlock]. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type CodeExecutionToolResultBlockContentUnion struct { + // This field is from variant [CodeExecutionToolResultError]. + ErrorCode CodeExecutionToolResultErrorCode `json:"error_code"` + Type string `json:"type"` + Content []CodeExecutionOutputBlock `json:"content"` + ReturnCode int64 `json:"return_code"` + Stderr string `json:"stderr"` + // This field is from variant [CodeExecutionResultBlock]. + Stdout string `json:"stdout"` + // This field is from variant [EncryptedCodeExecutionResultBlock]. + EncryptedStdout string `json:"encrypted_stdout"` + JSON struct { + ErrorCode respjson.Field + Type respjson.Field + Content respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Stdout respjson.Field + EncryptedStdout respjson.Field + raw string + } `json:"-"` } -func NewThinkingBlock(signature string, thinking string) ContentBlockParamUnion { - var variant ThinkingBlockParam - variant.Signature = signature - variant.Thinking = thinking - return ContentBlockParamUnion{OfThinking: &variant} +func (u CodeExecutionToolResultBlockContentUnion) AsResponseCodeExecutionToolResultError() (v CodeExecutionToolResultError) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func NewRedactedThinkingBlock(data string) ContentBlockParamUnion { - var redactedThinking RedactedThinkingBlockParam - redactedThinking.Data = data - return ContentBlockParamUnion{OfRedactedThinking: &redactedThinking} +func (u CodeExecutionToolResultBlockContentUnion) AsResponseCodeExecutionResultBlock() (v CodeExecutionResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func NewToolUseBlock(id string, input any, name string) ContentBlockParamUnion { - var toolUse ToolUseBlockParam - toolUse.ID = id - toolUse.Input = input - toolUse.Name = name - return ContentBlockParamUnion{OfToolUse: &toolUse} +func (u CodeExecutionToolResultBlockContentUnion) AsResponseEncryptedCodeExecutionResultBlock() (v EncryptedCodeExecutionResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func NewToolResultBlock(toolUseID string, content string, isError bool) ContentBlockParamUnion { - toolBlock := ToolResultBlockParam{ - ToolUseID: toolUseID, - Content: []ToolResultBlockParamContentUnion{ - {OfText: &TextBlockParam{Text: content}}, - }, - IsError: Bool(isError), - } - return ContentBlockParamUnion{OfToolResult: &toolBlock} +// Returns the unmodified JSON received from the API +func (u CodeExecutionToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } + +func (r *CodeExecutionToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func NewServerToolUseBlock(id string, input any) ContentBlockParamUnion { - var serverToolUse ServerToolUseBlockParam - serverToolUse.ID = id - serverToolUse.Input = input - return ContentBlockParamUnion{OfServerToolUse: &serverToolUse} +// The properties Content, ToolUseID, Type are required. +type CodeExecutionToolResultBlockParam struct { + // Code execution result with encrypted stdout for PFC + web_search results. + Content CodeExecutionToolResultBlockParamContentUnion `json:"content,omitzero,required"` + ToolUseID string `json:"tool_use_id,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as + // "code_execution_tool_result". + Type constant.CodeExecutionToolResult `json:"type,required"` + paramObj } -func NewWebSearchToolResultBlock[ - T []WebSearchResultBlockParam | WebSearchToolRequestErrorParam, -](content T, toolUseID string) ContentBlockParamUnion { - var webSearchToolResult WebSearchToolResultBlockParam - switch v := any(content).(type) { - case []WebSearchResultBlockParam: - webSearchToolResult.Content.OfWebSearchToolResultBlockItem = v - case WebSearchToolRequestErrorParam: - webSearchToolResult.Content.OfRequestWebSearchToolResultError = &v - } - webSearchToolResult.ToolUseID = toolUseID - return ContentBlockParamUnion{OfWebSearchToolResult: &webSearchToolResult} +func (r CodeExecutionToolResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow CodeExecutionToolResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *CodeExecutionToolResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +func CodeExecutionToolResultBlockParamContentOfRequestCodeExecutionToolResultError(errorCode CodeExecutionToolResultErrorCode) CodeExecutionToolResultBlockParamContentUnion { + var variant CodeExecutionToolResultErrorParam + variant.ErrorCode = errorCode + return CodeExecutionToolResultBlockParamContentUnion{OfRequestCodeExecutionToolResultError: &variant} } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. -type ContentBlockParamUnion struct { - OfText *TextBlockParam `json:",omitzero,inline"` - OfImage *ImageBlockParam `json:",omitzero,inline"` - OfDocument *DocumentBlockParam `json:",omitzero,inline"` - OfSearchResult *SearchResultBlockParam `json:",omitzero,inline"` - OfThinking *ThinkingBlockParam `json:",omitzero,inline"` - OfRedactedThinking *RedactedThinkingBlockParam `json:",omitzero,inline"` - OfToolUse *ToolUseBlockParam `json:",omitzero,inline"` - OfToolResult *ToolResultBlockParam `json:",omitzero,inline"` - OfServerToolUse *ServerToolUseBlockParam `json:",omitzero,inline"` - OfWebSearchToolResult *WebSearchToolResultBlockParam `json:",omitzero,inline"` +type CodeExecutionToolResultBlockParamContentUnion struct { + OfRequestCodeExecutionToolResultError *CodeExecutionToolResultErrorParam `json:",omitzero,inline"` + OfRequestCodeExecutionResultBlock *CodeExecutionResultBlockParam `json:",omitzero,inline"` + OfRequestEncryptedCodeExecutionResultBlock *EncryptedCodeExecutionResultBlockParam `json:",omitzero,inline"` paramUnion } -func (u ContentBlockParamUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfText, - u.OfImage, - u.OfDocument, - u.OfSearchResult, - u.OfThinking, - u.OfRedactedThinking, - u.OfToolUse, - u.OfToolResult, - u.OfServerToolUse, - u.OfWebSearchToolResult) +func (u CodeExecutionToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfRequestCodeExecutionToolResultError, u.OfRequestCodeExecutionResultBlock, u.OfRequestEncryptedCodeExecutionResultBlock) } - -func (u *ContentBlockParamUnion) UnmarshalJSON(data []byte) error { +func (u *CodeExecutionToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } -func (u *ContentBlockParamUnion) asAny() any { - if !param.IsOmitted(u.OfText) { - return u.OfText - } else if !param.IsOmitted(u.OfImage) { - return u.OfImage - } else if !param.IsOmitted(u.OfDocument) { - return u.OfDocument - } else if !param.IsOmitted(u.OfSearchResult) { - return u.OfSearchResult - } else if !param.IsOmitted(u.OfThinking) { - return u.OfThinking - } else if !param.IsOmitted(u.OfRedactedThinking) { - return u.OfRedactedThinking - } else if !param.IsOmitted(u.OfToolUse) { - return u.OfToolUse - } else if !param.IsOmitted(u.OfToolResult) { - return u.OfToolResult - } else if !param.IsOmitted(u.OfServerToolUse) { - return u.OfServerToolUse - } else if !param.IsOmitted(u.OfWebSearchToolResult) { - return u.OfWebSearchToolResult +func (u *CodeExecutionToolResultBlockParamContentUnion) asAny() any { + if !param.IsOmitted(u.OfRequestCodeExecutionToolResultError) { + return u.OfRequestCodeExecutionToolResultError + } else if !param.IsOmitted(u.OfRequestCodeExecutionResultBlock) { + return u.OfRequestCodeExecutionResultBlock + } else if !param.IsOmitted(u.OfRequestEncryptedCodeExecutionResultBlock) { + return u.OfRequestEncryptedCodeExecutionResultBlock } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetText() *string { - if vt := u.OfText; vt != nil { - return &vt.Text +func (u CodeExecutionToolResultBlockParamContentUnion) GetErrorCode() *string { + if vt := u.OfRequestCodeExecutionToolResultError; vt != nil { + return (*string)(&vt.ErrorCode) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetContext() *string { - if vt := u.OfDocument; vt != nil && vt.Context.Valid() { - return &vt.Context.Value - } - return nil -} - -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetSignature() *string { - if vt := u.OfThinking; vt != nil { - return &vt.Signature - } - return nil -} - -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetThinking() *string { - if vt := u.OfThinking; vt != nil { - return &vt.Thinking - } - return nil -} - -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetData() *string { - if vt := u.OfRedactedThinking; vt != nil { - return &vt.Data +func (u CodeExecutionToolResultBlockParamContentUnion) GetStdout() *string { + if vt := u.OfRequestCodeExecutionResultBlock; vt != nil { + return &vt.Stdout } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetIsError() *bool { - if vt := u.OfToolResult; vt != nil && vt.IsError.Valid() { - return &vt.IsError.Value +func (u CodeExecutionToolResultBlockParamContentUnion) GetEncryptedStdout() *string { + if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return &vt.EncryptedStdout } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetType() *string { - if vt := u.OfText; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfImage; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfDocument; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfSearchResult; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfThinking; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfRedactedThinking; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfToolUse; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfToolResult; vt != nil { +func (u CodeExecutionToolResultBlockParamContentUnion) GetType() *string { + if vt := u.OfRequestCodeExecutionToolResultError; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfServerToolUse; vt != nil { + } else if vt := u.OfRequestCodeExecutionResultBlock; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfWebSearchToolResult; vt != nil { + } else if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { return (*string)(&vt.Type) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetTitle() *string { - if vt := u.OfDocument; vt != nil && vt.Title.Valid() { - return &vt.Title.Value - } else if vt := u.OfSearchResult; vt != nil { - return (*string)(&vt.Title) - } - return nil -} - -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetID() *string { - if vt := u.OfToolUse; vt != nil { - return (*string)(&vt.ID) - } else if vt := u.OfServerToolUse; vt != nil { - return (*string)(&vt.ID) +func (u CodeExecutionToolResultBlockParamContentUnion) GetReturnCode() *int64 { + if vt := u.OfRequestCodeExecutionResultBlock; vt != nil { + return (*int64)(&vt.ReturnCode) + } else if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return (*int64)(&vt.ReturnCode) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetName() *string { - if vt := u.OfToolUse; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfServerToolUse; vt != nil { - return (*string)(&vt.Name) +func (u CodeExecutionToolResultBlockParamContentUnion) GetStderr() *string { + if vt := u.OfRequestCodeExecutionResultBlock; vt != nil { + return (*string)(&vt.Stderr) + } else if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return (*string)(&vt.Stderr) } return nil } -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockParamUnion) GetToolUseID() *string { - if vt := u.OfToolResult; vt != nil { - return (*string)(&vt.ToolUseID) - } else if vt := u.OfWebSearchToolResult; vt != nil { - return (*string)(&vt.ToolUseID) +// Returns a pointer to the underlying variant's Content property, if present. +func (u CodeExecutionToolResultBlockParamContentUnion) GetContent() []CodeExecutionOutputBlockParam { + if vt := u.OfRequestCodeExecutionResultBlock; vt != nil { + return vt.Content + } else if vt := u.OfRequestEncryptedCodeExecutionResultBlock; vt != nil { + return vt.Content } return nil } -// Returns a pointer to the underlying variant's CacheControl property, if present. -func (u ContentBlockParamUnion) GetCacheControl() *CacheControlEphemeralParam { - if vt := u.OfText; vt != nil { - return &vt.CacheControl - } else if vt := u.OfImage; vt != nil { - return &vt.CacheControl - } else if vt := u.OfDocument; vt != nil { - return &vt.CacheControl - } else if vt := u.OfSearchResult; vt != nil { - return &vt.CacheControl - } else if vt := u.OfToolUse; vt != nil { - return &vt.CacheControl - } else if vt := u.OfToolResult; vt != nil { - return &vt.CacheControl - } else if vt := u.OfServerToolUse; vt != nil { - return &vt.CacheControl - } else if vt := u.OfWebSearchToolResult; vt != nil { - return &vt.CacheControl - } - return nil +type CodeExecutionToolResultError struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded". + ErrorCode CodeExecutionToolResultErrorCode `json:"error_code,required"` + Type constant.CodeExecutionToolResultError `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ErrorCode respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -// Returns a subunion which exports methods to access subproperties -// -// Or use AsAny() to get the underlying value -func (u ContentBlockParamUnion) GetCitations() (res contentBlockParamUnionCitations) { - if vt := u.OfText; vt != nil { - res.any = &vt.Citations - } else if vt := u.OfDocument; vt != nil { - res.any = &vt.Citations - } else if vt := u.OfSearchResult; vt != nil { - res.any = &vt.Citations - } - return res +// Returns the unmodified JSON received from the API +func (r CodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } +func (r *CodeExecutionToolResultError) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Can have the runtime types [*[]TextCitationParamUnion], [*CitationsConfigParam] -type contentBlockParamUnionCitations struct{ any } +type CodeExecutionToolResultErrorCode string -// Use the following switch statement to get the type of the union: -// -// switch u.AsAny().(type) { -// case *[]anthropic.TextCitationParamUnion: -// case *anthropic.CitationsConfigParam: -// default: -// fmt.Errorf("not present") -// } -func (u contentBlockParamUnionCitations) AsAny() any { return u.any } +const ( + CodeExecutionToolResultErrorCodeInvalidToolInput CodeExecutionToolResultErrorCode = "invalid_tool_input" + CodeExecutionToolResultErrorCodeUnavailable CodeExecutionToolResultErrorCode = "unavailable" + CodeExecutionToolResultErrorCodeTooManyRequests CodeExecutionToolResultErrorCode = "too_many_requests" + CodeExecutionToolResultErrorCodeExecutionTimeExceeded CodeExecutionToolResultErrorCode = "execution_time_exceeded" +) -// Returns a pointer to the underlying variant's property, if present. -func (u contentBlockParamUnionCitations) GetEnabled() *bool { - switch vt := u.any.(type) { - case *CitationsConfigParam: - return paramutil.AddrIfPresent(vt.Enabled) - } - return nil +// The properties ErrorCode, Type are required. +type CodeExecutionToolResultErrorParam struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded". + ErrorCode CodeExecutionToolResultErrorCode `json:"error_code,omitzero,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_tool_result_error". + Type constant.CodeExecutionToolResultError `json:"type,required"` + paramObj } -// Returns a subunion which exports methods to access subproperties -// -// Or use AsAny() to get the underlying value -func (u ContentBlockParamUnion) GetSource() (res contentBlockParamUnionSource) { - if vt := u.OfImage; vt != nil { - res.any = vt.Source.asAny() - } else if vt := u.OfDocument; vt != nil { - res.any = vt.Source.asAny() - } else if vt := u.OfSearchResult; vt != nil { - res.any = &vt.Source - } - return res +func (r CodeExecutionToolResultErrorParam) MarshalJSON() (data []byte, err error) { + type shadow CodeExecutionToolResultErrorParam + return param.MarshalObject(r, (*shadow)(&r)) } - -// Can have the runtime types [*Base64ImageSourceParam], [*URLImageSourceParam], -// [*Base64PDFSourceParam], [*PlainTextSourceParam], [*ContentBlockSourceParam], -// [*URLPDFSourceParam], [*string] -type contentBlockParamUnionSource struct{ any } - -// Use the following switch statement to get the type of the union: -// -// switch u.AsAny().(type) { -// case *anthropic.Base64ImageSourceParam: -// case *anthropic.URLImageSourceParam: -// case *anthropic.Base64PDFSourceParam: -// case *anthropic.PlainTextSourceParam: -// case *anthropic.ContentBlockSourceParam: -// case *anthropic.URLPDFSourceParam: -// case *string: -// default: -// fmt.Errorf("not present") -// } -func (u contentBlockParamUnionSource) AsAny() any { return u.any } - -// Returns a pointer to the underlying variant's property, if present. -func (u contentBlockParamUnionSource) GetContent() *ContentBlockSourceContentUnionParam { - switch vt := u.any.(type) { - case *DocumentBlockParamSourceUnion: - return vt.GetContent() - } - return nil +func (r *CodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns a pointer to the underlying variant's property, if present. -func (u contentBlockParamUnionSource) GetData() *string { - switch vt := u.any.(type) { - case *ImageBlockParamSourceUnion: - return vt.GetData() - case *DocumentBlockParamSourceUnion: - return vt.GetData() - } - return nil +// Information about the container used in the request (for the code execution +// tool) +type Container struct { + // Identifier for the container used in this request + ID string `json:"id,required"` + // The time at which the container will expire. + ExpiresAt time.Time `json:"expires_at,required" format:"date-time"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + ExpiresAt respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -// Returns a pointer to the underlying variant's property, if present. -func (u contentBlockParamUnionSource) GetMediaType() *string { - switch vt := u.any.(type) { - case *ImageBlockParamSourceUnion: - return vt.GetMediaType() - case *DocumentBlockParamSourceUnion: - return vt.GetMediaType() - } - return nil +// Returns the unmodified JSON received from the API +func (r Container) RawJSON() string { return r.JSON.raw } +func (r *Container) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns a pointer to the underlying variant's property, if present. -func (u contentBlockParamUnionSource) GetType() *string { - switch vt := u.any.(type) { - case *ImageBlockParamSourceUnion: - return vt.GetType() - case *DocumentBlockParamSourceUnion: - return vt.GetType() - } - return nil +// Response model for a file uploaded to the container. +type ContainerUploadBlock struct { + FileID string `json:"file_id,required"` + Type constant.ContainerUpload `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + FileID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -// Returns a pointer to the underlying variant's property, if present. -func (u contentBlockParamUnionSource) GetURL() *string { - switch vt := u.any.(type) { - case *ImageBlockParamSourceUnion: - return vt.GetURL() - case *DocumentBlockParamSourceUnion: - return vt.GetURL() - } - return nil +// Returns the unmodified JSON received from the API +func (r ContainerUploadBlock) RawJSON() string { return r.JSON.raw } +func (r *ContainerUploadBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns a subunion which exports methods to access subproperties +// A content block that represents a file to be uploaded to the container Files +// uploaded via this block will be available in the container's input directory. // -// Or use AsAny() to get the underlying value -func (u ContentBlockParamUnion) GetContent() (res contentBlockParamUnionContent) { - if vt := u.OfSearchResult; vt != nil { - res.any = &vt.Content - } else if vt := u.OfToolResult; vt != nil { - res.any = &vt.Content - } else if vt := u.OfWebSearchToolResult; vt != nil { - res.any = vt.Content.asAny() - } - return res +// The properties FileID, Type are required. +type ContainerUploadBlockParam struct { + FileID string `json:"file_id,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as "container_upload". + Type constant.ContainerUpload `json:"type,required"` + paramObj } -// Can have the runtime types [_[]TextBlockParam], -// [_[]ToolResultBlockParamContentUnion], [\*[]WebSearchResultBlockParam] -type contentBlockParamUnionContent struct{ any } +func (r ContainerUploadBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ContainerUploadBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ContainerUploadBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -// Use the following switch statement to get the type of the union: -// -// switch u.AsAny().(type) { -// case *[]anthropic.TextBlockParam: -// case *[]anthropic.ToolResultBlockParamContentUnion: -// case *[]anthropic.WebSearchResultBlockParam: +// ContentBlockUnion contains all possible properties and values from [TextBlock], +// [ThinkingBlock], [RedactedThinkingBlock], [ToolUseBlock], [ServerToolUseBlock], +// [WebSearchToolResultBlock], [WebFetchToolResultBlock], +// [CodeExecutionToolResultBlock], [BashCodeExecutionToolResultBlock], +// [TextEditorCodeExecutionToolResultBlock], [ToolSearchToolResultBlock], +// [ContainerUploadBlock]. +// +// Use the [ContentBlockUnion.AsAny] method to switch on the variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type ContentBlockUnion struct { + // This field is from variant [TextBlock]. + Citations []TextCitationUnion `json:"citations"` + // This field is from variant [TextBlock]. + Text string `json:"text"` + // Any of "text", "thinking", "redacted_thinking", "tool_use", "server_tool_use", + // "web_search_tool_result", "web_fetch_tool_result", "code_execution_tool_result", + // "bash_code_execution_tool_result", "text_editor_code_execution_tool_result", + // "tool_search_tool_result", "container_upload". + Type string `json:"type"` + // This field is from variant [ThinkingBlock]. + Signature string `json:"signature"` + // This field is from variant [ThinkingBlock]. + Thinking string `json:"thinking"` + // This field is from variant [RedactedThinkingBlock]. + Data string `json:"data"` + ID string `json:"id"` + // necessary custom code modification + Input json.RawMessage `json:"input"` + Name string `json:"name"` + // This field is from variant [WebSearchToolResultBlock]. + Content WebSearchToolResultBlockContentUnion `json:"content"` + // This field is from variant [WebSearchToolResultBlock]. + ToolUseID string `json:"tool_use_id"` + JSON struct { + Citations respjson.Field + Text respjson.Field + Type respjson.Field + Signature respjson.Field + Thinking respjson.Field + Data respjson.Field + ID respjson.Field + Caller respjson.Field + Input respjson.Field + Name respjson.Field + Content respjson.Field + ToolUseID respjson.Field + FileID respjson.Field + raw string + } `json:"-"` +} + +// anyContentBlock is implemented by each variant of [ContentBlockUnion] to add +// type safety for the return type of [ContentBlockUnion.AsAny] +type anyContentBlock interface { + implContentBlockUnion() + toParamUnion() ContentBlockParamUnion +} + +func (TextBlock) implContentBlockUnion() {} +func (ThinkingBlock) implContentBlockUnion() {} +func (RedactedThinkingBlock) implContentBlockUnion() {} +func (ToolUseBlock) implContentBlockUnion() {} +func (ServerToolUseBlock) implContentBlockUnion() {} +func (WebSearchToolResultBlock) implContentBlockUnion() {} +func (WebFetchToolResultBlock) implContentBlockUnion() {} +func (CodeExecutionToolResultBlock) implContentBlockUnion() {} +func (BashCodeExecutionToolResultBlock) implContentBlockUnion() {} +func (TextEditorCodeExecutionToolResultBlock) implContentBlockUnion() {} +func (ToolSearchToolResultBlock) implContentBlockUnion() {} +func (ContainerUploadBlock) implContentBlockUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := ContentBlockUnion.AsAny().(type) { +// case anthropic.TextBlock: +// case anthropic.ThinkingBlock: +// case anthropic.RedactedThinkingBlock: +// case anthropic.ToolUseBlock: +// case anthropic.ServerToolUseBlock: +// case anthropic.WebSearchToolResultBlock: +// case anthropic.WebFetchToolResultBlock: +// case anthropic.CodeExecutionToolResultBlock: +// case anthropic.BashCodeExecutionToolResultBlock: +// case anthropic.TextEditorCodeExecutionToolResultBlock: +// case anthropic.ToolSearchToolResultBlock: +// case anthropic.ContainerUploadBlock: // default: -// fmt.Errorf("not present") +// fmt.Errorf("no variant present") // } -func (u contentBlockParamUnionContent) AsAny() any { return u.any } - -// Returns a pointer to the underlying variant's Input property, if present. -func (u ContentBlockParamUnion) GetInput() *any { - if vt := u.OfToolUse; vt != nil { - return &vt.Input - } else if vt := u.OfServerToolUse; vt != nil { - return &vt.Input +func (u ContentBlockUnion) AsAny() anyContentBlock { + switch u.Type { + case "text": + return u.AsText() + case "thinking": + return u.AsThinking() + case "redacted_thinking": + return u.AsRedactedThinking() + case "tool_use": + return u.AsToolUse() + case "server_tool_use": + return u.AsServerToolUse() + case "web_search_tool_result": + return u.AsWebSearchToolResult() + case "web_fetch_tool_result": + return u.AsWebFetchToolResult() + case "code_execution_tool_result": + return u.AsCodeExecutionToolResult() + case "bash_code_execution_tool_result": + return u.AsBashCodeExecutionToolResult() + case "text_editor_code_execution_tool_result": + return u.AsTextEditorCodeExecutionToolResult() + case "tool_search_tool_result": + return u.AsToolSearchToolResult() + case "container_upload": + return u.AsContainerUpload() } return nil } -func init() { - apijson.RegisterUnion[ContentBlockParamUnion]( - "type", - apijson.Discriminator[TextBlockParam]("text"), - apijson.Discriminator[ImageBlockParam]("image"), - apijson.Discriminator[DocumentBlockParam]("document"), - apijson.Discriminator[SearchResultBlockParam]("search_result"), - apijson.Discriminator[ThinkingBlockParam]("thinking"), - apijson.Discriminator[RedactedThinkingBlockParam]("redacted_thinking"), - apijson.Discriminator[ToolUseBlockParam]("tool_use"), - apijson.Discriminator[ToolResultBlockParam]("tool_result"), - apijson.Discriminator[ServerToolUseBlockParam]("server_tool_use"), - apijson.Discriminator[WebSearchToolResultBlockParam]("web_search_tool_result"), - ) - - // Register custom decoder for []ContentBlockParamUnion to handle string content - apijson.RegisterCustomDecoder[[]ContentBlockParamUnion](func(node gjson.Result, value reflect.Value, defaultDecoder func(gjson.Result, reflect.Value) error) error { - // If it's a string, convert it to a TextBlock automatically - if node.Type == gjson.String { - textBlock := TextBlockParam{ - Text: node.String(), - Type: "text", - } - contentUnion := ContentBlockParamUnion{ - OfText: &textBlock, - } - arrayValue := reflect.MakeSlice(value.Type(), 1, 1) - arrayValue.Index(0).Set(reflect.ValueOf(contentUnion)) - value.Set(arrayValue) - return nil - } - - return defaultDecoder(node, value) - }) +func (u ContentBlockUnion) AsText() (v TextBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion[ContentBlockSourceContentItemUnionParam]( - "type", - apijson.Discriminator[TextBlockParam]("text"), - apijson.Discriminator[ImageBlockParam]("image"), - ) +func (u ContentBlockUnion) AsThinking() (v ThinkingBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion[DocumentBlockParamSourceUnion]( - "type", - apijson.Discriminator[Base64PDFSourceParam]("base64"), - apijson.Discriminator[PlainTextSourceParam]("text"), - apijson.Discriminator[ContentBlockSourceParam]("content"), - apijson.Discriminator[URLPDFSourceParam]("url"), - ) +func (u ContentBlockUnion) AsRedactedThinking() (v RedactedThinkingBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion[ImageBlockParamSourceUnion]( - "type", - apijson.Discriminator[Base64ImageSourceParam]("base64"), - apijson.Discriminator[URLImageSourceParam]("url"), - ) +func (u ContentBlockUnion) AsToolUse() (v ToolUseBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion[TextCitationParamUnion]( - "type", - apijson.Discriminator[CitationCharLocationParam]("char_location"), - apijson.Discriminator[CitationPageLocationParam]("page_location"), - apijson.Discriminator[CitationContentBlockLocationParam]("content_block_location"), - apijson.Discriminator[CitationWebSearchResultLocationParam]("web_search_result_location"), - apijson.Discriminator[CitationSearchResultLocationParam]("search_result_location"), - ) +func (u ContentBlockUnion) AsServerToolUse() (v ServerToolUseBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion[ThinkingConfigParamUnion]( - "type", - apijson.Discriminator[ThinkingConfigEnabledParam]("enabled"), - apijson.Discriminator[ThinkingConfigDisabledParam]("disabled"), - ) +func (u ContentBlockUnion) AsWebSearchToolResult() (v WebSearchToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion[ToolChoiceUnionParam]( - "type", - apijson.Discriminator[ToolChoiceAutoParam]("auto"), - apijson.Discriminator[ToolChoiceAnyParam]("any"), - apijson.Discriminator[ToolChoiceToolParam]("tool"), - apijson.Discriminator[ToolChoiceNoneParam]("none"), - ) +func (u ContentBlockUnion) AsWebFetchToolResult() (v WebFetchToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func init() { - apijson.RegisterUnion[ToolResultBlockParamContentUnion]( - "type", - apijson.Discriminator[TextBlockParam]("text"), - apijson.Discriminator[ImageBlockParam]("image"), - apijson.Discriminator[SearchResultBlockParam]("search_result"), - apijson.Discriminator[DocumentBlockParam]("document"), - ) +func (u ContentBlockUnion) AsCodeExecutionToolResult() (v CodeExecutionToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} - // Register custom decoder for []ToolResultBlockParamContentUnion to handle string content - apijson.RegisterCustomDecoder[[]ToolResultBlockParamContentUnion](func(node gjson.Result, value reflect.Value, defaultDecoder func(gjson.Result, reflect.Value) error) error { - // If it's a string, convert it to a TextBlock automatically - if node.Type == gjson.String { - textBlock := TextBlockParam{ - Text: node.String(), - Type: "text", - } - contentUnion := ToolResultBlockParamContentUnion{ - OfText: &textBlock, - } - arrayValue := reflect.MakeSlice(value.Type(), 1, 1) - arrayValue.Index(0).Set(reflect.ValueOf(contentUnion)) - value.Set(arrayValue) - return nil - } +func (u ContentBlockUnion) AsBashCodeExecutionToolResult() (v BashCodeExecutionToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} - // If it's already an array, use the default decoder - return defaultDecoder(node, value) - }) +func (u ContentBlockUnion) AsTextEditorCodeExecutionToolResult() (v TextEditorCodeExecutionToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// The properties Content, Type are required. -type ContentBlockSourceParam struct { - Content ContentBlockSourceContentUnionParam `json:"content,omitzero,required"` - // This field can be elided, and will marshal its zero value as "content". - Type constant.Content `json:"type,required"` - paramObj +func (u ContentBlockUnion) AsToolSearchToolResult() (v ToolSearchToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r ContentBlockSourceParam) MarshalJSON() (data []byte, err error) { - type shadow ContentBlockSourceParam - return param.MarshalObject(r, (*shadow)(&r)) +func (u ContentBlockUnion) AsContainerUpload() (v ContainerUploadBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r *ContentBlockSourceParam) UnmarshalJSON(data []byte) error { +// Returns the unmodified JSON received from the API +func (u ContentBlockUnion) RawJSON() string { return u.JSON.raw } + +func (r *ContentBlockUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Only one field can be non-zero. +// ContentBlockUnionCaller is an implicit subunion of [ContentBlockUnion]. +// ContentBlockUnionCaller provides convenient access to the sub-properties of the +// union. // -// Use [param.IsOmitted] to confirm if a field is set. -type ContentBlockSourceContentUnionParam struct { - OfString param.Opt[string] `json:",omitzero,inline"` - OfContentBlockSourceContent []ContentBlockSourceContentItemUnionParam `json:",omitzero,inline"` - paramUnion +// For type safety it is recommended to directly use a variant of the +// [ContentBlockUnion]. +type ContentBlockUnionCaller struct { + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` } -func (u ContentBlockSourceContentUnionParam) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfString, u.OfContentBlockSourceContent) +func (r *ContentBlockUnionCaller) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u *ContentBlockSourceContentUnionParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, u) +// ContentBlockUnionContent is an implicit subunion of [ContentBlockUnion]. +// ContentBlockUnionContent provides convenient access to the sub-properties of the +// union. +// +// For type safety it is recommended to directly use a variant of the +// [ContentBlockUnion]. +// +// If the underlying value is not a json object, one of the following properties +// will be valid: OfWebSearchResultBlockArray] +type ContentBlockUnionContent struct { + // This field will be present if the value is a [[]WebSearchResultBlock] instead of + // an object. + OfWebSearchResultBlockArray []WebSearchResultBlock `json:",inline"` + ErrorCode string `json:"error_code"` + Type string `json:"type"` + // This field is a union of [DocumentBlock], [[]CodeExecutionOutputBlock], + // [[]CodeExecutionOutputBlock], [[]BashCodeExecutionOutputBlock], [string] + Content ContentBlockUnionContentContent `json:"content"` + // This field is from variant [WebFetchToolResultBlockContentUnion]. + RetrievedAt string `json:"retrieved_at"` + // This field is from variant [WebFetchToolResultBlockContentUnion]. + URL string `json:"url"` + ReturnCode int64 `json:"return_code"` + Stderr string `json:"stderr"` + Stdout string `json:"stdout"` + // This field is from variant [CodeExecutionToolResultBlockContentUnion]. + EncryptedStdout string `json:"encrypted_stdout"` + ErrorMessage string `json:"error_message"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + FileType TextEditorCodeExecutionViewResultBlockFileType `json:"file_type"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + NumLines int64 `json:"num_lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + StartLine int64 `json:"start_line"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + TotalLines int64 `json:"total_lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + IsFileUpdate bool `json:"is_file_update"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + Lines []string `json:"lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + NewLines int64 `json:"new_lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + NewStart int64 `json:"new_start"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + OldLines int64 `json:"old_lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + OldStart int64 `json:"old_start"` + // This field is from variant [ToolSearchToolResultBlockContentUnion]. + ToolReferences []ToolReferenceBlock `json:"tool_references"` + JSON struct { + OfWebSearchResultBlockArray respjson.Field + ErrorCode respjson.Field + Type respjson.Field + Content respjson.Field + RetrievedAt respjson.Field + URL respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Stdout respjson.Field + EncryptedStdout respjson.Field + ErrorMessage respjson.Field + FileType respjson.Field + NumLines respjson.Field + StartLine respjson.Field + TotalLines respjson.Field + IsFileUpdate respjson.Field + Lines respjson.Field + NewLines respjson.Field + NewStart respjson.Field + OldLines respjson.Field + OldStart respjson.Field + ToolReferences respjson.Field + raw string + } `json:"-"` } -func (u *ContentBlockSourceContentUnionParam) asAny() any { - if !param.IsOmitted(u.OfString) { - return &u.OfString.Value - } else if !param.IsOmitted(u.OfContentBlockSourceContent) { - return &u.OfContentBlockSourceContent - } - return nil +func (r *ContentBlockUnionContent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func ContentBlockSourceContentItemParamOfText(text string) ContentBlockSourceContentItemUnionParam { +// ContentBlockUnionContentContent is an implicit subunion of [ContentBlockUnion]. +// ContentBlockUnionContentContent provides convenient access to the sub-properties +// of the union. +// +// For type safety it is recommended to directly use a variant of the +// [ContentBlockUnion]. +// +// If the underlying value is not a json object, one of the following properties +// will be valid: OfContent OfString] +type ContentBlockUnionContentContent struct { + // This field will be present if the value is a [[]CodeExecutionOutputBlock] + // instead of an object. + OfContent []CodeExecutionOutputBlock `json:",inline"` + // This field will be present if the value is a [string] instead of an object. + OfString string `json:",inline"` + // This field is from variant [DocumentBlock]. + Citations CitationsConfig `json:"citations"` + // This field is from variant [DocumentBlock]. + Source DocumentBlockSourceUnion `json:"source"` + // This field is from variant [DocumentBlock]. + Title string `json:"title"` + // This field is from variant [DocumentBlock]. + Type constant.Document `json:"type"` + JSON struct { + OfContent respjson.Field + OfString respjson.Field + Citations respjson.Field + Source respjson.Field + Title respjson.Field + Type respjson.Field + raw string + } `json:"-"` +} + +func (r *ContentBlockUnionContentContent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +func NewTextBlock(text string) ContentBlockParamUnion { var variant TextBlockParam variant.Text = text - return ContentBlockSourceContentItemUnionParam{OfText: &variant} + return ContentBlockParamUnion{OfText: &variant} } -func ContentBlockSourceContentItemParamOfImage[T Base64ImageSourceParam | URLImageSourceParam](source T) ContentBlockSourceContentItemUnionParam { +func NewImageBlock[T Base64ImageSourceParam | URLImageSourceParam](source T) ContentBlockParamUnion { var image ImageBlockParam switch v := any(source).(type) { case Base64ImageSourceParam: @@ -1419,1049 +1767,1722 @@ func ContentBlockSourceContentItemParamOfImage[T Base64ImageSourceParam | URLIma case URLImageSourceParam: image.Source.OfURL = &v } - return ContentBlockSourceContentItemUnionParam{OfImage: &image} + return ContentBlockParamUnion{OfImage: &image} } -// Only one field can be non-zero. -// -// Use [param.IsOmitted] to confirm if a field is set. -type ContentBlockSourceContentItemUnionParam struct { - OfText *TextBlockParam `json:",omitzero,inline"` - OfImage *ImageBlockParam `json:",omitzero,inline"` - paramUnion +func NewImageBlockBase64(mediaType string, encodedData string) ContentBlockParamUnion { + return ContentBlockParamUnion{ + OfImage: &ImageBlockParam{ + Source: ImageBlockParamSourceUnion{ + OfBase64: &Base64ImageSourceParam{ + Data: encodedData, + MediaType: Base64ImageSourceMediaType(mediaType), + }, + }, + }, + } } -func (u ContentBlockSourceContentItemUnionParam) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfText, u.OfImage) +func NewDocumentBlock[ + T Base64PDFSourceParam | PlainTextSourceParam | ContentBlockSourceParam | URLPDFSourceParam, +](source T) ContentBlockParamUnion { + var document DocumentBlockParam + switch v := any(source).(type) { + case Base64PDFSourceParam: + document.Source.OfBase64 = &v + case PlainTextSourceParam: + document.Source.OfText = &v + case ContentBlockSourceParam: + document.Source.OfContent = &v + case URLPDFSourceParam: + document.Source.OfURL = &v + } + return ContentBlockParamUnion{OfDocument: &document} } -func (u *ContentBlockSourceContentItemUnionParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, u) +func NewSearchResultBlock(content []TextBlockParam, source string, title string) ContentBlockParamUnion { + var searchResult SearchResultBlockParam + searchResult.Content = content + searchResult.Source = source + searchResult.Title = title + return ContentBlockParamUnion{OfSearchResult: &searchResult} } -func (u *ContentBlockSourceContentItemUnionParam) asAny() any { - if !param.IsOmitted(u.OfText) { - return u.OfText - } else if !param.IsOmitted(u.OfImage) { - return u.OfImage - } - return nil +func NewThinkingBlock(signature string, thinking string) ContentBlockParamUnion { + var variant ThinkingBlockParam + variant.Signature = signature + variant.Thinking = thinking + return ContentBlockParamUnion{OfThinking: &variant} } -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockSourceContentItemUnionParam) GetText() *string { - if vt := u.OfText; vt != nil { - return &vt.Text +func NewRedactedThinkingBlock(data string) ContentBlockParamUnion { + var redactedThinking RedactedThinkingBlockParam + redactedThinking.Data = data + return ContentBlockParamUnion{OfRedactedThinking: &redactedThinking} +} + +func NewToolUseBlock(id string, input any, name string) ContentBlockParamUnion { + var toolUse ToolUseBlockParam + toolUse.ID = id + toolUse.Input = input + toolUse.Name = name + return ContentBlockParamUnion{OfToolUse: &toolUse} +} + +func NewToolResultBlock(toolUseID string, content string, isError bool) ContentBlockParamUnion { + toolBlock := ToolResultBlockParam{ + ToolUseID: toolUseID, + Content: []ToolResultBlockParamContentUnion{ + {OfText: &TextBlockParam{Text: content}}, + }, + IsError: Bool(isError), } - return nil + return ContentBlockParamUnion{OfToolResult: &toolBlock} } -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockSourceContentItemUnionParam) GetCitations() []TextCitationParamUnion { - if vt := u.OfText; vt != nil { - return vt.Citations +func NewServerToolUseBlock(id string, input any, name ServerToolUseBlockParamName) ContentBlockParamUnion { + var serverToolUse ServerToolUseBlockParam + serverToolUse.ID = id + serverToolUse.Input = input + serverToolUse.Name = name + return ContentBlockParamUnion{OfServerToolUse: &serverToolUse} +} + +func NewWebSearchToolResultBlock[ + T []WebSearchResultBlockParam | WebSearchToolRequestErrorParam, +](content T, toolUseID string) ContentBlockParamUnion { + var webSearchToolResult WebSearchToolResultBlockParam + switch v := any(content).(type) { + case []WebSearchResultBlockParam: + webSearchToolResult.Content.OfWebSearchToolResultBlockItem = v + case WebSearchToolRequestErrorParam: + webSearchToolResult.Content.OfRequestWebSearchToolResultError = &v } - return nil + webSearchToolResult.ToolUseID = toolUseID + return ContentBlockParamUnion{OfWebSearchToolResult: &webSearchToolResult} } -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockSourceContentItemUnionParam) GetSource() *ImageBlockParamSourceUnion { - if vt := u.OfImage; vt != nil { - return &vt.Source +func NewWebFetchToolResultBlock[ + T WebFetchToolResultErrorBlockParam | WebFetchBlockParam, +](content T, toolUseID string) ContentBlockParamUnion { + var webFetchToolResult WebFetchToolResultBlockParam + switch v := any(content).(type) { + case WebFetchToolResultErrorBlockParam: + webFetchToolResult.Content.OfRequestWebFetchToolResultError = &v + case WebFetchBlockParam: + webFetchToolResult.Content.OfRequestWebFetchResultBlock = &v } - return nil + webFetchToolResult.ToolUseID = toolUseID + return ContentBlockParamUnion{OfWebFetchToolResult: &webFetchToolResult} } -// Returns a pointer to the underlying variant's property, if present. -func (u ContentBlockSourceContentItemUnionParam) GetType() *string { - if vt := u.OfText; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfImage; vt != nil { - return (*string)(&vt.Type) +func NewCodeExecutionToolResultBlock[ + T CodeExecutionToolResultErrorParam | CodeExecutionResultBlockParam | EncryptedCodeExecutionResultBlockParam, +](content T, toolUseID string) ContentBlockParamUnion { + var codeExecutionToolResult CodeExecutionToolResultBlockParam + switch v := any(content).(type) { + case CodeExecutionToolResultErrorParam: + codeExecutionToolResult.Content.OfRequestCodeExecutionToolResultError = &v + case CodeExecutionResultBlockParam: + codeExecutionToolResult.Content.OfRequestCodeExecutionResultBlock = &v + case EncryptedCodeExecutionResultBlockParam: + codeExecutionToolResult.Content.OfRequestEncryptedCodeExecutionResultBlock = &v } - return nil + codeExecutionToolResult.ToolUseID = toolUseID + return ContentBlockParamUnion{OfCodeExecutionToolResult: &codeExecutionToolResult} } -// Returns a pointer to the underlying variant's CacheControl property, if present. -func (u ContentBlockSourceContentItemUnionParam) GetCacheControl() *CacheControlEphemeralParam { - if vt := u.OfText; vt != nil { - return &vt.CacheControl - } else if vt := u.OfImage; vt != nil { - return &vt.CacheControl +func NewBashCodeExecutionToolResultBlock[ + T BashCodeExecutionToolResultErrorParam | BashCodeExecutionResultBlockParam, +](content T, toolUseID string) ContentBlockParamUnion { + var bashCodeExecutionToolResult BashCodeExecutionToolResultBlockParam + switch v := any(content).(type) { + case BashCodeExecutionToolResultErrorParam: + bashCodeExecutionToolResult.Content.OfRequestBashCodeExecutionToolResultError = &v + case BashCodeExecutionResultBlockParam: + bashCodeExecutionToolResult.Content.OfRequestBashCodeExecutionResultBlock = &v } - return nil + bashCodeExecutionToolResult.ToolUseID = toolUseID + return ContentBlockParamUnion{OfBashCodeExecutionToolResult: &bashCodeExecutionToolResult} } -// The properties Source, Type are required. -type DocumentBlockParam struct { - Source DocumentBlockParamSourceUnion `json:"source,omitzero,required"` - Context param.Opt[string] `json:"context,omitzero"` - Title param.Opt[string] `json:"title,omitzero"` - // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` - Citations CitationsConfigParam `json:"citations,omitzero"` - // This field can be elided, and will marshal its zero value as "document". - Type constant.Document `json:"type,required"` - paramObj +func NewTextEditorCodeExecutionToolResultBlock[ + T TextEditorCodeExecutionToolResultErrorParam | TextEditorCodeExecutionViewResultBlockParam | TextEditorCodeExecutionCreateResultBlockParam | TextEditorCodeExecutionStrReplaceResultBlockParam, +](content T, toolUseID string) ContentBlockParamUnion { + var textEditorCodeExecutionToolResult TextEditorCodeExecutionToolResultBlockParam + switch v := any(content).(type) { + case TextEditorCodeExecutionToolResultErrorParam: + textEditorCodeExecutionToolResult.Content.OfRequestTextEditorCodeExecutionToolResultError = &v + case TextEditorCodeExecutionViewResultBlockParam: + textEditorCodeExecutionToolResult.Content.OfRequestTextEditorCodeExecutionViewResultBlock = &v + case TextEditorCodeExecutionCreateResultBlockParam: + textEditorCodeExecutionToolResult.Content.OfRequestTextEditorCodeExecutionCreateResultBlock = &v + case TextEditorCodeExecutionStrReplaceResultBlockParam: + textEditorCodeExecutionToolResult.Content.OfRequestTextEditorCodeExecutionStrReplaceResultBlock = &v + } + textEditorCodeExecutionToolResult.ToolUseID = toolUseID + return ContentBlockParamUnion{OfTextEditorCodeExecutionToolResult: &textEditorCodeExecutionToolResult} } -func (r DocumentBlockParam) MarshalJSON() (data []byte, err error) { - type shadow DocumentBlockParam - return param.MarshalObject(r, (*shadow)(&r)) +func NewToolSearchToolResultBlock[ + T ToolSearchToolResultErrorParam | ToolSearchToolSearchResultBlockParam, +](content T, toolUseID string) ContentBlockParamUnion { + var toolSearchToolResult ToolSearchToolResultBlockParam + switch v := any(content).(type) { + case ToolSearchToolResultErrorParam: + toolSearchToolResult.Content.OfRequestToolSearchToolResultError = &v + case ToolSearchToolSearchResultBlockParam: + toolSearchToolResult.Content.OfRequestToolSearchToolSearchResultBlock = &v + } + toolSearchToolResult.ToolUseID = toolUseID + return ContentBlockParamUnion{OfToolSearchToolResult: &toolSearchToolResult} } -func (r *DocumentBlockParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func NewContainerUploadBlock(fileID string) ContentBlockParamUnion { + var containerUpload ContainerUploadBlockParam + containerUpload.FileID = fileID + return ContentBlockParamUnion{OfContainerUpload: &containerUpload} } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. -type DocumentBlockParamSourceUnion struct { - OfBase64 *Base64PDFSourceParam `json:",omitzero,inline"` - OfText *PlainTextSourceParam `json:",omitzero,inline"` - OfContent *ContentBlockSourceParam `json:",omitzero,inline"` - OfURL *URLPDFSourceParam `json:",omitzero,inline"` +type ContentBlockParamUnion struct { + OfText *TextBlockParam `json:",omitzero,inline"` + OfImage *ImageBlockParam `json:",omitzero,inline"` + OfDocument *DocumentBlockParam `json:",omitzero,inline"` + OfSearchResult *SearchResultBlockParam `json:",omitzero,inline"` + OfThinking *ThinkingBlockParam `json:",omitzero,inline"` + OfRedactedThinking *RedactedThinkingBlockParam `json:",omitzero,inline"` + OfToolUse *ToolUseBlockParam `json:",omitzero,inline"` + OfToolResult *ToolResultBlockParam `json:",omitzero,inline"` + OfServerToolUse *ServerToolUseBlockParam `json:",omitzero,inline"` + OfWebSearchToolResult *WebSearchToolResultBlockParam `json:",omitzero,inline"` + OfWebFetchToolResult *WebFetchToolResultBlockParam `json:",omitzero,inline"` + OfCodeExecutionToolResult *CodeExecutionToolResultBlockParam `json:",omitzero,inline"` + OfBashCodeExecutionToolResult *BashCodeExecutionToolResultBlockParam `json:",omitzero,inline"` + OfTextEditorCodeExecutionToolResult *TextEditorCodeExecutionToolResultBlockParam `json:",omitzero,inline"` + OfToolSearchToolResult *ToolSearchToolResultBlockParam `json:",omitzero,inline"` + OfContainerUpload *ContainerUploadBlockParam `json:",omitzero,inline"` paramUnion } -func (u DocumentBlockParamSourceUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfBase64, u.OfText, u.OfContent, u.OfURL) +func (u ContentBlockParamUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfText, + u.OfImage, + u.OfDocument, + u.OfSearchResult, + u.OfThinking, + u.OfRedactedThinking, + u.OfToolUse, + u.OfToolResult, + u.OfServerToolUse, + u.OfWebSearchToolResult, + u.OfWebFetchToolResult, + u.OfCodeExecutionToolResult, + u.OfBashCodeExecutionToolResult, + u.OfTextEditorCodeExecutionToolResult, + u.OfToolSearchToolResult, + u.OfContainerUpload) } - -func (u *DocumentBlockParamSourceUnion) UnmarshalJSON(data []byte) error { +func (u *ContentBlockParamUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } -func (u *DocumentBlockParamSourceUnion) asAny() any { - if !param.IsOmitted(u.OfBase64) { - return u.OfBase64 - } else if !param.IsOmitted(u.OfText) { +func (u *ContentBlockParamUnion) asAny() any { + if !param.IsOmitted(u.OfText) { return u.OfText - } else if !param.IsOmitted(u.OfContent) { - return u.OfContent - } else if !param.IsOmitted(u.OfURL) { - return u.OfURL + } else if !param.IsOmitted(u.OfImage) { + return u.OfImage + } else if !param.IsOmitted(u.OfDocument) { + return u.OfDocument + } else if !param.IsOmitted(u.OfSearchResult) { + return u.OfSearchResult + } else if !param.IsOmitted(u.OfThinking) { + return u.OfThinking + } else if !param.IsOmitted(u.OfRedactedThinking) { + return u.OfRedactedThinking + } else if !param.IsOmitted(u.OfToolUse) { + return u.OfToolUse + } else if !param.IsOmitted(u.OfToolResult) { + return u.OfToolResult + } else if !param.IsOmitted(u.OfServerToolUse) { + return u.OfServerToolUse + } else if !param.IsOmitted(u.OfWebSearchToolResult) { + return u.OfWebSearchToolResult + } else if !param.IsOmitted(u.OfWebFetchToolResult) { + return u.OfWebFetchToolResult + } else if !param.IsOmitted(u.OfCodeExecutionToolResult) { + return u.OfCodeExecutionToolResult + } else if !param.IsOmitted(u.OfBashCodeExecutionToolResult) { + return u.OfBashCodeExecutionToolResult + } else if !param.IsOmitted(u.OfTextEditorCodeExecutionToolResult) { + return u.OfTextEditorCodeExecutionToolResult + } else if !param.IsOmitted(u.OfToolSearchToolResult) { + return u.OfToolSearchToolResult + } else if !param.IsOmitted(u.OfContainerUpload) { + return u.OfContainerUpload } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u DocumentBlockParamSourceUnion) GetContent() *ContentBlockSourceContentUnionParam { - if vt := u.OfContent; vt != nil { - return &vt.Content +func (u ContentBlockParamUnion) GetText() *string { + if vt := u.OfText; vt != nil { + return &vt.Text } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u DocumentBlockParamSourceUnion) GetURL() *string { - if vt := u.OfURL; vt != nil { - return &vt.URL +func (u ContentBlockParamUnion) GetContext() *string { + if vt := u.OfDocument; vt != nil && vt.Context.Valid() { + return &vt.Context.Value } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u DocumentBlockParamSourceUnion) GetData() *string { - if vt := u.OfBase64; vt != nil { - return (*string)(&vt.Data) - } else if vt := u.OfText; vt != nil { - return (*string)(&vt.Data) +func (u ContentBlockParamUnion) GetSignature() *string { + if vt := u.OfThinking; vt != nil { + return &vt.Signature } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u DocumentBlockParamSourceUnion) GetMediaType() *string { - if vt := u.OfBase64; vt != nil { - return (*string)(&vt.MediaType) - } else if vt := u.OfText; vt != nil { - return (*string)(&vt.MediaType) +func (u ContentBlockParamUnion) GetThinking() *string { + if vt := u.OfThinking; vt != nil { + return &vt.Thinking } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u DocumentBlockParamSourceUnion) GetType() *string { - if vt := u.OfBase64; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfText; vt != nil { +func (u ContentBlockParamUnion) GetData() *string { + if vt := u.OfRedactedThinking; vt != nil { + return &vt.Data + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockParamUnion) GetIsError() *bool { + if vt := u.OfToolResult; vt != nil && vt.IsError.Valid() { + return &vt.IsError.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockParamUnion) GetFileID() *string { + if vt := u.OfContainerUpload; vt != nil { + return &vt.FileID + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockParamUnion) GetType() *string { + if vt := u.OfText; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfContent; vt != nil { + } else if vt := u.OfImage; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfURL; vt != nil { + } else if vt := u.OfDocument; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfSearchResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfThinking; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRedactedThinking; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolUse; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfServerToolUse; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebSearchToolResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebFetchToolResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecutionToolResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfBashCodeExecutionToolResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfTextEditorCodeExecutionToolResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfContainerUpload; vt != nil { return (*string)(&vt.Type) } return nil } -// The properties Source, Type are required. -type ImageBlockParam struct { - Source ImageBlockParamSourceUnion `json:"source,omitzero,required"` - // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` - // This field can be elided, and will marshal its zero value as "image". - Type constant.Image `json:"type,required"` - paramObj +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockParamUnion) GetTitle() *string { + if vt := u.OfDocument; vt != nil && vt.Title.Valid() { + return &vt.Title.Value + } else if vt := u.OfSearchResult; vt != nil { + return (*string)(&vt.Title) + } + return nil } -func (r ImageBlockParam) MarshalJSON() (data []byte, err error) { - type shadow ImageBlockParam - return param.MarshalObject(r, (*shadow)(&r)) +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockParamUnion) GetID() *string { + if vt := u.OfToolUse; vt != nil { + return (*string)(&vt.ID) + } else if vt := u.OfServerToolUse; vt != nil { + return (*string)(&vt.ID) + } + return nil } -func (r *ImageBlockParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockParamUnion) GetName() *string { + if vt := u.OfToolUse; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfServerToolUse; vt != nil { + return (*string)(&vt.Name) + } + return nil } -// Only one field can be non-zero. -// -// Use [param.IsOmitted] to confirm if a field is set. -type ImageBlockParamSourceUnion struct { - OfBase64 *Base64ImageSourceParam `json:",omitzero,inline"` - OfURL *URLImageSourceParam `json:",omitzero,inline"` - paramUnion +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockParamUnion) GetToolUseID() *string { + if vt := u.OfToolResult; vt != nil { + return (*string)(&vt.ToolUseID) + } else if vt := u.OfWebSearchToolResult; vt != nil { + return (*string)(&vt.ToolUseID) + } else if vt := u.OfWebFetchToolResult; vt != nil { + return (*string)(&vt.ToolUseID) + } else if vt := u.OfCodeExecutionToolResult; vt != nil { + return (*string)(&vt.ToolUseID) + } else if vt := u.OfBashCodeExecutionToolResult; vt != nil { + return (*string)(&vt.ToolUseID) + } else if vt := u.OfTextEditorCodeExecutionToolResult; vt != nil { + return (*string)(&vt.ToolUseID) + } else if vt := u.OfToolSearchToolResult; vt != nil { + return (*string)(&vt.ToolUseID) + } + return nil } -func (u ImageBlockParamSourceUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfBase64, u.OfURL) +// Returns a pointer to the underlying variant's CacheControl property, if present. +func (u ContentBlockParamUnion) GetCacheControl() *CacheControlEphemeralParam { + if vt := u.OfText; vt != nil { + return &vt.CacheControl + } else if vt := u.OfImage; vt != nil { + return &vt.CacheControl + } else if vt := u.OfDocument; vt != nil { + return &vt.CacheControl + } else if vt := u.OfSearchResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolUse; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfServerToolUse; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebSearchToolResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebFetchToolResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfCodeExecutionToolResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfBashCodeExecutionToolResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfTextEditorCodeExecutionToolResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfContainerUpload; vt != nil { + return &vt.CacheControl + } + return nil } -func (u *ImageBlockParamSourceUnion) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, u) +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u ContentBlockParamUnion) GetCitations() (res contentBlockParamUnionCitations) { + if vt := u.OfText; vt != nil { + res.any = &vt.Citations + } else if vt := u.OfDocument; vt != nil { + res.any = &vt.Citations + } else if vt := u.OfSearchResult; vt != nil { + res.any = &vt.Citations + } + return } -func (u *ImageBlockParamSourceUnion) asAny() any { - if !param.IsOmitted(u.OfBase64) { - return u.OfBase64 - } else if !param.IsOmitted(u.OfURL) { - return u.OfURL +// Can have the runtime types [*[]TextCitationParamUnion], [*CitationsConfigParam] +type contentBlockParamUnionCitations struct{ any } + +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *[]anthropic.TextCitationParamUnion: +// case *anthropic.CitationsConfigParam: +// default: +// fmt.Errorf("not present") +// } +func (u contentBlockParamUnionCitations) AsAny() any { return u.any } + +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionCitations) GetEnabled() *bool { + switch vt := u.any.(type) { + case *CitationsConfigParam: + return paramutil.AddrIfPresent(vt.Enabled) } return nil } +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u ContentBlockParamUnion) GetSource() (res contentBlockParamUnionSource) { + if vt := u.OfImage; vt != nil { + res.any = vt.Source.asAny() + } else if vt := u.OfDocument; vt != nil { + res.any = vt.Source.asAny() + } else if vt := u.OfSearchResult; vt != nil { + res.any = &vt.Source + } + return +} + +// Can have the runtime types [*Base64ImageSourceParam], [*URLImageSourceParam], +// [*Base64PDFSourceParam], [*PlainTextSourceParam], [*ContentBlockSourceParam], +// [*URLPDFSourceParam], [*string] +type contentBlockParamUnionSource struct{ any } + +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *anthropic.Base64ImageSourceParam: +// case *anthropic.URLImageSourceParam: +// case *anthropic.Base64PDFSourceParam: +// case *anthropic.PlainTextSourceParam: +// case *anthropic.ContentBlockSourceParam: +// case *anthropic.URLPDFSourceParam: +// case *string: +// default: +// fmt.Errorf("not present") +// } +func (u contentBlockParamUnionSource) AsAny() any { return u.any } + // Returns a pointer to the underlying variant's property, if present. -func (u ImageBlockParamSourceUnion) GetData() *string { - if vt := u.OfBase64; vt != nil { - return &vt.Data +func (u contentBlockParamUnionSource) GetContent() *ContentBlockSourceContentUnionParam { + switch vt := u.any.(type) { + case *DocumentBlockParamSourceUnion: + return vt.GetContent() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ImageBlockParamSourceUnion) GetMediaType() *string { - if vt := u.OfBase64; vt != nil { - return (*string)(&vt.MediaType) +func (u contentBlockParamUnionSource) GetData() *string { + switch vt := u.any.(type) { + case *ImageBlockParamSourceUnion: + return vt.GetData() + case *DocumentBlockParamSourceUnion: + return vt.GetData() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ImageBlockParamSourceUnion) GetURL() *string { - if vt := u.OfURL; vt != nil { - return &vt.URL +func (u contentBlockParamUnionSource) GetMediaType() *string { + switch vt := u.any.(type) { + case *ImageBlockParamSourceUnion: + return vt.GetMediaType() + case *DocumentBlockParamSourceUnion: + return vt.GetMediaType() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ImageBlockParamSourceUnion) GetType() *string { - if vt := u.OfBase64; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfURL; vt != nil { - return (*string)(&vt.Type) +func (u contentBlockParamUnionSource) GetType() *string { + switch vt := u.any.(type) { + case *ImageBlockParamSourceUnion: + return vt.GetType() + case *DocumentBlockParamSourceUnion: + return vt.GetType() } return nil } -type InputJSONDelta struct { - PartialJSON string `json:"partial_json,required"` - Type constant.InputJSONDelta `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - PartialJSON respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionSource) GetURL() *string { + switch vt := u.any.(type) { + case *ImageBlockParamSourceUnion: + return vt.GetURL() + case *DocumentBlockParamSourceUnion: + return vt.GetURL() + } + return nil } -// Returns the unmodified JSON received from the API -func (r InputJSONDelta) RawJSON() string { return r.JSON.raw } - -func (r *InputJSONDelta) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u ContentBlockParamUnion) GetContent() (res contentBlockParamUnionContent) { + if vt := u.OfSearchResult; vt != nil { + res.any = &vt.Content + } else if vt := u.OfToolResult; vt != nil { + res.any = &vt.Content + } else if vt := u.OfWebSearchToolResult; vt != nil { + res.any = vt.Content.asAny() + } else if vt := u.OfWebFetchToolResult; vt != nil { + res.any = vt.Content.asAny() + } else if vt := u.OfCodeExecutionToolResult; vt != nil { + res.any = vt.Content.asAny() + } else if vt := u.OfBashCodeExecutionToolResult; vt != nil { + res.any = vt.Content.asAny() + } else if vt := u.OfTextEditorCodeExecutionToolResult; vt != nil { + res.any = vt.Content.asAny() + } else if vt := u.OfToolSearchToolResult; vt != nil { + res.any = vt.Content.asAny() + } + return } -type Message struct { - // Unique object identifier. - // - // The format and length of IDs may change over time. - ID string `json:"id,required"` - // Content generated by the model. - // - // This is an array of content blocks, each of which has a `type` that determines - // its shape. - // - // Example: - // - // ```json - // [{ "type": "text", "text": "Hi, I'm Claude." }] - // ``` - // - // If the request input `messages` ended with an `assistant` turn, then the - // response `content` will continue directly from that last turn. You can use this - // to constrain the model's output. - // - // For example, if the input `messages` were: - // - // ```json - // [ - // - // { - // "role": "user", - // "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" - // }, - // { "role": "assistant", "content": "The best answer is (" } - // - // ] - // ``` - // - // Then the response `content` might be: - // - // ```json - // [{ "type": "text", "text": "B)" }] - // ``` - Content []ContentBlockUnion `json:"content,required"` - // The model that will complete your prompt.\n\nSee - // [models](https://docs.anthropic.com/en/docs/models-overview) for additional - // details and options. - Model Model `json:"model,required"` - // Conversational role of the generated message. - // - // This will always be `"assistant"`. - Role constant.Assistant `json:"role,required"` - // The reason that we stopped. - // - // This may be one the following values: - // - // - `"end_turn"`: the model reached a natural stopping point - // - `"max_tokens"`: we exceeded the requested `max_tokens` or the model's maximum - // - `"stop_sequence"`: one of your provided custom `stop_sequences` was generated - // - `"tool_use"`: the model invoked one or more tools - // - `"pause_turn"`: we paused a long-running turn. You may provide the response - // back as-is in a subsequent request to let the model continue. - // - `"refusal"`: when streaming classifiers intervene to handle potential policy - // violations - // - // In non-streaming mode this value is always non-null. In streaming mode, it is - // null in the `message_start` event and non-null otherwise. - // - // Any of "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", - // "refusal", "model_context_window_exceeded". - StopReason StopReason `json:"stop_reason,required"` - // Which custom stop sequence was generated, if any. - // - // This value will be a non-null string if one of your custom stop sequences was - // generated. - StopSequence string `json:"stop_sequence,required"` - // Object type. - // - // For Messages, this is always `"message"`. - Type constant.Message `json:"type,required"` - // Billing and rate-limit usage. - // - // Anthropic's API bills and rate-limits by token counts, as tokens represent the - // underlying cost to our systems. - // - // Under the hood, the API transforms requests into a format suitable for the - // model. The model's output then goes through a parsing stage before becoming an - // API response. As a result, the token counts in `usage` will not match one-to-one - // with the exact visible content of an API request or response. - // - // For example, `output_tokens` will be non-zero, even for an empty string response - // from Claude. - // - // Total input tokens in a request is the summation of `input_tokens`, - // `cache_creation_input_tokens`, and `cache_read_input_tokens`. - Usage Usage `json:"usage,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - ID respjson.Field - Content respjson.Field - Model respjson.Field - Role respjson.Field - StopReason respjson.Field - StopSequence respjson.Field - Type respjson.Field - Usage respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` -} +// Can have the runtime types [_[]TextBlockParam], +// [_[]ToolResultBlockParamContentUnion], [*[]WebSearchResultBlockParam], +// [*WebFetchToolResultErrorBlockParam], [*WebFetchBlockParam], +// [*CodeExecutionToolResultErrorParam], [*CodeExecutionResultBlockParam], +// [*EncryptedCodeExecutionResultBlockParam], +// [*BashCodeExecutionToolResultErrorParam], [*BashCodeExecutionResultBlockParam], +// [*TextEditorCodeExecutionToolResultErrorParam], +// [*TextEditorCodeExecutionViewResultBlockParam], +// [*TextEditorCodeExecutionCreateResultBlockParam], +// [*TextEditorCodeExecutionStrReplaceResultBlockParam], +// [*ToolSearchToolResultErrorParam], [*ToolSearchToolSearchResultBlockParam] +type contentBlockParamUnionContent struct{ any } -// Returns the unmodified JSON received from the API -func (r Message) RawJSON() string { return r.JSON.raw } +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *[]anthropic.TextBlockParam: +// case *[]anthropic.ToolResultBlockParamContentUnion: +// case *[]anthropic.WebSearchResultBlockParam: +// case *anthropic.WebFetchToolResultErrorBlockParam: +// case *anthropic.WebFetchBlockParam: +// case *anthropic.CodeExecutionToolResultErrorParam: +// case *anthropic.CodeExecutionResultBlockParam: +// case *anthropic.EncryptedCodeExecutionResultBlockParam: +// case *anthropic.BashCodeExecutionToolResultErrorParam: +// case *anthropic.BashCodeExecutionResultBlockParam: +// case *anthropic.TextEditorCodeExecutionToolResultErrorParam: +// case *anthropic.TextEditorCodeExecutionViewResultBlockParam: +// case *anthropic.TextEditorCodeExecutionCreateResultBlockParam: +// case *anthropic.TextEditorCodeExecutionStrReplaceResultBlockParam: +// case *anthropic.ToolSearchToolResultErrorParam: +// case *anthropic.ToolSearchToolSearchResultBlockParam: +// default: +// fmt.Errorf("not present") +// } +func (u contentBlockParamUnionContent) AsAny() any { return u.any } -func (r *Message) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetURL() *string { + switch vt := u.any.(type) { + case *WebFetchToolResultBlockParamContentUnion: + return vt.GetURL() + } + return nil } -func (r Message) ToParam() MessageParam { - var p MessageParam - p.Role = MessageParamRole(r.Role) - p.Content = make([]ContentBlockParamUnion, len(r.Content)) - for i, c := range r.Content { - p.Content[i] = c.ToParam() +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetRetrievedAt() *string { + switch vt := u.any.(type) { + case *WebFetchToolResultBlockParamContentUnion: + return vt.GetRetrievedAt() } - return p + return nil } -// The reason that we stopped. -// -// This may be one the following values: -// -// - `"end_turn"`: the model reached a natural stopping point -// - `"max_tokens"`: we exceeded the requested `max_tokens` or the model's maximum -// - `"stop_sequence"`: one of your provided custom `stop_sequences` was generated -// - `"tool_use"`: the model invoked one or more tools -// -// In non-streaming mode this value is always non-null. In streaming mode, it is -// null in the `message_start` event and non-null otherwise. -type MessageStopReason string +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetEncryptedStdout() *string { + switch vt := u.any.(type) { + case *CodeExecutionToolResultBlockParamContentUnion: + return vt.GetEncryptedStdout() + } + return nil +} -const ( - MessageStopReasonEndTurn MessageStopReason = "end_turn" - MessageStopReasonMaxTokens MessageStopReason = "max_tokens" - MessageStopReasonStopSequence MessageStopReason = "stop_sequence" - MessageStopReasonToolUse MessageStopReason = "tool_use" -) +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetErrorMessage() *string { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetErrorMessage() + } + return nil +} -func MessageCountTokensToolParamOfTool(inputSchema ToolInputSchemaParam, name string) MessageCountTokensToolUnionParam { - var variant ToolParam - variant.InputSchema = inputSchema - variant.Name = name - return MessageCountTokensToolUnionParam{OfTool: &variant} +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetFileType() *string { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetFileType() + } + return nil } -// Only one field can be non-zero. -// -// Use [param.IsOmitted] to confirm if a field is set. -type MessageCountTokensToolUnionParam struct { - OfTool *ToolParam `json:",omitzero,inline"` - OfBashTool20250124 *ToolBash20250124Param `json:",omitzero,inline"` - OfTextEditor20250124 *ToolTextEditor20250124Param `json:",omitzero,inline"` - OfTextEditor20250429 *ToolTextEditor20250429Param `json:",omitzero,inline"` - OfTextEditor20250728 *ToolTextEditor20250728Param `json:",omitzero,inline"` - OfWebSearchTool20250305 *WebSearchTool20250305Param `json:",omitzero,inline"` - paramUnion +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetNumLines() *int64 { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetNumLines() + } + return nil } -func (u MessageCountTokensToolUnionParam) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfTool, - u.OfBashTool20250124, - u.OfTextEditor20250124, - u.OfTextEditor20250429, - u.OfTextEditor20250728, - u.OfWebSearchTool20250305) +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetStartLine() *int64 { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetStartLine() + } + return nil } -func (u *MessageCountTokensToolUnionParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, u) +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetTotalLines() *int64 { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetTotalLines() + } + return nil } -func (u *MessageCountTokensToolUnionParam) asAny() any { - if !param.IsOmitted(u.OfTool) { - return u.OfTool - } else if !param.IsOmitted(u.OfBashTool20250124) { - return u.OfBashTool20250124 - } else if !param.IsOmitted(u.OfTextEditor20250124) { - return u.OfTextEditor20250124 - } else if !param.IsOmitted(u.OfTextEditor20250429) { - return u.OfTextEditor20250429 - } else if !param.IsOmitted(u.OfTextEditor20250728) { - return u.OfTextEditor20250728 - } else if !param.IsOmitted(u.OfWebSearchTool20250305) { - return u.OfWebSearchTool20250305 +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetIsFileUpdate() *bool { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetIsFileUpdate() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetInputSchema() *ToolInputSchemaParam { - if vt := u.OfTool; vt != nil { - return &vt.InputSchema +func (u contentBlockParamUnionContent) GetLines() []string { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetLines() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetDescription() *string { - if vt := u.OfTool; vt != nil && vt.Description.Valid() { - return &vt.Description.Value +func (u contentBlockParamUnionContent) GetNewLines() *int64 { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetNewLines() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetMaxCharacters() *int64 { - if vt := u.OfTextEditor20250728; vt != nil && vt.MaxCharacters.Valid() { - return &vt.MaxCharacters.Value +func (u contentBlockParamUnionContent) GetNewStart() *int64 { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetNewStart() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetAllowedDomains() []string { - if vt := u.OfWebSearchTool20250305; vt != nil { - return vt.AllowedDomains +func (u contentBlockParamUnionContent) GetOldLines() *int64 { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetOldLines() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetBlockedDomains() []string { - if vt := u.OfWebSearchTool20250305; vt != nil { - return vt.BlockedDomains +func (u contentBlockParamUnionContent) GetOldStart() *int64 { + switch vt := u.any.(type) { + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetOldStart() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetMaxUses() *int64 { - if vt := u.OfWebSearchTool20250305; vt != nil && vt.MaxUses.Valid() { - return &vt.MaxUses.Value +func (u contentBlockParamUnionContent) GetToolReferences() []ToolReferenceBlockParam { + switch vt := u.any.(type) { + case *ToolSearchToolResultBlockParamContentUnion: + return vt.GetToolReferences() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetUserLocation() *WebSearchTool20250305UserLocationParam { - if vt := u.OfWebSearchTool20250305; vt != nil { - return &vt.UserLocation +func (u contentBlockParamUnionContent) GetErrorCode() *string { + switch vt := u.any.(type) { + case *WebSearchToolResultBlockParamContentUnion: + if vt.OfRequestWebSearchToolResultError != nil { + return (*string)(&vt.OfRequestWebSearchToolResultError.ErrorCode) + } + case *WebFetchToolResultBlockParamContentUnion: + return vt.GetErrorCode() + case *CodeExecutionToolResultBlockParamContentUnion: + return vt.GetErrorCode() + case *BashCodeExecutionToolResultBlockParamContentUnion: + return vt.GetErrorCode() + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetErrorCode() + case *ToolSearchToolResultBlockParamContentUnion: + return vt.GetErrorCode() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetName() *string { - if vt := u.OfTool; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfBashTool20250124; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfTextEditor20250124; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfTextEditor20250429; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfTextEditor20250728; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfWebSearchTool20250305; vt != nil { - return (*string)(&vt.Name) +func (u contentBlockParamUnionContent) GetType() *string { + switch vt := u.any.(type) { + case *WebSearchToolResultBlockParamContentUnion: + if vt.OfRequestWebSearchToolResultError != nil { + return (*string)(&vt.OfRequestWebSearchToolResultError.Type) + } + case *WebFetchToolResultBlockParamContentUnion: + return vt.GetType() + case *CodeExecutionToolResultBlockParamContentUnion: + return vt.GetType() + case *BashCodeExecutionToolResultBlockParamContentUnion: + return vt.GetType() + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + return vt.GetType() + case *ToolSearchToolResultBlockParamContentUnion: + return vt.GetType() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u MessageCountTokensToolUnionParam) GetType() *string { - if vt := u.OfTool; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfBashTool20250124; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfTextEditor20250124; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfTextEditor20250429; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfTextEditor20250728; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfWebSearchTool20250305; vt != nil { - return (*string)(&vt.Type) +func (u contentBlockParamUnionContent) GetReturnCode() *int64 { + switch vt := u.any.(type) { + case *CodeExecutionToolResultBlockParamContentUnion: + return vt.GetReturnCode() + case *BashCodeExecutionToolResultBlockParamContentUnion: + return vt.GetReturnCode() } return nil } -// Returns a pointer to the underlying variant's CacheControl property, if present. -func (u MessageCountTokensToolUnionParam) GetCacheControl() *CacheControlEphemeralParam { - if vt := u.OfTool; vt != nil { - return &vt.CacheControl - } else if vt := u.OfBashTool20250124; vt != nil { - return &vt.CacheControl - } else if vt := u.OfTextEditor20250124; vt != nil { - return &vt.CacheControl - } else if vt := u.OfTextEditor20250429; vt != nil { - return &vt.CacheControl - } else if vt := u.OfTextEditor20250728; vt != nil { - return &vt.CacheControl - } else if vt := u.OfWebSearchTool20250305; vt != nil { - return &vt.CacheControl +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetStderr() *string { + switch vt := u.any.(type) { + case *CodeExecutionToolResultBlockParamContentUnion: + return vt.GetStderr() + case *BashCodeExecutionToolResultBlockParamContentUnion: + return vt.GetStderr() } return nil } -type MessageDeltaUsage struct { - // The cumulative number of input tokens used to create the cache entry. - CacheCreationInputTokens int64 `json:"cache_creation_input_tokens,required"` - // The cumulative number of input tokens read from the cache. - CacheReadInputTokens int64 `json:"cache_read_input_tokens,required"` - // The cumulative number of input tokens which were used. - InputTokens int64 `json:"input_tokens,required"` - // The cumulative number of output tokens which were used. - OutputTokens int64 `json:"output_tokens,required"` - // The number of server tool requests. - ServerToolUse ServerToolUsage `json:"server_tool_use,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - CacheCreationInputTokens respjson.Field - CacheReadInputTokens respjson.Field - InputTokens respjson.Field - OutputTokens respjson.Field - ServerToolUse respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionContent) GetStdout() *string { + switch vt := u.any.(type) { + case *CodeExecutionToolResultBlockParamContentUnion: + return vt.GetStdout() + case *BashCodeExecutionToolResultBlockParamContentUnion: + return vt.GetStdout() + } + return nil } -// Returns the unmodified JSON received from the API -func (r MessageDeltaUsage) RawJSON() string { return r.JSON.raw } - -func (r *MessageDeltaUsage) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u contentBlockParamUnionContent) GetContent() (res contentBlockParamUnionContentContent) { + switch vt := u.any.(type) { + case *WebFetchToolResultBlockParamContentUnion: + res.any = vt.GetContent() + case *CodeExecutionToolResultBlockParamContentUnion: + res.any = vt.GetContent() + case *BashCodeExecutionToolResultBlockParamContentUnion: + res.any = vt.GetContent() + case *TextEditorCodeExecutionToolResultBlockParamContentUnion: + res.any = vt.GetContent() + } + return res } -// The properties Content, Role are required. -type MessageParam struct { - Content []ContentBlockParamUnion `json:"content,omitzero,required"` - // Any of "user", "assistant". - Role MessageParamRole `json:"role,omitzero,required"` - paramObj -} +// Can have the runtime types [*DocumentBlockParam], +// [_[]CodeExecutionOutputBlockParam], [_[]BashCodeExecutionOutputBlockParam], +// [*string] +type contentBlockParamUnionContentContent struct{ any } -func NewUserMessage(blocks ...ContentBlockParamUnion) MessageParam { - return MessageParam{ - Role: MessageParamRoleUser, - Content: blocks, +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *anthropic.DocumentBlockParam: +// case *[]anthropic.CodeExecutionOutputBlockParam: +// case *[]anthropic.BashCodeExecutionOutputBlockParam: +// case *string: +// default: +// fmt.Errorf("not present") +// } +func (u contentBlockParamUnionContentContent) AsAny() any { return u.any } + +// Returns a pointer to the underlying variant's Input property, if present. +func (u ContentBlockParamUnion) GetInput() *any { + if vt := u.OfToolUse; vt != nil { + return &vt.Input + } else if vt := u.OfServerToolUse; vt != nil { + return &vt.Input } + return nil } -func NewAssistantMessage(blocks ...ContentBlockParamUnion) MessageParam { - return MessageParam{ - Role: MessageParamRoleAssistant, - Content: blocks, +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u ContentBlockParamUnion) GetCaller() (res contentBlockParamUnionCaller) { + if vt := u.OfToolUse; vt != nil { + res.any = vt.Caller.asAny() + } else if vt := u.OfServerToolUse; vt != nil { + res.any = vt.Caller.asAny() + } else if vt := u.OfWebSearchToolResult; vt != nil { + res.any = vt.Caller.asAny() + } else if vt := u.OfWebFetchToolResult; vt != nil { + res.any = vt.Caller.asAny() } + return } -func (r MessageParam) MarshalJSON() (data []byte, err error) { - type shadow MessageParam - return param.MarshalObject(r, (*shadow)(&r)) +// Can have the runtime types [*DirectCallerParam], [*ServerToolCallerParam], +// [*ServerToolCaller20260120Param] +type contentBlockParamUnionCaller struct{ any } + +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *anthropic.DirectCallerParam: +// case *anthropic.ServerToolCallerParam: +// case *anthropic.ServerToolCaller20260120Param: +// default: +// fmt.Errorf("not present") +// } +func (u contentBlockParamUnionCaller) AsAny() any { return u.any } + +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionCaller) GetType() *string { + switch vt := u.any.(type) { + case *ToolUseBlockParamCallerUnion: + return vt.GetType() + case *ServerToolUseBlockParamCallerUnion: + return vt.GetType() + case *WebSearchToolResultBlockParamCallerUnion: + return vt.GetType() + case *WebFetchToolResultBlockParamCallerUnion: + return vt.GetType() + } + return nil } -func (r *MessageParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's property, if present. +func (u contentBlockParamUnionCaller) GetToolID() *string { + switch vt := u.any.(type) { + case *ToolUseBlockParamCallerUnion: + return vt.GetToolID() + case *ServerToolUseBlockParamCallerUnion: + return vt.GetToolID() + case *WebSearchToolResultBlockParamCallerUnion: + return vt.GetToolID() + case *WebFetchToolResultBlockParamCallerUnion: + return vt.GetToolID() + } + return nil } -type MessageParamRole string +func init() { + apijson.RegisterUnion[ContentBlockParamUnion]( + "type", + apijson.Discriminator[TextBlockParam]("text"), + apijson.Discriminator[ImageBlockParam]("image"), + apijson.Discriminator[DocumentBlockParam]("document"), + apijson.Discriminator[SearchResultBlockParam]("search_result"), + apijson.Discriminator[ThinkingBlockParam]("thinking"), + apijson.Discriminator[RedactedThinkingBlockParam]("redacted_thinking"), + apijson.Discriminator[ToolUseBlockParam]("tool_use"), + apijson.Discriminator[ToolResultBlockParam]("tool_result"), + apijson.Discriminator[ServerToolUseBlockParam]("server_tool_use"), + apijson.Discriminator[WebSearchToolResultBlockParam]("web_search_tool_result"), + apijson.Discriminator[WebFetchToolResultBlockParam]("web_fetch_tool_result"), + apijson.Discriminator[CodeExecutionToolResultBlockParam]("code_execution_tool_result"), + apijson.Discriminator[BashCodeExecutionToolResultBlockParam]("bash_code_execution_tool_result"), + apijson.Discriminator[TextEditorCodeExecutionToolResultBlockParam]("text_editor_code_execution_tool_result"), + apijson.Discriminator[ToolSearchToolResultBlockParam]("tool_search_tool_result"), + apijson.Discriminator[ContainerUploadBlockParam]("container_upload"), + ) -const ( - MessageParamRoleUser MessageParamRole = "user" - MessageParamRoleAssistant MessageParamRole = "assistant" -) + // Register custom decoder for []ContentBlockParamUnion to handle string content + apijson.RegisterCustomDecoder[[]ContentBlockParamUnion](func(node gjson.Result, value reflect.Value, defaultDecoder func(gjson.Result, reflect.Value) error) error { + // If it's a string, convert it to a TextBlock automatically + if node.Type == gjson.String { + textBlock := TextBlockParam{ + Text: node.String(), + Type: "text", + } + contentUnion := ContentBlockParamUnion{ + OfText: &textBlock, + } + arrayValue := reflect.MakeSlice(value.Type(), 1, 1) + arrayValue.Index(0).Set(reflect.ValueOf(contentUnion)) + value.Set(arrayValue) + return nil + } -type MessageTokensCount struct { - // The total number of tokens across the provided list of messages, system prompt, - // and tools. - InputTokens int64 `json:"input_tokens,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - InputTokens respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` + return defaultDecoder(node, value) + }) } -// Returns the unmodified JSON received from the API -func (r MessageTokensCount) RawJSON() string { return r.JSON.raw } - -func (r *MessageTokensCount) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func init() { + apijson.RegisterUnion[ContentBlockSourceContentItemUnionParam]( + "type", + apijson.Discriminator[TextBlockParam]("text"), + apijson.Discriminator[ImageBlockParam]("image"), + ) } -type MetadataParam struct { - // An external identifier for the user who is associated with the request. - // - // This should be a uuid, hash value, or other opaque identifier. Anthropic may use - // this id to help detect abuse. Do not include any identifying information such as - // name, email address, or phone number. - UserID param.Opt[string] `json:"user_id,omitzero"` - paramObj +func init() { + apijson.RegisterUnion[DocumentBlockParamSourceUnion]( + "type", + apijson.Discriminator[Base64PDFSourceParam]("base64"), + apijson.Discriminator[PlainTextSourceParam]("text"), + apijson.Discriminator[ContentBlockSourceParam]("content"), + apijson.Discriminator[URLPDFSourceParam]("url"), + ) } -func (r MetadataParam) MarshalJSON() (data []byte, err error) { - type shadow MetadataParam - return param.MarshalObject(r, (*shadow)(&r)) +func init() { + apijson.RegisterUnion[ImageBlockParamSourceUnion]( + "type", + apijson.Discriminator[Base64ImageSourceParam]("base64"), + apijson.Discriminator[URLImageSourceParam]("url"), + ) } -func (r *MetadataParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func init() { + apijson.RegisterUnion[TextCitationParamUnion]( + "type", + apijson.Discriminator[CitationCharLocationParam]("char_location"), + apijson.Discriminator[CitationPageLocationParam]("page_location"), + apijson.Discriminator[CitationContentBlockLocationParam]("content_block_location"), + apijson.Discriminator[CitationWebSearchResultLocationParam]("web_search_result_location"), + apijson.Discriminator[CitationSearchResultLocationParam]("search_result_location"), + ) } -// The model that will complete your prompt.\n\nSee -// [models](https://docs.anthropic.com/en/docs/models-overview) for additional -// details and options. -type Model string +func init() { + apijson.RegisterUnion[ThinkingConfigParamUnion]( + "type", + apijson.Discriminator[ThinkingConfigEnabledParam]("enabled"), + apijson.Discriminator[ThinkingConfigDisabledParam]("disabled"), + ) +} -const ( - ModelClaude3_7SonnetLatest Model = "claude-3-7-sonnet-latest" - ModelClaude3_7Sonnet20250219 Model = "claude-3-7-sonnet-20250219" - ModelClaude3_5HaikuLatest Model = "claude-3-5-haiku-latest" - ModelClaude3_5Haiku20241022 Model = "claude-3-5-haiku-20241022" - ModelClaudeHaiku4_5 Model = "claude-haiku-4-5" - ModelClaudeHaiku4_5_20251001 Model = "claude-haiku-4-5-20251001" - ModelClaudeSonnet4_20250514 Model = "claude-sonnet-4-20250514" - ModelClaudeSonnet4_0 Model = "claude-sonnet-4-0" - ModelClaudeSonnet4_5 Model = "claude-sonnet-4-5" - ModelClaudeSonnet4_5_20250929 Model = "claude-sonnet-4-5-20250929" - ModelClaude4Sonnet20250514 Model = "claude-4-sonnet-20250514" - ModelClaude3_5SonnetLatest Model = "claude-3-5-sonnet-latest" - // Deprecated: Will reach end-of-life on October 22nd, 2025. Please migrate to a - // newer model. Visit - // https://docs.anthropic.com/en/docs/resources/model-deprecations for more - // information. - ModelClaude3_5Sonnet20241022 Model = "claude-3-5-sonnet-20241022" - // Deprecated: Will reach end-of-life on October 22nd, 2025. Please migrate to a - // newer model. Visit - // https://docs.anthropic.com/en/docs/resources/model-deprecations for more - // information. - ModelClaude_3_5_Sonnet_20240620 Model = "claude-3-5-sonnet-20240620" - ModelClaudeOpus4_0 Model = "claude-opus-4-0" - ModelClaudeOpus4_20250514 Model = "claude-opus-4-20250514" - ModelClaude4Opus20250514 Model = "claude-4-opus-20250514" - ModelClaudeOpus4_1_20250805 Model = "claude-opus-4-1-20250805" - // Deprecated: Will reach end-of-life on January 5th, 2026. Please migrate to a - // newer model. Visit - // https://docs.anthropic.com/en/docs/resources/model-deprecations for more - // information. - ModelClaude3OpusLatest Model = "claude-3-opus-latest" - // Deprecated: Will reach end-of-life on January 5th, 2026. Please migrate to a - // newer model. Visit - // https://docs.anthropic.com/en/docs/resources/model-deprecations for more - // information. - ModelClaude_3_Opus_20240229 Model = "claude-3-opus-20240229" - ModelClaude_3_Haiku_20240307 Model = "claude-3-haiku-20240307" -) +func init() { + apijson.RegisterUnion[ToolChoiceUnionParam]( + "type", + apijson.Discriminator[ToolChoiceAutoParam]("auto"), + apijson.Discriminator[ToolChoiceAnyParam]("any"), + apijson.Discriminator[ToolChoiceToolParam]("tool"), + apijson.Discriminator[ToolChoiceNoneParam]("none"), + ) +} -// The properties Data, MediaType, Type are required. -type PlainTextSourceParam struct { - Data string `json:"data,required"` - // This field can be elided, and will marshal its zero value as "text/plain". - MediaType constant.TextPlain `json:"media_type,required"` - // This field can be elided, and will marshal its zero value as "text". - Type constant.Text `json:"type,required"` +func init() { + apijson.RegisterUnion[ToolResultBlockParamContentUnion]( + "type", + apijson.Discriminator[TextBlockParam]("text"), + apijson.Discriminator[ImageBlockParam]("image"), + apijson.Discriminator[SearchResultBlockParam]("search_result"), + apijson.Discriminator[DocumentBlockParam]("document"), + ) + + // Register custom decoder for []ToolResultBlockParamContentUnion to handle string content + apijson.RegisterCustomDecoder[[]ToolResultBlockParamContentUnion](func(node gjson.Result, value reflect.Value, defaultDecoder func(gjson.Result, reflect.Value) error) error { + // If it's a string, convert it to a TextBlock automatically + if node.Type == gjson.String { + textBlock := TextBlockParam{ + Text: node.String(), + Type: "text", + } + contentUnion := ToolResultBlockParamContentUnion{ + OfText: &textBlock, + } + arrayValue := reflect.MakeSlice(value.Type(), 1, 1) + arrayValue.Index(0).Set(reflect.ValueOf(contentUnion)) + value.Set(arrayValue) + return nil + } + + // If it's already an array, use the default decoder + return defaultDecoder(node, value) + }) +} + +// The properties Content, Type are required. +type ContentBlockSourceParam struct { + Content ContentBlockSourceContentUnionParam `json:"content,omitzero,required"` + // This field can be elided, and will marshal its zero value as "content". + Type constant.Content `json:"type,required"` paramObj } -func (r PlainTextSourceParam) MarshalJSON() (data []byte, err error) { - type shadow PlainTextSourceParam +func (r ContentBlockSourceParam) MarshalJSON() (data []byte, err error) { + type shadow ContentBlockSourceParam return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *PlainTextSourceParam) UnmarshalJSON(data []byte) error { +func (r *ContentBlockSourceParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// RawContentBlockDeltaUnion contains all possible properties and values from -// [TextDelta], [InputJSONDelta], [CitationsDelta], [ThinkingDelta], -// [SignatureDelta]. -// -// Use the [RawContentBlockDeltaUnion.AsAny] method to switch on the variant. +// Only one field can be non-zero. // -// Use the methods beginning with 'As' to cast the union to one of its variants. -type RawContentBlockDeltaUnion struct { - // This field is from variant [TextDelta]. - Text string `json:"text"` - // Any of "text_delta", "input_json_delta", "citations_delta", "thinking_delta", - // "signature_delta". - Type string `json:"type"` - // This field is from variant [InputJSONDelta]. - PartialJSON string `json:"partial_json"` - // This field is from variant [CitationsDelta]. - Citation CitationsDeltaCitationUnion `json:"citation"` - // This field is from variant [ThinkingDelta]. - Thinking string `json:"thinking"` - // This field is from variant [SignatureDelta]. - Signature string `json:"signature"` - JSON struct { - Text respjson.Field - Type respjson.Field - PartialJSON respjson.Field - Citation respjson.Field - Thinking respjson.Field - Signature respjson.Field - raw string - } `json:"-"` +// Use [param.IsOmitted] to confirm if a field is set. +type ContentBlockSourceContentUnionParam struct { + OfString param.Opt[string] `json:",omitzero,inline"` + OfContentBlockSourceContent []ContentBlockSourceContentItemUnionParam `json:",omitzero,inline"` + paramUnion } -// anyRawContentBlockDelta is implemented by each variant of -// [RawContentBlockDeltaUnion] to add type safety for the return type of -// [RawContentBlockDeltaUnion.AsAny] -type anyRawContentBlockDelta interface { - implRawContentBlockDeltaUnion() +func (u ContentBlockSourceContentUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfString, u.OfContentBlockSourceContent) +} +func (u *ContentBlockSourceContentUnionParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) } -func (TextDelta) implRawContentBlockDeltaUnion() {} -func (InputJSONDelta) implRawContentBlockDeltaUnion() {} -func (CitationsDelta) implRawContentBlockDeltaUnion() {} -func (ThinkingDelta) implRawContentBlockDeltaUnion() {} -func (SignatureDelta) implRawContentBlockDeltaUnion() {} - -// Use the following switch statement to find the correct variant -// -// switch variant := RawContentBlockDeltaUnion.AsAny().(type) { -// case anthropic.TextDelta: -// case anthropic.InputJSONDelta: -// case anthropic.CitationsDelta: -// case anthropic.ThinkingDelta: -// case anthropic.SignatureDelta: -// default: -// fmt.Errorf("no variant present") -// } -func (u RawContentBlockDeltaUnion) AsAny() anyRawContentBlockDelta { - switch u.Type { - case "text_delta": - return u.AsTextDelta() - case "input_json_delta": - return u.AsInputJSONDelta() - case "citations_delta": - return u.AsCitationsDelta() - case "thinking_delta": - return u.AsThinkingDelta() - case "signature_delta": - return u.AsSignatureDelta() +func (u *ContentBlockSourceContentUnionParam) asAny() any { + if !param.IsOmitted(u.OfString) { + return &u.OfString.Value + } else if !param.IsOmitted(u.OfContentBlockSourceContent) { + return &u.OfContentBlockSourceContent } return nil } -func (u RawContentBlockDeltaUnion) AsTextDelta() (v TextDelta) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func ContentBlockSourceContentItemParamOfText(text string) ContentBlockSourceContentItemUnionParam { + var variant TextBlockParam + variant.Text = text + return ContentBlockSourceContentItemUnionParam{OfText: &variant} } -func (u RawContentBlockDeltaUnion) AsInputJSONDelta() (v InputJSONDelta) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func ContentBlockSourceContentItemParamOfImage[T Base64ImageSourceParam | URLImageSourceParam](source T) ContentBlockSourceContentItemUnionParam { + var image ImageBlockParam + switch v := any(source).(type) { + case Base64ImageSourceParam: + image.Source.OfBase64 = &v + case URLImageSourceParam: + image.Source.OfURL = &v + } + return ContentBlockSourceContentItemUnionParam{OfImage: &image} } -func (u RawContentBlockDeltaUnion) AsCitationsDelta() (v CitationsDelta) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type ContentBlockSourceContentItemUnionParam struct { + OfText *TextBlockParam `json:",omitzero,inline"` + OfImage *ImageBlockParam `json:",omitzero,inline"` + paramUnion } -func (u RawContentBlockDeltaUnion) AsThinkingDelta() (v ThinkingDelta) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (u ContentBlockSourceContentItemUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfText, u.OfImage) } - -func (u RawContentBlockDeltaUnion) AsSignatureDelta() (v SignatureDelta) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (u *ContentBlockSourceContentItemUnionParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) } -// Returns the unmodified JSON received from the API -func (u RawContentBlockDeltaUnion) RawJSON() string { return u.JSON.raw } - -func (r *RawContentBlockDeltaUnion) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func (u *ContentBlockSourceContentItemUnionParam) asAny() any { + if !param.IsOmitted(u.OfText) { + return u.OfText + } else if !param.IsOmitted(u.OfImage) { + return u.OfImage + } + return nil } -type ContentBlockDeltaEvent struct { - Delta RawContentBlockDeltaUnion `json:"delta,required"` - Index int64 `json:"index,required"` - Type constant.ContentBlockDelta `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Delta respjson.Field - Index respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockSourceContentItemUnionParam) GetText() *string { + if vt := u.OfText; vt != nil { + return &vt.Text + } + return nil } -// Returns the unmodified JSON received from the API -func (r ContentBlockDeltaEvent) RawJSON() string { return r.JSON.raw } - -func (r *ContentBlockDeltaEvent) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockSourceContentItemUnionParam) GetCitations() []TextCitationParamUnion { + if vt := u.OfText; vt != nil { + return vt.Citations + } + return nil } -type ContentBlockStartEvent struct { - ContentBlock ContentBlockStartEventContentBlockUnion `json:"content_block,required"` - Index int64 `json:"index,required"` - Type constant.ContentBlockStart `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - ContentBlock respjson.Field - Index respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockSourceContentItemUnionParam) GetSource() *ImageBlockParamSourceUnion { + if vt := u.OfImage; vt != nil { + return &vt.Source + } + return nil } -// Returns the unmodified JSON received from the API -func (r ContentBlockStartEvent) RawJSON() string { return r.JSON.raw } +// Returns a pointer to the underlying variant's property, if present. +func (u ContentBlockSourceContentItemUnionParam) GetType() *string { + if vt := u.OfText; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfImage; vt != nil { + return (*string)(&vt.Type) + } + return nil +} -func (r *ContentBlockStartEvent) UnmarshalJSON(data []byte) error { +// Returns a pointer to the underlying variant's CacheControl property, if present. +func (u ContentBlockSourceContentItemUnionParam) GetCacheControl() *CacheControlEphemeralParam { + if vt := u.OfText; vt != nil { + return &vt.CacheControl + } else if vt := u.OfImage; vt != nil { + return &vt.CacheControl + } + return nil +} + +func init() { + apijson.RegisterUnion[ContentBlockSourceContentItemUnionParam]( + "type", + apijson.Discriminator[TextBlockParam]("text"), + apijson.Discriminator[ImageBlockParam]("image"), + ) +} + +// Tool invocation directly from the model. +type DirectCaller struct { + Type constant.Direct `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r DirectCaller) RawJSON() string { return r.JSON.raw } +func (r *DirectCaller) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// ContentBlockStartEventContentBlockUnion contains all possible properties and -// values from [TextBlock], [ThinkingBlock], [RedactedThinkingBlock], -// [ToolUseBlock], [ServerToolUseBlock], [WebSearchToolResultBlock]. +// ToParam converts this DirectCaller to a DirectCallerParam. // -// Use the [ContentBlockStartEventContentBlockUnion.AsAny] method to switch on the -// variant. +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// DirectCallerParam.Overrides() +func (r DirectCaller) ToParam() DirectCallerParam { + return param.Override[DirectCallerParam](json.RawMessage(r.RawJSON())) +} + +func NewDirectCallerParam() DirectCallerParam { + return DirectCallerParam{ + Type: "direct", + } +} + +// Tool invocation directly from the model. +// +// This struct has a constant value, construct it with [NewDirectCallerParam]. +type DirectCallerParam struct { + Type constant.Direct `json:"type,required"` + paramObj +} + +func (r DirectCallerParam) MarshalJSON() (data []byte, err error) { + type shadow DirectCallerParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *DirectCallerParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type DocumentBlock struct { + // Citation configuration for the document + Citations CitationsConfig `json:"citations,required"` + Source DocumentBlockSourceUnion `json:"source,required"` + // The title of the document + Title string `json:"title,required"` + Type constant.Document `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Citations respjson.Field + Source respjson.Field + Title respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r DocumentBlock) RawJSON() string { return r.JSON.raw } +func (r *DocumentBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// DocumentBlockSourceUnion contains all possible properties and values from +// [Base64PDFSource], [PlainTextSource]. +// +// Use the [DocumentBlockSourceUnion.AsAny] method to switch on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. -type ContentBlockStartEventContentBlockUnion struct { - // This field is from variant [TextBlock]. - Citations []TextCitationUnion `json:"citations"` - // This field is from variant [TextBlock]. - Text string `json:"text"` - // Any of "text", "thinking", "redacted_thinking", "tool_use", "server_tool_use", - // "web_search_tool_result". +type DocumentBlockSourceUnion struct { + Data string `json:"data"` + MediaType string `json:"media_type"` + // Any of "base64", "text". Type string `json:"type"` - // This field is from variant [ThinkingBlock]. - Signature string `json:"signature"` - // This field is from variant [ThinkingBlock]. - Thinking string `json:"thinking"` - // This field is from variant [RedactedThinkingBlock]. - Data string `json:"data"` - ID string `json:"id"` - Input any `json:"input"` - Name string `json:"name"` - // This field is from variant [WebSearchToolResultBlock]. - Content WebSearchToolResultBlockContentUnion `json:"content"` - // This field is from variant [WebSearchToolResultBlock]. - ToolUseID string `json:"tool_use_id"` - JSON struct { - Citations respjson.Field - Text respjson.Field - Type respjson.Field - Signature respjson.Field - Thinking respjson.Field + JSON struct { Data respjson.Field - ID respjson.Field - Input respjson.Field - Name respjson.Field - Content respjson.Field - ToolUseID respjson.Field + MediaType respjson.Field + Type respjson.Field raw string } `json:"-"` } -// anyContentBlockStartEventContentBlock is implemented by each variant of -// [ContentBlockStartEventContentBlockUnion] to add type safety for the return type -// of [ContentBlockStartEventContentBlockUnion.AsAny] -type anyContentBlockStartEventContentBlock interface { - implContentBlockStartEventContentBlockUnion() +// anyDocumentBlockSource is implemented by each variant of +// [DocumentBlockSourceUnion] to add type safety for the return type of +// [DocumentBlockSourceUnion.AsAny] +type anyDocumentBlockSource interface { + implDocumentBlockSourceUnion() } -func (TextBlock) implContentBlockStartEventContentBlockUnion() {} -func (ThinkingBlock) implContentBlockStartEventContentBlockUnion() {} -func (RedactedThinkingBlock) implContentBlockStartEventContentBlockUnion() {} -func (ToolUseBlock) implContentBlockStartEventContentBlockUnion() {} -func (ServerToolUseBlock) implContentBlockStartEventContentBlockUnion() {} -func (WebSearchToolResultBlock) implContentBlockStartEventContentBlockUnion() {} +func (Base64PDFSource) implDocumentBlockSourceUnion() {} +func (PlainTextSource) implDocumentBlockSourceUnion() {} // Use the following switch statement to find the correct variant // -// switch variant := ContentBlockStartEventContentBlockUnion.AsAny().(type) { -// case anthropic.TextBlock: -// case anthropic.ThinkingBlock: -// case anthropic.RedactedThinkingBlock: -// case anthropic.ToolUseBlock: -// case anthropic.ServerToolUseBlock: -// case anthropic.WebSearchToolResultBlock: +// switch variant := DocumentBlockSourceUnion.AsAny().(type) { +// case anthropic.Base64PDFSource: +// case anthropic.PlainTextSource: // default: // fmt.Errorf("no variant present") // } -func (u ContentBlockStartEventContentBlockUnion) AsAny() anyContentBlockStartEventContentBlock { +func (u DocumentBlockSourceUnion) AsAny() anyDocumentBlockSource { switch u.Type { + case "base64": + return u.AsBase64() case "text": return u.AsText() - case "thinking": - return u.AsThinking() - case "redacted_thinking": - return u.AsRedactedThinking() - case "tool_use": - return u.AsToolUse() - case "server_tool_use": - return u.AsServerToolUse() - case "web_search_tool_result": - return u.AsWebSearchToolResult() } return nil } -func (u ContentBlockStartEventContentBlockUnion) AsText() (v TextBlock) { +func (u DocumentBlockSourceUnion) AsBase64() (v Base64PDFSource) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } -func (u ContentBlockStartEventContentBlockUnion) AsThinking() (v ThinkingBlock) { +func (u DocumentBlockSourceUnion) AsText() (v PlainTextSource) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } -func (u ContentBlockStartEventContentBlockUnion) AsRedactedThinking() (v RedactedThinkingBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// Returns the unmodified JSON received from the API +func (u DocumentBlockSourceUnion) RawJSON() string { return u.JSON.raw } + +func (r *DocumentBlockSourceUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u ContentBlockStartEventContentBlockUnion) AsToolUse() (v ToolUseBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// The properties Source, Type are required. +type DocumentBlockParam struct { + Source DocumentBlockParamSourceUnion `json:"source,omitzero,required"` + Context param.Opt[string] `json:"context,omitzero"` + Title param.Opt[string] `json:"title,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + Citations CitationsConfigParam `json:"citations,omitzero"` + // This field can be elided, and will marshal its zero value as "document". + Type constant.Document `json:"type,required"` + paramObj } -func (u ContentBlockStartEventContentBlockUnion) AsServerToolUse() (v ServerToolUseBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (r DocumentBlockParam) MarshalJSON() (data []byte, err error) { + type shadow DocumentBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *DocumentBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u ContentBlockStartEventContentBlockUnion) AsWebSearchToolResult() (v WebSearchToolResultBlock) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type DocumentBlockParamSourceUnion struct { + OfBase64 *Base64PDFSourceParam `json:",omitzero,inline"` + OfText *PlainTextSourceParam `json:",omitzero,inline"` + OfContent *ContentBlockSourceParam `json:",omitzero,inline"` + OfURL *URLPDFSourceParam `json:",omitzero,inline"` + paramUnion } -// Returns the unmodified JSON received from the API -func (u ContentBlockStartEventContentBlockUnion) RawJSON() string { return u.JSON.raw } +func (u DocumentBlockParamSourceUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfBase64, u.OfText, u.OfContent, u.OfURL) +} +func (u *DocumentBlockParamSourceUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} -func (r *ContentBlockStartEventContentBlockUnion) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func (u *DocumentBlockParamSourceUnion) asAny() any { + if !param.IsOmitted(u.OfBase64) { + return u.OfBase64 + } else if !param.IsOmitted(u.OfText) { + return u.OfText + } else if !param.IsOmitted(u.OfContent) { + return u.OfContent + } else if !param.IsOmitted(u.OfURL) { + return u.OfURL + } + return nil } -type ContentBlockStopEvent struct { - Index int64 `json:"index,required"` - Type constant.ContentBlockStop `json:"type,required"` +// Returns a pointer to the underlying variant's property, if present. +func (u DocumentBlockParamSourceUnion) GetContent() *ContentBlockSourceContentUnionParam { + if vt := u.OfContent; vt != nil { + return &vt.Content + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u DocumentBlockParamSourceUnion) GetURL() *string { + if vt := u.OfURL; vt != nil { + return &vt.URL + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u DocumentBlockParamSourceUnion) GetData() *string { + if vt := u.OfBase64; vt != nil { + return (*string)(&vt.Data) + } else if vt := u.OfText; vt != nil { + return (*string)(&vt.Data) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u DocumentBlockParamSourceUnion) GetMediaType() *string { + if vt := u.OfBase64; vt != nil { + return (*string)(&vt.MediaType) + } else if vt := u.OfText; vt != nil { + return (*string)(&vt.MediaType) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u DocumentBlockParamSourceUnion) GetType() *string { + if vt := u.OfBase64; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfText; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfContent; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfURL; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +func init() { + apijson.RegisterUnion[DocumentBlockParamSourceUnion]( + "type", + apijson.Discriminator[Base64PDFSourceParam]("base64"), + apijson.Discriminator[PlainTextSourceParam]("text"), + apijson.Discriminator[ContentBlockSourceParam]("content"), + apijson.Discriminator[URLPDFSourceParam]("url"), + ) +} + +// Code execution result with encrypted stdout for PFC + web_search results. +type EncryptedCodeExecutionResultBlock struct { + Content []CodeExecutionOutputBlock `json:"content,required"` + EncryptedStdout string `json:"encrypted_stdout,required"` + ReturnCode int64 `json:"return_code,required"` + Stderr string `json:"stderr,required"` + Type constant.EncryptedCodeExecutionResult `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - Index respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string + Content respjson.Field + EncryptedStdout respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string } `json:"-"` } // Returns the unmodified JSON received from the API -func (r ContentBlockStopEvent) RawJSON() string { return r.JSON.raw } - -func (r *ContentBlockStopEvent) UnmarshalJSON(data []byte) error { +func (r EncryptedCodeExecutionResultBlock) RawJSON() string { return r.JSON.raw } +func (r *EncryptedCodeExecutionResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type MessageDeltaEvent struct { - Delta MessageDeltaEventDelta `json:"delta,required"` - Type constant.MessageDelta `json:"type,required"` +// Code execution result with encrypted stdout for PFC + web_search results. +// +// The properties Content, EncryptedStdout, ReturnCode, Stderr, Type are required. +type EncryptedCodeExecutionResultBlockParam struct { + Content []CodeExecutionOutputBlockParam `json:"content,omitzero,required"` + EncryptedStdout string `json:"encrypted_stdout,required"` + ReturnCode int64 `json:"return_code,required"` + Stderr string `json:"stderr,required"` + // This field can be elided, and will marshal its zero value as + // "encrypted_code_execution_result". + Type constant.EncryptedCodeExecutionResult `json:"type,required"` + paramObj +} + +func (r EncryptedCodeExecutionResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow EncryptedCodeExecutionResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *EncryptedCodeExecutionResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Source, Type are required. +type ImageBlockParam struct { + Source ImageBlockParamSourceUnion `json:"source,omitzero,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as "image". + Type constant.Image `json:"type,required"` + paramObj +} + +func (r ImageBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ImageBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ImageBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type ImageBlockParamSourceUnion struct { + OfBase64 *Base64ImageSourceParam `json:",omitzero,inline"` + OfURL *URLImageSourceParam `json:",omitzero,inline"` + paramUnion +} + +func (u ImageBlockParamSourceUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfBase64, u.OfURL) +} +func (u *ImageBlockParamSourceUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *ImageBlockParamSourceUnion) asAny() any { + if !param.IsOmitted(u.OfBase64) { + return u.OfBase64 + } else if !param.IsOmitted(u.OfURL) { + return u.OfURL + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ImageBlockParamSourceUnion) GetData() *string { + if vt := u.OfBase64; vt != nil { + return &vt.Data + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ImageBlockParamSourceUnion) GetMediaType() *string { + if vt := u.OfBase64; vt != nil { + return (*string)(&vt.MediaType) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ImageBlockParamSourceUnion) GetURL() *string { + if vt := u.OfURL; vt != nil { + return &vt.URL + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ImageBlockParamSourceUnion) GetType() *string { + if vt := u.OfBase64; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfURL; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +type InputJSONDelta struct { + PartialJSON string `json:"partial_json,required"` + Type constant.InputJSONDelta `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + PartialJSON respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r InputJSONDelta) RawJSON() string { return r.JSON.raw } +func (r *InputJSONDelta) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Schema, Type are required. +type JSONOutputFormatParam struct { + // The JSON schema of the format + Schema map[string]any `json:"schema,omitzero,required"` + // This field can be elided, and will marshal its zero value as "json_schema". + Type constant.JSONSchema `json:"type,required"` + paramObj +} + +func (r JSONOutputFormatParam) MarshalJSON() (data []byte, err error) { + type shadow JSONOutputFormatParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *JSONOutputFormatParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Name, Type are required. +type MemoryTool20250818Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "memory". + Name constant.Memory `json:"name,required"` + // This field can be elided, and will marshal its zero value as "memory_20250818". + Type constant.Memory20250818 `json:"type,required"` + paramObj +} + +func (r MemoryTool20250818Param) MarshalJSON() (data []byte, err error) { + type shadow MemoryTool20250818Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *MemoryTool20250818Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type Message struct { + // Unique object identifier. + // + // The format and length of IDs may change over time. + ID string `json:"id,required"` + // Information about the container used in the request (for the code execution + // tool) + Container Container `json:"container,required"` + // Content generated by the model. + // + // This is an array of content blocks, each of which has a `type` that determines + // its shape. + // + // Example: + // + // ```json + // [{ "type": "text", "text": "Hi, I'm Claude." }] + // ``` + // + // If the request input `messages` ended with an `assistant` turn, then the + // response `content` will continue directly from that last turn. You can use this + // to constrain the model's output. + // + // For example, if the input `messages` were: + // + // ```json + // [ + // + // { + // "role": "user", + // "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" + // }, + // { "role": "assistant", "content": "The best answer is (" } + // + // ] + // ``` + // + // Then the response `content` might be: + // + // ```json + // [{ "type": "text", "text": "B)" }] + // ``` + Content []ContentBlockUnion `json:"content,required"` + // The model that will complete your prompt.\n\nSee + // [models](https://docs.anthropic.com/en/docs/models-overview) for additional + // details and options. + Model Model `json:"model,required"` + // Conversational role of the generated message. + // + // This will always be `"assistant"`. + Role constant.Assistant `json:"role,required"` + // The reason that we stopped. + // + // This may be one the following values: + // + // - `"end_turn"`: the model reached a natural stopping point + // - `"max_tokens"`: we exceeded the requested `max_tokens` or the model's maximum + // - `"stop_sequence"`: one of your provided custom `stop_sequences` was generated + // - `"tool_use"`: the model invoked one or more tools + // - `"pause_turn"`: we paused a long-running turn. You may provide the response + // back as-is in a subsequent request to let the model continue. + // - `"refusal"`: when streaming classifiers intervene to handle potential policy + // violations + // + // In non-streaming mode this value is always non-null. In streaming mode, it is + // null in the `message_start` event and non-null otherwise. + // + // Any of "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", + // "refusal". + StopReason StopReason `json:"stop_reason,required"` + // Which custom stop sequence was generated, if any. + // + // This value will be a non-null string if one of your custom stop sequences was + // generated. + StopSequence string `json:"stop_sequence,required"` + // Object type. + // + // For Messages, this is always `"message"`. + Type constant.Message `json:"type,required"` // Billing and rate-limit usage. // // Anthropic's API bills and rate-limits by token counts, as tokens represent the @@ -2477,51 +3498,2297 @@ type MessageDeltaEvent struct { // // Total input tokens in a request is the summation of `input_tokens`, // `cache_creation_input_tokens`, and `cache_read_input_tokens`. - Usage MessageDeltaUsage `json:"usage,required"` + Usage Usage `json:"usage,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + Container respjson.Field + Content respjson.Field + Model respjson.Field + Role respjson.Field + StopReason respjson.Field + StopSequence respjson.Field + Type respjson.Field + Usage respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r Message) RawJSON() string { return r.JSON.raw } +func (r *Message) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The reason that we stopped. +// +// This may be one the following values: +// +// - `"end_turn"`: the model reached a natural stopping point +// - `"max_tokens"`: we exceeded the requested `max_tokens` or the model's maximum +// - `"stop_sequence"`: one of your provided custom `stop_sequences` was generated +// - `"tool_use"`: the model invoked one or more tools +// +// In non-streaming mode this value is always non-null. In streaming mode, it is +// null in the `message_start` event and non-null otherwise. +type MessageStopReason string + +const ( + MessageStopReasonEndTurn MessageStopReason = "end_turn" + MessageStopReasonMaxTokens MessageStopReason = "max_tokens" + MessageStopReasonStopSequence MessageStopReason = "stop_sequence" + MessageStopReasonToolUse MessageStopReason = "tool_use" +) + +func MessageCountTokensToolParamOfTool(inputSchema ToolInputSchemaParam, name string) MessageCountTokensToolUnionParam { + var variant ToolParam + variant.InputSchema = inputSchema + variant.Name = name + return MessageCountTokensToolUnionParam{OfTool: &variant} +} + +func MessageCountTokensToolParamOfToolSearchToolBm25_20251119(type_ ToolSearchToolBm25_20251119Type) MessageCountTokensToolUnionParam { + var variant ToolSearchToolBm25_20251119Param + variant.Type = type_ + return MessageCountTokensToolUnionParam{OfToolSearchToolBm25_20251119: &variant} +} + +func MessageCountTokensToolParamOfToolSearchToolRegex20251119(type_ ToolSearchToolRegex20251119Type) MessageCountTokensToolUnionParam { + var variant ToolSearchToolRegex20251119Param + variant.Type = type_ + return MessageCountTokensToolUnionParam{OfToolSearchToolRegex20251119: &variant} +} + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type MessageCountTokensToolUnionParam struct { + OfTool *ToolParam `json:",omitzero,inline"` + OfBashTool20250124 *ToolBash20250124Param `json:",omitzero,inline"` + OfCodeExecutionTool20250522 *CodeExecutionTool20250522Param `json:",omitzero,inline"` + OfCodeExecutionTool20250825 *CodeExecutionTool20250825Param `json:",omitzero,inline"` + OfCodeExecutionTool20260120 *CodeExecutionTool20260120Param `json:",omitzero,inline"` + OfMemoryTool20250818 *MemoryTool20250818Param `json:",omitzero,inline"` + OfTextEditor20250124 *ToolTextEditor20250124Param `json:",omitzero,inline"` + OfTextEditor20250429 *ToolTextEditor20250429Param `json:",omitzero,inline"` + OfTextEditor20250728 *ToolTextEditor20250728Param `json:",omitzero,inline"` + OfWebSearchTool20250305 *WebSearchTool20250305Param `json:",omitzero,inline"` + OfWebFetchTool20250910 *WebFetchTool20250910Param `json:",omitzero,inline"` + OfWebSearchTool20260209 *WebSearchTool20260209Param `json:",omitzero,inline"` + OfWebFetchTool20260209 *WebFetchTool20260209Param `json:",omitzero,inline"` + OfToolSearchToolBm25_20251119 *ToolSearchToolBm25_20251119Param `json:",omitzero,inline"` + OfToolSearchToolRegex20251119 *ToolSearchToolRegex20251119Param `json:",omitzero,inline"` + paramUnion +} + +func (u MessageCountTokensToolUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfTool, + u.OfBashTool20250124, + u.OfCodeExecutionTool20250522, + u.OfCodeExecutionTool20250825, + u.OfCodeExecutionTool20260120, + u.OfMemoryTool20250818, + u.OfTextEditor20250124, + u.OfTextEditor20250429, + u.OfTextEditor20250728, + u.OfWebSearchTool20250305, + u.OfWebFetchTool20250910, + u.OfWebSearchTool20260209, + u.OfWebFetchTool20260209, + u.OfToolSearchToolBm25_20251119, + u.OfToolSearchToolRegex20251119) +} +func (u *MessageCountTokensToolUnionParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *MessageCountTokensToolUnionParam) asAny() any { + if !param.IsOmitted(u.OfTool) { + return u.OfTool + } else if !param.IsOmitted(u.OfBashTool20250124) { + return u.OfBashTool20250124 + } else if !param.IsOmitted(u.OfCodeExecutionTool20250522) { + return u.OfCodeExecutionTool20250522 + } else if !param.IsOmitted(u.OfCodeExecutionTool20250825) { + return u.OfCodeExecutionTool20250825 + } else if !param.IsOmitted(u.OfCodeExecutionTool20260120) { + return u.OfCodeExecutionTool20260120 + } else if !param.IsOmitted(u.OfMemoryTool20250818) { + return u.OfMemoryTool20250818 + } else if !param.IsOmitted(u.OfTextEditor20250124) { + return u.OfTextEditor20250124 + } else if !param.IsOmitted(u.OfTextEditor20250429) { + return u.OfTextEditor20250429 + } else if !param.IsOmitted(u.OfTextEditor20250728) { + return u.OfTextEditor20250728 + } else if !param.IsOmitted(u.OfWebSearchTool20250305) { + return u.OfWebSearchTool20250305 + } else if !param.IsOmitted(u.OfWebFetchTool20250910) { + return u.OfWebFetchTool20250910 + } else if !param.IsOmitted(u.OfWebSearchTool20260209) { + return u.OfWebSearchTool20260209 + } else if !param.IsOmitted(u.OfWebFetchTool20260209) { + return u.OfWebFetchTool20260209 + } else if !param.IsOmitted(u.OfToolSearchToolBm25_20251119) { + return u.OfToolSearchToolBm25_20251119 + } else if !param.IsOmitted(u.OfToolSearchToolRegex20251119) { + return u.OfToolSearchToolRegex20251119 + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetInputSchema() *ToolInputSchemaParam { + if vt := u.OfTool; vt != nil { + return &vt.InputSchema + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetDescription() *string { + if vt := u.OfTool; vt != nil && vt.Description.Valid() { + return &vt.Description.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetEagerInputStreaming() *bool { + if vt := u.OfTool; vt != nil && vt.EagerInputStreaming.Valid() { + return &vt.EagerInputStreaming.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetMaxCharacters() *int64 { + if vt := u.OfTextEditor20250728; vt != nil && vt.MaxCharacters.Valid() { + return &vt.MaxCharacters.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetName() *string { + if vt := u.OfTool; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfBashTool20250124; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfMemoryTool20250818; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfTextEditor20250124; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfTextEditor20250429; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfTextEditor20250728; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return (*string)(&vt.Name) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetDeferLoading() *bool { + if vt := u.OfTool; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfBashTool20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20250522; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20250825; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20260120; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfMemoryTool20250818; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250429; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250728; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebSearchTool20250305; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetStrict() *bool { + if vt := u.OfTool; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfBashTool20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20250522; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20250825; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20260120; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfMemoryTool20250818; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250429; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250728; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebSearchTool20250305; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetType() *string { + if vt := u.OfTool; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfBashTool20250124; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfMemoryTool20250818; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfTextEditor20250124; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfTextEditor20250429; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfTextEditor20250728; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetMaxUses() *int64 { + if vt := u.OfWebSearchTool20250305; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u MessageCountTokensToolUnionParam) GetMaxContentTokens() *int64 { + if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxContentTokens.Valid() { + return &vt.MaxContentTokens.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.MaxContentTokens.Valid() { + return &vt.MaxContentTokens.Value + } + return nil +} + +// Returns a pointer to the underlying variant's AllowedCallers property, if +// present. +func (u MessageCountTokensToolUnionParam) GetAllowedCallers() []string { + if vt := u.OfTool; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfBashTool20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfMemoryTool20250818; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250429; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250728; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return vt.AllowedCallers + } + return nil +} + +// Returns a pointer to the underlying variant's CacheControl property, if present. +func (u MessageCountTokensToolUnionParam) GetCacheControl() *CacheControlEphemeralParam { + if vt := u.OfTool; vt != nil { + return &vt.CacheControl + } else if vt := u.OfBashTool20250124; vt != nil { + return &vt.CacheControl + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return &vt.CacheControl + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return &vt.CacheControl + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return &vt.CacheControl + } else if vt := u.OfMemoryTool20250818; vt != nil { + return &vt.CacheControl + } else if vt := u.OfTextEditor20250124; vt != nil { + return &vt.CacheControl + } else if vt := u.OfTextEditor20250429; vt != nil { + return &vt.CacheControl + } else if vt := u.OfTextEditor20250728; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return &vt.CacheControl + } + return nil +} + +// Returns a pointer to the underlying variant's InputExamples property, if +// present. +func (u MessageCountTokensToolUnionParam) GetInputExamples() []map[string]any { + if vt := u.OfTool; vt != nil { + return vt.InputExamples + } else if vt := u.OfBashTool20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfMemoryTool20250818; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250429; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250728; vt != nil { + return vt.InputExamples + } + return nil +} + +// Returns a pointer to the underlying variant's AllowedDomains property, if +// present. +func (u MessageCountTokensToolUnionParam) GetAllowedDomains() []string { + if vt := u.OfWebSearchTool20250305; vt != nil { + return vt.AllowedDomains + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return vt.AllowedDomains + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.AllowedDomains + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.AllowedDomains + } + return nil +} + +// Returns a pointer to the underlying variant's BlockedDomains property, if +// present. +func (u MessageCountTokensToolUnionParam) GetBlockedDomains() []string { + if vt := u.OfWebSearchTool20250305; vt != nil { + return vt.BlockedDomains + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return vt.BlockedDomains + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.BlockedDomains + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.BlockedDomains + } + return nil +} + +// Returns a pointer to the underlying variant's UserLocation property, if present. +func (u MessageCountTokensToolUnionParam) GetUserLocation() *UserLocationParam { + if vt := u.OfWebSearchTool20250305; vt != nil { + return &vt.UserLocation + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return &vt.UserLocation + } + return nil +} + +// Returns a pointer to the underlying variant's Citations property, if present. +func (u MessageCountTokensToolUnionParam) GetCitations() *CitationsConfigParam { + if vt := u.OfWebFetchTool20250910; vt != nil { + return &vt.Citations + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return &vt.Citations + } + return nil +} + +type MessageDeltaUsage struct { + // The cumulative number of input tokens used to create the cache entry. + CacheCreationInputTokens int64 `json:"cache_creation_input_tokens,required"` + // The cumulative number of input tokens read from the cache. + CacheReadInputTokens int64 `json:"cache_read_input_tokens,required"` + // The cumulative number of input tokens which were used. + InputTokens int64 `json:"input_tokens,required"` + // The cumulative number of output tokens which were used. + OutputTokens int64 `json:"output_tokens,required"` + // The number of server tool requests. + ServerToolUse ServerToolUsage `json:"server_tool_use,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + CacheCreationInputTokens respjson.Field + CacheReadInputTokens respjson.Field + InputTokens respjson.Field + OutputTokens respjson.Field + ServerToolUse respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r MessageDeltaUsage) RawJSON() string { return r.JSON.raw } +func (r *MessageDeltaUsage) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Content, Role are required. +type MessageParam struct { + Content []ContentBlockParamUnion `json:"content,omitzero,required"` + // Any of "user", "assistant". + Role MessageParamRole `json:"role,omitzero,required"` + paramObj +} + +func NewUserMessage(blocks ...ContentBlockParamUnion) MessageParam { + return MessageParam{ + Role: MessageParamRoleUser, + Content: blocks, + } +} + +func NewAssistantMessage(blocks ...ContentBlockParamUnion) MessageParam { + return MessageParam{ + Role: MessageParamRoleAssistant, + Content: blocks, + } +} + +func (r MessageParam) MarshalJSON() (data []byte, err error) { + type shadow MessageParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *MessageParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type MessageParamRole string + +const ( + MessageParamRoleUser MessageParamRole = "user" + MessageParamRoleAssistant MessageParamRole = "assistant" +) + +type MessageTokensCount struct { + // The total number of tokens across the provided list of messages, system prompt, + // and tools. + InputTokens int64 `json:"input_tokens,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + InputTokens respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r MessageTokensCount) RawJSON() string { return r.JSON.raw } +func (r *MessageTokensCount) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type MetadataParam struct { + // An external identifier for the user who is associated with the request. + // + // This should be a uuid, hash value, or other opaque identifier. Anthropic may use + // this id to help detect abuse. Do not include any identifying information such as + // name, email address, or phone number. + UserID param.Opt[string] `json:"user_id,omitzero"` + paramObj +} + +func (r MetadataParam) MarshalJSON() (data []byte, err error) { + type shadow MetadataParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *MetadataParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The model that will complete your prompt.\n\nSee +// [models](https://docs.anthropic.com/en/docs/models-overview) for additional +// details and options. +type Model string + +const ( + ModelClaudeOpus4_6 Model = "claude-opus-4-6" + ModelClaudeSonnet4_6 Model = "claude-sonnet-4-6" + ModelClaudeOpus4_5_20251101 Model = "claude-opus-4-5-20251101" + ModelClaudeOpus4_5 Model = "claude-opus-4-5" + // Deprecated: Will reach end-of-life on February 19th, 2026. Please migrate to a + // newer model. Visit + // https://docs.anthropic.com/en/docs/resources/model-deprecations for more + // information. + ModelClaude3_7SonnetLatest Model = "claude-3-7-sonnet-latest" + // Deprecated: Will reach end-of-life on February 19th, 2026. Please migrate to a + // newer model. Visit + // https://docs.anthropic.com/en/docs/resources/model-deprecations for more + // information. + ModelClaude3_7Sonnet20250219 Model = "claude-3-7-sonnet-20250219" + // Deprecated: Will reach end-of-life on February 19th, 2026. Please migrate to a + // newer model. Visit + // https://docs.anthropic.com/en/docs/resources/model-deprecations for more + // information. + ModelClaude3_5HaikuLatest Model = "claude-3-5-haiku-latest" + // Deprecated: Will reach end-of-life on February 19th, 2026. Please migrate to a + // newer model. Visit + // https://docs.anthropic.com/en/docs/resources/model-deprecations for more + // information. + ModelClaude3_5Haiku20241022 Model = "claude-3-5-haiku-20241022" + ModelClaudeHaiku4_5 Model = "claude-haiku-4-5" + ModelClaudeHaiku4_5_20251001 Model = "claude-haiku-4-5-20251001" + ModelClaudeSonnet4_20250514 Model = "claude-sonnet-4-20250514" + ModelClaudeSonnet4_0 Model = "claude-sonnet-4-0" + ModelClaude4Sonnet20250514 Model = "claude-4-sonnet-20250514" + ModelClaudeSonnet4_5 Model = "claude-sonnet-4-5" + ModelClaudeSonnet4_5_20250929 Model = "claude-sonnet-4-5-20250929" + ModelClaudeOpus4_0 Model = "claude-opus-4-0" + ModelClaudeOpus4_20250514 Model = "claude-opus-4-20250514" + ModelClaude4Opus20250514 Model = "claude-4-opus-20250514" + ModelClaudeOpus4_1_20250805 Model = "claude-opus-4-1-20250805" + // Deprecated: Will reach end-of-life on January 5th, 2026. Please migrate to a + // newer model. Visit + // https://docs.anthropic.com/en/docs/resources/model-deprecations for more + // information. + ModelClaude3OpusLatest Model = "claude-3-opus-latest" + // Deprecated: Will reach end-of-life on January 5th, 2026. Please migrate to a + // newer model. Visit + // https://docs.anthropic.com/en/docs/resources/model-deprecations for more + // information. + ModelClaude_3_Opus_20240229 Model = "claude-3-opus-20240229" + ModelClaude_3_Haiku_20240307 Model = "claude-3-haiku-20240307" +) + +type OutputConfigParam struct { + // All possible effort levels. + // + // Any of "low", "medium", "high", "max". + Effort OutputConfigEffort `json:"effort,omitzero"` + // A schema to specify Claude's output format in responses. See + // [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + Format JSONOutputFormatParam `json:"format,omitzero"` + paramObj +} + +func (r OutputConfigParam) MarshalJSON() (data []byte, err error) { + type shadow OutputConfigParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *OutputConfigParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// All possible effort levels. +type OutputConfigEffort string + +const ( + OutputConfigEffortLow OutputConfigEffort = "low" + OutputConfigEffortMedium OutputConfigEffort = "medium" + OutputConfigEffortHigh OutputConfigEffort = "high" + OutputConfigEffortMax OutputConfigEffort = "max" +) + +type PlainTextSource struct { + Data string `json:"data,required"` + MediaType constant.TextPlain `json:"media_type,required"` + Type constant.Text `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Data respjson.Field + MediaType respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r PlainTextSource) RawJSON() string { return r.JSON.raw } +func (r *PlainTextSource) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this PlainTextSource to a PlainTextSourceParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// PlainTextSourceParam.Overrides() +func (r PlainTextSource) ToParam() PlainTextSourceParam { + return param.Override[PlainTextSourceParam](json.RawMessage(r.RawJSON())) +} + +// The properties Data, MediaType, Type are required. +type PlainTextSourceParam struct { + Data string `json:"data,required"` + // This field can be elided, and will marshal its zero value as "text/plain". + MediaType constant.TextPlain `json:"media_type,required"` + // This field can be elided, and will marshal its zero value as "text". + Type constant.Text `json:"type,required"` + paramObj +} + +func (r PlainTextSourceParam) MarshalJSON() (data []byte, err error) { + type shadow PlainTextSourceParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *PlainTextSourceParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// RawContentBlockDeltaUnion contains all possible properties and values from +// [TextDelta], [InputJSONDelta], [CitationsDelta], [ThinkingDelta], +// [SignatureDelta]. +// +// Use the [RawContentBlockDeltaUnion.AsAny] method to switch on the variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type RawContentBlockDeltaUnion struct { + // This field is from variant [TextDelta]. + Text string `json:"text"` + // Any of "text_delta", "input_json_delta", "citations_delta", "thinking_delta", + // "signature_delta". + Type string `json:"type"` + // This field is from variant [InputJSONDelta]. + PartialJSON string `json:"partial_json"` + // This field is from variant [CitationsDelta]. + Citation CitationsDeltaCitationUnion `json:"citation"` + // This field is from variant [ThinkingDelta]. + Thinking string `json:"thinking"` + // This field is from variant [SignatureDelta]. + Signature string `json:"signature"` + JSON struct { + Text respjson.Field + Type respjson.Field + PartialJSON respjson.Field + Citation respjson.Field + Thinking respjson.Field + Signature respjson.Field + raw string + } `json:"-"` +} + +// anyRawContentBlockDelta is implemented by each variant of +// [RawContentBlockDeltaUnion] to add type safety for the return type of +// [RawContentBlockDeltaUnion.AsAny] +type anyRawContentBlockDelta interface { + implRawContentBlockDeltaUnion() +} + +func (TextDelta) implRawContentBlockDeltaUnion() {} +func (InputJSONDelta) implRawContentBlockDeltaUnion() {} +func (CitationsDelta) implRawContentBlockDeltaUnion() {} +func (ThinkingDelta) implRawContentBlockDeltaUnion() {} +func (SignatureDelta) implRawContentBlockDeltaUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := RawContentBlockDeltaUnion.AsAny().(type) { +// case anthropic.TextDelta: +// case anthropic.InputJSONDelta: +// case anthropic.CitationsDelta: +// case anthropic.ThinkingDelta: +// case anthropic.SignatureDelta: +// default: +// fmt.Errorf("no variant present") +// } +func (u RawContentBlockDeltaUnion) AsAny() anyRawContentBlockDelta { + switch u.Type { + case "text_delta": + return u.AsTextDelta() + case "input_json_delta": + return u.AsInputJSONDelta() + case "citations_delta": + return u.AsCitationsDelta() + case "thinking_delta": + return u.AsThinkingDelta() + case "signature_delta": + return u.AsSignatureDelta() + } + return nil +} + +func (u RawContentBlockDeltaUnion) AsTextDelta() (v TextDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u RawContentBlockDeltaUnion) AsInputJSONDelta() (v InputJSONDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u RawContentBlockDeltaUnion) AsCitationsDelta() (v CitationsDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u RawContentBlockDeltaUnion) AsThinkingDelta() (v ThinkingDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u RawContentBlockDeltaUnion) AsSignatureDelta() (v SignatureDelta) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u RawContentBlockDeltaUnion) RawJSON() string { return u.JSON.raw } + +func (r *RawContentBlockDeltaUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ContentBlockDeltaEvent struct { + Delta RawContentBlockDeltaUnion `json:"delta,required"` + Index int64 `json:"index,required"` + Type constant.ContentBlockDelta `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Delta respjson.Field + Index respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ContentBlockDeltaEvent) RawJSON() string { return r.JSON.raw } +func (r *ContentBlockDeltaEvent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ContentBlockStartEvent struct { + // Response model for a file uploaded to the container. + ContentBlock ContentBlockStartEventContentBlockUnion `json:"content_block,required"` + Index int64 `json:"index,required"` + Type constant.ContentBlockStart `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ContentBlock respjson.Field + Index respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ContentBlockStartEvent) RawJSON() string { return r.JSON.raw } +func (r *ContentBlockStartEvent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ContentBlockStartEventContentBlockUnion contains all possible properties and +// values from [TextBlock], [ThinkingBlock], [RedactedThinkingBlock], +// [ToolUseBlock], [ServerToolUseBlock], [WebSearchToolResultBlock], +// [WebFetchToolResultBlock], [CodeExecutionToolResultBlock], +// [BashCodeExecutionToolResultBlock], [TextEditorCodeExecutionToolResultBlock], +// [ToolSearchToolResultBlock], [ContainerUploadBlock]. +// +// Use the [ContentBlockStartEventContentBlockUnion.AsAny] method to switch on the +// variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type ContentBlockStartEventContentBlockUnion struct { + // This field is from variant [TextBlock]. + Citations []TextCitationUnion `json:"citations"` + // This field is from variant [TextBlock]. + Text string `json:"text"` + // Any of "text", "thinking", "redacted_thinking", "tool_use", "server_tool_use", + // "web_search_tool_result", "web_fetch_tool_result", "code_execution_tool_result", + // "bash_code_execution_tool_result", "text_editor_code_execution_tool_result", + // "tool_search_tool_result", "container_upload". + Type string `json:"type"` + // This field is from variant [ThinkingBlock]. + Signature string `json:"signature"` + // This field is from variant [ThinkingBlock]. + Thinking string `json:"thinking"` + // This field is from variant [RedactedThinkingBlock]. + Data string `json:"data"` + ID string `json:"id"` + // This field is a union of [ToolUseBlockCallerUnion], + // [ServerToolUseBlockCallerUnion], [WebSearchToolResultBlockCallerUnion], + // [WebFetchToolResultBlockCallerUnion] + Caller ContentBlockStartEventContentBlockUnionCaller `json:"caller"` + Input any `json:"input"` + Name string `json:"name"` + // This field is a union of [WebSearchToolResultBlockContentUnion], + // [WebFetchToolResultBlockContentUnion], + // [CodeExecutionToolResultBlockContentUnion], + // [BashCodeExecutionToolResultBlockContentUnion], + // [TextEditorCodeExecutionToolResultBlockContentUnion], + // [ToolSearchToolResultBlockContentUnion] + Content ContentBlockStartEventContentBlockUnionContent `json:"content"` + ToolUseID string `json:"tool_use_id"` + // This field is from variant [ContainerUploadBlock]. + FileID string `json:"file_id"` + JSON struct { + Citations respjson.Field + Text respjson.Field + Type respjson.Field + Signature respjson.Field + Thinking respjson.Field + Data respjson.Field + ID respjson.Field + Caller respjson.Field + Input respjson.Field + Name respjson.Field + Content respjson.Field + ToolUseID respjson.Field + FileID respjson.Field + raw string + } `json:"-"` +} + +// anyContentBlockStartEventContentBlock is implemented by each variant of +// [ContentBlockStartEventContentBlockUnion] to add type safety for the return type +// of [ContentBlockStartEventContentBlockUnion.AsAny] +type anyContentBlockStartEventContentBlock interface { + implContentBlockStartEventContentBlockUnion() +} + +func (TextBlock) implContentBlockStartEventContentBlockUnion() {} +func (ThinkingBlock) implContentBlockStartEventContentBlockUnion() {} +func (RedactedThinkingBlock) implContentBlockStartEventContentBlockUnion() {} +func (ToolUseBlock) implContentBlockStartEventContentBlockUnion() {} +func (ServerToolUseBlock) implContentBlockStartEventContentBlockUnion() {} +func (WebSearchToolResultBlock) implContentBlockStartEventContentBlockUnion() {} +func (WebFetchToolResultBlock) implContentBlockStartEventContentBlockUnion() {} +func (CodeExecutionToolResultBlock) implContentBlockStartEventContentBlockUnion() {} +func (BashCodeExecutionToolResultBlock) implContentBlockStartEventContentBlockUnion() {} +func (TextEditorCodeExecutionToolResultBlock) implContentBlockStartEventContentBlockUnion() {} +func (ToolSearchToolResultBlock) implContentBlockStartEventContentBlockUnion() {} +func (ContainerUploadBlock) implContentBlockStartEventContentBlockUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := ContentBlockStartEventContentBlockUnion.AsAny().(type) { +// case anthropic.TextBlock: +// case anthropic.ThinkingBlock: +// case anthropic.RedactedThinkingBlock: +// case anthropic.ToolUseBlock: +// case anthropic.ServerToolUseBlock: +// case anthropic.WebSearchToolResultBlock: +// case anthropic.WebFetchToolResultBlock: +// case anthropic.CodeExecutionToolResultBlock: +// case anthropic.BashCodeExecutionToolResultBlock: +// case anthropic.TextEditorCodeExecutionToolResultBlock: +// case anthropic.ToolSearchToolResultBlock: +// case anthropic.ContainerUploadBlock: +// default: +// fmt.Errorf("no variant present") +// } +func (u ContentBlockStartEventContentBlockUnion) AsAny() anyContentBlockStartEventContentBlock { + switch u.Type { + case "text": + return u.AsText() + case "thinking": + return u.AsThinking() + case "redacted_thinking": + return u.AsRedactedThinking() + case "tool_use": + return u.AsToolUse() + case "server_tool_use": + return u.AsServerToolUse() + case "web_search_tool_result": + return u.AsWebSearchToolResult() + case "web_fetch_tool_result": + return u.AsWebFetchToolResult() + case "code_execution_tool_result": + return u.AsCodeExecutionToolResult() + case "bash_code_execution_tool_result": + return u.AsBashCodeExecutionToolResult() + case "text_editor_code_execution_tool_result": + return u.AsTextEditorCodeExecutionToolResult() + case "tool_search_tool_result": + return u.AsToolSearchToolResult() + case "container_upload": + return u.AsContainerUpload() + } + return nil +} + +func (u ContentBlockStartEventContentBlockUnion) AsText() (v TextBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsThinking() (v ThinkingBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsRedactedThinking() (v RedactedThinkingBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsToolUse() (v ToolUseBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsServerToolUse() (v ServerToolUseBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsWebSearchToolResult() (v WebSearchToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsWebFetchToolResult() (v WebFetchToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsCodeExecutionToolResult() (v CodeExecutionToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsBashCodeExecutionToolResult() (v BashCodeExecutionToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsTextEditorCodeExecutionToolResult() (v TextEditorCodeExecutionToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsToolSearchToolResult() (v ToolSearchToolResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ContentBlockStartEventContentBlockUnion) AsContainerUpload() (v ContainerUploadBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u ContentBlockStartEventContentBlockUnion) RawJSON() string { return u.JSON.raw } + +func (r *ContentBlockStartEventContentBlockUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ContentBlockStartEventContentBlockUnionCaller is an implicit subunion of +// [ContentBlockStartEventContentBlockUnion]. +// ContentBlockStartEventContentBlockUnionCaller provides convenient access to the +// sub-properties of the union. +// +// For type safety it is recommended to directly use a variant of the +// [ContentBlockStartEventContentBlockUnion]. +type ContentBlockStartEventContentBlockUnionCaller struct { + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +func (r *ContentBlockStartEventContentBlockUnionCaller) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ContentBlockStartEventContentBlockUnionContent is an implicit subunion of +// [ContentBlockStartEventContentBlockUnion]. +// ContentBlockStartEventContentBlockUnionContent provides convenient access to the +// sub-properties of the union. +// +// For type safety it is recommended to directly use a variant of the +// [ContentBlockStartEventContentBlockUnion]. +// +// If the underlying value is not a json object, one of the following properties +// will be valid: OfWebSearchResultBlockArray] +type ContentBlockStartEventContentBlockUnionContent struct { + // This field will be present if the value is a [[]WebSearchResultBlock] instead of + // an object. + OfWebSearchResultBlockArray []WebSearchResultBlock `json:",inline"` + ErrorCode string `json:"error_code"` + Type string `json:"type"` + // This field is a union of [DocumentBlock], [[]CodeExecutionOutputBlock], + // [[]CodeExecutionOutputBlock], [[]BashCodeExecutionOutputBlock], [string] + Content ContentBlockStartEventContentBlockUnionContentContent `json:"content"` + // This field is from variant [WebFetchToolResultBlockContentUnion]. + RetrievedAt string `json:"retrieved_at"` + // This field is from variant [WebFetchToolResultBlockContentUnion]. + URL string `json:"url"` + ReturnCode int64 `json:"return_code"` + Stderr string `json:"stderr"` + Stdout string `json:"stdout"` + // This field is from variant [CodeExecutionToolResultBlockContentUnion]. + EncryptedStdout string `json:"encrypted_stdout"` + ErrorMessage string `json:"error_message"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + FileType TextEditorCodeExecutionViewResultBlockFileType `json:"file_type"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + NumLines int64 `json:"num_lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + StartLine int64 `json:"start_line"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + TotalLines int64 `json:"total_lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + IsFileUpdate bool `json:"is_file_update"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + Lines []string `json:"lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + NewLines int64 `json:"new_lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + NewStart int64 `json:"new_start"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + OldLines int64 `json:"old_lines"` + // This field is from variant [TextEditorCodeExecutionToolResultBlockContentUnion]. + OldStart int64 `json:"old_start"` + // This field is from variant [ToolSearchToolResultBlockContentUnion]. + ToolReferences []ToolReferenceBlock `json:"tool_references"` + JSON struct { + OfWebSearchResultBlockArray respjson.Field + ErrorCode respjson.Field + Type respjson.Field + Content respjson.Field + RetrievedAt respjson.Field + URL respjson.Field + ReturnCode respjson.Field + Stderr respjson.Field + Stdout respjson.Field + EncryptedStdout respjson.Field + ErrorMessage respjson.Field + FileType respjson.Field + NumLines respjson.Field + StartLine respjson.Field + TotalLines respjson.Field + IsFileUpdate respjson.Field + Lines respjson.Field + NewLines respjson.Field + NewStart respjson.Field + OldLines respjson.Field + OldStart respjson.Field + ToolReferences respjson.Field + raw string + } `json:"-"` +} + +func (r *ContentBlockStartEventContentBlockUnionContent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ContentBlockStartEventContentBlockUnionContentContent is an implicit subunion of +// [ContentBlockStartEventContentBlockUnion]. +// ContentBlockStartEventContentBlockUnionContentContent provides convenient access +// to the sub-properties of the union. +// +// For type safety it is recommended to directly use a variant of the +// [ContentBlockStartEventContentBlockUnion]. +// +// If the underlying value is not a json object, one of the following properties +// will be valid: OfContent OfString] +type ContentBlockStartEventContentBlockUnionContentContent struct { + // This field will be present if the value is a [[]CodeExecutionOutputBlock] + // instead of an object. + OfContent []CodeExecutionOutputBlock `json:",inline"` + // This field will be present if the value is a [string] instead of an object. + OfString string `json:",inline"` + // This field is from variant [DocumentBlock]. + Citations CitationsConfig `json:"citations"` + // This field is from variant [DocumentBlock]. + Source DocumentBlockSourceUnion `json:"source"` + // This field is from variant [DocumentBlock]. + Title string `json:"title"` + // This field is from variant [DocumentBlock]. + Type constant.Document `json:"type"` + JSON struct { + OfContent respjson.Field + OfString respjson.Field + Citations respjson.Field + Source respjson.Field + Title respjson.Field + Type respjson.Field + raw string + } `json:"-"` +} + +func (r *ContentBlockStartEventContentBlockUnionContentContent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ContentBlockStopEvent struct { + Index int64 `json:"index,required"` + Type constant.ContentBlockStop `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Index respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ContentBlockStopEvent) RawJSON() string { return r.JSON.raw } +func (r *ContentBlockStopEvent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type MessageDeltaEvent struct { + Delta MessageDeltaEventDelta `json:"delta,required"` + Type constant.MessageDelta `json:"type,required"` + // Billing and rate-limit usage. + // + // Anthropic's API bills and rate-limits by token counts, as tokens represent the + // underlying cost to our systems. + // + // Under the hood, the API transforms requests into a format suitable for the + // model. The model's output then goes through a parsing stage before becoming an + // API response. As a result, the token counts in `usage` will not match one-to-one + // with the exact visible content of an API request or response. + // + // For example, `output_tokens` will be non-zero, even for an empty string response + // from Claude. + // + // Total input tokens in a request is the summation of `input_tokens`, + // `cache_creation_input_tokens`, and `cache_read_input_tokens`. + Usage MessageDeltaUsage `json:"usage,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Delta respjson.Field + Type respjson.Field + Usage respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r MessageDeltaEvent) RawJSON() string { return r.JSON.raw } +func (r *MessageDeltaEvent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type MessageDeltaEventDelta struct { + // Information about the container used in the request (for the code execution + // tool) + Container Container `json:"container,required"` + // Any of "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", + // "refusal". + StopReason StopReason `json:"stop_reason,required"` + StopSequence string `json:"stop_sequence,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Container respjson.Field + StopReason respjson.Field + StopSequence respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r MessageDeltaEventDelta) RawJSON() string { return r.JSON.raw } +func (r *MessageDeltaEventDelta) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type MessageStartEvent struct { + Message Message `json:"message,required"` + Type constant.MessageStart `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Message respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r MessageStartEvent) RawJSON() string { return r.JSON.raw } +func (r *MessageStartEvent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type MessageStopEvent struct { + Type constant.MessageStop `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r MessageStopEvent) RawJSON() string { return r.JSON.raw } +func (r *MessageStopEvent) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// MessageStreamEventUnion contains all possible properties and values from +// [MessageStartEvent], [MessageDeltaEvent], [MessageStopEvent], +// [ContentBlockStartEvent], [ContentBlockDeltaEvent], [ContentBlockStopEvent]. +// +// Use the [MessageStreamEventUnion.AsAny] method to switch on the variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type MessageStreamEventUnion struct { + // This field is from variant [MessageStartEvent]. + Message Message `json:"message"` + // Any of "message_start", "message_delta", "message_stop", "content_block_start", + // "content_block_delta", "content_block_stop". + Type string `json:"type"` + // This field is a union of [MessageDeltaEventDelta], [RawContentBlockDeltaUnion] + Delta MessageStreamEventUnionDelta `json:"delta"` + // This field is from variant [MessageDeltaEvent]. + Usage MessageDeltaUsage `json:"usage"` + // This field is from variant [ContentBlockStartEvent]. + ContentBlock ContentBlockStartEventContentBlockUnion `json:"content_block"` + Index int64 `json:"index"` + JSON struct { + Message respjson.Field + Type respjson.Field + Delta respjson.Field + Usage respjson.Field + ContentBlock respjson.Field + Index respjson.Field + raw string + } `json:"-"` +} + +// anyMessageStreamEvent is implemented by each variant of +// [MessageStreamEventUnion] to add type safety for the return type of +// [MessageStreamEventUnion.AsAny] +type anyMessageStreamEvent interface { + implMessageStreamEventUnion() +} + +func (MessageStartEvent) implMessageStreamEventUnion() {} +func (MessageDeltaEvent) implMessageStreamEventUnion() {} +func (MessageStopEvent) implMessageStreamEventUnion() {} +func (ContentBlockStartEvent) implMessageStreamEventUnion() {} +func (ContentBlockDeltaEvent) implMessageStreamEventUnion() {} +func (ContentBlockStopEvent) implMessageStreamEventUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := MessageStreamEventUnion.AsAny().(type) { +// case anthropic.MessageStartEvent: +// case anthropic.MessageDeltaEvent: +// case anthropic.MessageStopEvent: +// case anthropic.ContentBlockStartEvent: +// case anthropic.ContentBlockDeltaEvent: +// case anthropic.ContentBlockStopEvent: +// default: +// fmt.Errorf("no variant present") +// } +func (u MessageStreamEventUnion) AsAny() anyMessageStreamEvent { + switch u.Type { + case "message_start": + return u.AsMessageStart() + case "message_delta": + return u.AsMessageDelta() + case "message_stop": + return u.AsMessageStop() + case "content_block_start": + return u.AsContentBlockStart() + case "content_block_delta": + return u.AsContentBlockDelta() + case "content_block_stop": + return u.AsContentBlockStop() + } + return nil +} + +func (u MessageStreamEventUnion) AsMessageStart() (v MessageStartEvent) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageStreamEventUnion) AsMessageDelta() (v MessageDeltaEvent) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageStreamEventUnion) AsMessageStop() (v MessageStopEvent) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageStreamEventUnion) AsContentBlockStart() (v ContentBlockStartEvent) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageStreamEventUnion) AsContentBlockDelta() (v ContentBlockDeltaEvent) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u MessageStreamEventUnion) AsContentBlockStop() (v ContentBlockStopEvent) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u MessageStreamEventUnion) RawJSON() string { return u.JSON.raw } + +func (r *MessageStreamEventUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// MessageStreamEventUnionDelta is an implicit subunion of +// [MessageStreamEventUnion]. MessageStreamEventUnionDelta provides convenient +// access to the sub-properties of the union. +// +// For type safety it is recommended to directly use a variant of the +// [MessageStreamEventUnion]. +type MessageStreamEventUnionDelta struct { + // This field is from variant [MessageDeltaEventDelta]. + Container Container `json:"container"` + // This field is from variant [MessageDeltaEventDelta]. + StopReason StopReason `json:"stop_reason"` + // This field is from variant [MessageDeltaEventDelta]. + StopSequence string `json:"stop_sequence"` + // This field is from variant [RawContentBlockDeltaUnion]. + Text string `json:"text"` + Type string `json:"type"` + // This field is from variant [RawContentBlockDeltaUnion]. + PartialJSON string `json:"partial_json"` + // This field is from variant [RawContentBlockDeltaUnion]. + Citation CitationsDeltaCitationUnion `json:"citation"` + // This field is from variant [RawContentBlockDeltaUnion]. + Thinking string `json:"thinking"` + // This field is from variant [RawContentBlockDeltaUnion]. + Signature string `json:"signature"` + JSON struct { + Container respjson.Field + StopReason respjson.Field + StopSequence respjson.Field + Text respjson.Field + Type respjson.Field + PartialJSON respjson.Field + Citation respjson.Field + Thinking respjson.Field + Signature respjson.Field + raw string + } `json:"-"` +} + +func (r *MessageStreamEventUnionDelta) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type RedactedThinkingBlock struct { + Data string `json:"data,required"` + Type constant.RedactedThinking `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Data respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r RedactedThinkingBlock) RawJSON() string { return r.JSON.raw } +func (r *RedactedThinkingBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Data, Type are required. +type RedactedThinkingBlockParam struct { + Data string `json:"data,required"` + // This field can be elided, and will marshal its zero value as + // "redacted_thinking". + Type constant.RedactedThinking `json:"type,required"` + paramObj +} + +func (r RedactedThinkingBlockParam) MarshalJSON() (data []byte, err error) { + type shadow RedactedThinkingBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *RedactedThinkingBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Content, Source, Title, Type are required. +type SearchResultBlockParam struct { + Content []TextBlockParam `json:"content,omitzero,required"` + Source string `json:"source,required"` + Title string `json:"title,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + Citations CitationsConfigParam `json:"citations,omitzero"` + // This field can be elided, and will marshal its zero value as "search_result". + Type constant.SearchResult `json:"type,required"` + paramObj +} + +func (r SearchResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow SearchResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *SearchResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Tool invocation generated by a server-side tool. +type ServerToolCaller struct { + ToolID string `json:"tool_id,required"` + Type constant.CodeExecution20250825 `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ToolID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ServerToolCaller) RawJSON() string { return r.JSON.raw } +func (r *ServerToolCaller) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this ServerToolCaller to a ServerToolCallerParam. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// ServerToolCallerParam.Overrides() +func (r ServerToolCaller) ToParam() ServerToolCallerParam { + return param.Override[ServerToolCallerParam](json.RawMessage(r.RawJSON())) +} + +// Tool invocation generated by a server-side tool. +// +// The properties ToolID, Type are required. +type ServerToolCallerParam struct { + ToolID string `json:"tool_id,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_20250825". + Type constant.CodeExecution20250825 `json:"type,required"` + paramObj +} + +func (r ServerToolCallerParam) MarshalJSON() (data []byte, err error) { + type shadow ServerToolCallerParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ServerToolCallerParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ServerToolCaller20260120 struct { + ToolID string `json:"tool_id,required"` + Type constant.CodeExecution20260120 `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ToolID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ServerToolCaller20260120) RawJSON() string { return r.JSON.raw } +func (r *ServerToolCaller20260120) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ToParam converts this ServerToolCaller20260120 to a +// ServerToolCaller20260120Param. +// +// Warning: the fields of the param type will not be present. ToParam should only +// be used at the last possible moment before sending a request. Test for this with +// ServerToolCaller20260120Param.Overrides() +func (r ServerToolCaller20260120) ToParam() ServerToolCaller20260120Param { + return param.Override[ServerToolCaller20260120Param](json.RawMessage(r.RawJSON())) +} + +// The properties ToolID, Type are required. +type ServerToolCaller20260120Param struct { + ToolID string `json:"tool_id,required"` + // This field can be elided, and will marshal its zero value as + // "code_execution_20260120". + Type constant.CodeExecution20260120 `json:"type,required"` + paramObj +} + +func (r ServerToolCaller20260120Param) MarshalJSON() (data []byte, err error) { + type shadow ServerToolCaller20260120Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ServerToolCaller20260120Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ServerToolUsage struct { + // The number of web fetch tool requests. + WebFetchRequests int64 `json:"web_fetch_requests,required"` + // The number of web search tool requests. + WebSearchRequests int64 `json:"web_search_requests,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + WebFetchRequests respjson.Field + WebSearchRequests respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ServerToolUsage) RawJSON() string { return r.JSON.raw } +func (r *ServerToolUsage) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ServerToolUseBlock struct { + ID string `json:"id,required"` + // Tool invocation directly from the model. + Caller ServerToolUseBlockCallerUnion `json:"caller,required"` + Input any `json:"input,required"` + // Any of "web_search", "web_fetch", "code_execution", "bash_code_execution", + // "text_editor_code_execution", "tool_search_tool_regex", "tool_search_tool_bm25". + Name ServerToolUseBlockName `json:"name,required"` + Type constant.ServerToolUse `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + Caller respjson.Field + Input respjson.Field + Name respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ServerToolUseBlock) RawJSON() string { return r.JSON.raw } +func (r *ServerToolUseBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// ServerToolUseBlockCallerUnion contains all possible properties and values from +// [DirectCaller], [ServerToolCaller], [ServerToolCaller20260120]. +// +// Use the [ServerToolUseBlockCallerUnion.AsAny] method to switch on the variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type ServerToolUseBlockCallerUnion struct { + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +// anyServerToolUseBlockCaller is implemented by each variant of +// [ServerToolUseBlockCallerUnion] to add type safety for the return type of +// [ServerToolUseBlockCallerUnion.AsAny] +type anyServerToolUseBlockCaller interface { + implServerToolUseBlockCallerUnion() +} + +func (DirectCaller) implServerToolUseBlockCallerUnion() {} +func (ServerToolCaller) implServerToolUseBlockCallerUnion() {} +func (ServerToolCaller20260120) implServerToolUseBlockCallerUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := ServerToolUseBlockCallerUnion.AsAny().(type) { +// case anthropic.DirectCaller: +// case anthropic.ServerToolCaller: +// case anthropic.ServerToolCaller20260120: +// default: +// fmt.Errorf("no variant present") +// } +func (u ServerToolUseBlockCallerUnion) AsAny() anyServerToolUseBlockCaller { + switch u.Type { + case "direct": + return u.AsDirect() + case "code_execution_20250825": + return u.AsCodeExecution20250825() + case "code_execution_20260120": + return u.AsCodeExecution20260120() + } + return nil +} + +func (u ServerToolUseBlockCallerUnion) AsDirect() (v DirectCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ServerToolUseBlockCallerUnion) AsCodeExecution20250825() (v ServerToolCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ServerToolUseBlockCallerUnion) AsCodeExecution20260120() (v ServerToolCaller20260120) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u ServerToolUseBlockCallerUnion) RawJSON() string { return u.JSON.raw } + +func (r *ServerToolUseBlockCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ServerToolUseBlockName string + +const ( + ServerToolUseBlockNameWebSearch ServerToolUseBlockName = "web_search" + ServerToolUseBlockNameWebFetch ServerToolUseBlockName = "web_fetch" + ServerToolUseBlockNameCodeExecution ServerToolUseBlockName = "code_execution" + ServerToolUseBlockNameBashCodeExecution ServerToolUseBlockName = "bash_code_execution" + ServerToolUseBlockNameTextEditorCodeExecution ServerToolUseBlockName = "text_editor_code_execution" + ServerToolUseBlockNameToolSearchToolRegex ServerToolUseBlockName = "tool_search_tool_regex" + ServerToolUseBlockNameToolSearchToolBm25 ServerToolUseBlockName = "tool_search_tool_bm25" +) + +// The properties ID, Input, Name, Type are required. +type ServerToolUseBlockParam struct { + ID string `json:"id,required"` + Input any `json:"input,omitzero,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Tool invocation directly from the model. + Caller ServerToolUseBlockParamCallerUnion `json:"caller,omitzero"` + // Any of "web_search", "web_fetch", "code_execution", "bash_code_execution", + // "text_editor_code_execution", "tool_search_tool_regex", "tool_search_tool_bm25". + Name ServerToolUseBlockParamName `json:"name,required"` + // This field can be elided, and will marshal its zero value as "server_tool_use". + Type constant.ServerToolUse `json:"type,required"` + paramObj +} + +func (r ServerToolUseBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ServerToolUseBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ServerToolUseBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type ServerToolUseBlockParamName string + +const ( + ServerToolUseBlockParamNameWebSearch ServerToolUseBlockParamName = "web_search" + ServerToolUseBlockParamNameWebFetch ServerToolUseBlockParamName = "web_fetch" + ServerToolUseBlockParamNameCodeExecution ServerToolUseBlockParamName = "code_execution" + ServerToolUseBlockParamNameBashCodeExecution ServerToolUseBlockParamName = "bash_code_execution" + ServerToolUseBlockParamNameTextEditorCodeExecution ServerToolUseBlockParamName = "text_editor_code_execution" + ServerToolUseBlockParamNameToolSearchToolRegex ServerToolUseBlockParamName = "tool_search_tool_regex" + ServerToolUseBlockParamNameToolSearchToolBm25 ServerToolUseBlockParamName = "tool_search_tool_bm25" +) + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type ServerToolUseBlockParamCallerUnion struct { + OfDirect *DirectCallerParam `json:",omitzero,inline"` + OfCodeExecution20250825 *ServerToolCallerParam `json:",omitzero,inline"` + OfCodeExecution20260120 *ServerToolCaller20260120Param `json:",omitzero,inline"` + paramUnion +} + +func (u ServerToolUseBlockParamCallerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfDirect, u.OfCodeExecution20250825, u.OfCodeExecution20260120) +} +func (u *ServerToolUseBlockParamCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *ServerToolUseBlockParamCallerUnion) asAny() any { + if !param.IsOmitted(u.OfDirect) { + return u.OfDirect + } else if !param.IsOmitted(u.OfCodeExecution20250825) { + return u.OfCodeExecution20250825 + } else if !param.IsOmitted(u.OfCodeExecution20260120) { + return u.OfCodeExecution20260120 + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ServerToolUseBlockParamCallerUnion) GetType() *string { + if vt := u.OfDirect; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ServerToolUseBlockParamCallerUnion) GetToolID() *string { + if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.ToolID) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.ToolID) + } + return nil +} + +func init() { + apijson.RegisterUnion[ServerToolUseBlockParamCallerUnion]( + "type", + apijson.Discriminator[DirectCallerParam]("direct"), + apijson.Discriminator[ServerToolCallerParam]("code_execution_20250825"), + apijson.Discriminator[ServerToolCaller20260120Param]("code_execution_20260120"), + ) +} + +type SignatureDelta struct { + Signature string `json:"signature,required"` + Type constant.SignatureDelta `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Signature respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r SignatureDelta) RawJSON() string { return r.JSON.raw } +func (r *SignatureDelta) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type StopReason string + +const ( + StopReasonEndTurn StopReason = "end_turn" + StopReasonMaxTokens StopReason = "max_tokens" + StopReasonStopSequence StopReason = "stop_sequence" + StopReasonToolUse StopReason = "tool_use" + StopReasonPauseTurn StopReason = "pause_turn" + StopReasonRefusal StopReason = "refusal" +) + +type TextBlock struct { + // Citations supporting the text block. + // + // The type of citation returned will depend on the type of document being cited. + // Citing a PDF results in `page_location`, plain text results in `char_location`, + // and content document results in `content_block_location`. + Citations []TextCitationUnion `json:"citations,required"` + Text string `json:"text,required"` + Type constant.Text `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Citations respjson.Field + Text respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r TextBlock) RawJSON() string { return r.JSON.raw } +func (r *TextBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Text, Type are required. +type TextBlockParam struct { + Text string `json:"text,required"` + Citations []TextCitationParamUnion `json:"citations,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as "text". + Type constant.Text `json:"type,required"` + paramObj +} + +func (r TextBlockParam) MarshalJSON() (data []byte, err error) { + type shadow TextBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *TextBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// TextCitationUnion contains all possible properties and values from +// [CitationCharLocation], [CitationPageLocation], [CitationContentBlockLocation], +// [CitationsWebSearchResultLocation], [CitationsSearchResultLocation]. +// +// Use the [TextCitationUnion.AsAny] method to switch on the variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type TextCitationUnion struct { + CitedText string `json:"cited_text"` + DocumentIndex int64 `json:"document_index"` + DocumentTitle string `json:"document_title"` + // This field is from variant [CitationCharLocation]. + EndCharIndex int64 `json:"end_char_index"` + FileID string `json:"file_id"` + // This field is from variant [CitationCharLocation]. + StartCharIndex int64 `json:"start_char_index"` + // Any of "char_location", "page_location", "content_block_location", + // "web_search_result_location", "search_result_location". + Type string `json:"type"` + // This field is from variant [CitationPageLocation]. + EndPageNumber int64 `json:"end_page_number"` + // This field is from variant [CitationPageLocation]. + StartPageNumber int64 `json:"start_page_number"` + EndBlockIndex int64 `json:"end_block_index"` + StartBlockIndex int64 `json:"start_block_index"` + // This field is from variant [CitationsWebSearchResultLocation]. + EncryptedIndex string `json:"encrypted_index"` + Title string `json:"title"` + // This field is from variant [CitationsWebSearchResultLocation]. + URL string `json:"url"` + // This field is from variant [CitationsSearchResultLocation]. + SearchResultIndex int64 `json:"search_result_index"` + // This field is from variant [CitationsSearchResultLocation]. + Source string `json:"source"` + JSON struct { + CitedText respjson.Field + DocumentIndex respjson.Field + DocumentTitle respjson.Field + EndCharIndex respjson.Field + FileID respjson.Field + StartCharIndex respjson.Field + Type respjson.Field + EndPageNumber respjson.Field + StartPageNumber respjson.Field + EndBlockIndex respjson.Field + StartBlockIndex respjson.Field + EncryptedIndex respjson.Field + Title respjson.Field + URL respjson.Field + SearchResultIndex respjson.Field + Source respjson.Field + raw string + } `json:"-"` +} + +// anyTextCitation is implemented by each variant of [TextCitationUnion] to add +// type safety for the return type of [TextCitationUnion.AsAny] +type anyTextCitation interface { + implTextCitationUnion() + toParamUnion() TextCitationParamUnion +} + +func (CitationCharLocation) implTextCitationUnion() {} +func (CitationPageLocation) implTextCitationUnion() {} +func (CitationContentBlockLocation) implTextCitationUnion() {} +func (CitationsWebSearchResultLocation) implTextCitationUnion() {} +func (CitationsSearchResultLocation) implTextCitationUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := TextCitationUnion.AsAny().(type) { +// case anthropic.CitationCharLocation: +// case anthropic.CitationPageLocation: +// case anthropic.CitationContentBlockLocation: +// case anthropic.CitationsWebSearchResultLocation: +// case anthropic.CitationsSearchResultLocation: +// default: +// fmt.Errorf("no variant present") +// } +func (u TextCitationUnion) AsAny() anyTextCitation { + switch u.Type { + case "char_location": + return u.AsCharLocation() + case "page_location": + return u.AsPageLocation() + case "content_block_location": + return u.AsContentBlockLocation() + case "web_search_result_location": + return u.AsWebSearchResultLocation() + case "search_result_location": + return u.AsSearchResultLocation() + } + return nil +} + +func (u TextCitationUnion) AsCharLocation() (v CitationCharLocation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u TextCitationUnion) AsPageLocation() (v CitationPageLocation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u TextCitationUnion) AsContentBlockLocation() (v CitationContentBlockLocation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u TextCitationUnion) AsWebSearchResultLocation() (v CitationsWebSearchResultLocation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u TextCitationUnion) AsSearchResultLocation() (v CitationsSearchResultLocation) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u TextCitationUnion) RawJSON() string { return u.JSON.raw } + +func (r *TextCitationUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type TextCitationParamUnion struct { + OfCharLocation *CitationCharLocationParam `json:",omitzero,inline"` + OfPageLocation *CitationPageLocationParam `json:",omitzero,inline"` + OfContentBlockLocation *CitationContentBlockLocationParam `json:",omitzero,inline"` + OfWebSearchResultLocation *CitationWebSearchResultLocationParam `json:",omitzero,inline"` + OfSearchResultLocation *CitationSearchResultLocationParam `json:",omitzero,inline"` + paramUnion +} + +func (u TextCitationParamUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfCharLocation, + u.OfPageLocation, + u.OfContentBlockLocation, + u.OfWebSearchResultLocation, + u.OfSearchResultLocation) +} +func (u *TextCitationParamUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *TextCitationParamUnion) asAny() any { + if !param.IsOmitted(u.OfCharLocation) { + return u.OfCharLocation + } else if !param.IsOmitted(u.OfPageLocation) { + return u.OfPageLocation + } else if !param.IsOmitted(u.OfContentBlockLocation) { + return u.OfContentBlockLocation + } else if !param.IsOmitted(u.OfWebSearchResultLocation) { + return u.OfWebSearchResultLocation + } else if !param.IsOmitted(u.OfSearchResultLocation) { + return u.OfSearchResultLocation + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetEndCharIndex() *int64 { + if vt := u.OfCharLocation; vt != nil { + return &vt.EndCharIndex + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetStartCharIndex() *int64 { + if vt := u.OfCharLocation; vt != nil { + return &vt.StartCharIndex + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetEndPageNumber() *int64 { + if vt := u.OfPageLocation; vt != nil { + return &vt.EndPageNumber + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetStartPageNumber() *int64 { + if vt := u.OfPageLocation; vt != nil { + return &vt.StartPageNumber + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetEncryptedIndex() *string { + if vt := u.OfWebSearchResultLocation; vt != nil { + return &vt.EncryptedIndex + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetURL() *string { + if vt := u.OfWebSearchResultLocation; vt != nil { + return &vt.URL + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetSearchResultIndex() *int64 { + if vt := u.OfSearchResultLocation; vt != nil { + return &vt.SearchResultIndex + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetSource() *string { + if vt := u.OfSearchResultLocation; vt != nil { + return &vt.Source + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetCitedText() *string { + if vt := u.OfCharLocation; vt != nil { + return (*string)(&vt.CitedText) + } else if vt := u.OfPageLocation; vt != nil { + return (*string)(&vt.CitedText) + } else if vt := u.OfContentBlockLocation; vt != nil { + return (*string)(&vt.CitedText) + } else if vt := u.OfWebSearchResultLocation; vt != nil { + return (*string)(&vt.CitedText) + } else if vt := u.OfSearchResultLocation; vt != nil { + return (*string)(&vt.CitedText) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetDocumentIndex() *int64 { + if vt := u.OfCharLocation; vt != nil { + return (*int64)(&vt.DocumentIndex) + } else if vt := u.OfPageLocation; vt != nil { + return (*int64)(&vt.DocumentIndex) + } else if vt := u.OfContentBlockLocation; vt != nil { + return (*int64)(&vt.DocumentIndex) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetDocumentTitle() *string { + if vt := u.OfCharLocation; vt != nil && vt.DocumentTitle.Valid() { + return &vt.DocumentTitle.Value + } else if vt := u.OfPageLocation; vt != nil && vt.DocumentTitle.Valid() { + return &vt.DocumentTitle.Value + } else if vt := u.OfContentBlockLocation; vt != nil && vt.DocumentTitle.Valid() { + return &vt.DocumentTitle.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetType() *string { + if vt := u.OfCharLocation; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfPageLocation; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfContentBlockLocation; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebSearchResultLocation; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfSearchResultLocation; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetEndBlockIndex() *int64 { + if vt := u.OfContentBlockLocation; vt != nil { + return (*int64)(&vt.EndBlockIndex) + } else if vt := u.OfSearchResultLocation; vt != nil { + return (*int64)(&vt.EndBlockIndex) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetStartBlockIndex() *int64 { + if vt := u.OfContentBlockLocation; vt != nil { + return (*int64)(&vt.StartBlockIndex) + } else if vt := u.OfSearchResultLocation; vt != nil { + return (*int64)(&vt.StartBlockIndex) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextCitationParamUnion) GetTitle() *string { + if vt := u.OfWebSearchResultLocation; vt != nil && vt.Title.Valid() { + return &vt.Title.Value + } else if vt := u.OfSearchResultLocation; vt != nil && vt.Title.Valid() { + return &vt.Title.Value + } + return nil +} + +type TextDelta struct { + Text string `json:"text,required"` + Type constant.TextDelta `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - Delta respjson.Field + Text respjson.Field Type respjson.Field - Usage respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API -func (r MessageDeltaEvent) RawJSON() string { return r.JSON.raw } - -func (r *MessageDeltaEvent) UnmarshalJSON(data []byte) error { +func (r TextDelta) RawJSON() string { return r.JSON.raw } +func (r *TextDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type MessageDeltaEventDelta struct { - // Any of "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", - // "refusal", "model_context_window_exceeded". - StopReason StopReason `json:"stop_reason,required"` - StopSequence string `json:"stop_sequence,required"` +type TextEditorCodeExecutionCreateResultBlock struct { + IsFileUpdate bool `json:"is_file_update,required"` + Type constant.TextEditorCodeExecutionCreateResult `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - StopReason respjson.Field - StopSequence respjson.Field + IsFileUpdate respjson.Field + Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API -func (r MessageDeltaEventDelta) RawJSON() string { return r.JSON.raw } +func (r TextEditorCodeExecutionCreateResultBlock) RawJSON() string { return r.JSON.raw } +func (r *TextEditorCodeExecutionCreateResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r *MessageDeltaEventDelta) UnmarshalJSON(data []byte) error { +// The properties IsFileUpdate, Type are required. +type TextEditorCodeExecutionCreateResultBlockParam struct { + IsFileUpdate bool `json:"is_file_update,required"` + // This field can be elided, and will marshal its zero value as + // "text_editor_code_execution_create_result". + Type constant.TextEditorCodeExecutionCreateResult `json:"type,required"` + paramObj +} + +func (r TextEditorCodeExecutionCreateResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow TextEditorCodeExecutionCreateResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *TextEditorCodeExecutionCreateResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type MessageStartEvent struct { - Message Message `json:"message,required"` - Type constant.MessageStart `json:"type,required"` +type TextEditorCodeExecutionStrReplaceResultBlock struct { + Lines []string `json:"lines,required"` + NewLines int64 `json:"new_lines,required"` + NewStart int64 `json:"new_start,required"` + OldLines int64 `json:"old_lines,required"` + OldStart int64 `json:"old_start,required"` + Type constant.TextEditorCodeExecutionStrReplaceResult `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - Message respjson.Field + Lines respjson.Field + NewLines respjson.Field + NewStart respjson.Field + OldLines respjson.Field + OldStart respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string @@ -2529,16 +5796,40 @@ type MessageStartEvent struct { } // Returns the unmodified JSON received from the API -func (r MessageStartEvent) RawJSON() string { return r.JSON.raw } +func (r TextEditorCodeExecutionStrReplaceResultBlock) RawJSON() string { return r.JSON.raw } +func (r *TextEditorCodeExecutionStrReplaceResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r *MessageStartEvent) UnmarshalJSON(data []byte) error { +// The property Type is required. +type TextEditorCodeExecutionStrReplaceResultBlockParam struct { + NewLines param.Opt[int64] `json:"new_lines,omitzero"` + NewStart param.Opt[int64] `json:"new_start,omitzero"` + OldLines param.Opt[int64] `json:"old_lines,omitzero"` + OldStart param.Opt[int64] `json:"old_start,omitzero"` + Lines []string `json:"lines,omitzero"` + // This field can be elided, and will marshal its zero value as + // "text_editor_code_execution_str_replace_result". + Type constant.TextEditorCodeExecutionStrReplaceResult `json:"type,required"` + paramObj +} + +func (r TextEditorCodeExecutionStrReplaceResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow TextEditorCodeExecutionStrReplaceResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *TextEditorCodeExecutionStrReplaceResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type MessageStopEvent struct { - Type constant.MessageStop `json:"type,required"` +type TextEditorCodeExecutionToolResultBlock struct { + Content TextEditorCodeExecutionToolResultBlockContentUnion `json:"content,required"` + ToolUseID string `json:"tool_use_id,required"` + Type constant.TextEditorCodeExecutionToolResult `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { + Content respjson.Field + ToolUseID respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string @@ -2546,245 +5837,386 @@ type MessageStopEvent struct { } // Returns the unmodified JSON received from the API -func (r MessageStopEvent) RawJSON() string { return r.JSON.raw } - -func (r *MessageStopEvent) UnmarshalJSON(data []byte) error { +func (r TextEditorCodeExecutionToolResultBlock) RawJSON() string { return r.JSON.raw } +func (r *TextEditorCodeExecutionToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// MessageStreamEventUnion contains all possible properties and values from -// [MessageStartEvent], [MessageDeltaEvent], [MessageStopEvent], -// [ContentBlockStartEvent], [ContentBlockDeltaEvent], [ContentBlockStopEvent]. -// -// Use the [MessageStreamEventUnion.AsAny] method to switch on the variant. +// TextEditorCodeExecutionToolResultBlockContentUnion contains all possible +// properties and values from [TextEditorCodeExecutionToolResultError], +// [TextEditorCodeExecutionViewResultBlock], +// [TextEditorCodeExecutionCreateResultBlock], +// [TextEditorCodeExecutionStrReplaceResultBlock]. // // Use the methods beginning with 'As' to cast the union to one of its variants. -type MessageStreamEventUnion struct { - // This field is from variant [MessageStartEvent]. - Message Message `json:"message"` - // Any of "message_start", "message_delta", "message_stop", "content_block_start", - // "content_block_delta", "content_block_stop". - Type string `json:"type"` - // This field is a union of [MessageDeltaEventDelta], [RawContentBlockDeltaUnion] - Delta MessageStreamEventUnionDelta `json:"delta"` - // This field is from variant [MessageDeltaEvent]. - Usage MessageDeltaUsage `json:"usage"` - // This field is from variant [ContentBlockStartEvent]. - ContentBlock ContentBlockStartEventContentBlockUnion `json:"content_block"` - Index int64 `json:"index"` - JSON struct { - Message respjson.Field +type TextEditorCodeExecutionToolResultBlockContentUnion struct { + // This field is from variant [TextEditorCodeExecutionToolResultError]. + ErrorCode TextEditorCodeExecutionToolResultErrorCode `json:"error_code"` + // This field is from variant [TextEditorCodeExecutionToolResultError]. + ErrorMessage string `json:"error_message"` + Type string `json:"type"` + // This field is from variant [TextEditorCodeExecutionViewResultBlock]. + Content string `json:"content"` + // This field is from variant [TextEditorCodeExecutionViewResultBlock]. + FileType TextEditorCodeExecutionViewResultBlockFileType `json:"file_type"` + // This field is from variant [TextEditorCodeExecutionViewResultBlock]. + NumLines int64 `json:"num_lines"` + // This field is from variant [TextEditorCodeExecutionViewResultBlock]. + StartLine int64 `json:"start_line"` + // This field is from variant [TextEditorCodeExecutionViewResultBlock]. + TotalLines int64 `json:"total_lines"` + // This field is from variant [TextEditorCodeExecutionCreateResultBlock]. + IsFileUpdate bool `json:"is_file_update"` + // This field is from variant [TextEditorCodeExecutionStrReplaceResultBlock]. + Lines []string `json:"lines"` + // This field is from variant [TextEditorCodeExecutionStrReplaceResultBlock]. + NewLines int64 `json:"new_lines"` + // This field is from variant [TextEditorCodeExecutionStrReplaceResultBlock]. + NewStart int64 `json:"new_start"` + // This field is from variant [TextEditorCodeExecutionStrReplaceResultBlock]. + OldLines int64 `json:"old_lines"` + // This field is from variant [TextEditorCodeExecutionStrReplaceResultBlock]. + OldStart int64 `json:"old_start"` + JSON struct { + ErrorCode respjson.Field + ErrorMessage respjson.Field Type respjson.Field - Delta respjson.Field - Usage respjson.Field - ContentBlock respjson.Field - Index respjson.Field + Content respjson.Field + FileType respjson.Field + NumLines respjson.Field + StartLine respjson.Field + TotalLines respjson.Field + IsFileUpdate respjson.Field + Lines respjson.Field + NewLines respjson.Field + NewStart respjson.Field + OldLines respjson.Field + OldStart respjson.Field raw string } `json:"-"` } -// anyMessageStreamEvent is implemented by each variant of -// [MessageStreamEventUnion] to add type safety for the return type of -// [MessageStreamEventUnion.AsAny] -type anyMessageStreamEvent interface { - implMessageStreamEventUnion() +func (u TextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionToolResultError() (v TextEditorCodeExecutionToolResultError) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (MessageStartEvent) implMessageStreamEventUnion() {} -func (MessageDeltaEvent) implMessageStreamEventUnion() {} -func (MessageStopEvent) implMessageStreamEventUnion() {} -func (ContentBlockStartEvent) implMessageStreamEventUnion() {} -func (ContentBlockDeltaEvent) implMessageStreamEventUnion() {} -func (ContentBlockStopEvent) implMessageStreamEventUnion() {} +func (u TextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionViewResultBlock() (v TextEditorCodeExecutionViewResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} -// Use the following switch statement to find the correct variant +func (u TextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionCreateResultBlock() (v TextEditorCodeExecutionCreateResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u TextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionStrReplaceResultBlock() (v TextEditorCodeExecutionStrReplaceResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u TextEditorCodeExecutionToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } + +func (r *TextEditorCodeExecutionToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Content, ToolUseID, Type are required. +type TextEditorCodeExecutionToolResultBlockParam struct { + Content TextEditorCodeExecutionToolResultBlockParamContentUnion `json:"content,omitzero,required"` + ToolUseID string `json:"tool_use_id,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as + // "text_editor_code_execution_tool_result". + Type constant.TextEditorCodeExecutionToolResult `json:"type,required"` + paramObj +} + +func (r TextEditorCodeExecutionToolResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow TextEditorCodeExecutionToolResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *TextEditorCodeExecutionToolResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Only one field can be non-zero. // -// switch variant := MessageStreamEventUnion.AsAny().(type) { -// case anthropic.MessageStartEvent: -// case anthropic.MessageDeltaEvent: -// case anthropic.MessageStopEvent: -// case anthropic.ContentBlockStartEvent: -// case anthropic.ContentBlockDeltaEvent: -// case anthropic.ContentBlockStopEvent: -// default: -// fmt.Errorf("no variant present") -// } -func (u MessageStreamEventUnion) AsAny() anyMessageStreamEvent { - switch u.Type { - case "message_start": - return u.AsMessageStart() - case "message_delta": - return u.AsMessageDelta() - case "message_stop": - return u.AsMessageStop() - case "content_block_start": - return u.AsContentBlockStart() - case "content_block_delta": - return u.AsContentBlockDelta() - case "content_block_stop": - return u.AsContentBlockStop() +// Use [param.IsOmitted] to confirm if a field is set. +type TextEditorCodeExecutionToolResultBlockParamContentUnion struct { + OfRequestTextEditorCodeExecutionToolResultError *TextEditorCodeExecutionToolResultErrorParam `json:",omitzero,inline"` + OfRequestTextEditorCodeExecutionViewResultBlock *TextEditorCodeExecutionViewResultBlockParam `json:",omitzero,inline"` + OfRequestTextEditorCodeExecutionCreateResultBlock *TextEditorCodeExecutionCreateResultBlockParam `json:",omitzero,inline"` + OfRequestTextEditorCodeExecutionStrReplaceResultBlock *TextEditorCodeExecutionStrReplaceResultBlockParam `json:",omitzero,inline"` + paramUnion +} + +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfRequestTextEditorCodeExecutionToolResultError, u.OfRequestTextEditorCodeExecutionViewResultBlock, u.OfRequestTextEditorCodeExecutionCreateResultBlock, u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock) +} +func (u *TextEditorCodeExecutionToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *TextEditorCodeExecutionToolResultBlockParamContentUnion) asAny() any { + if !param.IsOmitted(u.OfRequestTextEditorCodeExecutionToolResultError) { + return u.OfRequestTextEditorCodeExecutionToolResultError + } else if !param.IsOmitted(u.OfRequestTextEditorCodeExecutionViewResultBlock) { + return u.OfRequestTextEditorCodeExecutionViewResultBlock + } else if !param.IsOmitted(u.OfRequestTextEditorCodeExecutionCreateResultBlock) { + return u.OfRequestTextEditorCodeExecutionCreateResultBlock + } else if !param.IsOmitted(u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock) { + return u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock } return nil } -func (u MessageStreamEventUnion) AsMessageStart() (v MessageStartEvent) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetErrorCode() *string { + if vt := u.OfRequestTextEditorCodeExecutionToolResultError; vt != nil { + return (*string)(&vt.ErrorCode) + } + return nil } -func (u MessageStreamEventUnion) AsMessageDelta() (v MessageDeltaEvent) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetErrorMessage() *string { + if vt := u.OfRequestTextEditorCodeExecutionToolResultError; vt != nil && vt.ErrorMessage.Valid() { + return &vt.ErrorMessage.Value + } + return nil } -func (u MessageStreamEventUnion) AsMessageStop() (v MessageStopEvent) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetContent() *string { + if vt := u.OfRequestTextEditorCodeExecutionViewResultBlock; vt != nil { + return &vt.Content + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetFileType() *string { + if vt := u.OfRequestTextEditorCodeExecutionViewResultBlock; vt != nil { + return (*string)(&vt.FileType) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetNumLines() *int64 { + if vt := u.OfRequestTextEditorCodeExecutionViewResultBlock; vt != nil && vt.NumLines.Valid() { + return &vt.NumLines.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetStartLine() *int64 { + if vt := u.OfRequestTextEditorCodeExecutionViewResultBlock; vt != nil && vt.StartLine.Valid() { + return &vt.StartLine.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetTotalLines() *int64 { + if vt := u.OfRequestTextEditorCodeExecutionViewResultBlock; vt != nil && vt.TotalLines.Valid() { + return &vt.TotalLines.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetIsFileUpdate() *bool { + if vt := u.OfRequestTextEditorCodeExecutionCreateResultBlock; vt != nil { + return &vt.IsFileUpdate + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetLines() []string { + if vt := u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock; vt != nil { + return vt.Lines + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetNewLines() *int64 { + if vt := u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock; vt != nil && vt.NewLines.Valid() { + return &vt.NewLines.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetNewStart() *int64 { + if vt := u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock; vt != nil && vt.NewStart.Valid() { + return &vt.NewStart.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetOldLines() *int64 { + if vt := u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock; vt != nil && vt.OldLines.Valid() { + return &vt.OldLines.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetOldStart() *int64 { + if vt := u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock; vt != nil && vt.OldStart.Valid() { + return &vt.OldStart.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u TextEditorCodeExecutionToolResultBlockParamContentUnion) GetType() *string { + if vt := u.OfRequestTextEditorCodeExecutionToolResultError; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRequestTextEditorCodeExecutionViewResultBlock; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRequestTextEditorCodeExecutionCreateResultBlock; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRequestTextEditorCodeExecutionStrReplaceResultBlock; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +type TextEditorCodeExecutionToolResultError struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded", "file_not_found". + ErrorCode TextEditorCodeExecutionToolResultErrorCode `json:"error_code,required"` + ErrorMessage string `json:"error_message,required"` + Type constant.TextEditorCodeExecutionToolResultError `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ErrorCode respjson.Field + ErrorMessage respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r TextEditorCodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } +func (r *TextEditorCodeExecutionToolResultError) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type TextEditorCodeExecutionToolResultErrorCode string + +const ( + TextEditorCodeExecutionToolResultErrorCodeInvalidToolInput TextEditorCodeExecutionToolResultErrorCode = "invalid_tool_input" + TextEditorCodeExecutionToolResultErrorCodeUnavailable TextEditorCodeExecutionToolResultErrorCode = "unavailable" + TextEditorCodeExecutionToolResultErrorCodeTooManyRequests TextEditorCodeExecutionToolResultErrorCode = "too_many_requests" + TextEditorCodeExecutionToolResultErrorCodeExecutionTimeExceeded TextEditorCodeExecutionToolResultErrorCode = "execution_time_exceeded" + TextEditorCodeExecutionToolResultErrorCodeFileNotFound TextEditorCodeExecutionToolResultErrorCode = "file_not_found" +) + +// The properties ErrorCode, Type are required. +type TextEditorCodeExecutionToolResultErrorParam struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded", "file_not_found". + ErrorCode TextEditorCodeExecutionToolResultErrorCode `json:"error_code,omitzero,required"` + ErrorMessage param.Opt[string] `json:"error_message,omitzero"` + // This field can be elided, and will marshal its zero value as + // "text_editor_code_execution_tool_result_error". + Type constant.TextEditorCodeExecutionToolResultError `json:"type,required"` + paramObj } -func (u MessageStreamEventUnion) AsContentBlockStart() (v ContentBlockStartEvent) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (r TextEditorCodeExecutionToolResultErrorParam) MarshalJSON() (data []byte, err error) { + type shadow TextEditorCodeExecutionToolResultErrorParam + return param.MarshalObject(r, (*shadow)(&r)) } - -func (u MessageStreamEventUnion) AsContentBlockDelta() (v ContentBlockDeltaEvent) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (r *TextEditorCodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u MessageStreamEventUnion) AsContentBlockStop() (v ContentBlockStopEvent) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +type TextEditorCodeExecutionViewResultBlock struct { + Content string `json:"content,required"` + // Any of "text", "image", "pdf". + FileType TextEditorCodeExecutionViewResultBlockFileType `json:"file_type,required"` + NumLines int64 `json:"num_lines,required"` + StartLine int64 `json:"start_line,required"` + TotalLines int64 `json:"total_lines,required"` + Type constant.TextEditorCodeExecutionViewResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + FileType respjson.Field + NumLines respjson.Field + StartLine respjson.Field + TotalLines respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } // Returns the unmodified JSON received from the API -func (u MessageStreamEventUnion) RawJSON() string { return u.JSON.raw } - -func (r *MessageStreamEventUnion) UnmarshalJSON(data []byte) error { +func (r TextEditorCodeExecutionViewResultBlock) RawJSON() string { return r.JSON.raw } +func (r *TextEditorCodeExecutionViewResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// MessageStreamEventUnionDelta is an implicit subunion of -// [MessageStreamEventUnion]. MessageStreamEventUnionDelta provides convenient -// access to the sub-properties of the union. -// -// For type safety it is recommended to directly use a variant of the -// [MessageStreamEventUnion]. -type MessageStreamEventUnionDelta struct { - // This field is from variant [MessageDeltaEventDelta]. - StopReason StopReason `json:"stop_reason"` - // This field is from variant [MessageDeltaEventDelta]. - StopSequence string `json:"stop_sequence"` - // This field is from variant [RawContentBlockDeltaUnion]. - Text string `json:"text"` - Type string `json:"type"` - // This field is from variant [RawContentBlockDeltaUnion]. - PartialJSON string `json:"partial_json"` - // This field is from variant [RawContentBlockDeltaUnion]. - Citation CitationsDeltaCitationUnion `json:"citation"` - // This field is from variant [RawContentBlockDeltaUnion]. - Thinking string `json:"thinking"` - // This field is from variant [RawContentBlockDeltaUnion]. - Signature string `json:"signature"` - JSON struct { - StopReason respjson.Field - StopSequence respjson.Field - Text respjson.Field - Type respjson.Field - PartialJSON respjson.Field - Citation respjson.Field - Thinking respjson.Field - Signature respjson.Field - raw string - } `json:"-"` +type TextEditorCodeExecutionViewResultBlockFileType string + +const ( + TextEditorCodeExecutionViewResultBlockFileTypeText TextEditorCodeExecutionViewResultBlockFileType = "text" + TextEditorCodeExecutionViewResultBlockFileTypeImage TextEditorCodeExecutionViewResultBlockFileType = "image" + TextEditorCodeExecutionViewResultBlockFileTypePDF TextEditorCodeExecutionViewResultBlockFileType = "pdf" +) + +// The properties Content, FileType, Type are required. +type TextEditorCodeExecutionViewResultBlockParam struct { + Content string `json:"content,required"` + // Any of "text", "image", "pdf". + FileType TextEditorCodeExecutionViewResultBlockParamFileType `json:"file_type,omitzero,required"` + NumLines param.Opt[int64] `json:"num_lines,omitzero"` + StartLine param.Opt[int64] `json:"start_line,omitzero"` + TotalLines param.Opt[int64] `json:"total_lines,omitzero"` + // This field can be elided, and will marshal its zero value as + // "text_editor_code_execution_view_result". + Type constant.TextEditorCodeExecutionViewResult `json:"type,required"` + paramObj } -func (r *MessageStreamEventUnionDelta) UnmarshalJSON(data []byte) error { +func (r TextEditorCodeExecutionViewResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow TextEditorCodeExecutionViewResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *TextEditorCodeExecutionViewResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Accumulate builds up the Message incrementally from a MessageStreamEvent. The Message then can be used as -// any other Message, except with the caveat that the Message.JSON field which normally can be used to inspect -// the JSON sent over the network may not be populated fully. -// -// message := anthropic.Message{} -// for stream.Next() { -// event := stream.Current() -// message.Accumulate(event) -// } -func (acc *Message) Accumulate(event MessageStreamEventUnion) error { - if acc == nil { - return fmt.Errorf("accumulate: cannot accumlate into nil Message") - } - - switch event := event.AsAny().(type) { - case MessageStartEvent: - *acc = event.Message - case MessageDeltaEvent: - acc.StopReason = event.Delta.StopReason - acc.StopSequence = event.Delta.StopSequence - acc.Usage.OutputTokens = event.Usage.OutputTokens - case MessageStopEvent: - accJson, err := json.Marshal(acc) - if err != nil { - return fmt.Errorf("error converting content block to JSON: %w", err) - } - acc.JSON.raw = string(accJson) - case ContentBlockStartEvent: - acc.Content = append(acc.Content, ContentBlockUnion{}) - err := acc.Content[len(acc.Content)-1].UnmarshalJSON([]byte(event.ContentBlock.RawJSON())) - if err != nil { - return err - } - case ContentBlockDeltaEvent: - if len(acc.Content) == 0 { - return fmt.Errorf("received event of type %s but there was no content block", event.Type) - } - cb := &acc.Content[len(acc.Content)-1] - switch delta := event.Delta.AsAny().(type) { - case TextDelta: - cb.Text += delta.Text - case InputJSONDelta: - if len(delta.PartialJSON) != 0 { - if string(cb.Input) == "{}" { - cb.Input = []byte(delta.PartialJSON) - } else { - cb.Input = append(cb.Input, []byte(delta.PartialJSON)...) - } - } - case ThinkingDelta: - cb.Thinking += delta.Thinking - case SignatureDelta: - cb.Signature += delta.Signature - case CitationsDelta: - citation := TextCitationUnion{} - err := citation.UnmarshalJSON([]byte(delta.Citation.RawJSON())) - if err != nil { - return fmt.Errorf("could not unmarshal citation delta into citation type: %w", err) - } - cb.Citations = append(cb.Citations, citation) - } - case ContentBlockStopEvent: - if len(acc.Content) == 0 { - return fmt.Errorf("received event of type %s but there was no content block", event.Type) - } - contentBlock := &acc.Content[len(acc.Content)-1] - cbJson, err := json.Marshal(contentBlock) - if err != nil { - return fmt.Errorf("error converting content block to JSON: %w", err) - } - contentBlock.JSON.raw = string(cbJson) - } +type TextEditorCodeExecutionViewResultBlockParamFileType string - return nil -} +const ( + TextEditorCodeExecutionViewResultBlockParamFileTypeText TextEditorCodeExecutionViewResultBlockParamFileType = "text" + TextEditorCodeExecutionViewResultBlockParamFileTypeImage TextEditorCodeExecutionViewResultBlockParamFileType = "image" + TextEditorCodeExecutionViewResultBlockParamFileTypePDF TextEditorCodeExecutionViewResultBlockParamFileType = "pdf" +) -type RedactedThinkingBlock struct { - Data string `json:"data,required"` - Type constant.RedactedThinking `json:"type,required"` +type ThinkingBlock struct { + Signature string `json:"signature,required"` + Thinking string `json:"thinking,required"` + Type constant.Thinking `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - Data respjson.Field + Signature respjson.Field + Thinking respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string @@ -2792,585 +6224,814 @@ type RedactedThinkingBlock struct { } // Returns the unmodified JSON received from the API -func (r RedactedThinkingBlock) RawJSON() string { return r.JSON.raw } +func (r ThinkingBlock) RawJSON() string { return r.JSON.raw } +func (r *ThinkingBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r *RedactedThinkingBlock) UnmarshalJSON(data []byte) error { +// The properties Signature, Thinking, Type are required. +type ThinkingBlockParam struct { + Signature string `json:"signature,required"` + Thinking string `json:"thinking,required"` + // This field can be elided, and will marshal its zero value as "thinking". + Type constant.Thinking `json:"type,required"` + paramObj +} + +func (r ThinkingBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ThinkingBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ThinkingBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r RedactedThinkingBlock) ToParam() RedactedThinkingBlockParam { - var p RedactedThinkingBlockParam - p.Type = r.Type - p.Data = r.Data - return p +func NewThinkingConfigAdaptiveParam() ThinkingConfigAdaptiveParam { + return ThinkingConfigAdaptiveParam{ + Type: "adaptive", + } } -// The properties Data, Type are required. -type RedactedThinkingBlockParam struct { - Data string `json:"data,required"` - // This field can be elided, and will marshal its zero value as - // "redacted_thinking". - Type constant.RedactedThinking `json:"type,required"` +// This struct has a constant value, construct it with +// [NewThinkingConfigAdaptiveParam]. +type ThinkingConfigAdaptiveParam struct { + Type constant.Adaptive `json:"type,required"` paramObj } -func (r RedactedThinkingBlockParam) MarshalJSON() (data []byte, err error) { - type shadow RedactedThinkingBlockParam +func (r ThinkingConfigAdaptiveParam) MarshalJSON() (data []byte, err error) { + type shadow ThinkingConfigAdaptiveParam return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *RedactedThinkingBlockParam) UnmarshalJSON(data []byte) error { +func (r *ThinkingConfigAdaptiveParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// The properties Content, Source, Title, Type are required. -type SearchResultBlockParam struct { - Content []TextBlockParam `json:"content,omitzero,required"` - Source string `json:"source,required"` - Title string `json:"title,required"` - // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` - Citations CitationsConfigParam `json:"citations,omitzero"` - // This field can be elided, and will marshal its zero value as "search_result". - Type constant.SearchResult `json:"type,required"` +func NewThinkingConfigDisabledParam() ThinkingConfigDisabledParam { + return ThinkingConfigDisabledParam{ + Type: "disabled", + } +} + +// This struct has a constant value, construct it with +// [NewThinkingConfigDisabledParam]. +type ThinkingConfigDisabledParam struct { + Type constant.Disabled `json:"type,required"` paramObj } -func (r SearchResultBlockParam) MarshalJSON() (data []byte, err error) { - type shadow SearchResultBlockParam +func (r ThinkingConfigDisabledParam) MarshalJSON() (data []byte, err error) { + type shadow ThinkingConfigDisabledParam return param.MarshalObject(r, (*shadow)(&r)) } +func (r *ThinkingConfigDisabledParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r *SearchResultBlockParam) UnmarshalJSON(data []byte) error { +// The properties BudgetTokens, Type are required. +type ThinkingConfigEnabledParam struct { + // Determines how many tokens Claude can use for its internal reasoning process. + // Larger budgets can enable more thorough analysis for complex problems, improving + // response quality. + // + // Must be ≥1024 and less than `max_tokens`. + // + // See + // [extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking) + // for details. + BudgetTokens int64 `json:"budget_tokens,required"` + // This field can be elided, and will marshal its zero value as "enabled". + Type constant.Enabled `json:"type,required"` + paramObj +} + +func (r ThinkingConfigEnabledParam) MarshalJSON() (data []byte, err error) { + type shadow ThinkingConfigEnabledParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ThinkingConfigEnabledParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type ServerToolUsage struct { - // The number of web search tool requests. - WebSearchRequests int64 `json:"web_search_requests,required"` +func ThinkingConfigParamOfEnabled(budgetTokens int64) ThinkingConfigParamUnion { + var enabled ThinkingConfigEnabledParam + enabled.BudgetTokens = budgetTokens + return ThinkingConfigParamUnion{OfEnabled: &enabled} +} + +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type ThinkingConfigParamUnion struct { + OfEnabled *ThinkingConfigEnabledParam `json:",omitzero,inline"` + OfDisabled *ThinkingConfigDisabledParam `json:",omitzero,inline"` + OfAdaptive *ThinkingConfigAdaptiveParam `json:",omitzero,inline"` + paramUnion +} + +func (u ThinkingConfigParamUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfEnabled, u.OfDisabled, u.OfAdaptive) +} +func (u *ThinkingConfigParamUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *ThinkingConfigParamUnion) asAny() any { + if !param.IsOmitted(u.OfEnabled) { + return u.OfEnabled + } else if !param.IsOmitted(u.OfDisabled) { + return u.OfDisabled + } else if !param.IsOmitted(u.OfAdaptive) { + return u.OfAdaptive + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ThinkingConfigParamUnion) GetBudgetTokens() *int64 { + if vt := u.OfEnabled; vt != nil { + return &vt.BudgetTokens + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ThinkingConfigParamUnion) GetType() *string { + if vt := u.OfEnabled; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfDisabled; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfAdaptive; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + + +type ThinkingDelta struct { + Thinking string `json:"thinking,required"` + Type constant.ThinkingDelta `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - WebSearchRequests respjson.Field - ExtraFields map[string]respjson.Field - raw string + Thinking respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string } `json:"-"` } -// Returns the unmodified JSON received from the API -func (r ServerToolUsage) RawJSON() string { return r.JSON.raw } - -func (r *ServerToolUsage) UnmarshalJSON(data []byte) error { +// Returns the unmodified JSON received from the API +func (r ThinkingDelta) RawJSON() string { return r.JSON.raw } +func (r *ThinkingDelta) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties InputSchema, Name are required. +type ToolParam struct { + // [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. + // + // This defines the shape of the `input` that your tool accepts and that the model + // will produce. + InputSchema ToolInputSchemaParam `json:"input_schema,omitzero,required"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + Name string `json:"name,required"` + // Enable eager input streaming for this tool. When true, tool input parameters + // will be streamed incrementally as they are generated, and types will be inferred + // on-the-fly rather than buffering the full JSON output. When false, streaming is + // disabled for this tool even if the fine-grained-tool-streaming beta is active. + // When null (default), uses the default behavior based on beta headers. + EagerInputStreaming param.Opt[bool] `json:"eager_input_streaming,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // Description of what this tool does. + // + // Tool descriptions should be as detailed as possible. The more information that + // the model has about what the tool is and how to use it, the better it will + // perform. You can use natural language descriptions to reinforce important + // aspects of the tool input JSON schema. + Description param.Opt[string] `json:"description,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "custom". + Type ToolType `json:"type,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` + paramObj +} + +func (r ToolParam) MarshalJSON() (data []byte, err error) { + type shadow ToolParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type ServerToolUseBlock struct { - ID string `json:"id,required"` - Input any `json:"input,required"` - Name constant.WebSearch `json:"name,required"` - Type constant.ServerToolUse `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - ID respjson.Field - Input respjson.Field - Name respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +// [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. +// +// This defines the shape of the `input` that your tool accepts and that the model +// will produce. +// +// The property Type is required. +type ToolInputSchemaParam struct { + Properties any `json:"properties,omitzero"` + Required []string `json:"required,omitzero"` + // This field can be elided, and will marshal its zero value as "object". + Type constant.Object `json:"type,required"` + ExtraFields map[string]any `json:"-"` + paramObj } -// Returns the unmodified JSON received from the API -func (r ServerToolUseBlock) RawJSON() string { return r.JSON.raw } - -func (r *ServerToolUseBlock) UnmarshalJSON(data []byte) error { +func (r ToolInputSchemaParam) MarshalJSON() (data []byte, err error) { + type shadow ToolInputSchemaParam + return param.MarshalWithExtras(r, (*shadow)(&r), r.ExtraFields) +} +func (r *ToolInputSchemaParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// The properties ID, Input, Name, Type are required. -type ServerToolUseBlockParam struct { - ID string `json:"id,required"` - Input any `json:"input,omitzero,required"` +type ToolType string + +const ( + ToolTypeCustom ToolType = "custom" +) + +// The properties Name, Type are required. +type ToolBash20250124Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` - // This field can be elided, and will marshal its zero value as "web_search". - Name constant.WebSearch `json:"name,required"` - // This field can be elided, and will marshal its zero value as "server_tool_use". - Type constant.ServerToolUse `json:"type,required"` + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "bash". + Name constant.Bash `json:"name,required"` + // This field can be elided, and will marshal its zero value as "bash_20250124". + Type constant.Bash20250124 `json:"type,required"` paramObj } -func (r ServerToolUseBlockParam) MarshalJSON() (data []byte, err error) { - type shadow ServerToolUseBlockParam +func (r ToolBash20250124Param) MarshalJSON() (data []byte, err error) { + type shadow ToolBash20250124Param return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ServerToolUseBlockParam) UnmarshalJSON(data []byte) error { +func (r *ToolBash20250124Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type SignatureDelta struct { - Signature string `json:"signature,required"` - Type constant.SignatureDelta `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Signature respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +func ToolChoiceParamOfTool(name string) ToolChoiceUnionParam { + var tool ToolChoiceToolParam + tool.Name = name + return ToolChoiceUnionParam{OfTool: &tool} } -// Returns the unmodified JSON received from the API -func (r SignatureDelta) RawJSON() string { return r.JSON.raw } - -func (r *SignatureDelta) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type ToolChoiceUnionParam struct { + OfAuto *ToolChoiceAutoParam `json:",omitzero,inline"` + OfAny *ToolChoiceAnyParam `json:",omitzero,inline"` + OfTool *ToolChoiceToolParam `json:",omitzero,inline"` + OfNone *ToolChoiceNoneParam `json:",omitzero,inline"` + paramUnion } -type StopReason string - -const ( - StopReasonEndTurn StopReason = "end_turn" - StopReasonMaxTokens StopReason = "max_tokens" - StopReasonStopSequence StopReason = "stop_sequence" - StopReasonToolUse StopReason = "tool_use" - StopReasonPauseTurn StopReason = "pause_turn" - StopReasonRefusal StopReason = "refusal" - StopReasonModelContextWindowExceeded StopReason = "model_context_window_exceeded" -) +func (u ToolChoiceUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfAuto, u.OfAny, u.OfTool, u.OfNone) +} +func (u *ToolChoiceUnionParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} -type TextBlock struct { - // Citations supporting the text block. - // - // The type of citation returned will depend on the type of document being cited. - // Citing a PDF results in `page_location`, plain text results in `char_location`, - // and content document results in `content_block_location`. - Citations []TextCitationUnion `json:"citations,required"` - Text string `json:"text,required"` - Type constant.Text `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Citations respjson.Field - Text respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +func (u *ToolChoiceUnionParam) asAny() any { + if !param.IsOmitted(u.OfAuto) { + return u.OfAuto + } else if !param.IsOmitted(u.OfAny) { + return u.OfAny + } else if !param.IsOmitted(u.OfTool) { + return u.OfTool + } else if !param.IsOmitted(u.OfNone) { + return u.OfNone + } + return nil } -// Returns the unmodified JSON received from the API -func (r TextBlock) RawJSON() string { return r.JSON.raw } +// Returns a pointer to the underlying variant's property, if present. +func (u ToolChoiceUnionParam) GetName() *string { + if vt := u.OfTool; vt != nil { + return &vt.Name + } + return nil +} -func (r *TextBlock) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's property, if present. +func (u ToolChoiceUnionParam) GetType() *string { + if vt := u.OfAuto; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfAny; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfTool; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfNone; vt != nil { + return (*string)(&vt.Type) + } + return nil } -func (r TextBlock) ToParam() TextBlockParam { - var p TextBlockParam - p.Type = r.Type - p.Text = r.Text - - // Distinguish between a nil and zero length slice, since some compatible - // APIs may not require citations. - if r.Citations != nil { - p.Citations = make([]TextCitationParamUnion, len(r.Citations)) - } - - for i, citation := range r.Citations { - switch citationVariant := citation.AsAny().(type) { - case CitationCharLocation: - var citationParam CitationCharLocationParam - citationParam.Type = citationVariant.Type - citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) - citationParam.CitedText = citationVariant.CitedText - citationParam.DocumentIndex = citationVariant.DocumentIndex - citationParam.EndCharIndex = citationVariant.EndCharIndex - citationParam.StartCharIndex = citationVariant.StartCharIndex - p.Citations[i] = TextCitationParamUnion{OfCharLocation: &citationParam} - case CitationPageLocation: - var citationParam CitationPageLocationParam - citationParam.Type = citationVariant.Type - citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) - citationParam.DocumentIndex = citationVariant.DocumentIndex - citationParam.EndPageNumber = citationVariant.EndPageNumber - citationParam.StartPageNumber = citationVariant.StartPageNumber - p.Citations[i] = TextCitationParamUnion{OfPageLocation: &citationParam} - case CitationContentBlockLocation: - var citationParam CitationContentBlockLocationParam - citationParam.Type = citationVariant.Type - citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) - citationParam.CitedText = citationVariant.CitedText - citationParam.DocumentIndex = citationVariant.DocumentIndex - citationParam.EndBlockIndex = citationVariant.EndBlockIndex - citationParam.StartBlockIndex = citationVariant.StartBlockIndex - p.Citations[i] = TextCitationParamUnion{OfContentBlockLocation: &citationParam} - } +// Returns a pointer to the underlying variant's property, if present. +func (u ToolChoiceUnionParam) GetDisableParallelToolUse() *bool { + if vt := u.OfAuto; vt != nil && vt.DisableParallelToolUse.Valid() { + return &vt.DisableParallelToolUse.Value + } else if vt := u.OfAny; vt != nil && vt.DisableParallelToolUse.Valid() { + return &vt.DisableParallelToolUse.Value + } else if vt := u.OfTool; vt != nil && vt.DisableParallelToolUse.Valid() { + return &vt.DisableParallelToolUse.Value } - return p + return nil } -// The properties Text, Type are required. -type TextBlockParam struct { - Text string `json:"text,required"` - Citations []TextCitationParamUnion `json:"citations,omitzero"` - // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` - // This field can be elided, and will marshal its zero value as "text". - Type constant.Text `json:"type,required"` +// The model will use any available tools. +// +// The property Type is required. +type ToolChoiceAnyParam struct { + // Whether to disable parallel tool use. + // + // Defaults to `false`. If set to `true`, the model will output exactly one tool + // use. + DisableParallelToolUse param.Opt[bool] `json:"disable_parallel_tool_use,omitzero"` + // This field can be elided, and will marshal its zero value as "any". + Type constant.Any `json:"type,required"` paramObj } -func (r TextBlockParam) MarshalJSON() (data []byte, err error) { - type shadow TextBlockParam +func (r ToolChoiceAnyParam) MarshalJSON() (data []byte, err error) { + type shadow ToolChoiceAnyParam return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *TextBlockParam) UnmarshalJSON(data []byte) error { +func (r *ToolChoiceAnyParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// TextCitationUnion contains all possible properties and values from -// [CitationCharLocation], [CitationPageLocation], [CitationContentBlockLocation], -// [CitationsWebSearchResultLocation], [CitationsSearchResultLocation]. -// -// Use the [TextCitationUnion.AsAny] method to switch on the variant. +// The model will automatically decide whether to use tools. // -// Use the methods beginning with 'As' to cast the union to one of its variants. -type TextCitationUnion struct { - CitedText string `json:"cited_text"` - DocumentIndex int64 `json:"document_index"` - DocumentTitle string `json:"document_title"` - // This field is from variant [CitationCharLocation]. - EndCharIndex int64 `json:"end_char_index"` - FileID string `json:"file_id"` - // This field is from variant [CitationCharLocation]. - StartCharIndex int64 `json:"start_char_index"` - // Any of "char_location", "page_location", "content_block_location", - // "web_search_result_location", "search_result_location". - Type string `json:"type"` - // This field is from variant [CitationPageLocation]. - EndPageNumber int64 `json:"end_page_number"` - // This field is from variant [CitationPageLocation]. - StartPageNumber int64 `json:"start_page_number"` - EndBlockIndex int64 `json:"end_block_index"` - StartBlockIndex int64 `json:"start_block_index"` - // This field is from variant [CitationsWebSearchResultLocation]. - EncryptedIndex string `json:"encrypted_index"` - Title string `json:"title"` - // This field is from variant [CitationsWebSearchResultLocation]. - URL string `json:"url"` - // This field is from variant [CitationsSearchResultLocation]. - SearchResultIndex int64 `json:"search_result_index"` - // This field is from variant [CitationsSearchResultLocation]. - Source string `json:"source"` - JSON struct { - CitedText respjson.Field - DocumentIndex respjson.Field - DocumentTitle respjson.Field - EndCharIndex respjson.Field - FileID respjson.Field - StartCharIndex respjson.Field - Type respjson.Field - EndPageNumber respjson.Field - StartPageNumber respjson.Field - EndBlockIndex respjson.Field - StartBlockIndex respjson.Field - EncryptedIndex respjson.Field - Title respjson.Field - URL respjson.Field - SearchResultIndex respjson.Field - Source respjson.Field - raw string - } `json:"-"` +// The property Type is required. +type ToolChoiceAutoParam struct { + // Whether to disable parallel tool use. + // + // Defaults to `false`. If set to `true`, the model will output at most one tool + // use. + DisableParallelToolUse param.Opt[bool] `json:"disable_parallel_tool_use,omitzero"` + // This field can be elided, and will marshal its zero value as "auto". + Type constant.Auto `json:"type,required"` + paramObj } -// anyTextCitation is implemented by each variant of [TextCitationUnion] to add -// type safety for the return type of [TextCitationUnion.AsAny] -type anyTextCitation interface { - implTextCitationUnion() +func (r ToolChoiceAutoParam) MarshalJSON() (data []byte, err error) { + type shadow ToolChoiceAutoParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolChoiceAutoParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (CitationCharLocation) implTextCitationUnion() {} -func (CitationPageLocation) implTextCitationUnion() {} -func (CitationContentBlockLocation) implTextCitationUnion() {} -func (CitationsWebSearchResultLocation) implTextCitationUnion() {} -func (CitationsSearchResultLocation) implTextCitationUnion() {} - -// Use the following switch statement to find the correct variant -// -// switch variant := TextCitationUnion.AsAny().(type) { -// case anthropic.CitationCharLocation: -// case anthropic.CitationPageLocation: -// case anthropic.CitationContentBlockLocation: -// case anthropic.CitationsWebSearchResultLocation: -// case anthropic.CitationsSearchResultLocation: -// default: -// fmt.Errorf("no variant present") -// } -func (u TextCitationUnion) AsAny() anyTextCitation { - switch u.Type { - case "char_location": - return u.AsCharLocation() - case "page_location": - return u.AsPageLocation() - case "content_block_location": - return u.AsContentBlockLocation() - case "web_search_result_location": - return u.AsWebSearchResultLocation() - case "search_result_location": - return u.AsSearchResultLocation() +func NewToolChoiceNoneParam() ToolChoiceNoneParam { + return ToolChoiceNoneParam{ + Type: "none", } - return nil } -func (u TextCitationUnion) AsCharLocation() (v CitationCharLocation) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// The model will not be allowed to use tools. +// +// This struct has a constant value, construct it with [NewToolChoiceNoneParam]. +type ToolChoiceNoneParam struct { + Type constant.None `json:"type,required"` + paramObj } -func (u TextCitationUnion) AsPageLocation() (v CitationPageLocation) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (r ToolChoiceNoneParam) MarshalJSON() (data []byte, err error) { + type shadow ToolChoiceNoneParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolChoiceNoneParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u TextCitationUnion) AsContentBlockLocation() (v CitationContentBlockLocation) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +// The model will use the specified tool with `tool_choice.name`. +// +// The properties Name, Type are required. +type ToolChoiceToolParam struct { + // The name of the tool to use. + Name string `json:"name,required"` + // Whether to disable parallel tool use. + // + // Defaults to `false`. If set to `true`, the model will output exactly one tool + // use. + DisableParallelToolUse param.Opt[bool] `json:"disable_parallel_tool_use,omitzero"` + // This field can be elided, and will marshal its zero value as "tool". + Type constant.Tool `json:"type,required"` + paramObj } -func (u TextCitationUnion) AsWebSearchResultLocation() (v CitationsWebSearchResultLocation) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +func (r ToolChoiceToolParam) MarshalJSON() (data []byte, err error) { + type shadow ToolChoiceToolParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolChoiceToolParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u TextCitationUnion) AsSearchResultLocation() (v CitationsSearchResultLocation) { - apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v +type ToolReferenceBlock struct { + ToolName string `json:"tool_name,required"` + Type constant.ToolReference `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ToolName respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } // Returns the unmodified JSON received from the API -func (u TextCitationUnion) RawJSON() string { return u.JSON.raw } +func (r ToolReferenceBlock) RawJSON() string { return r.JSON.raw } +func (r *ToolReferenceBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r *TextCitationUnion) UnmarshalJSON(data []byte) error { +// Tool reference block that can be included in tool_result content. +// +// The properties ToolName, Type are required. +type ToolReferenceBlockParam struct { + ToolName string `json:"tool_name,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as "tool_reference". + Type constant.ToolReference `json:"type,required"` + paramObj +} + +func (r ToolReferenceBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ToolReferenceBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolReferenceBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties ToolUseID, Type are required. +type ToolResultBlockParam struct { + ToolUseID string `json:"tool_use_id,required"` + IsError param.Opt[bool] `json:"is_error,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + Content []ToolResultBlockParamContentUnion `json:"content,omitzero"` + // This field can be elided, and will marshal its zero value as "tool_result". + Type constant.ToolResult `json:"type,required"` + paramObj +} + +func (r ToolResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ToolResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. -type TextCitationParamUnion struct { - OfCharLocation *CitationCharLocationParam `json:",omitzero,inline"` - OfPageLocation *CitationPageLocationParam `json:",omitzero,inline"` - OfContentBlockLocation *CitationContentBlockLocationParam `json:",omitzero,inline"` - OfWebSearchResultLocation *CitationWebSearchResultLocationParam `json:",omitzero,inline"` - OfSearchResultLocation *CitationSearchResultLocationParam `json:",omitzero,inline"` +type ToolResultBlockParamContentUnion struct { + OfText *TextBlockParam `json:",omitzero,inline"` + OfImage *ImageBlockParam `json:",omitzero,inline"` + OfSearchResult *SearchResultBlockParam `json:",omitzero,inline"` + OfDocument *DocumentBlockParam `json:",omitzero,inline"` + OfToolReference *ToolReferenceBlockParam `json:",omitzero,inline"` paramUnion } -func (u TextCitationParamUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfCharLocation, - u.OfPageLocation, - u.OfContentBlockLocation, - u.OfWebSearchResultLocation, - u.OfSearchResultLocation) +func (u ToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfText, + u.OfImage, + u.OfSearchResult, + u.OfDocument, + u.OfToolReference) } - -func (u *TextCitationParamUnion) UnmarshalJSON(data []byte) error { +func (u *ToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } -func (u *TextCitationParamUnion) asAny() any { - if !param.IsOmitted(u.OfCharLocation) { - return u.OfCharLocation - } else if !param.IsOmitted(u.OfPageLocation) { - return u.OfPageLocation - } else if !param.IsOmitted(u.OfContentBlockLocation) { - return u.OfContentBlockLocation - } else if !param.IsOmitted(u.OfWebSearchResultLocation) { - return u.OfWebSearchResultLocation - } else if !param.IsOmitted(u.OfSearchResultLocation) { - return u.OfSearchResultLocation +func (u *ToolResultBlockParamContentUnion) asAny() any { + if !param.IsOmitted(u.OfText) { + return u.OfText + } else if !param.IsOmitted(u.OfImage) { + return u.OfImage + } else if !param.IsOmitted(u.OfSearchResult) { + return u.OfSearchResult + } else if !param.IsOmitted(u.OfDocument) { + return u.OfDocument + } else if !param.IsOmitted(u.OfToolReference) { + return u.OfToolReference } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetEndCharIndex() *int64 { - if vt := u.OfCharLocation; vt != nil { - return &vt.EndCharIndex +func (u ToolResultBlockParamContentUnion) GetText() *string { + if vt := u.OfText; vt != nil { + return &vt.Text } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetStartCharIndex() *int64 { - if vt := u.OfCharLocation; vt != nil { - return &vt.StartCharIndex +func (u ToolResultBlockParamContentUnion) GetContent() []TextBlockParam { + if vt := u.OfSearchResult; vt != nil { + return vt.Content } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetEndPageNumber() *int64 { - if vt := u.OfPageLocation; vt != nil { - return &vt.EndPageNumber +func (u ToolResultBlockParamContentUnion) GetContext() *string { + if vt := u.OfDocument; vt != nil && vt.Context.Valid() { + return &vt.Context.Value } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetStartPageNumber() *int64 { - if vt := u.OfPageLocation; vt != nil { - return &vt.StartPageNumber +func (u ToolResultBlockParamContentUnion) GetToolName() *string { + if vt := u.OfToolReference; vt != nil { + return &vt.ToolName } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetEncryptedIndex() *string { - if vt := u.OfWebSearchResultLocation; vt != nil { - return &vt.EncryptedIndex +func (u ToolResultBlockParamContentUnion) GetType() *string { + if vt := u.OfText; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfImage; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfSearchResult; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfDocument; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolReference; vt != nil { + return (*string)(&vt.Type) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetURL() *string { - if vt := u.OfWebSearchResultLocation; vt != nil { - return &vt.URL +func (u ToolResultBlockParamContentUnion) GetTitle() *string { + if vt := u.OfSearchResult; vt != nil { + return (*string)(&vt.Title) + } else if vt := u.OfDocument; vt != nil && vt.Title.Valid() { + return &vt.Title.Value + } + return nil +} + +// Returns a pointer to the underlying variant's CacheControl property, if present. +func (u ToolResultBlockParamContentUnion) GetCacheControl() *CacheControlEphemeralParam { + if vt := u.OfText; vt != nil { + return &vt.CacheControl + } else if vt := u.OfImage; vt != nil { + return &vt.CacheControl + } else if vt := u.OfSearchResult; vt != nil { + return &vt.CacheControl + } else if vt := u.OfDocument; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolReference; vt != nil { + return &vt.CacheControl } return nil } +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u ToolResultBlockParamContentUnion) GetCitations() (res toolResultBlockParamContentUnionCitations) { + if vt := u.OfText; vt != nil { + res.any = &vt.Citations + } else if vt := u.OfSearchResult; vt != nil { + res.any = &vt.Citations + } else if vt := u.OfDocument; vt != nil { + res.any = &vt.Citations + } + return +} + +// Can have the runtime types [*[]TextCitationParamUnion], [*CitationsConfigParam] +type toolResultBlockParamContentUnionCitations struct{ any } + +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *[]anthropic.TextCitationParamUnion: +// case *anthropic.CitationsConfigParam: +// default: +// fmt.Errorf("not present") +// } +func (u toolResultBlockParamContentUnionCitations) AsAny() any { return u.any } + // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetSearchResultIndex() *int64 { - if vt := u.OfSearchResultLocation; vt != nil { - return &vt.SearchResultIndex +func (u toolResultBlockParamContentUnionCitations) GetEnabled() *bool { + switch vt := u.any.(type) { + case *CitationsConfigParam: + return paramutil.AddrIfPresent(vt.Enabled) } return nil } -// Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetSource() *string { - if vt := u.OfSearchResultLocation; vt != nil { - return &vt.Source +// Returns a subunion which exports methods to access subproperties +// +// Or use AsAny() to get the underlying value +func (u ToolResultBlockParamContentUnion) GetSource() (res toolResultBlockParamContentUnionSource) { + if vt := u.OfImage; vt != nil { + res.any = vt.Source.asAny() + } else if vt := u.OfSearchResult; vt != nil { + res.any = &vt.Source + } else if vt := u.OfDocument; vt != nil { + res.any = vt.Source.asAny() } - return nil + return } -// Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetCitedText() *string { - if vt := u.OfCharLocation; vt != nil { - return (*string)(&vt.CitedText) - } else if vt := u.OfPageLocation; vt != nil { - return (*string)(&vt.CitedText) - } else if vt := u.OfContentBlockLocation; vt != nil { - return (*string)(&vt.CitedText) - } else if vt := u.OfWebSearchResultLocation; vt != nil { - return (*string)(&vt.CitedText) - } else if vt := u.OfSearchResultLocation; vt != nil { - return (*string)(&vt.CitedText) - } - return nil -} +// Can have the runtime types [*Base64ImageSourceParam], [*URLImageSourceParam], +// [*string], [*Base64PDFSourceParam], [*PlainTextSourceParam], +// [*ContentBlockSourceParam], [*URLPDFSourceParam] +type toolResultBlockParamContentUnionSource struct{ any } + +// Use the following switch statement to get the type of the union: +// +// switch u.AsAny().(type) { +// case *anthropic.Base64ImageSourceParam: +// case *anthropic.URLImageSourceParam: +// case *string: +// case *anthropic.Base64PDFSourceParam: +// case *anthropic.PlainTextSourceParam: +// case *anthropic.ContentBlockSourceParam: +// case *anthropic.URLPDFSourceParam: +// default: +// fmt.Errorf("not present") +// } +func (u toolResultBlockParamContentUnionSource) AsAny() any { return u.any } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetDocumentIndex() *int64 { - if vt := u.OfCharLocation; vt != nil { - return (*int64)(&vt.DocumentIndex) - } else if vt := u.OfPageLocation; vt != nil { - return (*int64)(&vt.DocumentIndex) - } else if vt := u.OfContentBlockLocation; vt != nil { - return (*int64)(&vt.DocumentIndex) +func (u toolResultBlockParamContentUnionSource) GetContent() *ContentBlockSourceContentUnionParam { + switch vt := u.any.(type) { + case *DocumentBlockParamSourceUnion: + return vt.GetContent() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetDocumentTitle() *string { - if vt := u.OfCharLocation; vt != nil && vt.DocumentTitle.Valid() { - return &vt.DocumentTitle.Value - } else if vt := u.OfPageLocation; vt != nil && vt.DocumentTitle.Valid() { - return &vt.DocumentTitle.Value - } else if vt := u.OfContentBlockLocation; vt != nil && vt.DocumentTitle.Valid() { - return &vt.DocumentTitle.Value +func (u toolResultBlockParamContentUnionSource) GetData() *string { + switch vt := u.any.(type) { + case *ImageBlockParamSourceUnion: + return vt.GetData() + case *DocumentBlockParamSourceUnion: + return vt.GetData() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetType() *string { - if vt := u.OfCharLocation; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfPageLocation; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfContentBlockLocation; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfWebSearchResultLocation; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfSearchResultLocation; vt != nil { - return (*string)(&vt.Type) +func (u toolResultBlockParamContentUnionSource) GetMediaType() *string { + switch vt := u.any.(type) { + case *ImageBlockParamSourceUnion: + return vt.GetMediaType() + case *DocumentBlockParamSourceUnion: + return vt.GetMediaType() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetEndBlockIndex() *int64 { - if vt := u.OfContentBlockLocation; vt != nil { - return (*int64)(&vt.EndBlockIndex) - } else if vt := u.OfSearchResultLocation; vt != nil { - return (*int64)(&vt.EndBlockIndex) +func (u toolResultBlockParamContentUnionSource) GetType() *string { + switch vt := u.any.(type) { + case *ImageBlockParamSourceUnion: + return vt.GetType() + case *DocumentBlockParamSourceUnion: + return vt.GetType() } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetStartBlockIndex() *int64 { - if vt := u.OfContentBlockLocation; vt != nil { - return (*int64)(&vt.StartBlockIndex) - } else if vt := u.OfSearchResultLocation; vt != nil { - return (*int64)(&vt.StartBlockIndex) +func (u toolResultBlockParamContentUnionSource) GetURL() *string { + switch vt := u.any.(type) { + case *ImageBlockParamSourceUnion: + return vt.GetURL() + case *DocumentBlockParamSourceUnion: + return vt.GetURL() } return nil } -// Returns a pointer to the underlying variant's property, if present. -func (u TextCitationParamUnion) GetTitle() *string { - if vt := u.OfWebSearchResultLocation; vt != nil && vt.Title.Valid() { - return &vt.Title.Value - } else if vt := u.OfSearchResultLocation; vt != nil && vt.Title.Valid() { - return &vt.Title.Value - } - return nil + +// The properties Name, Type are required. +type ToolSearchToolBm25_20251119Param struct { + // Any of "tool_search_tool_bm25_20251119", "tool_search_tool_bm25". + Type ToolSearchToolBm25_20251119Type `json:"type,omitzero,required"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_bm25". + Name constant.ToolSearchToolBm25 `json:"name,required"` + paramObj } -type TextDelta struct { - Text string `json:"text,required"` - Type constant.TextDelta `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - Text respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +func (r ToolSearchToolBm25_20251119Param) MarshalJSON() (data []byte, err error) { + type shadow ToolSearchToolBm25_20251119Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolSearchToolBm25_20251119Param) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns the unmodified JSON received from the API -func (r TextDelta) RawJSON() string { return r.JSON.raw } +type ToolSearchToolBm25_20251119Type string -func (r *TextDelta) UnmarshalJSON(data []byte) error { +const ( + ToolSearchToolBm25_20251119TypeToolSearchToolBm25_20251119 ToolSearchToolBm25_20251119Type = "tool_search_tool_bm25_20251119" + ToolSearchToolBm25_20251119TypeToolSearchToolBm25 ToolSearchToolBm25_20251119Type = "tool_search_tool_bm25" +) + +// The properties Name, Type are required. +type ToolSearchToolRegex20251119Param struct { + // Any of "tool_search_tool_regex_20251119", "tool_search_tool_regex". + Type ToolSearchToolRegex20251119Type `json:"type,omitzero,required"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_regex". + Name constant.ToolSearchToolRegex `json:"name,required"` + paramObj +} + +func (r ToolSearchToolRegex20251119Param) MarshalJSON() (data []byte, err error) { + type shadow ToolSearchToolRegex20251119Param + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolSearchToolRegex20251119Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type ThinkingBlock struct { - Signature string `json:"signature,required"` - Thinking string `json:"thinking,required"` - Type constant.Thinking `json:"type,required"` +type ToolSearchToolRegex20251119Type string + +const ( + ToolSearchToolRegex20251119TypeToolSearchToolRegex20251119 ToolSearchToolRegex20251119Type = "tool_search_tool_regex_20251119" + ToolSearchToolRegex20251119TypeToolSearchToolRegex ToolSearchToolRegex20251119Type = "tool_search_tool_regex" +) + +type ToolSearchToolResultBlock struct { + Content ToolSearchToolResultBlockContentUnion `json:"content,required"` + ToolUseID string `json:"tool_use_id,required"` + Type constant.ToolSearchToolResult `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - Signature respjson.Field - Thinking respjson.Field + Content respjson.Field + ToolUseID respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string @@ -3378,1021 +7039,1494 @@ type ThinkingBlock struct { } // Returns the unmodified JSON received from the API -func (r ThinkingBlock) RawJSON() string { return r.JSON.raw } - -func (r *ThinkingBlock) UnmarshalJSON(data []byte) error { +func (r ToolSearchToolResultBlock) RawJSON() string { return r.JSON.raw } +func (r *ToolSearchToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func (r ThinkingBlock) ToParam() ThinkingBlockParam { - var p ThinkingBlockParam - p.Type = r.Type - p.Signature = r.Signature - p.Thinking = r.Thinking - return p -} - -// The properties Signature, Thinking, Type are required. -type ThinkingBlockParam struct { - Signature string `json:"signature,required"` - Thinking string `json:"thinking,required"` - // This field can be elided, and will marshal its zero value as "thinking". - Type constant.Thinking `json:"type,required"` - paramObj -} - -func (r ThinkingBlockParam) MarshalJSON() (data []byte, err error) { - type shadow ThinkingBlockParam - return param.MarshalObject(r, (*shadow)(&r)) -} - -func (r *ThinkingBlockParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// ToolSearchToolResultBlockContentUnion contains all possible properties and +// values from [ToolSearchToolResultError], [ToolSearchToolSearchResultBlock]. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type ToolSearchToolResultBlockContentUnion struct { + // This field is from variant [ToolSearchToolResultError]. + ErrorCode ToolSearchToolResultErrorCode `json:"error_code"` + // This field is from variant [ToolSearchToolResultError]. + ErrorMessage string `json:"error_message"` + Type string `json:"type"` + // This field is from variant [ToolSearchToolSearchResultBlock]. + ToolReferences []ToolReferenceBlock `json:"tool_references"` + JSON struct { + ErrorCode respjson.Field + ErrorMessage respjson.Field + Type respjson.Field + ToolReferences respjson.Field + raw string + } `json:"-"` } -func NewThinkingConfigDisabledParam() ThinkingConfigDisabledParam { - return ThinkingConfigDisabledParam{ - Type: "disabled", - } +func (u ToolSearchToolResultBlockContentUnion) AsResponseToolSearchToolResultError() (v ToolSearchToolResultError) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// This struct has a constant value, construct it with -// [NewThinkingConfigDisabledParam]. -type ThinkingConfigDisabledParam struct { - Type constant.Disabled `json:"type,required"` - paramObj +func (u ToolSearchToolResultBlockContentUnion) AsResponseToolSearchToolSearchResultBlock() (v ToolSearchToolSearchResultBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -func (r ThinkingConfigDisabledParam) MarshalJSON() (data []byte, err error) { - type shadow ThinkingConfigDisabledParam - return param.MarshalObject(r, (*shadow)(&r)) -} +// Returns the unmodified JSON received from the API +func (u ToolSearchToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } -func (r *ThinkingConfigDisabledParam) UnmarshalJSON(data []byte) error { +func (r *ToolSearchToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// The properties BudgetTokens, Type are required. -type ThinkingConfigEnabledParam struct { - // Determines how many tokens Claude can use for its internal reasoning process. - // Larger budgets can enable more thorough analysis for complex problems, improving - // response quality. - // - // Must be ≥1024 and less than `max_tokens`. - // - // See - // [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) - // for details. - BudgetTokens int64 `json:"budget_tokens,required"` - // This field can be elided, and will marshal its zero value as "enabled". - Type constant.Enabled `json:"type,required"` +// The properties Content, ToolUseID, Type are required. +type ToolSearchToolResultBlockParam struct { + Content ToolSearchToolResultBlockParamContentUnion `json:"content,omitzero,required"` + ToolUseID string `json:"tool_use_id,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_result". + Type constant.ToolSearchToolResult `json:"type,required"` paramObj } -func (r ThinkingConfigEnabledParam) MarshalJSON() (data []byte, err error) { - type shadow ThinkingConfigEnabledParam +func (r ToolSearchToolResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ToolSearchToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ThinkingConfigEnabledParam) UnmarshalJSON(data []byte) error { +func (r *ToolSearchToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func ThinkingConfigParamOfEnabled(budgetTokens int64) ThinkingConfigParamUnion { - var enabled ThinkingConfigEnabledParam - enabled.BudgetTokens = budgetTokens - return ThinkingConfigParamUnion{OfEnabled: &enabled} -} - // Only one field can be non-zero. -// -// Use [param.IsOmitted] to confirm if a field is set. -type ThinkingConfigParamUnion struct { - OfEnabled *ThinkingConfigEnabledParam `json:",omitzero,inline"` - OfDisabled *ThinkingConfigDisabledParam `json:",omitzero,inline"` +// +// Use [param.IsOmitted] to confirm if a field is set. +type ToolSearchToolResultBlockParamContentUnion struct { + OfRequestToolSearchToolResultError *ToolSearchToolResultErrorParam `json:",omitzero,inline"` + OfRequestToolSearchToolSearchResultBlock *ToolSearchToolSearchResultBlockParam `json:",omitzero,inline"` paramUnion } -func (u ThinkingConfigParamUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfEnabled, u.OfDisabled) +func (u ToolSearchToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfRequestToolSearchToolResultError, u.OfRequestToolSearchToolSearchResultBlock) } - -func (u *ThinkingConfigParamUnion) UnmarshalJSON(data []byte) error { +func (u *ToolSearchToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } -func (u *ThinkingConfigParamUnion) asAny() any { - if !param.IsOmitted(u.OfEnabled) { - return u.OfEnabled - } else if !param.IsOmitted(u.OfDisabled) { - return u.OfDisabled +func (u *ToolSearchToolResultBlockParamContentUnion) asAny() any { + if !param.IsOmitted(u.OfRequestToolSearchToolResultError) { + return u.OfRequestToolSearchToolResultError + } else if !param.IsOmitted(u.OfRequestToolSearchToolSearchResultBlock) { + return u.OfRequestToolSearchToolSearchResultBlock } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ThinkingConfigParamUnion) GetBudgetTokens() *int64 { - if vt := u.OfEnabled; vt != nil { - return &vt.BudgetTokens +func (u ToolSearchToolResultBlockParamContentUnion) GetErrorCode() *string { + if vt := u.OfRequestToolSearchToolResultError; vt != nil { + return (*string)(&vt.ErrorCode) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ThinkingConfigParamUnion) GetType() *string { - if vt := u.OfEnabled; vt != nil { +func (u ToolSearchToolResultBlockParamContentUnion) GetToolReferences() []ToolReferenceBlockParam { + if vt := u.OfRequestToolSearchToolSearchResultBlock; vt != nil { + return vt.ToolReferences + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ToolSearchToolResultBlockParamContentUnion) GetType() *string { + if vt := u.OfRequestToolSearchToolResultError; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfDisabled; vt != nil { + } else if vt := u.OfRequestToolSearchToolSearchResultBlock; vt != nil { return (*string)(&vt.Type) } return nil } -type ThinkingDelta struct { - Thinking string `json:"thinking,required"` - Type constant.ThinkingDelta `json:"type,required"` +type ToolSearchToolResultError struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded". + ErrorCode ToolSearchToolResultErrorCode `json:"error_code,required"` + ErrorMessage string `json:"error_message,required"` + Type constant.ToolSearchToolResultError `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - Thinking respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string + ErrorCode respjson.Field + ErrorMessage respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string } `json:"-"` } // Returns the unmodified JSON received from the API -func (r ThinkingDelta) RawJSON() string { return r.JSON.raw } +func (r ToolSearchToolResultError) RawJSON() string { return r.JSON.raw } +func (r *ToolSearchToolResultError) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r *ThinkingDelta) UnmarshalJSON(data []byte) error { +type ToolSearchToolResultErrorCode string + +const ( + ToolSearchToolResultErrorCodeInvalidToolInput ToolSearchToolResultErrorCode = "invalid_tool_input" + ToolSearchToolResultErrorCodeUnavailable ToolSearchToolResultErrorCode = "unavailable" + ToolSearchToolResultErrorCodeTooManyRequests ToolSearchToolResultErrorCode = "too_many_requests" + ToolSearchToolResultErrorCodeExecutionTimeExceeded ToolSearchToolResultErrorCode = "execution_time_exceeded" +) + +// The properties ErrorCode, Type are required. +type ToolSearchToolResultErrorParam struct { + // Any of "invalid_tool_input", "unavailable", "too_many_requests", + // "execution_time_exceeded". + ErrorCode ToolSearchToolResultErrorCode `json:"error_code,omitzero,required"` + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_result_error". + Type constant.ToolSearchToolResultError `json:"type,required"` + paramObj +} + +func (r ToolSearchToolResultErrorParam) MarshalJSON() (data []byte, err error) { + type shadow ToolSearchToolResultErrorParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolSearchToolResultErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// The properties InputSchema, Name are required. -type ToolParam struct { - // [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. - // - // This defines the shape of the `input` that your tool accepts and that the model - // will produce. - InputSchema ToolInputSchemaParam `json:"input_schema,omitzero,required"` +type ToolSearchToolSearchResultBlock struct { + ToolReferences []ToolReferenceBlock `json:"tool_references,required"` + Type constant.ToolSearchToolSearchResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ToolReferences respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ToolSearchToolSearchResultBlock) RawJSON() string { return r.JSON.raw } +func (r *ToolSearchToolSearchResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties ToolReferences, Type are required. +type ToolSearchToolSearchResultBlockParam struct { + ToolReferences []ToolReferenceBlockParam `json:"tool_references,omitzero,required"` + // This field can be elided, and will marshal its zero value as + // "tool_search_tool_search_result". + Type constant.ToolSearchToolSearchResult `json:"type,required"` + paramObj +} + +func (r ToolSearchToolSearchResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ToolSearchToolSearchResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ToolSearchToolSearchResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Name, Type are required. +type ToolTextEditor20250124Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. - Name string `json:"name,required"` - // Description of what this tool does. // - // Tool descriptions should be as detailed as possible. The more information that - // the model has about what the tool is and how to use it, the better it will - // perform. You can use natural language descriptions to reinforce important - // aspects of the tool input JSON schema. - Description param.Opt[string] `json:"description,omitzero"` - // Any of "custom". - Type ToolType `json:"type,omitzero"` - // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // This field can be elided, and will marshal its zero value as + // "str_replace_editor". + Name constant.StrReplaceEditor `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "text_editor_20250124". + Type constant.TextEditor20250124 `json:"type,required"` paramObj } -func (r ToolParam) MarshalJSON() (data []byte, err error) { - type shadow ToolParam +func (r ToolTextEditor20250124Param) MarshalJSON() (data []byte, err error) { + type shadow ToolTextEditor20250124Param return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ToolParam) UnmarshalJSON(data []byte) error { +func (r *ToolTextEditor20250124Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. -// -// This defines the shape of the `input` that your tool accepts and that the model -// will produce. -// -// The property Type is required. -type ToolInputSchemaParam struct { - Properties any `json:"properties,omitzero"` - Required []string `json:"required,omitzero"` - // This field can be elided, and will marshal its zero value as "object". - Type constant.Object `json:"type,required"` - ExtraFields map[string]any `json:"-"` +// The properties Name, Type are required. +type ToolTextEditor20250429Param struct { + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as + // "str_replace_based_edit_tool". + Name constant.StrReplaceBasedEditTool `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "text_editor_20250429". + Type constant.TextEditor20250429 `json:"type,required"` paramObj } -func (r ToolInputSchemaParam) MarshalJSON() (data []byte, err error) { - type shadow ToolInputSchemaParam - return param.MarshalWithExtras(r, (*shadow)(&r), r.ExtraFields) +func (r ToolTextEditor20250429Param) MarshalJSON() (data []byte, err error) { + type shadow ToolTextEditor20250429Param + return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ToolInputSchemaParam) UnmarshalJSON(data []byte) error { +func (r *ToolTextEditor20250429Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type ToolType string - -const ( - ToolTypeCustom ToolType = "custom" -) - // The properties Name, Type are required. -type ToolBash20250124Param struct { +type ToolTextEditor20250728Param struct { + // Maximum number of characters to display when viewing a file. If not specified, + // defaults to displaying the full file. + MaxCharacters param.Opt[int64] `json:"max_characters,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + InputExamples []map[string]any `json:"input_examples,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. // - // This field can be elided, and will marshal its zero value as "bash". - Name constant.Bash `json:"name,required"` - // This field can be elided, and will marshal its zero value as "bash_20250124". - Type constant.Bash20250124 `json:"type,required"` + // This field can be elided, and will marshal its zero value as + // "str_replace_based_edit_tool". + Name constant.StrReplaceBasedEditTool `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "text_editor_20250728". + Type constant.TextEditor20250728 `json:"type,required"` paramObj } -func (r ToolBash20250124Param) MarshalJSON() (data []byte, err error) { - type shadow ToolBash20250124Param +func (r ToolTextEditor20250728Param) MarshalJSON() (data []byte, err error) { + type shadow ToolTextEditor20250728Param return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ToolBash20250124Param) UnmarshalJSON(data []byte) error { +func (r *ToolTextEditor20250728Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func ToolChoiceParamOfTool(name string) ToolChoiceUnionParam { - var tool ToolChoiceToolParam - tool.Name = name - return ToolChoiceUnionParam{OfTool: &tool} +func ToolUnionParamOfTool(inputSchema ToolInputSchemaParam, name string) ToolUnionParam { + var variant ToolParam + variant.InputSchema = inputSchema + variant.Name = name + return ToolUnionParam{OfTool: &variant} +} + +func ToolUnionParamOfToolSearchToolBm25_20251119(type_ ToolSearchToolBm25_20251119Type) ToolUnionParam { + var variant ToolSearchToolBm25_20251119Param + variant.Type = type_ + return ToolUnionParam{OfToolSearchToolBm25_20251119: &variant} +} + +func ToolUnionParamOfToolSearchToolRegex20251119(type_ ToolSearchToolRegex20251119Type) ToolUnionParam { + var variant ToolSearchToolRegex20251119Param + variant.Type = type_ + return ToolUnionParam{OfToolSearchToolRegex20251119: &variant} } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. -type ToolChoiceUnionParam struct { - OfAuto *ToolChoiceAutoParam `json:",omitzero,inline"` - OfAny *ToolChoiceAnyParam `json:",omitzero,inline"` - OfTool *ToolChoiceToolParam `json:",omitzero,inline"` - OfNone *ToolChoiceNoneParam `json:",omitzero,inline"` +type ToolUnionParam struct { + OfTool *ToolParam `json:",omitzero,inline"` + OfBashTool20250124 *ToolBash20250124Param `json:",omitzero,inline"` + OfCodeExecutionTool20250522 *CodeExecutionTool20250522Param `json:",omitzero,inline"` + OfCodeExecutionTool20250825 *CodeExecutionTool20250825Param `json:",omitzero,inline"` + OfCodeExecutionTool20260120 *CodeExecutionTool20260120Param `json:",omitzero,inline"` + OfMemoryTool20250818 *MemoryTool20250818Param `json:",omitzero,inline"` + OfTextEditor20250124 *ToolTextEditor20250124Param `json:",omitzero,inline"` + OfTextEditor20250429 *ToolTextEditor20250429Param `json:",omitzero,inline"` + OfTextEditor20250728 *ToolTextEditor20250728Param `json:",omitzero,inline"` + OfWebSearchTool20250305 *WebSearchTool20250305Param `json:",omitzero,inline"` + OfWebFetchTool20250910 *WebFetchTool20250910Param `json:",omitzero,inline"` + OfWebSearchTool20260209 *WebSearchTool20260209Param `json:",omitzero,inline"` + OfWebFetchTool20260209 *WebFetchTool20260209Param `json:",omitzero,inline"` + OfToolSearchToolBm25_20251119 *ToolSearchToolBm25_20251119Param `json:",omitzero,inline"` + OfToolSearchToolRegex20251119 *ToolSearchToolRegex20251119Param `json:",omitzero,inline"` paramUnion } -func (u ToolChoiceUnionParam) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfAuto, u.OfAny, u.OfTool, u.OfNone) +func (u ToolUnionParam) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfTool, + u.OfBashTool20250124, + u.OfCodeExecutionTool20250522, + u.OfCodeExecutionTool20250825, + u.OfCodeExecutionTool20260120, + u.OfMemoryTool20250818, + u.OfTextEditor20250124, + u.OfTextEditor20250429, + u.OfTextEditor20250728, + u.OfWebSearchTool20250305, + u.OfWebFetchTool20250910, + u.OfWebSearchTool20260209, + u.OfWebFetchTool20260209, + u.OfToolSearchToolBm25_20251119, + u.OfToolSearchToolRegex20251119) } - -func (u *ToolChoiceUnionParam) UnmarshalJSON(data []byte) error { +func (u *ToolUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } -func (u *ToolChoiceUnionParam) asAny() any { - if !param.IsOmitted(u.OfAuto) { - return u.OfAuto - } else if !param.IsOmitted(u.OfAny) { - return u.OfAny - } else if !param.IsOmitted(u.OfTool) { - return u.OfTool - } else if !param.IsOmitted(u.OfNone) { - return u.OfNone +func (u *ToolUnionParam) asAny() any { + if !param.IsOmitted(u.OfTool) { + return u.OfTool + } else if !param.IsOmitted(u.OfBashTool20250124) { + return u.OfBashTool20250124 + } else if !param.IsOmitted(u.OfCodeExecutionTool20250522) { + return u.OfCodeExecutionTool20250522 + } else if !param.IsOmitted(u.OfCodeExecutionTool20250825) { + return u.OfCodeExecutionTool20250825 + } else if !param.IsOmitted(u.OfCodeExecutionTool20260120) { + return u.OfCodeExecutionTool20260120 + } else if !param.IsOmitted(u.OfMemoryTool20250818) { + return u.OfMemoryTool20250818 + } else if !param.IsOmitted(u.OfTextEditor20250124) { + return u.OfTextEditor20250124 + } else if !param.IsOmitted(u.OfTextEditor20250429) { + return u.OfTextEditor20250429 + } else if !param.IsOmitted(u.OfTextEditor20250728) { + return u.OfTextEditor20250728 + } else if !param.IsOmitted(u.OfWebSearchTool20250305) { + return u.OfWebSearchTool20250305 + } else if !param.IsOmitted(u.OfWebFetchTool20250910) { + return u.OfWebFetchTool20250910 + } else if !param.IsOmitted(u.OfWebSearchTool20260209) { + return u.OfWebSearchTool20260209 + } else if !param.IsOmitted(u.OfWebFetchTool20260209) { + return u.OfWebFetchTool20260209 + } else if !param.IsOmitted(u.OfToolSearchToolBm25_20251119) { + return u.OfToolSearchToolBm25_20251119 + } else if !param.IsOmitted(u.OfToolSearchToolRegex20251119) { + return u.OfToolSearchToolRegex20251119 + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ToolUnionParam) GetInputSchema() *ToolInputSchemaParam { + if vt := u.OfTool; vt != nil { + return &vt.InputSchema + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ToolUnionParam) GetDescription() *string { + if vt := u.OfTool; vt != nil && vt.Description.Valid() { + return &vt.Description.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ToolUnionParam) GetEagerInputStreaming() *bool { + if vt := u.OfTool; vt != nil && vt.EagerInputStreaming.Valid() { + return &vt.EagerInputStreaming.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ToolUnionParam) GetMaxCharacters() *int64 { + if vt := u.OfTextEditor20250728; vt != nil && vt.MaxCharacters.Valid() { + return &vt.MaxCharacters.Value + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ToolUnionParam) GetName() *string { + if vt := u.OfTool; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfBashTool20250124; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfMemoryTool20250818; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfTextEditor20250124; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfTextEditor20250429; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfTextEditor20250728; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return (*string)(&vt.Name) + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return (*string)(&vt.Name) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u ToolUnionParam) GetDeferLoading() *bool { + if vt := u.OfTool; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfBashTool20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20250522; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20250825; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfCodeExecutionTool20260120; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfMemoryTool20250818; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250124; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250429; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfTextEditor20250728; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebSearchTool20250305; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil && vt.DeferLoading.Valid() { + return &vt.DeferLoading.Value } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ToolChoiceUnionParam) GetName() *string { - if vt := u.OfTool; vt != nil { - return &vt.Name +func (u ToolUnionParam) GetStrict() *bool { + if vt := u.OfTool; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfBashTool20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20250522; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20250825; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfCodeExecutionTool20260120; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfMemoryTool20250818; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250124; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250429; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfTextEditor20250728; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebSearchTool20250305; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil && vt.Strict.Valid() { + return &vt.Strict.Value } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ToolChoiceUnionParam) GetType() *string { - if vt := u.OfAuto; vt != nil { +func (u ToolUnionParam) GetType() *string { + if vt := u.OfTool; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfAny; vt != nil { + } else if vt := u.OfBashTool20250124; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfTool; vt != nil { + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfNone; vt != nil { + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfMemoryTool20250818; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfTextEditor20250124; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfTextEditor20250429; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfTextEditor20250728; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { return (*string)(&vt.Type) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ToolChoiceUnionParam) GetDisableParallelToolUse() *bool { - if vt := u.OfAuto; vt != nil && vt.DisableParallelToolUse.Valid() { - return &vt.DisableParallelToolUse.Value - } else if vt := u.OfAny; vt != nil && vt.DisableParallelToolUse.Valid() { - return &vt.DisableParallelToolUse.Value - } else if vt := u.OfTool; vt != nil && vt.DisableParallelToolUse.Valid() { - return &vt.DisableParallelToolUse.Value +func (u ToolUnionParam) GetMaxUses() *int64 { + if vt := u.OfWebSearchTool20250305; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } else if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } else if vt := u.OfWebSearchTool20260209; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.MaxUses.Valid() { + return &vt.MaxUses.Value } return nil } -// The model will use any available tools. -// -// The property Type is required. -type ToolChoiceAnyParam struct { - // Whether to disable parallel tool use. - // - // Defaults to `false`. If set to `true`, the model will output exactly one tool - // use. - DisableParallelToolUse param.Opt[bool] `json:"disable_parallel_tool_use,omitzero"` - // This field can be elided, and will marshal its zero value as "any". - Type constant.Any `json:"type,required"` - paramObj +// Returns a pointer to the underlying variant's property, if present. +func (u ToolUnionParam) GetMaxContentTokens() *int64 { + if vt := u.OfWebFetchTool20250910; vt != nil && vt.MaxContentTokens.Valid() { + return &vt.MaxContentTokens.Value + } else if vt := u.OfWebFetchTool20260209; vt != nil && vt.MaxContentTokens.Valid() { + return &vt.MaxContentTokens.Value + } + return nil } -func (r ToolChoiceAnyParam) MarshalJSON() (data []byte, err error) { - type shadow ToolChoiceAnyParam - return param.MarshalObject(r, (*shadow)(&r)) +// Returns a pointer to the underlying variant's AllowedCallers property, if +// present. +func (u ToolUnionParam) GetAllowedCallers() []string { + if vt := u.OfTool; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfBashTool20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfMemoryTool20250818; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250124; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250429; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfTextEditor20250728; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return vt.AllowedCallers + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return vt.AllowedCallers + } + return nil } -func (r *ToolChoiceAnyParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's CacheControl property, if present. +func (u ToolUnionParam) GetCacheControl() *CacheControlEphemeralParam { + if vt := u.OfTool; vt != nil { + return &vt.CacheControl + } else if vt := u.OfBashTool20250124; vt != nil { + return &vt.CacheControl + } else if vt := u.OfCodeExecutionTool20250522; vt != nil { + return &vt.CacheControl + } else if vt := u.OfCodeExecutionTool20250825; vt != nil { + return &vt.CacheControl + } else if vt := u.OfCodeExecutionTool20260120; vt != nil { + return &vt.CacheControl + } else if vt := u.OfMemoryTool20250818; vt != nil { + return &vt.CacheControl + } else if vt := u.OfTextEditor20250124; vt != nil { + return &vt.CacheControl + } else if vt := u.OfTextEditor20250429; vt != nil { + return &vt.CacheControl + } else if vt := u.OfTextEditor20250728; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebSearchTool20250305; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return &vt.CacheControl + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolBm25_20251119; vt != nil { + return &vt.CacheControl + } else if vt := u.OfToolSearchToolRegex20251119; vt != nil { + return &vt.CacheControl + } + return nil } -// The model will automatically decide whether to use tools. -// -// The property Type is required. -type ToolChoiceAutoParam struct { - // Whether to disable parallel tool use. - // - // Defaults to `false`. If set to `true`, the model will output at most one tool - // use. - DisableParallelToolUse param.Opt[bool] `json:"disable_parallel_tool_use,omitzero"` - // This field can be elided, and will marshal its zero value as "auto". - Type constant.Auto `json:"type,required"` - paramObj +// Returns a pointer to the underlying variant's InputExamples property, if +// present. +func (u ToolUnionParam) GetInputExamples() []map[string]any { + if vt := u.OfTool; vt != nil { + return vt.InputExamples + } else if vt := u.OfBashTool20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfMemoryTool20250818; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250124; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250429; vt != nil { + return vt.InputExamples + } else if vt := u.OfTextEditor20250728; vt != nil { + return vt.InputExamples + } + return nil } -func (r ToolChoiceAutoParam) MarshalJSON() (data []byte, err error) { - type shadow ToolChoiceAutoParam - return param.MarshalObject(r, (*shadow)(&r)) +// Returns a pointer to the underlying variant's AllowedDomains property, if +// present. +func (u ToolUnionParam) GetAllowedDomains() []string { + if vt := u.OfWebSearchTool20250305; vt != nil { + return vt.AllowedDomains + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return vt.AllowedDomains + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.AllowedDomains + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.AllowedDomains + } + return nil } -func (r *ToolChoiceAutoParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's BlockedDomains property, if +// present. +func (u ToolUnionParam) GetBlockedDomains() []string { + if vt := u.OfWebSearchTool20250305; vt != nil { + return vt.BlockedDomains + } else if vt := u.OfWebFetchTool20250910; vt != nil { + return vt.BlockedDomains + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return vt.BlockedDomains + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return vt.BlockedDomains + } + return nil } -func NewToolChoiceNoneParam() ToolChoiceNoneParam { - return ToolChoiceNoneParam{ - Type: "none", +// Returns a pointer to the underlying variant's UserLocation property, if present. +func (u ToolUnionParam) GetUserLocation() *UserLocationParam { + if vt := u.OfWebSearchTool20250305; vt != nil { + return &vt.UserLocation + } else if vt := u.OfWebSearchTool20260209; vt != nil { + return &vt.UserLocation } + return nil } -// The model will not be allowed to use tools. -// -// This struct has a constant value, construct it with [NewToolChoiceNoneParam]. -type ToolChoiceNoneParam struct { - Type constant.None `json:"type,required"` - paramObj +// Returns a pointer to the underlying variant's Citations property, if present. +func (u ToolUnionParam) GetCitations() *CitationsConfigParam { + if vt := u.OfWebFetchTool20250910; vt != nil { + return &vt.Citations + } else if vt := u.OfWebFetchTool20260209; vt != nil { + return &vt.Citations + } + return nil } -func (r ToolChoiceNoneParam) MarshalJSON() (data []byte, err error) { - type shadow ToolChoiceNoneParam - return param.MarshalObject(r, (*shadow)(&r)) +type ToolUseBlock struct { + ID string `json:"id,required"` + // necessary custom code modification + Input json.RawMessage `json:"input,required"` + Name string `json:"name,required"` + Type constant.ToolUse `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + Caller respjson.Field + Input respjson.Field + Name respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -func (r *ToolChoiceNoneParam) UnmarshalJSON(data []byte) error { +// Returns the unmodified JSON received from the API +func (r ToolUseBlock) RawJSON() string { return r.JSON.raw } +func (r *ToolUseBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// The model will use the specified tool with `tool_choice.name`. +// ToolUseBlockCallerUnion contains all possible properties and values from +// [DirectCaller], [ServerToolCaller], [ServerToolCaller20260120]. // -// The properties Name, Type are required. -type ToolChoiceToolParam struct { - // The name of the tool to use. - Name string `json:"name,required"` - // Whether to disable parallel tool use. - // - // Defaults to `false`. If set to `true`, the model will output exactly one tool - // use. - DisableParallelToolUse param.Opt[bool] `json:"disable_parallel_tool_use,omitzero"` - // This field can be elided, and will marshal its zero value as "tool". - Type constant.Tool `json:"type,required"` - paramObj +// Use the [ToolUseBlockCallerUnion.AsAny] method to switch on the variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type ToolUseBlockCallerUnion struct { + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` } -func (r ToolChoiceToolParam) MarshalJSON() (data []byte, err error) { - type shadow ToolChoiceToolParam - return param.MarshalObject(r, (*shadow)(&r)) +// anyToolUseBlockCaller is implemented by each variant of +// [ToolUseBlockCallerUnion] to add type safety for the return type of +// [ToolUseBlockCallerUnion.AsAny] +type anyToolUseBlockCaller interface { + implToolUseBlockCallerUnion() } -func (r *ToolChoiceToolParam) UnmarshalJSON(data []byte) error { +func (DirectCaller) implToolUseBlockCallerUnion() {} +func (ServerToolCaller) implToolUseBlockCallerUnion() {} +func (ServerToolCaller20260120) implToolUseBlockCallerUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := ToolUseBlockCallerUnion.AsAny().(type) { +// case anthropic.DirectCaller: +// case anthropic.ServerToolCaller: +// case anthropic.ServerToolCaller20260120: +// default: +// fmt.Errorf("no variant present") +// } +func (u ToolUseBlockCallerUnion) AsAny() anyToolUseBlockCaller { + switch u.Type { + case "direct": + return u.AsDirect() + case "code_execution_20250825": + return u.AsCodeExecution20250825() + case "code_execution_20260120": + return u.AsCodeExecution20260120() + } + return nil +} + +func (u ToolUseBlockCallerUnion) AsDirect() (v DirectCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ToolUseBlockCallerUnion) AsCodeExecution20250825() (v ServerToolCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ToolUseBlockCallerUnion) AsCodeExecution20260120() (v ServerToolCaller20260120) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u ToolUseBlockCallerUnion) RawJSON() string { return u.JSON.raw } + +func (r *ToolUseBlockCallerUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// The properties ToolUseID, Type are required. -type ToolResultBlockParam struct { - ToolUseID string `json:"tool_use_id,required"` - IsError param.Opt[bool] `json:"is_error,omitzero"` +// The properties ID, Input, Name, Type are required. +type ToolUseBlockParam struct { + ID string `json:"id,required"` + Input any `json:"input,omitzero,required"` + Name string `json:"name,required"` // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` - Content []ToolResultBlockParamContentUnion `json:"content,omitzero"` - // This field can be elided, and will marshal its zero value as "tool_result". - Type constant.ToolResult `json:"type,required"` + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Tool invocation directly from the model. + Caller ToolUseBlockParamCallerUnion `json:"caller,omitzero"` + // This field can be elided, and will marshal its zero value as "tool_use". + Type constant.ToolUse `json:"type,required"` paramObj } -func (r ToolResultBlockParam) MarshalJSON() (data []byte, err error) { - type shadow ToolResultBlockParam +func (r ToolUseBlockParam) MarshalJSON() (data []byte, err error) { + type shadow ToolUseBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ToolResultBlockParam) UnmarshalJSON(data []byte) error { +func (r *ToolUseBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. -type ToolResultBlockParamContentUnion struct { - OfText *TextBlockParam `json:",omitzero,inline"` - OfImage *ImageBlockParam `json:",omitzero,inline"` - OfSearchResult *SearchResultBlockParam `json:",omitzero,inline"` - OfDocument *DocumentBlockParam `json:",omitzero,inline"` +type ToolUseBlockParamCallerUnion struct { + OfDirect *DirectCallerParam `json:",omitzero,inline"` + OfCodeExecution20250825 *ServerToolCallerParam `json:",omitzero,inline"` + OfCodeExecution20260120 *ServerToolCaller20260120Param `json:",omitzero,inline"` paramUnion } -func (u ToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfText, u.OfImage, u.OfSearchResult, u.OfDocument) +func (u ToolUseBlockParamCallerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfDirect, u.OfCodeExecution20250825, u.OfCodeExecution20260120) } - -func (u *ToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { +func (u *ToolUseBlockParamCallerUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } -func (u *ToolResultBlockParamContentUnion) asAny() any { - if !param.IsOmitted(u.OfText) { - return u.OfText - } else if !param.IsOmitted(u.OfImage) { - return u.OfImage - } else if !param.IsOmitted(u.OfSearchResult) { - return u.OfSearchResult - } else if !param.IsOmitted(u.OfDocument) { - return u.OfDocument - } - return nil -} - -// Returns a pointer to the underlying variant's property, if present. -func (u ToolResultBlockParamContentUnion) GetText() *string { - if vt := u.OfText; vt != nil { - return &vt.Text - } - return nil -} - -// Returns a pointer to the underlying variant's property, if present. -func (u ToolResultBlockParamContentUnion) GetContent() []TextBlockParam { - if vt := u.OfSearchResult; vt != nil { - return vt.Content - } - return nil -} - -// Returns a pointer to the underlying variant's property, if present. -func (u ToolResultBlockParamContentUnion) GetContext() *string { - if vt := u.OfDocument; vt != nil && vt.Context.Valid() { - return &vt.Context.Value +func (u *ToolUseBlockParamCallerUnion) asAny() any { + if !param.IsOmitted(u.OfDirect) { + return u.OfDirect + } else if !param.IsOmitted(u.OfCodeExecution20250825) { + return u.OfCodeExecution20250825 + } else if !param.IsOmitted(u.OfCodeExecution20260120) { + return u.OfCodeExecution20260120 } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ToolResultBlockParamContentUnion) GetType() *string { - if vt := u.OfText; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfImage; vt != nil { +func (u ToolUseBlockParamCallerUnion) GetType() *string { + if vt := u.OfDirect; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfSearchResult; vt != nil { + } else if vt := u.OfCodeExecution20250825; vt != nil { return (*string)(&vt.Type) - } else if vt := u.OfDocument; vt != nil { + } else if vt := u.OfCodeExecution20260120; vt != nil { return (*string)(&vt.Type) } return nil } // Returns a pointer to the underlying variant's property, if present. -func (u ToolResultBlockParamContentUnion) GetTitle() *string { - if vt := u.OfSearchResult; vt != nil { - return (*string)(&vt.Title) - } else if vt := u.OfDocument; vt != nil && vt.Title.Valid() { - return &vt.Title.Value +func (u ToolUseBlockParamCallerUnion) GetToolID() *string { + if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.ToolID) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.ToolID) } return nil } -// Returns a pointer to the underlying variant's CacheControl property, if present. -func (u ToolResultBlockParamContentUnion) GetCacheControl() *CacheControlEphemeralParam { - if vt := u.OfText; vt != nil { - return &vt.CacheControl - } else if vt := u.OfImage; vt != nil { - return &vt.CacheControl - } else if vt := u.OfSearchResult; vt != nil { - return &vt.CacheControl - } else if vt := u.OfDocument; vt != nil { - return &vt.CacheControl - } - return nil +func init() { + apijson.RegisterUnion[ToolUseBlockParamCallerUnion]( + "type", + apijson.Discriminator[DirectCallerParam]("direct"), + apijson.Discriminator[ServerToolCallerParam]("code_execution_20250825"), + apijson.Discriminator[ServerToolCaller20260120Param]("code_execution_20260120"), + ) } -// Returns a subunion which exports methods to access subproperties -// -// Or use AsAny() to get the underlying value -func (u ToolResultBlockParamContentUnion) GetCitations() (res toolResultBlockParamContentUnionCitations) { - if vt := u.OfText; vt != nil { - res.any = &vt.Citations - } else if vt := u.OfSearchResult; vt != nil { - res.any = &vt.Citations - } else if vt := u.OfDocument; vt != nil { - res.any = &vt.Citations - } - return res +// The properties Type, URL are required. +type URLImageSourceParam struct { + URL string `json:"url,required"` + // This field can be elided, and will marshal its zero value as "url". + Type constant.URL `json:"type,required"` + paramObj } -// Can have the runtime types [*[]TextCitationParamUnion], [*CitationsConfigParam] -type toolResultBlockParamContentUnionCitations struct{ any } +func (r URLImageSourceParam) MarshalJSON() (data []byte, err error) { + type shadow URLImageSourceParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *URLImageSourceParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -// Use the following switch statement to get the type of the union: -// -// switch u.AsAny().(type) { -// case *[]anthropic.TextCitationParamUnion: -// case *anthropic.CitationsConfigParam: -// default: -// fmt.Errorf("not present") -// } -func (u toolResultBlockParamContentUnionCitations) AsAny() any { return u.any } +// The properties Type, URL are required. +type URLPDFSourceParam struct { + URL string `json:"url,required"` + // This field can be elided, and will marshal its zero value as "url". + Type constant.URL `json:"type,required"` + paramObj +} -// Returns a pointer to the underlying variant's property, if present. -func (u toolResultBlockParamContentUnionCitations) GetEnabled() *bool { - switch vt := u.any.(type) { - case *CitationsConfigParam: - return paramutil.AddrIfPresent(vt.Enabled) - } - return nil +func (r URLPDFSourceParam) MarshalJSON() (data []byte, err error) { + type shadow URLPDFSourceParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *URLPDFSourceParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns a subunion which exports methods to access subproperties -// -// Or use AsAny() to get the underlying value -func (u ToolResultBlockParamContentUnion) GetSource() (res toolResultBlockParamContentUnionSource) { - if vt := u.OfImage; vt != nil { - res.any = vt.Source.asAny() - } else if vt := u.OfSearchResult; vt != nil { - res.any = &vt.Source - } else if vt := u.OfDocument; vt != nil { - res.any = vt.Source.asAny() - } - return res +type Usage struct { + // Breakdown of cached tokens by TTL + CacheCreation CacheCreation `json:"cache_creation,required"` + // The number of input tokens used to create the cache entry. + CacheCreationInputTokens int64 `json:"cache_creation_input_tokens,required"` + // The number of input tokens read from the cache. + CacheReadInputTokens int64 `json:"cache_read_input_tokens,required"` + // The geographic region where inference was performed for this request. + InferenceGeo string `json:"inference_geo,required"` + // The number of input tokens which were used. + InputTokens int64 `json:"input_tokens,required"` + // The number of output tokens which were used. + OutputTokens int64 `json:"output_tokens,required"` + // The number of server tool requests. + ServerToolUse ServerToolUsage `json:"server_tool_use,required"` + // If the request used the priority, standard, or batch tier. + // + // Any of "standard", "priority", "batch". + ServiceTier UsageServiceTier `json:"service_tier,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + CacheCreation respjson.Field + CacheCreationInputTokens respjson.Field + CacheReadInputTokens respjson.Field + InferenceGeo respjson.Field + InputTokens respjson.Field + OutputTokens respjson.Field + ServerToolUse respjson.Field + ServiceTier respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -// Can have the runtime types [*Base64ImageSourceParam], [*URLImageSourceParam], -// [*string], [*Base64PDFSourceParam], [*PlainTextSourceParam], -// [*ContentBlockSourceParam], [*URLPDFSourceParam] -type toolResultBlockParamContentUnionSource struct{ any } +// Returns the unmodified JSON received from the API +func (r Usage) RawJSON() string { return r.JSON.raw } +func (r *Usage) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -// Use the following switch statement to get the type of the union: -// -// switch u.AsAny().(type) { -// case *anthropic.Base64ImageSourceParam: -// case *anthropic.URLImageSourceParam: -// case *string: -// case *anthropic.Base64PDFSourceParam: -// case *anthropic.PlainTextSourceParam: -// case *anthropic.ContentBlockSourceParam: -// case *anthropic.URLPDFSourceParam: -// default: -// fmt.Errorf("not present") -// } -func (u toolResultBlockParamContentUnionSource) AsAny() any { return u.any } +// If the request used the priority, standard, or batch tier. +type UsageServiceTier string -// Returns a pointer to the underlying variant's property, if present. -func (u toolResultBlockParamContentUnionSource) GetContent() *ContentBlockSourceContentUnionParam { - switch vt := u.any.(type) { - case *DocumentBlockParamSourceUnion: - return vt.GetContent() - } - return nil -} +const ( + UsageServiceTierStandard UsageServiceTier = "standard" + UsageServiceTierPriority UsageServiceTier = "priority" + UsageServiceTierBatch UsageServiceTier = "batch" +) -// Returns a pointer to the underlying variant's property, if present. -func (u toolResultBlockParamContentUnionSource) GetData() *string { - switch vt := u.any.(type) { - case *ImageBlockParamSourceUnion: - return vt.GetData() - case *DocumentBlockParamSourceUnion: - return vt.GetData() - } - return nil +// The property Type is required. +type UserLocationParam struct { + // The city of the user. + City param.Opt[string] `json:"city,omitzero"` + // The two letter + // [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the + // user. + Country param.Opt[string] `json:"country,omitzero"` + // The region of the user. + Region param.Opt[string] `json:"region,omitzero"` + // The [IANA timezone](https://nodatime.org/TimeZones) of the user. + Timezone param.Opt[string] `json:"timezone,omitzero"` + // This field can be elided, and will marshal its zero value as "approximate". + Type constant.Approximate `json:"type,required"` + paramObj } -// Returns a pointer to the underlying variant's property, if present. -func (u toolResultBlockParamContentUnionSource) GetMediaType() *string { - switch vt := u.any.(type) { - case *ImageBlockParamSourceUnion: - return vt.GetMediaType() - case *DocumentBlockParamSourceUnion: - return vt.GetMediaType() - } - return nil +func (r UserLocationParam) MarshalJSON() (data []byte, err error) { + type shadow UserLocationParam + return param.MarshalObject(r, (*shadow)(&r)) } - -// Returns a pointer to the underlying variant's property, if present. -func (u toolResultBlockParamContentUnionSource) GetType() *string { - switch vt := u.any.(type) { - case *ImageBlockParamSourceUnion: - return vt.GetType() - case *DocumentBlockParamSourceUnion: - return vt.GetType() - } - return nil +func (r *UserLocationParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns a pointer to the underlying variant's property, if present. -func (u toolResultBlockParamContentUnionSource) GetURL() *string { - switch vt := u.any.(type) { - case *ImageBlockParamSourceUnion: - return vt.GetURL() - case *DocumentBlockParamSourceUnion: - return vt.GetURL() - } - return nil +type WebFetchBlock struct { + Content DocumentBlock `json:"content,required"` + // ISO 8601 timestamp when the content was retrieved + RetrievedAt string `json:"retrieved_at,required"` + Type constant.WebFetchResult `json:"type,required"` + // Fetched content URL + URL string `json:"url,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Content respjson.Field + RetrievedAt respjson.Field + Type respjson.Field + URL respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -// The properties Name, Type are required. -type ToolTextEditor20250124Param struct { - // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` - // Name of the tool. - // - // This is how the tool will be called by the model and in `tool_use` blocks. - // - // This field can be elided, and will marshal its zero value as - // "str_replace_editor". - Name constant.StrReplaceEditor `json:"name,required"` - // This field can be elided, and will marshal its zero value as - // "text_editor_20250124". - Type constant.TextEditor20250124 `json:"type,required"` +// Returns the unmodified JSON received from the API +func (r WebFetchBlock) RawJSON() string { return r.JSON.raw } +func (r *WebFetchBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// The properties Content, Type, URL are required. +type WebFetchBlockParam struct { + Content DocumentBlockParam `json:"content,omitzero,required"` + // Fetched content URL + URL string `json:"url,required"` + // ISO 8601 timestamp when the content was retrieved + RetrievedAt param.Opt[string] `json:"retrieved_at,omitzero"` + // This field can be elided, and will marshal its zero value as "web_fetch_result". + Type constant.WebFetchResult `json:"type,required"` paramObj } -func (r ToolTextEditor20250124Param) MarshalJSON() (data []byte, err error) { - type shadow ToolTextEditor20250124Param +func (r WebFetchBlockParam) MarshalJSON() (data []byte, err error) { + type shadow WebFetchBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ToolTextEditor20250124Param) UnmarshalJSON(data []byte) error { +func (r *WebFetchBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Name, Type are required. -type ToolTextEditor20250429Param struct { +type WebFetchTool20250910Param struct { + // Maximum number of tokens used by including web page text content in the context. + // The limit is approximate and does not apply to binary content such as PDFs. + MaxContentTokens param.Opt[int64] `json:"max_content_tokens,omitzero"` + // Maximum number of times the tool can be used in the API request. + MaxUses param.Opt[int64] `json:"max_uses,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // List of domains to allow fetching from + AllowedDomains []string `json:"allowed_domains,omitzero"` + // List of domains to block fetching from + BlockedDomains []string `json:"blocked_domains,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Citations configuration for fetched documents. Citations are disabled by + // default. + Citations CitationsConfigParam `json:"citations,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. // + // This field can be elided, and will marshal its zero value as "web_fetch". + Name constant.WebFetch `json:"name,required"` // This field can be elided, and will marshal its zero value as - // "str_replace_based_edit_tool". - Name constant.StrReplaceBasedEditTool `json:"name,required"` - // This field can be elided, and will marshal its zero value as - // "text_editor_20250429". - Type constant.TextEditor20250429 `json:"type,required"` + // "web_fetch_20250910". + Type constant.WebFetch20250910 `json:"type,required"` paramObj } -func (r ToolTextEditor20250429Param) MarshalJSON() (data []byte, err error) { - type shadow ToolTextEditor20250429Param +func (r WebFetchTool20250910Param) MarshalJSON() (data []byte, err error) { + type shadow WebFetchTool20250910Param return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ToolTextEditor20250429Param) UnmarshalJSON(data []byte) error { +func (r *WebFetchTool20250910Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Name, Type are required. -type ToolTextEditor20250728Param struct { - // Maximum number of characters to display when viewing a file. If not specified, - // defaults to displaying the full file. - MaxCharacters param.Opt[int64] `json:"max_characters,omitzero"` +type WebFetchTool20260209Param struct { + // Maximum number of tokens used by including web page text content in the context. + // The limit is approximate and does not apply to binary content such as PDFs. + MaxContentTokens param.Opt[int64] `json:"max_content_tokens,omitzero"` + // Maximum number of times the tool can be used in the API request. + MaxUses param.Opt[int64] `json:"max_uses,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // List of domains to allow fetching from + AllowedDomains []string `json:"allowed_domains,omitzero"` + // List of domains to block fetching from + BlockedDomains []string `json:"blocked_domains,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Citations configuration for fetched documents. Citations are disabled by + // default. + Citations CitationsConfigParam `json:"citations,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. // + // This field can be elided, and will marshal its zero value as "web_fetch". + Name constant.WebFetch `json:"name,required"` // This field can be elided, and will marshal its zero value as - // "str_replace_based_edit_tool". - Name constant.StrReplaceBasedEditTool `json:"name,required"` - // This field can be elided, and will marshal its zero value as - // "text_editor_20250728". - Type constant.TextEditor20250728 `json:"type,required"` + // "web_fetch_20260209". + Type constant.WebFetch20260209 `json:"type,required"` paramObj } -func (r ToolTextEditor20250728Param) MarshalJSON() (data []byte, err error) { - type shadow ToolTextEditor20250728Param +func (r WebFetchTool20260209Param) MarshalJSON() (data []byte, err error) { + type shadow WebFetchTool20260209Param return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *ToolTextEditor20250728Param) UnmarshalJSON(data []byte) error { +func (r *WebFetchTool20260209Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func ToolUnionParamOfTool(inputSchema ToolInputSchemaParam, name string) ToolUnionParam { - var variant ToolParam - variant.InputSchema = inputSchema - variant.Name = name - return ToolUnionParam{OfTool: &variant} +type WebFetchToolResultBlock struct { + // Tool invocation directly from the model. + Caller WebFetchToolResultBlockCallerUnion `json:"caller,required"` + Content WebFetchToolResultBlockContentUnion `json:"content,required"` + ToolUseID string `json:"tool_use_id,required"` + Type constant.WebFetchToolResult `json:"type,required"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Caller respjson.Field + Content respjson.Field + ToolUseID respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` } -// Only one field can be non-zero. -// -// Use [param.IsOmitted] to confirm if a field is set. -type ToolUnionParam struct { - OfTool *ToolParam `json:",omitzero,inline"` - OfBashTool20250124 *ToolBash20250124Param `json:",omitzero,inline"` - OfTextEditor20250124 *ToolTextEditor20250124Param `json:",omitzero,inline"` - OfTextEditor20250429 *ToolTextEditor20250429Param `json:",omitzero,inline"` - OfTextEditor20250728 *ToolTextEditor20250728Param `json:",omitzero,inline"` - OfWebSearchTool20250305 *WebSearchTool20250305Param `json:",omitzero,inline"` - paramUnion +// Returns the unmodified JSON received from the API +func (r WebFetchToolResultBlock) RawJSON() string { return r.JSON.raw } +func (r *WebFetchToolResultBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -func (u ToolUnionParam) MarshalJSON() ([]byte, error) { - return param.MarshalUnion(u, u.OfTool, - u.OfBashTool20250124, - u.OfTextEditor20250124, - u.OfTextEditor20250429, - u.OfTextEditor20250728, - u.OfWebSearchTool20250305) +// WebFetchToolResultBlockCallerUnion contains all possible properties and values +// from [DirectCaller], [ServerToolCaller], [ServerToolCaller20260120]. +// +// Use the [WebFetchToolResultBlockCallerUnion.AsAny] method to switch on the +// variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type WebFetchToolResultBlockCallerUnion struct { + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` } -func (u *ToolUnionParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, u) +// anyWebFetchToolResultBlockCaller is implemented by each variant of +// [WebFetchToolResultBlockCallerUnion] to add type safety for the return type of +// [WebFetchToolResultBlockCallerUnion.AsAny] +type anyWebFetchToolResultBlockCaller interface { + implWebFetchToolResultBlockCallerUnion() } -func (u *ToolUnionParam) asAny() any { - if !param.IsOmitted(u.OfTool) { - return u.OfTool - } else if !param.IsOmitted(u.OfBashTool20250124) { - return u.OfBashTool20250124 - } else if !param.IsOmitted(u.OfTextEditor20250124) { - return u.OfTextEditor20250124 - } else if !param.IsOmitted(u.OfTextEditor20250429) { - return u.OfTextEditor20250429 - } else if !param.IsOmitted(u.OfTextEditor20250728) { - return u.OfTextEditor20250728 - } else if !param.IsOmitted(u.OfWebSearchTool20250305) { - return u.OfWebSearchTool20250305 +func (DirectCaller) implWebFetchToolResultBlockCallerUnion() {} +func (ServerToolCaller) implWebFetchToolResultBlockCallerUnion() {} +func (ServerToolCaller20260120) implWebFetchToolResultBlockCallerUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := WebFetchToolResultBlockCallerUnion.AsAny().(type) { +// case anthropic.DirectCaller: +// case anthropic.ServerToolCaller: +// case anthropic.ServerToolCaller20260120: +// default: +// fmt.Errorf("no variant present") +// } +func (u WebFetchToolResultBlockCallerUnion) AsAny() anyWebFetchToolResultBlockCaller { + switch u.Type { + case "direct": + return u.AsDirect() + case "code_execution_20250825": + return u.AsCodeExecution20250825() + case "code_execution_20260120": + return u.AsCodeExecution20260120() } return nil } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetInputSchema() *ToolInputSchemaParam { - if vt := u.OfTool; vt != nil { - return &vt.InputSchema - } - return nil +func (u WebFetchToolResultBlockCallerUnion) AsDirect() (v DirectCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetDescription() *string { - if vt := u.OfTool; vt != nil && vt.Description.Valid() { - return &vt.Description.Value - } - return nil +func (u WebFetchToolResultBlockCallerUnion) AsCodeExecution20250825() (v ServerToolCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetMaxCharacters() *int64 { - if vt := u.OfTextEditor20250728; vt != nil && vt.MaxCharacters.Valid() { - return &vt.MaxCharacters.Value - } - return nil +func (u WebFetchToolResultBlockCallerUnion) AsCodeExecution20260120() (v ServerToolCaller20260120) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetAllowedDomains() []string { - if vt := u.OfWebSearchTool20250305; vt != nil { - return vt.AllowedDomains - } - return nil +// Returns the unmodified JSON received from the API +func (u WebFetchToolResultBlockCallerUnion) RawJSON() string { return u.JSON.raw } + +func (r *WebFetchToolResultBlockCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetBlockedDomains() []string { - if vt := u.OfWebSearchTool20250305; vt != nil { - return vt.BlockedDomains - } - return nil +// WebFetchToolResultBlockContentUnion contains all possible properties and values +// from [WebFetchToolResultErrorBlock], [WebFetchBlock]. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type WebFetchToolResultBlockContentUnion struct { + // This field is from variant [WebFetchToolResultErrorBlock]. + ErrorCode WebFetchToolResultErrorCode `json:"error_code"` + Type string `json:"type"` + // This field is from variant [WebFetchBlock]. + Content DocumentBlock `json:"content"` + // This field is from variant [WebFetchBlock]. + RetrievedAt string `json:"retrieved_at"` + // This field is from variant [WebFetchBlock]. + URL string `json:"url"` + JSON struct { + ErrorCode respjson.Field + Type respjson.Field + Content respjson.Field + RetrievedAt respjson.Field + URL respjson.Field + raw string + } `json:"-"` } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetMaxUses() *int64 { - if vt := u.OfWebSearchTool20250305; vt != nil && vt.MaxUses.Valid() { - return &vt.MaxUses.Value - } - return nil +func (u WebFetchToolResultBlockContentUnion) AsResponseWebFetchToolResultError() (v WebFetchToolResultErrorBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetUserLocation() *WebSearchTool20250305UserLocationParam { - if vt := u.OfWebSearchTool20250305; vt != nil { - return &vt.UserLocation - } - return nil +func (u WebFetchToolResultBlockContentUnion) AsResponseWebFetchResultBlock() (v WebFetchBlock) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetName() *string { - if vt := u.OfTool; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfBashTool20250124; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfTextEditor20250124; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfTextEditor20250429; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfTextEditor20250728; vt != nil { - return (*string)(&vt.Name) - } else if vt := u.OfWebSearchTool20250305; vt != nil { - return (*string)(&vt.Name) - } - return nil +// Returns the unmodified JSON received from the API +func (u WebFetchToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } + +func (r *WebFetchToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -// Returns a pointer to the underlying variant's property, if present. -func (u ToolUnionParam) GetType() *string { - if vt := u.OfTool; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfBashTool20250124; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfTextEditor20250124; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfTextEditor20250429; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfTextEditor20250728; vt != nil { - return (*string)(&vt.Type) - } else if vt := u.OfWebSearchTool20250305; vt != nil { - return (*string)(&vt.Type) - } - return nil +// The properties Content, ToolUseID, Type are required. +type WebFetchToolResultBlockParam struct { + Content WebFetchToolResultBlockParamContentUnion `json:"content,omitzero,required"` + ToolUseID string `json:"tool_use_id,required"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Tool invocation directly from the model. + Caller WebFetchToolResultBlockParamCallerUnion `json:"caller,omitzero"` + // This field can be elided, and will marshal its zero value as + // "web_fetch_tool_result". + Type constant.WebFetchToolResult `json:"type,required"` + paramObj } -// Returns a pointer to the underlying variant's CacheControl property, if present. -func (u ToolUnionParam) GetCacheControl() *CacheControlEphemeralParam { - if vt := u.OfTool; vt != nil { - return &vt.CacheControl - } else if vt := u.OfBashTool20250124; vt != nil { - return &vt.CacheControl - } else if vt := u.OfTextEditor20250124; vt != nil { - return &vt.CacheControl - } else if vt := u.OfTextEditor20250429; vt != nil { - return &vt.CacheControl - } else if vt := u.OfTextEditor20250728; vt != nil { - return &vt.CacheControl - } else if vt := u.OfWebSearchTool20250305; vt != nil { - return &vt.CacheControl - } - return nil +func (r WebFetchToolResultBlockParam) MarshalJSON() (data []byte, err error) { + type shadow WebFetchToolResultBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *WebFetchToolResultBlockParam) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) } -type ToolUseBlock struct { - ID string `json:"id,required"` - // necessary custom code modification - Input json.RawMessage `json:"input,required"` - Name string `json:"name,required"` - Type constant.ToolUse `json:"type,required"` - // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. - JSON struct { - ID respjson.Field - Input respjson.Field - Name respjson.Field - Type respjson.Field - ExtraFields map[string]respjson.Field - raw string - } `json:"-"` +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type WebFetchToolResultBlockParamContentUnion struct { + OfRequestWebFetchToolResultError *WebFetchToolResultErrorBlockParam `json:",omitzero,inline"` + OfRequestWebFetchResultBlock *WebFetchBlockParam `json:",omitzero,inline"` + paramUnion } -// Returns the unmodified JSON received from the API -func (r ToolUseBlock) RawJSON() string { return r.JSON.raw } +func (u WebFetchToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfRequestWebFetchToolResultError, u.OfRequestWebFetchResultBlock) +} +func (u *WebFetchToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} -func (r *ToolUseBlock) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func (u *WebFetchToolResultBlockParamContentUnion) asAny() any { + if !param.IsOmitted(u.OfRequestWebFetchToolResultError) { + return u.OfRequestWebFetchToolResultError + } else if !param.IsOmitted(u.OfRequestWebFetchResultBlock) { + return u.OfRequestWebFetchResultBlock + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u WebFetchToolResultBlockParamContentUnion) GetErrorCode() *string { + if vt := u.OfRequestWebFetchToolResultError; vt != nil { + return (*string)(&vt.ErrorCode) + } + return nil } -func (r ToolUseBlock) ToParam() ToolUseBlockParam { - var toolUse ToolUseBlockParam - toolUse.Type = r.Type - toolUse.ID = r.ID - toolUse.Input = r.Input - toolUse.Name = r.Name - return toolUse +// Returns a pointer to the underlying variant's property, if present. +func (u WebFetchToolResultBlockParamContentUnion) GetContent() *DocumentBlockParam { + if vt := u.OfRequestWebFetchResultBlock; vt != nil { + return &vt.Content + } + return nil } -// The properties ID, Input, Name, Type are required. -type ToolUseBlockParam struct { - ID string `json:"id,required"` - Input any `json:"input,omitzero,required"` - Name string `json:"name,required"` - // Create a cache control breakpoint at this content block. - CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` - // This field can be elided, and will marshal its zero value as "tool_use". - Type constant.ToolUse `json:"type,required"` - paramObj +// Returns a pointer to the underlying variant's property, if present. +func (u WebFetchToolResultBlockParamContentUnion) GetURL() *string { + if vt := u.OfRequestWebFetchResultBlock; vt != nil { + return &vt.URL + } + return nil } -func (r ToolUseBlockParam) MarshalJSON() (data []byte, err error) { - type shadow ToolUseBlockParam - return param.MarshalObject(r, (*shadow)(&r)) +// Returns a pointer to the underlying variant's property, if present. +func (u WebFetchToolResultBlockParamContentUnion) GetRetrievedAt() *string { + if vt := u.OfRequestWebFetchResultBlock; vt != nil && vt.RetrievedAt.Valid() { + return &vt.RetrievedAt.Value + } + return nil } -func (r *ToolUseBlockParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +// Returns a pointer to the underlying variant's property, if present. +func (u WebFetchToolResultBlockParamContentUnion) GetType() *string { + if vt := u.OfRequestWebFetchToolResultError; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfRequestWebFetchResultBlock; vt != nil { + return (*string)(&vt.Type) + } + return nil } -// The properties Type, URL are required. -type URLImageSourceParam struct { - URL string `json:"url,required"` - // This field can be elided, and will marshal its zero value as "url". - Type constant.URL `json:"type,required"` - paramObj +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type WebFetchToolResultBlockParamCallerUnion struct { + OfDirect *DirectCallerParam `json:",omitzero,inline"` + OfCodeExecution20250825 *ServerToolCallerParam `json:",omitzero,inline"` + OfCodeExecution20260120 *ServerToolCaller20260120Param `json:",omitzero,inline"` + paramUnion } -func (r URLImageSourceParam) MarshalJSON() (data []byte, err error) { - type shadow URLImageSourceParam - return param.MarshalObject(r, (*shadow)(&r)) +func (u WebFetchToolResultBlockParamCallerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfDirect, u.OfCodeExecution20250825, u.OfCodeExecution20260120) +} +func (u *WebFetchToolResultBlockParamCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) } -func (r *URLImageSourceParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func (u *WebFetchToolResultBlockParamCallerUnion) asAny() any { + if !param.IsOmitted(u.OfDirect) { + return u.OfDirect + } else if !param.IsOmitted(u.OfCodeExecution20250825) { + return u.OfCodeExecution20250825 + } else if !param.IsOmitted(u.OfCodeExecution20260120) { + return u.OfCodeExecution20260120 + } + return nil } -// The properties Type, URL are required. -type URLPDFSourceParam struct { - URL string `json:"url,required"` - // This field can be elided, and will marshal its zero value as "url". - Type constant.URL `json:"type,required"` - paramObj +// Returns a pointer to the underlying variant's property, if present. +func (u WebFetchToolResultBlockParamCallerUnion) GetType() *string { + if vt := u.OfDirect; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.Type) + } + return nil } -func (r URLPDFSourceParam) MarshalJSON() (data []byte, err error) { - type shadow URLPDFSourceParam - return param.MarshalObject(r, (*shadow)(&r)) +// Returns a pointer to the underlying variant's property, if present. +func (u WebFetchToolResultBlockParamCallerUnion) GetToolID() *string { + if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.ToolID) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.ToolID) + } + return nil } -func (r *URLPDFSourceParam) UnmarshalJSON(data []byte) error { - return apijson.UnmarshalRoot(data, r) +func init() { + apijson.RegisterUnion[WebFetchToolResultBlockParamCallerUnion]( + "type", + apijson.Discriminator[DirectCallerParam]("direct"), + apijson.Discriminator[ServerToolCallerParam]("code_execution_20250825"), + apijson.Discriminator[ServerToolCaller20260120Param]("code_execution_20260120"), + ) } -type Usage struct { - // Breakdown of cached tokens by TTL - CacheCreation CacheCreation `json:"cache_creation,required"` - // The number of input tokens used to create the cache entry. - CacheCreationInputTokens int64 `json:"cache_creation_input_tokens,required"` - // The number of input tokens read from the cache. - CacheReadInputTokens int64 `json:"cache_read_input_tokens,required"` - // The number of input tokens which were used. - InputTokens int64 `json:"input_tokens,required"` - // The number of output tokens which were used. - OutputTokens int64 `json:"output_tokens,required"` - // The number of server tool requests. - ServerToolUse ServerToolUsage `json:"server_tool_use,required"` - // If the request used the priority, standard, or batch tier. - // - // Any of "standard", "priority", "batch". - ServiceTier UsageServiceTier `json:"service_tier,required"` +type WebFetchToolResultErrorBlock struct { + // Any of "invalid_tool_input", "url_too_long", "url_not_allowed", + // "url_not_accessible", "unsupported_content_type", "too_many_requests", + // "max_uses_exceeded", "unavailable". + ErrorCode WebFetchToolResultErrorCode `json:"error_code,required"` + Type constant.WebFetchToolResultError `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - CacheCreation respjson.Field - CacheCreationInputTokens respjson.Field - CacheReadInputTokens respjson.Field - InputTokens respjson.Field - OutputTokens respjson.Field - ServerToolUse respjson.Field - ServiceTier respjson.Field - ExtraFields map[string]respjson.Field - raw string + ErrorCode respjson.Field + Type respjson.Field + ExtraFields map[string]respjson.Field + raw string } `json:"-"` } // Returns the unmodified JSON received from the API -func (r Usage) RawJSON() string { return r.JSON.raw } +func (r WebFetchToolResultErrorBlock) RawJSON() string { return r.JSON.raw } +func (r *WebFetchToolResultErrorBlock) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} -func (r *Usage) UnmarshalJSON(data []byte) error { +// The properties ErrorCode, Type are required. +type WebFetchToolResultErrorBlockParam struct { + // Any of "invalid_tool_input", "url_too_long", "url_not_allowed", + // "url_not_accessible", "unsupported_content_type", "too_many_requests", + // "max_uses_exceeded", "unavailable". + ErrorCode WebFetchToolResultErrorCode `json:"error_code,omitzero,required"` + // This field can be elided, and will marshal its zero value as + // "web_fetch_tool_result_error". + Type constant.WebFetchToolResultError `json:"type,required"` + paramObj +} + +func (r WebFetchToolResultErrorBlockParam) MarshalJSON() (data []byte, err error) { + type shadow WebFetchToolResultErrorBlockParam + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *WebFetchToolResultErrorBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// If the request used the priority, standard, or batch tier. -type UsageServiceTier string +type WebFetchToolResultErrorCode string const ( - UsageServiceTierStandard UsageServiceTier = "standard" - UsageServiceTierPriority UsageServiceTier = "priority" - UsageServiceTierBatch UsageServiceTier = "batch" + WebFetchToolResultErrorCodeInvalidToolInput WebFetchToolResultErrorCode = "invalid_tool_input" + WebFetchToolResultErrorCodeURLTooLong WebFetchToolResultErrorCode = "url_too_long" + WebFetchToolResultErrorCodeURLNotAllowed WebFetchToolResultErrorCode = "url_not_allowed" + WebFetchToolResultErrorCodeURLNotAccessible WebFetchToolResultErrorCode = "url_not_accessible" + WebFetchToolResultErrorCodeUnsupportedContentType WebFetchToolResultErrorCode = "unsupported_content_type" + WebFetchToolResultErrorCodeTooManyRequests WebFetchToolResultErrorCode = "too_many_requests" + WebFetchToolResultErrorCodeMaxUsesExceeded WebFetchToolResultErrorCode = "max_uses_exceeded" + WebFetchToolResultErrorCodeUnavailable WebFetchToolResultErrorCode = "unavailable" ) type WebSearchResultBlock struct { @@ -4415,7 +8549,6 @@ type WebSearchResultBlock struct { // Returns the unmodified JSON received from the API func (r WebSearchResultBlock) RawJSON() string { return r.JSON.raw } - func (r *WebSearchResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4436,7 +8569,6 @@ func (r WebSearchResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow WebSearchResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *WebSearchResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4445,17 +8577,24 @@ func (r *WebSearchResultBlockParam) UnmarshalJSON(data []byte) error { type WebSearchTool20250305Param struct { // Maximum number of times the tool can be used in the API request. MaxUses param.Opt[int64] `json:"max_uses,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` // If provided, only these domains will be included in results. Cannot be used // alongside `blocked_domains`. AllowedDomains []string `json:"allowed_domains,omitzero"` // If provided, these domains will never appear in results. Cannot be used // alongside `allowed_domains`. BlockedDomains []string `json:"blocked_domains,omitzero"` - // Parameters for the user's location. Used to provide more relevant search - // results. - UserLocation WebSearchTool20250305UserLocationParam `json:"user_location,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` // Create a cache control breakpoint at this content block. CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Parameters for the user's location. Used to provide more relevant search + // results. + UserLocation UserLocationParam `json:"user_location,omitzero"` // Name of the tool. // // This is how the tool will be called by the model and in `tool_use` blocks. @@ -4472,45 +8611,57 @@ func (r WebSearchTool20250305Param) MarshalJSON() (data []byte, err error) { type shadow WebSearchTool20250305Param return param.MarshalObject(r, (*shadow)(&r)) } - func (r *WebSearchTool20250305Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// Parameters for the user's location. Used to provide more relevant search -// results. -// -// The property Type is required. -type WebSearchTool20250305UserLocationParam struct { - // The city of the user. - City param.Opt[string] `json:"city,omitzero"` - // The two letter - // [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the - // user. - Country param.Opt[string] `json:"country,omitzero"` - // The region of the user. - Region param.Opt[string] `json:"region,omitzero"` - // The [IANA timezone](https://nodatime.org/TimeZones) of the user. - Timezone param.Opt[string] `json:"timezone,omitzero"` - // This field can be elided, and will marshal its zero value as "approximate". - Type constant.Approximate `json:"type,required"` +// The properties Name, Type are required. +type WebSearchTool20260209Param struct { + // Maximum number of times the tool can be used in the API request. + MaxUses param.Opt[int64] `json:"max_uses,omitzero"` + // If true, tool will not be included in initial system prompt. Only loaded when + // returned via tool_reference from tool search. + DeferLoading param.Opt[bool] `json:"defer_loading,omitzero"` + // When true, guarantees schema validation on tool names and inputs + Strict param.Opt[bool] `json:"strict,omitzero"` + // If provided, only these domains will be included in results. Cannot be used + // alongside `blocked_domains`. + AllowedDomains []string `json:"allowed_domains,omitzero"` + // If provided, these domains will never appear in results. Cannot be used + // alongside `allowed_domains`. + BlockedDomains []string `json:"blocked_domains,omitzero"` + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + AllowedCallers []string `json:"allowed_callers,omitzero"` + // Create a cache control breakpoint at this content block. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Parameters for the user's location. Used to provide more relevant search + // results. + UserLocation UserLocationParam `json:"user_location,omitzero"` + // Name of the tool. + // + // This is how the tool will be called by the model and in `tool_use` blocks. + // + // This field can be elided, and will marshal its zero value as "web_search". + Name constant.WebSearch `json:"name,required"` + // This field can be elided, and will marshal its zero value as + // "web_search_20260209". + Type constant.WebSearch20260209 `json:"type,required"` paramObj } -func (r WebSearchTool20250305UserLocationParam) MarshalJSON() (data []byte, err error) { - type shadow WebSearchTool20250305UserLocationParam +func (r WebSearchTool20260209Param) MarshalJSON() (data []byte, err error) { + type shadow WebSearchTool20260209Param return param.MarshalObject(r, (*shadow)(&r)) } - -func (r *WebSearchTool20250305UserLocationParam) UnmarshalJSON(data []byte) error { +func (r *WebSearchTool20260209Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties ErrorCode, Type are required. type WebSearchToolRequestErrorParam struct { // Any of "invalid_tool_input", "unavailable", "max_uses_exceeded", - // "too_many_requests", "query_too_long". - ErrorCode WebSearchToolRequestErrorErrorCode `json:"error_code,omitzero,required"` + // "too_many_requests", "query_too_long", "request_too_large". + ErrorCode WebSearchToolResultErrorCode `json:"error_code,omitzero,required"` // This field can be elided, and will marshal its zero value as // "web_search_tool_result_error". Type constant.WebSearchToolResultError `json:"type,required"` @@ -4521,27 +8672,19 @@ func (r WebSearchToolRequestErrorParam) MarshalJSON() (data []byte, err error) { type shadow WebSearchToolRequestErrorParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *WebSearchToolRequestErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type WebSearchToolRequestErrorErrorCode string - -const ( - WebSearchToolRequestErrorErrorCodeInvalidToolInput WebSearchToolRequestErrorErrorCode = "invalid_tool_input" - WebSearchToolRequestErrorErrorCodeUnavailable WebSearchToolRequestErrorErrorCode = "unavailable" - WebSearchToolRequestErrorErrorCodeMaxUsesExceeded WebSearchToolRequestErrorErrorCode = "max_uses_exceeded" - WebSearchToolRequestErrorErrorCodeTooManyRequests WebSearchToolRequestErrorErrorCode = "too_many_requests" - WebSearchToolRequestErrorErrorCodeQueryTooLong WebSearchToolRequestErrorErrorCode = "query_too_long" -) - type WebSearchToolResultBlock struct { + // Tool invocation directly from the model. + Caller WebSearchToolResultBlockCallerUnion `json:"caller,required"` Content WebSearchToolResultBlockContentUnion `json:"content,required"` ToolUseID string `json:"tool_use_id,required"` Type constant.WebSearchToolResult `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { + Caller respjson.Field Content respjson.Field ToolUseID respjson.Field Type respjson.Field @@ -4552,11 +8695,82 @@ type WebSearchToolResultBlock struct { // Returns the unmodified JSON received from the API func (r WebSearchToolResultBlock) RawJSON() string { return r.JSON.raw } - func (r *WebSearchToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +// WebSearchToolResultBlockCallerUnion contains all possible properties and values +// from [DirectCaller], [ServerToolCaller], [ServerToolCaller20260120]. +// +// Use the [WebSearchToolResultBlockCallerUnion.AsAny] method to switch on the +// variant. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type WebSearchToolResultBlockCallerUnion struct { + // Any of "direct", "code_execution_20250825", "code_execution_20260120". + Type string `json:"type"` + ToolID string `json:"tool_id"` + JSON struct { + Type respjson.Field + ToolID respjson.Field + raw string + } `json:"-"` +} + +// anyWebSearchToolResultBlockCaller is implemented by each variant of +// [WebSearchToolResultBlockCallerUnion] to add type safety for the return type of +// [WebSearchToolResultBlockCallerUnion.AsAny] +type anyWebSearchToolResultBlockCaller interface { + implWebSearchToolResultBlockCallerUnion() +} + +func (DirectCaller) implWebSearchToolResultBlockCallerUnion() {} +func (ServerToolCaller) implWebSearchToolResultBlockCallerUnion() {} +func (ServerToolCaller20260120) implWebSearchToolResultBlockCallerUnion() {} + +// Use the following switch statement to find the correct variant +// +// switch variant := WebSearchToolResultBlockCallerUnion.AsAny().(type) { +// case anthropic.DirectCaller: +// case anthropic.ServerToolCaller: +// case anthropic.ServerToolCaller20260120: +// default: +// fmt.Errorf("no variant present") +// } +func (u WebSearchToolResultBlockCallerUnion) AsAny() anyWebSearchToolResultBlockCaller { + switch u.Type { + case "direct": + return u.AsDirect() + case "code_execution_20250825": + return u.AsCodeExecution20250825() + case "code_execution_20260120": + return u.AsCodeExecution20260120() + } + return nil +} + +func (u WebSearchToolResultBlockCallerUnion) AsDirect() (v DirectCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u WebSearchToolResultBlockCallerUnion) AsCodeExecution20250825() (v ServerToolCaller) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u WebSearchToolResultBlockCallerUnion) AsCodeExecution20260120() (v ServerToolCaller20260120) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u WebSearchToolResultBlockCallerUnion) RawJSON() string { return u.JSON.raw } + +func (r *WebSearchToolResultBlockCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + // WebSearchToolResultBlockContentUnion contains all possible properties and values // from [WebSearchToolResultError], [[]WebSearchResultBlock]. // @@ -4569,7 +8783,7 @@ type WebSearchToolResultBlockContentUnion struct { // an object. OfWebSearchResultBlockArray []WebSearchResultBlock `json:",inline"` // This field is from variant [WebSearchToolResultError]. - ErrorCode WebSearchToolResultErrorErrorCode `json:"error_code"` + ErrorCode WebSearchToolResultErrorCode `json:"error_code"` // This field is from variant [WebSearchToolResultError]. Type constant.WebSearchToolResultError `json:"type"` JSON struct { @@ -4582,12 +8796,12 @@ type WebSearchToolResultBlockContentUnion struct { func (u WebSearchToolResultBlockContentUnion) AsResponseWebSearchToolResultError() (v WebSearchToolResultError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } func (u WebSearchToolResultBlockContentUnion) AsWebSearchResultBlockArray() (v []WebSearchResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) - return v + return } // Returns the unmodified JSON received from the API @@ -4603,6 +8817,8 @@ type WebSearchToolResultBlockParam struct { ToolUseID string `json:"tool_use_id,required"` // Create a cache control breakpoint at this content block. CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Tool invocation directly from the model. + Caller WebSearchToolResultBlockParamCallerUnion `json:"caller,omitzero"` // This field can be elided, and will marshal its zero value as // "web_search_tool_result". Type constant.WebSearchToolResult `json:"type,required"` @@ -4613,12 +8829,70 @@ func (r WebSearchToolResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow WebSearchToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } - func (r *WebSearchToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -func NewWebSearchToolRequestError(errorCode WebSearchToolRequestErrorErrorCode) WebSearchToolResultBlockParamContentUnion { +// Only one field can be non-zero. +// +// Use [param.IsOmitted] to confirm if a field is set. +type WebSearchToolResultBlockParamCallerUnion struct { + OfDirect *DirectCallerParam `json:",omitzero,inline"` + OfCodeExecution20250825 *ServerToolCallerParam `json:",omitzero,inline"` + OfCodeExecution20260120 *ServerToolCaller20260120Param `json:",omitzero,inline"` + paramUnion +} + +func (u WebSearchToolResultBlockParamCallerUnion) MarshalJSON() ([]byte, error) { + return param.MarshalUnion(u, u.OfDirect, u.OfCodeExecution20250825, u.OfCodeExecution20260120) +} +func (u *WebSearchToolResultBlockParamCallerUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, u) +} + +func (u *WebSearchToolResultBlockParamCallerUnion) asAny() any { + if !param.IsOmitted(u.OfDirect) { + return u.OfDirect + } else if !param.IsOmitted(u.OfCodeExecution20250825) { + return u.OfCodeExecution20250825 + } else if !param.IsOmitted(u.OfCodeExecution20260120) { + return u.OfCodeExecution20260120 + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u WebSearchToolResultBlockParamCallerUnion) GetType() *string { + if vt := u.OfDirect; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.Type) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.Type) + } + return nil +} + +// Returns a pointer to the underlying variant's property, if present. +func (u WebSearchToolResultBlockParamCallerUnion) GetToolID() *string { + if vt := u.OfCodeExecution20250825; vt != nil { + return (*string)(&vt.ToolID) + } else if vt := u.OfCodeExecution20260120; vt != nil { + return (*string)(&vt.ToolID) + } + return nil +} + +func init() { + apijson.RegisterUnion[WebSearchToolResultBlockParamCallerUnion]( + "type", + apijson.Discriminator[DirectCallerParam]("direct"), + apijson.Discriminator[ServerToolCallerParam]("code_execution_20250825"), + apijson.Discriminator[ServerToolCaller20260120Param]("code_execution_20260120"), + ) +} + +func NewWebSearchToolRequestError(errorCode WebSearchToolResultErrorCode) WebSearchToolResultBlockParamContentUnion { var variant WebSearchToolRequestErrorParam variant.ErrorCode = errorCode return WebSearchToolResultBlockParamContentUnion{OfRequestWebSearchToolResultError: &variant} @@ -4636,7 +8910,6 @@ type WebSearchToolResultBlockParamContentUnion struct { func (u WebSearchToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfWebSearchToolResultBlockItem, u.OfRequestWebSearchToolResultError) } - func (u *WebSearchToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -4652,8 +8925,8 @@ func (u *WebSearchToolResultBlockParamContentUnion) asAny() any { type WebSearchToolResultError struct { // Any of "invalid_tool_input", "unavailable", "max_uses_exceeded", - // "too_many_requests", "query_too_long". - ErrorCode WebSearchToolResultErrorErrorCode `json:"error_code,required"` + // "too_many_requests", "query_too_long", "request_too_large". + ErrorCode WebSearchToolResultErrorCode `json:"error_code,required"` Type constant.WebSearchToolResultError `json:"type,required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { @@ -4666,19 +8939,19 @@ type WebSearchToolResultError struct { // Returns the unmodified JSON received from the API func (r WebSearchToolResultError) RawJSON() string { return r.JSON.raw } - func (r *WebSearchToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -type WebSearchToolResultErrorErrorCode string +type WebSearchToolResultErrorCode string const ( - WebSearchToolResultErrorErrorCodeInvalidToolInput WebSearchToolResultErrorErrorCode = "invalid_tool_input" - WebSearchToolResultErrorErrorCodeUnavailable WebSearchToolResultErrorErrorCode = "unavailable" - WebSearchToolResultErrorErrorCodeMaxUsesExceeded WebSearchToolResultErrorErrorCode = "max_uses_exceeded" - WebSearchToolResultErrorErrorCodeTooManyRequests WebSearchToolResultErrorErrorCode = "too_many_requests" - WebSearchToolResultErrorErrorCodeQueryTooLong WebSearchToolResultErrorErrorCode = "query_too_long" + WebSearchToolResultErrorCodeInvalidToolInput WebSearchToolResultErrorCode = "invalid_tool_input" + WebSearchToolResultErrorCodeUnavailable WebSearchToolResultErrorCode = "unavailable" + WebSearchToolResultErrorCodeMaxUsesExceeded WebSearchToolResultErrorCode = "max_uses_exceeded" + WebSearchToolResultErrorCodeTooManyRequests WebSearchToolResultErrorCode = "too_many_requests" + WebSearchToolResultErrorCodeQueryTooLong WebSearchToolResultErrorCode = "query_too_long" + WebSearchToolResultErrorCodeRequestTooLarge WebSearchToolResultErrorCode = "request_too_large" ) type MessageNewParams struct { @@ -4688,7 +8961,7 @@ type MessageNewParams struct { // only specifies the absolute maximum number of tokens to generate. // // Different models have different maximum values for this parameter. See - // [models](https://docs.anthropic.com/en/docs/models-overview) for details. + // [models](https://docs.claude.com/en/docs/models-overview) for details. MaxTokens int64 `json:"max_tokens,required"` // Input messages. // @@ -4751,12 +9024,12 @@ type MessageNewParams struct { // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // - // See [input examples](https://docs.anthropic.com/en/api/messages-examples). + // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a - // [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use - // the top-level `system` parameter — there is no `"system"` role for input - // messages in the Messages API. + // [system prompt](https://docs.claude.com/en/docs/system-prompts), you can use the + // top-level `system` parameter — there is no `"system"` role for input messages in + // the Messages API. // // There is a limit of 100,000 messages in a single request. Messages []MessageParam `json:"messages,omitzero,required"` @@ -4764,6 +9037,11 @@ type MessageNewParams struct { // [models](https://docs.anthropic.com/en/docs/models-overview) for additional // details and options. Model Model `json:"model,omitzero,required"` + // Container identifier for reuse across requests. + Container param.Opt[string] `json:"container,omitzero"` + // Specifies the geographic region for inference processing. If not specified, the + // workspace's `default_inference_geo` is used. + InferenceGeo param.Opt[string] `json:"inference_geo,omitzero"` // Amount of randomness injected into the response. // // Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` @@ -4791,13 +9069,18 @@ type MessageNewParams struct { // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopP param.Opt[float64] `json:"top_p,omitzero"` + // Top-level cache control automatically applies a cache_control marker to the last + // cacheable block in the request. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` // An object describing metadata about the request. Metadata MetadataParam `json:"metadata,omitzero"` + // Configuration options for the model's output, such as the output format. + OutputConfig OutputConfigParam `json:"output_config,omitzero"` // Determines whether to use priority capacity (if available) or standard capacity // for this request. // // Anthropic offers different levels of service for your API requests. See - // [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. + // [service-tiers](https://docs.claude.com/en/api/service-tiers) for details. // // Any of "auto", "standard_only". ServiceTier MessageNewParamsServiceTier `json:"service_tier,omitzero"` @@ -4815,7 +9098,7 @@ type MessageNewParams struct { // // A system prompt is a way of providing context and instructions to Claude, such // as specifying a particular goal or role. See our - // [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). + // [guide to system prompts](https://docs.claude.com/en/docs/system-prompts). System []TextBlockParam `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // @@ -4824,7 +9107,7 @@ type MessageNewParams struct { // tokens and counts towards your `max_tokens` limit. // // See - // [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + // [extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking) // for details. Thinking ThinkingConfigParamUnion `json:"thinking,omitzero"` // How the model should use the provided tools. The model can use a specific tool, @@ -4839,9 +9122,9 @@ type MessageNewParams struct { // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For - // [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), + // [server tools](https://docs.claude.com/en/docs/agents-and-tools/tool-use/overview#server-tools), // see their individual documentation as each has its own behavior (e.g., the - // [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). + // [web search tool](https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // @@ -4910,7 +9193,7 @@ type MessageNewParams struct { // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // - // See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. + // See our [guide](https://docs.claude.com/en/docs/tool-use) for more details. Tools []ToolUnionParam `json:"tools,omitzero"` paramObj } @@ -4919,7 +9202,6 @@ func (r MessageNewParams) MarshalJSON() (data []byte, err error) { type shadow MessageNewParams return param.MarshalObject(r, (*shadow)(&r)) } - func (r *MessageNewParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -4928,7 +9210,7 @@ func (r *MessageNewParams) UnmarshalJSON(data []byte) error { // for this request. // // Anthropic offers different levels of service for your API requests. See -// [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. +// [service-tiers](https://docs.claude.com/en/api/service-tiers) for details. type MessageNewParamsServiceTier string const ( @@ -4998,12 +9280,12 @@ type MessageCountTokensParams struct { // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // - // See [input examples](https://docs.anthropic.com/en/api/messages-examples). + // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a - // [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use - // the top-level `system` parameter — there is no `"system"` role for input - // messages in the Messages API. + // [system prompt](https://docs.claude.com/en/docs/system-prompts), you can use the + // top-level `system` parameter — there is no `"system"` role for input messages in + // the Messages API. // // There is a limit of 100,000 messages in a single request. Messages []MessageParam `json:"messages,omitzero,required"` @@ -5011,11 +9293,16 @@ type MessageCountTokensParams struct { // [models](https://docs.anthropic.com/en/docs/models-overview) for additional // details and options. Model Model `json:"model,omitzero,required"` + // Top-level cache control automatically applies a cache_control marker to the last + // cacheable block in the request. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` + // Configuration options for the model's output, such as the output format. + OutputConfig OutputConfigParam `json:"output_config,omitzero"` // System prompt. // // A system prompt is a way of providing context and instructions to Claude, such // as specifying a particular goal or role. See our - // [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). + // [guide to system prompts](https://docs.claude.com/en/docs/system-prompts). System MessageCountTokensParamsSystemUnion `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // @@ -5024,7 +9311,7 @@ type MessageCountTokensParams struct { // tokens and counts towards your `max_tokens` limit. // // See - // [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + // [extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking) // for details. Thinking ThinkingConfigParamUnion `json:"thinking,omitzero"` // How the model should use the provided tools. The model can use a specific tool, @@ -5039,9 +9326,9 @@ type MessageCountTokensParams struct { // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For - // [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), + // [server tools](https://docs.claude.com/en/docs/agents-and-tools/tool-use/overview#server-tools), // see their individual documentation as each has its own behavior (e.g., the - // [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). + // [web search tool](https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // @@ -5110,7 +9397,7 @@ type MessageCountTokensParams struct { // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // - // See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. + // See our [guide](https://docs.claude.com/en/docs/tool-use) for more details. Tools []MessageCountTokensToolUnionParam `json:"tools,omitzero"` paramObj } @@ -5119,7 +9406,6 @@ func (r MessageCountTokensParams) MarshalJSON() (data []byte, err error) { type shadow MessageCountTokensParams return param.MarshalObject(r, (*shadow)(&r)) } - func (r *MessageCountTokensParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } @@ -5136,7 +9422,6 @@ type MessageCountTokensParamsSystemUnion struct { func (u MessageCountTokensParamsSystemUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfString, u.OfTextBlockArray) } - func (u *MessageCountTokensParamsSystemUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } @@ -5149,30 +9434,3 @@ func (u *MessageCountTokensParamsSystemUnion) asAny() any { } return nil } - -// CalculateNonStreamingTimeout calculates the appropriate timeout for a non-streaming request -// based on the maximum number of tokens and the model's non-streaming token limit -func CalculateNonStreamingTimeout(maxTokens int, model Model, opts []option.RequestOption) (time.Duration, error) { - preCfg, err := requestconfig.PreRequestOptions(opts...) - if err != nil { - return 0, fmt.Errorf("error applying request options: %w", err) - } - // if the user has set a specific request timeout, use that - if preCfg.RequestTimeout != 0 { - return preCfg.RequestTimeout, nil - } - - maximumTime := time.Hour // 1 hour - defaultTime := 10 * time.Minute - - expectedTime := time.Duration(float64(maximumTime) * float64(maxTokens) / 128000.0) - - // If the model has a non-streaming token limit and max_tokens exceeds it, - // or if the expected time exceeds default time, require streaming - maxNonStreamingTokens, hasLimit := constant.ModelNonStreamingTokens[string(model)] - if expectedTime > defaultTime || (hasLimit && maxTokens > maxNonStreamingTokens) { - return 0, fmt.Errorf("streaming is required for operations that may take longer than 10 minutes") - } - - return defaultTime, nil -} diff --git a/message_test.go b/message_test.go index 976f7fd7f..52efb81ab 100644 --- a/message_test.go +++ b/message_test.go @@ -32,21 +32,58 @@ func TestMessageNewWithOptionalParams(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + CacheControl: anthropic.CacheControlEphemeralParam{ + TTL: anthropic.CacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.TextCitationParamUnion{{ + OfCharLocation: &anthropic.CitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeOpus4_6, + CacheControl: anthropic.CacheControlEphemeralParam{ + TTL: anthropic.CacheControlEphemeralTTLTTL5m, + }, + Container: anthropic.String("container"), + InferenceGeo: anthropic.String("inference_geo"), Metadata: anthropic.MetadataParam{ UserID: anthropic.String("13803d75-b4b5-4c3e-b2a2-6f21399b021b"), }, + OutputConfig: anthropic.OutputConfigParam{ + Effort: anthropic.OutputConfigEffortLow, + Format: anthropic.JSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, + }, ServiceTier: anthropic.MessageNewParamsServiceTierAuto, StopSequences: []string{"string"}, - System: []anthropic.TextBlockParam{{Text: "x", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}}, + System: []anthropic.TextBlockParam{{ + Text: "Today's date is 2024-06-01.", + CacheControl: anthropic.CacheControlEphemeralParam{ + TTL: anthropic.CacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.TextCitationParamUnion{{ + OfCharLocation: &anthropic.CitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }}, Temperature: anthropic.Float(1), Thinking: anthropic.ThinkingConfigParamUnion{ OfEnabled: &anthropic.ThinkingConfigEnabledParam{ @@ -61,24 +98,25 @@ func TestMessageNewWithOptionalParams(t *testing.T) { Tools: []anthropic.ToolUnionParam{{ OfTool: &anthropic.ToolParam{ InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "location": map[string]interface{}{ - "description": "The city and state, e.g. San Francisco, CA", - "type": "string", - }, - "unit": map[string]interface{}{ - "description": "Unit for the output - one of (celsius, fahrenheit)", - "type": "string", - }, + Properties: map[string]any{ + "location": "bar", + "unit": "bar", }, Required: []string{"location"}, }, - Name: "name", + Name: "name", + AllowedCallers: []string{"direct"}, CacheControl: anthropic.CacheControlEphemeralParam{ TTL: anthropic.CacheControlEphemeralTTLTTL5m, }, - Description: anthropic.String("Get the current weather in a given location"), - Type: anthropic.ToolTypeCustom, + DeferLoading: anthropic.Bool(true), + Description: anthropic.String("Get the current weather in a given location"), + EagerInputStreaming: anthropic.Bool(true), + InputExamples: []map[string]any{{ + "foo": "bar", + }}, + Strict: anthropic.Bool(true), + Type: anthropic.ToolTypeCustom, }, }}, TopK: anthropic.Int(5), @@ -108,13 +146,36 @@ func TestMessageCountTokensWithOptionalParams(t *testing.T) { _, err := client.Messages.CountTokens(context.TODO(), anthropic.MessageCountTokensParams{ Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + CacheControl: anthropic.CacheControlEphemeralParam{ + TTL: anthropic.CacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.TextCitationParamUnion{{ + OfCharLocation: &anthropic.CitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeOpus4_6, + CacheControl: anthropic.CacheControlEphemeralParam{ + TTL: anthropic.CacheControlEphemeralTTLTTL5m, + }, + OutputConfig: anthropic.OutputConfigParam{ + Effort: anthropic.OutputConfigEffortLow, + Format: anthropic.JSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, + }, System: anthropic.MessageCountTokensParamsSystemUnion{ OfTextBlockArray: []anthropic.TextBlockParam{{ Text: "Today's date is 2024-06-01.", @@ -145,24 +206,25 @@ func TestMessageCountTokensWithOptionalParams(t *testing.T) { Tools: []anthropic.MessageCountTokensToolUnionParam{{ OfTool: &anthropic.ToolParam{ InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "location": map[string]interface{}{ - "description": "The city and state, e.g. San Francisco, CA", - "type": "string", - }, - "unit": map[string]interface{}{ - "description": "Unit for the output - one of (celsius, fahrenheit)", - "type": "string", - }, + Properties: map[string]any{ + "location": "bar", + "unit": "bar", }, Required: []string{"location"}, }, - Name: "name", + Name: "name", + AllowedCallers: []string{"direct"}, CacheControl: anthropic.CacheControlEphemeralParam{ TTL: anthropic.CacheControlEphemeralTTLTTL5m, }, - Description: anthropic.String("Get the current weather in a given location"), - Type: anthropic.ToolTypeCustom, + DeferLoading: anthropic.Bool(true), + Description: anthropic.String("Get the current weather in a given location"), + EagerInputStreaming: anthropic.Bool(true), + InputExamples: []map[string]any{{ + "foo": "bar", + }}, + Strict: anthropic.Bool(true), + Type: anthropic.ToolTypeCustom, }, }}, }) diff --git a/messagebatch.go b/messagebatch.go index 78e66cd93..26ca9e1a8 100644 --- a/messagebatch.go +++ b/messagebatch.go @@ -50,7 +50,7 @@ func NewMessageBatchService(opts ...option.RequestOption) (r MessageBatchService // can take up to 24 hours to complete. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *MessageBatchService) New(ctx context.Context, body MessageBatchNewParams, opts ...option.RequestOption) (res *MessageBatch, err error) { opts = slices.Concat(r.Options, opts) path := "v1/messages/batches" @@ -63,7 +63,7 @@ func (r *MessageBatchService) New(ctx context.Context, body MessageBatchNewParam // `results_url` field in the response. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *MessageBatchService) Get(ctx context.Context, messageBatchID string, opts ...option.RequestOption) (res *MessageBatch, err error) { opts = slices.Concat(r.Options, opts) if messageBatchID == "" { @@ -79,7 +79,7 @@ func (r *MessageBatchService) Get(ctx context.Context, messageBatchID string, op // returned first. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *MessageBatchService) List(ctx context.Context, query MessageBatchListParams, opts ...option.RequestOption) (res *pagination.Page[MessageBatch], err error) { var raw *http.Response opts = slices.Concat(r.Options, opts) @@ -101,7 +101,7 @@ func (r *MessageBatchService) List(ctx context.Context, query MessageBatchListPa // returned first. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *MessageBatchService) ListAutoPaging(ctx context.Context, query MessageBatchListParams, opts ...option.RequestOption) *pagination.PageAutoPager[MessageBatch] { return pagination.NewPageAutoPager(r.List(ctx, query, opts...)) } @@ -112,7 +112,7 @@ func (r *MessageBatchService) ListAutoPaging(ctx context.Context, query MessageB // like to delete an in-progress batch, you must first cancel it. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *MessageBatchService) Delete(ctx context.Context, messageBatchID string, opts ...option.RequestOption) (res *DeletedMessageBatch, err error) { opts = slices.Concat(r.Options, opts) if messageBatchID == "" { @@ -135,7 +135,7 @@ func (r *MessageBatchService) Delete(ctx context.Context, messageBatchID string, // non-interruptible. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *MessageBatchService) Cancel(ctx context.Context, messageBatchID string, opts ...option.RequestOption) (res *MessageBatch, err error) { opts = slices.Concat(r.Options, opts) if messageBatchID == "" { @@ -154,7 +154,7 @@ func (r *MessageBatchService) Cancel(ctx context.Context, messageBatchID string, // requests. Use the `custom_id` field to match results to requests. // // Learn more about the Message Batches API in our -// [user guide](/en/docs/build-with-claude/batch-processing) +// [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *MessageBatchService) ResultsStreaming(ctx context.Context, messageBatchID string, opts ...option.RequestOption) (stream *jsonl.Stream[MessageBatchIndividualResponse]) { var ( raw *http.Response @@ -520,8 +520,8 @@ type MessageBatchNewParamsRequest struct { CustomID string `json:"custom_id,required"` // Messages API creation parameters for the individual request. // - // See the [Messages API reference](/en/api/messages) for full documentation on - // available parameters. + // See the [Messages API reference](https://docs.claude.com/en/api/messages) for + // full documentation on available parameters. Params MessageBatchNewParamsRequestParams `json:"params,omitzero,required"` paramObj } @@ -537,8 +537,8 @@ func (r *MessageBatchNewParamsRequest) UnmarshalJSON(data []byte) error { // Messages API creation parameters for the individual request. // -// See the [Messages API reference](/en/api/messages) for full documentation on -// available parameters. +// See the [Messages API reference](https://docs.claude.com/en/api/messages) for +// full documentation on available parameters. // // The properties MaxTokens, Messages, Model are required. type MessageBatchNewParamsRequestParams struct { @@ -548,7 +548,7 @@ type MessageBatchNewParamsRequestParams struct { // only specifies the absolute maximum number of tokens to generate. // // Different models have different maximum values for this parameter. See - // [models](https://docs.anthropic.com/en/docs/models-overview) for details. + // [models](https://docs.claude.com/en/docs/models-overview) for details. MaxTokens int64 `json:"max_tokens,required"` // Input messages. // @@ -611,12 +611,12 @@ type MessageBatchNewParamsRequestParams struct { // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // - // See [input examples](https://docs.anthropic.com/en/api/messages-examples). + // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a - // [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use - // the top-level `system` parameter — there is no `"system"` role for input - // messages in the Messages API. + // [system prompt](https://docs.claude.com/en/docs/system-prompts), you can use the + // top-level `system` parameter — there is no `"system"` role for input messages in + // the Messages API. // // There is a limit of 100,000 messages in a single request. Messages []MessageParam `json:"messages,omitzero,required"` @@ -624,10 +624,14 @@ type MessageBatchNewParamsRequestParams struct { // [models](https://docs.anthropic.com/en/docs/models-overview) for additional // details and options. Model Model `json:"model,omitzero,required"` + // Container identifier for reuse across requests. + Container param.Opt[string] `json:"container,omitzero"` + // Specifies the geographic region for inference processing. If not specified, the + // workspace's `default_inference_geo` is used. + InferenceGeo param.Opt[string] `json:"inference_geo,omitzero"` // Whether to incrementally stream the response using server-sent events. // - // See [streaming](https://docs.anthropic.com/en/api/messages-streaming) for - // details. + // See [streaming](https://docs.claude.com/en/api/messages-streaming) for details. Stream param.Opt[bool] `json:"stream,omitzero"` // Amount of randomness injected into the response. // @@ -656,13 +660,18 @@ type MessageBatchNewParamsRequestParams struct { // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopP param.Opt[float64] `json:"top_p,omitzero"` + // Top-level cache control automatically applies a cache_control marker to the last + // cacheable block in the request. + CacheControl CacheControlEphemeralParam `json:"cache_control,omitzero"` // An object describing metadata about the request. Metadata MetadataParam `json:"metadata,omitzero"` + // Configuration options for the model's output, such as the output format. + OutputConfig OutputConfigParam `json:"output_config,omitzero"` // Determines whether to use priority capacity (if available) or standard capacity // for this request. // // Anthropic offers different levels of service for your API requests. See - // [service-tiers](https://docs.anthropic.com/en/api/service-tiers) for details. + // [service-tiers](https://docs.claude.com/en/api/service-tiers) for details. // // Any of "auto", "standard_only". ServiceTier string `json:"service_tier,omitzero"` @@ -680,7 +689,7 @@ type MessageBatchNewParamsRequestParams struct { // // A system prompt is a way of providing context and instructions to Claude, such // as specifying a particular goal or role. See our - // [guide to system prompts](https://docs.anthropic.com/en/docs/system-prompts). + // [guide to system prompts](https://docs.claude.com/en/docs/system-prompts). System []TextBlockParam `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // @@ -689,7 +698,7 @@ type MessageBatchNewParamsRequestParams struct { // tokens and counts towards your `max_tokens` limit. // // See - // [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + // [extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking) // for details. Thinking ThinkingConfigParamUnion `json:"thinking,omitzero"` // How the model should use the provided tools. The model can use a specific tool, @@ -704,9 +713,9 @@ type MessageBatchNewParamsRequestParams struct { // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For - // [server tools](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#server-tools), + // [server tools](https://docs.claude.com/en/docs/agents-and-tools/tool-use/overview#server-tools), // see their individual documentation as each has its own behavior (e.g., the - // [web search tool](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/web-search-tool)). + // [web search tool](https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // @@ -775,7 +784,7 @@ type MessageBatchNewParamsRequestParams struct { // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // - // See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. + // See our [guide](https://docs.claude.com/en/docs/tool-use) for more details. Tools []ToolUnionParam `json:"tools,omitzero"` paramObj } diff --git a/messagebatch_test.go b/messagebatch_test.go index bc028f0d2..33f0f26c8 100644 --- a/messagebatch_test.go +++ b/messagebatch_test.go @@ -32,22 +32,59 @@ func TestMessageBatchNew(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + CacheControl: anthropic.CacheControlEphemeralParam{ + TTL: anthropic.CacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.TextCitationParamUnion{{ + OfCharLocation: &anthropic.CitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeOpus4_6, + CacheControl: anthropic.CacheControlEphemeralParam{ + TTL: anthropic.CacheControlEphemeralTTLTTL5m, + }, + Container: anthropic.String("container"), + InferenceGeo: anthropic.String("inference_geo"), Metadata: anthropic.MetadataParam{ UserID: anthropic.String("13803d75-b4b5-4c3e-b2a2-6f21399b021b"), }, + OutputConfig: anthropic.OutputConfigParam{ + Effort: anthropic.OutputConfigEffortLow, + Format: anthropic.JSONOutputFormatParam{ + Schema: map[string]any{ + "foo": "bar", + }, + }, + }, ServiceTier: "auto", StopSequences: []string{"string"}, Stream: anthropic.Bool(true), - System: []anthropic.TextBlockParam{{Text: "x", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}}, + System: []anthropic.TextBlockParam{{ + Text: "Today's date is 2024-06-01.", + CacheControl: anthropic.CacheControlEphemeralParam{ + TTL: anthropic.CacheControlEphemeralTTLTTL5m, + }, + Citations: []anthropic.TextCitationParamUnion{{ + OfCharLocation: &anthropic.CitationCharLocationParam{ + CitedText: "cited_text", + DocumentIndex: 0, + DocumentTitle: anthropic.String("x"), + EndCharIndex: 0, + StartCharIndex: 0, + }, + }}, + }}, Temperature: anthropic.Float(1), Thinking: anthropic.ThinkingConfigParamUnion{ OfEnabled: &anthropic.ThinkingConfigEnabledParam{ @@ -62,24 +99,25 @@ func TestMessageBatchNew(t *testing.T) { Tools: []anthropic.ToolUnionParam{{ OfTool: &anthropic.ToolParam{ InputSchema: anthropic.ToolInputSchemaParam{ - Properties: map[string]interface{}{ - "location": map[string]interface{}{ - "description": "The city and state, e.g. San Francisco, CA", - "type": "string", - }, - "unit": map[string]interface{}{ - "description": "Unit for the output - one of (celsius, fahrenheit)", - "type": "string", - }, + Properties: map[string]any{ + "location": "bar", + "unit": "bar", }, Required: []string{"location"}, }, - Name: "name", + Name: "name", + AllowedCallers: []string{"direct"}, CacheControl: anthropic.CacheControlEphemeralParam{ TTL: anthropic.CacheControlEphemeralTTLTTL5m, }, - Description: anthropic.String("Get the current weather in a given location"), - Type: anthropic.ToolTypeCustom, + DeferLoading: anthropic.Bool(true), + Description: anthropic.String("Get the current weather in a given location"), + EagerInputStreaming: anthropic.Bool(true), + InputExamples: []map[string]any{{ + "foo": "bar", + }}, + Strict: anthropic.Bool(true), + Type: anthropic.ToolTypeCustom, }, }}, TopK: anthropic.Int(5), diff --git a/messageutil.go b/messageutil.go new file mode 100644 index 000000000..ee0cd3f09 --- /dev/null +++ b/messageutil.go @@ -0,0 +1,413 @@ +package anthropic + +import ( + "encoding/json" + "fmt" + + "github.com/charmbracelet/anthropic-sdk-go/internal/paramutil" + "github.com/charmbracelet/anthropic-sdk-go/packages/param" +) + +// Accumulate builds up the Message incrementally from a MessageStreamEvent. The Message then can be used as +// any other Message, except with the caveat that the Message.JSON field which normally can be used to inspect +// the JSON sent over the network may not be populated fully. +// +// message := anthropic.Message{} +// for stream.Next() { +// event := stream.Current() +// message.Accumulate(event) +// } +func (acc *Message) Accumulate(event MessageStreamEventUnion) error { + if acc == nil { + return fmt.Errorf("accumulate: cannot accumulate into nil Message") + } + + switch event := event.AsAny().(type) { + case MessageStartEvent: + *acc = event.Message + case MessageDeltaEvent: + acc.StopReason = event.Delta.StopReason + acc.StopSequence = event.Delta.StopSequence + acc.Usage.OutputTokens = event.Usage.OutputTokens + case ContentBlockStartEvent: + acc.Content = append(acc.Content, ContentBlockUnion{}) + err := acc.Content[len(acc.Content)-1].UnmarshalJSON([]byte(event.ContentBlock.RawJSON())) + if err != nil { + return err + } + case ContentBlockDeltaEvent: + if len(acc.Content) == 0 { + return fmt.Errorf("received event of type %s but there was no content block", event.Type) + } + cb := &acc.Content[len(acc.Content)-1] + switch delta := event.Delta.AsAny().(type) { + case TextDelta: + cb.Text += delta.Text + case InputJSONDelta: + if len(delta.PartialJSON) != 0 { + if string(cb.Input) == "{}" { + cb.Input = []byte(delta.PartialJSON) + } else { + cb.Input = append(cb.Input, []byte(delta.PartialJSON)...) + } + } + case ThinkingDelta: + cb.Thinking += delta.Thinking + case SignatureDelta: + cb.Signature += delta.Signature + case CitationsDelta: + citation := TextCitationUnion{} + err := citation.UnmarshalJSON([]byte(delta.Citation.RawJSON())) + if err != nil { + return fmt.Errorf("could not unmarshal citation delta into citation type: %w", err) + } + cb.Citations = append(cb.Citations, citation) + } + case MessageStopEvent: + // Re-marshal the accumulated message to update JSON.raw so that AsAny() + // returns the accumulated data rather than the original stream data + accJSON, err := json.Marshal(acc) + if err != nil { + return fmt.Errorf("error converting accumulated message to JSON: %w", err) + } + acc.JSON.raw = string(accJSON) + case ContentBlockStopEvent: + // Re-marshal the content block to update JSON.raw so that AsAny() + // returns the accumulated data rather than the original stream data + if len(acc.Content) == 0 { + return fmt.Errorf("received event of type %s but there was no content block", event.Type) + } + contentBlock := &acc.Content[len(acc.Content)-1] + cbJSON, err := json.Marshal(contentBlock) + if err != nil { + return fmt.Errorf("error converting content block to JSON: %w", err) + } + contentBlock.JSON.raw = string(cbJSON) + } + + return nil +} + +// ToParam converters + +func (r Message) ToParam() MessageParam { + var p MessageParam + p.Role = MessageParamRole(r.Role) + p.Content = make([]ContentBlockParamUnion, len(r.Content)) + for i, c := range r.Content { + p.Content[i] = c.ToParam() + } + return p +} + +func (r ContentBlockUnion) ToParam() ContentBlockParamUnion { + return r.AsAny().toParamUnion() +} + +func (variant TextBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfText: &p} +} + +func (variant ToolUseBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfToolUse: &p} +} + +func (variant WebSearchToolResultBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfWebSearchToolResult: &p} +} + +func (variant ServerToolUseBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfServerToolUse: &p} +} + +func (variant ThinkingBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfThinking: &p} +} + +func (variant RedactedThinkingBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfRedactedThinking: &p} +} + +func (r RedactedThinkingBlock) ToParam() RedactedThinkingBlockParam { + var p RedactedThinkingBlockParam + p.Type = r.Type + p.Data = r.Data + return p +} + +func (r ToolUseBlock) ToParam() ToolUseBlockParam { + var toolUse ToolUseBlockParam + toolUse.Type = r.Type + toolUse.ID = r.ID + toolUse.Input = r.Input + toolUse.Name = r.Name + return toolUse +} + +func (citationVariant CitationCharLocation) toParamUnion() TextCitationParamUnion { + var citationParam CitationCharLocationParam + citationParam.Type = citationVariant.Type + citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) + citationParam.CitedText = citationVariant.CitedText + citationParam.DocumentIndex = citationVariant.DocumentIndex + citationParam.EndCharIndex = citationVariant.EndCharIndex + citationParam.StartCharIndex = citationVariant.StartCharIndex + return TextCitationParamUnion{OfCharLocation: &citationParam} +} + +func (citationVariant CitationPageLocation) toParamUnion() TextCitationParamUnion { + var citationParam CitationPageLocationParam + citationParam.Type = citationVariant.Type + citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) + citationParam.DocumentIndex = citationVariant.DocumentIndex + citationParam.EndPageNumber = citationVariant.EndPageNumber + citationParam.StartPageNumber = citationVariant.StartPageNumber + return TextCitationParamUnion{OfPageLocation: &citationParam} +} + +func (citationVariant CitationContentBlockLocation) toParamUnion() TextCitationParamUnion { + var citationParam CitationContentBlockLocationParam + citationParam.Type = citationVariant.Type + citationParam.DocumentTitle = paramutil.ToOpt(citationVariant.DocumentTitle, citationVariant.JSON.DocumentTitle) + citationParam.CitedText = citationVariant.CitedText + citationParam.DocumentIndex = citationVariant.DocumentIndex + citationParam.EndBlockIndex = citationVariant.EndBlockIndex + citationParam.StartBlockIndex = citationVariant.StartBlockIndex + return TextCitationParamUnion{OfContentBlockLocation: &citationParam} +} + +func (citationVariant CitationsSearchResultLocation) toParamUnion() TextCitationParamUnion { + var citationParam CitationSearchResultLocationParam + citationParam.Type = citationVariant.Type + citationParam.CitedText = citationVariant.CitedText + citationParam.Title = paramutil.ToOpt(citationVariant.Title, citationVariant.JSON.Title) + return TextCitationParamUnion{OfSearchResultLocation: &citationParam} +} + +func (citationVariant CitationsWebSearchResultLocation) toParamUnion() TextCitationParamUnion { + var citationParam CitationWebSearchResultLocationParam + citationParam.Type = citationVariant.Type + citationParam.CitedText = citationVariant.CitedText + citationParam.Title = paramutil.ToOpt(citationVariant.Title, citationVariant.JSON.Title) + return TextCitationParamUnion{OfWebSearchResultLocation: &citationParam} +} + +func (r TextBlock) ToParam() TextBlockParam { + var p TextBlockParam + p.Type = r.Type + p.Text = r.Text + + // Distinguish between a nil and zero length slice, since some compatible + // APIs may not require citations. + if r.Citations != nil { + p.Citations = make([]TextCitationParamUnion, 0, len(r.Citations)) + } + + for _, citation := range r.Citations { + p.Citations = append(p.Citations, citation.AsAny().toParamUnion()) + } + + return p +} + +func (r ThinkingBlock) ToParam() ThinkingBlockParam { + var p ThinkingBlockParam + p.Type = r.Type + p.Signature = r.Signature + p.Thinking = r.Thinking + return p +} + +func (r ServerToolUseBlock) ToParam() ServerToolUseBlockParam { + var p ServerToolUseBlockParam + p.Type = r.Type + p.ID = r.ID + p.Input = r.Input + p.Name = ServerToolUseBlockParamName(r.Name) + return p +} + +func (r WebSearchToolResultBlock) ToParam() WebSearchToolResultBlockParam { + var p WebSearchToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + p.Content = r.Content.ToParam() + return p +} + +func (r WebSearchResultBlock) ToParam() WebSearchResultBlockParam { + var p WebSearchResultBlockParam + p.Type = r.Type + p.EncryptedContent = r.EncryptedContent + p.Title = r.Title + p.URL = r.URL + p.PageAge = paramutil.ToOpt(r.PageAge, r.JSON.PageAge) + return p +} + +func (r WebSearchToolResultBlockContentUnion) ToParam() WebSearchToolResultBlockParamContentUnion { + var p WebSearchToolResultBlockParamContentUnion + + if len(r.OfWebSearchResultBlockArray) > 0 { + for _, block := range r.OfWebSearchResultBlockArray { + p.OfWebSearchToolResultBlockItem = append(p.OfWebSearchToolResultBlockItem, block.ToParam()) + } + return p + } + + p.OfRequestWebSearchToolResultError = &WebSearchToolRequestErrorParam{ + ErrorCode: WebSearchToolResultErrorCode(r.ErrorCode), + } + return p +} + +func (variant WebFetchToolResultBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfWebFetchToolResult: &p} +} + +func (variant CodeExecutionToolResultBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfCodeExecutionToolResult: &p} +} + +func (variant BashCodeExecutionToolResultBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfBashCodeExecutionToolResult: &p} +} + +func (variant TextEditorCodeExecutionToolResultBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfTextEditorCodeExecutionToolResult: &p} +} + +func (variant ToolSearchToolResultBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfToolSearchToolResult: &p} +} + +func (variant ContainerUploadBlock) toParamUnion() ContentBlockParamUnion { + p := variant.ToParam() + return ContentBlockParamUnion{OfContainerUpload: &p} +} + +func (r WebFetchToolResultBlock) ToParam() WebFetchToolResultBlockParam { + var p WebFetchToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + return p +} + +func (r ContainerUploadBlock) ToParam() ContainerUploadBlockParam { + var p ContainerUploadBlockParam + p.Type = r.Type + p.FileID = r.FileID + return p +} + +func (r BashCodeExecutionToolResultBlock) ToParam() BashCodeExecutionToolResultBlockParam { + var p BashCodeExecutionToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + + if r.Content.JSON.ErrorCode.Valid() { + p.Content.OfRequestBashCodeExecutionToolResultError = &BashCodeExecutionToolResultErrorParam{ + ErrorCode: BashCodeExecutionToolResultErrorCode(r.Content.ErrorCode), + } + } else { + requestBashContentResult := &BashCodeExecutionResultBlockParam{ + ReturnCode: r.Content.ReturnCode, + Stderr: r.Content.Stderr, + Stdout: r.Content.Stdout, + } + for _, block := range r.Content.Content { + requestBashContentResult.Content = append(requestBashContentResult.Content, block.ToParam()) + } + p.Content.OfRequestBashCodeExecutionResultBlock = requestBashContentResult + } + + return p +} + +func (r BashCodeExecutionOutputBlock) ToParam() BashCodeExecutionOutputBlockParam { + var p BashCodeExecutionOutputBlockParam + p.Type = r.Type + p.FileID = r.FileID + return p +} + +func (r CodeExecutionToolResultBlock) ToParam() CodeExecutionToolResultBlockParam { + var p CodeExecutionToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + if r.Content.JSON.ErrorCode.Valid() { + p.Content.OfRequestCodeExecutionToolResultError = &CodeExecutionToolResultErrorParam{ + ErrorCode: r.Content.ErrorCode, + } + } else { + p.Content.OfRequestCodeExecutionResultBlock = &CodeExecutionResultBlockParam{ + ReturnCode: r.Content.ReturnCode, + Stderr: r.Content.Stderr, + Stdout: r.Content.Stdout, + } + for _, block := range r.Content.Content { + p.Content.OfRequestCodeExecutionResultBlock.Content = append(p.Content.OfRequestCodeExecutionResultBlock.Content, block.ToParam()) + } + } + return p +} + +func (r CodeExecutionOutputBlock) ToParam() CodeExecutionOutputBlockParam { + var p CodeExecutionOutputBlockParam + p.Type = r.Type + p.FileID = r.FileID + return p +} + +func (r TextEditorCodeExecutionToolResultBlock) ToParam() TextEditorCodeExecutionToolResultBlockParam { + var p TextEditorCodeExecutionToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + if r.Content.JSON.ErrorCode.Valid() { + p.Content.OfRequestTextEditorCodeExecutionToolResultError = &TextEditorCodeExecutionToolResultErrorParam{ + ErrorCode: TextEditorCodeExecutionToolResultErrorCode(r.Content.ErrorCode), + ErrorMessage: paramutil.ToOpt(r.Content.ErrorMessage, r.Content.JSON.ErrorMessage), + } + } else { + p.Content = param.Override[TextEditorCodeExecutionToolResultBlockParamContentUnion](r.Content.RawJSON()) + } + return p +} + +func (r ToolSearchToolResultBlock) ToParam() ToolSearchToolResultBlockParam { + var p ToolSearchToolResultBlockParam + p.Type = r.Type + p.ToolUseID = r.ToolUseID + if r.Content.JSON.ErrorCode.Valid() { + p.Content.OfRequestToolSearchToolResultError = &ToolSearchToolResultErrorParam{ + ErrorCode: ToolSearchToolResultErrorCode(r.Content.ErrorCode), + } + } else { + p.Content.OfRequestToolSearchToolSearchResultBlock = &ToolSearchToolSearchResultBlockParam{} + for _, block := range r.Content.ToolReferences { + p.Content.OfRequestToolSearchToolSearchResultBlock.ToolReferences = append( + p.Content.OfRequestToolSearchToolSearchResultBlock.ToolReferences, + block.ToParam(), + ) + } + } + return p +} + +func (r ToolReferenceBlock) ToParam() ToolReferenceBlockParam { + var p ToolReferenceBlockParam + p.Type = r.Type + p.ToolName = r.ToolName + return p +} diff --git a/messageutil_test.go b/messageutil_test.go new file mode 100644 index 000000000..bd203a79c --- /dev/null +++ b/messageutil_test.go @@ -0,0 +1,56 @@ +package anthropic_test + +import ( + "encoding/json" + "testing" + + "github.com/charmbracelet/anthropic-sdk-go" + "github.com/charmbracelet/anthropic-sdk-go/shared/constant" +) + +func unmarshalContentBlockParam(t *testing.T, jsonData string) anthropic.ContentBlockParamUnion { + var block anthropic.ContentBlockUnion + err := json.Unmarshal([]byte(jsonData), &block) + if err != nil { + t.Fatalf("Failed to unmarshal JSON: %v", err) + } + result := block.ToParam() + return result +} + +func TestContentBlockUnionToParam(t *testing.T) { + t.Run("TextBlock with text only", func(t *testing.T) { + result := unmarshalContentBlockParam(t, `{"type":"text","text":"Hello, world!"}`) + if result.OfText == nil { + t.Fatal("Expected OfText to be non-nil") + } + if result.OfText.Text != "Hello, world!" { + t.Errorf("Expected text 'Hello, world!', got '%s'", result.OfText.Text) + } + if result.OfText.Type != constant.Text("text") { + t.Errorf("Expected type 'text', got '%s'", result.OfText.Type) + } + }) + + t.Run("WebSearchToolResultBlock with search results", func(t *testing.T) { + result := unmarshalContentBlockParam(t, `{"type":"web_search_tool_result","tool_use_id":"test123","content":[{"type":"web_search_result","title":"Test Web Title","url":"https://test.com","encrypted_content":"abc123","page_age":"1 day ago"}]}`) + var block anthropic.ContentBlockUnion + if err := json.Unmarshal([]byte(`{"type":"web_search_tool_result","tool_use_id":"test123","content":[{"type":"web_search_result","title":"Test Web Title","url":"https://test.com","encrypted_content":"abc123","page_age":"1 day ago"}]}`), &block); err != nil { + t.Fatalf("Failed to unmarshal: %v", err) + } + + if len(block.Content.OfWebSearchResultBlockArray) != 1 { + t.Errorf("Expected Content.OfWebSearchResultBlockArray to have 1 result, got %d", len(block.Content.OfWebSearchResultBlockArray)) + } + if len(block.Content.OfWebSearchResultBlockArray) > 0 && block.Content.OfWebSearchResultBlockArray[0].Title != "Test Web Title" { + t.Errorf("Expected title '', got '%s'", block.Content.OfWebSearchResultBlockArray[0].Title) + } + + if result.OfWebSearchToolResult == nil { + t.Fatal("Expected OfWebSearchToolResult to be non-nil") + } + if len(result.OfWebSearchToolResult.Content.OfWebSearchToolResultBlockItem) != 1 { + t.Errorf("Expected 1 search result in param, got %d", len(result.OfWebSearchToolResult.Content.OfWebSearchToolResultBlockItem)) + } + }) +} diff --git a/model.go b/model.go index 40a0d36c1..a09406a6d 100644 --- a/model.go +++ b/model.go @@ -46,7 +46,7 @@ func NewModelService(opts ...option.RequestOption) (r ModelService) { // 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) if modelID == "" { @@ -65,7 +65,7 @@ func (r *ModelService) Get(ctx context.Context, modelID string, query ModelGetPa 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("%s", v))) + opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...) diff --git a/packages/jsonl/jsonl.go b/packages/jsonl/jsonl.go index 95f8a2a68..676445304 100644 --- a/packages/jsonl/jsonl.go +++ b/packages/jsonl/jsonl.go @@ -5,6 +5,7 @@ package jsonl import ( "bufio" "encoding/json" + "fmt" "io" "net/http" ) @@ -17,8 +18,12 @@ type Stream[T any] struct { } func NewStream[T any](res *http.Response, err error) *Stream[T] { + if err != nil { + return &Stream[T]{err: err} + } + if res == nil || res.Body == nil { - return nil + return &Stream[T]{err: fmt.Errorf("No streaming response body")} } return &Stream[T]{ diff --git a/packages/pagination/pagination.go b/packages/pagination/pagination.go index 36c1ef1da..d9961bd96 100644 --- a/packages/pagination/pagination.go +++ b/packages/pagination/pagination.go @@ -137,3 +137,215 @@ func (r *PageAutoPager[T]) Err() error { func (r *PageAutoPager[T]) Index() int { return r.run } + +type TokenPage[T any] struct { + Data []T `json:"data"` + HasMore bool `json:"has_more"` + NextPage string `json:"next_page,nullable"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Data respjson.Field + HasMore respjson.Field + NextPage respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` + cfg *requestconfig.RequestConfig + res *http.Response +} + +// Returns the unmodified JSON received from the API +func (r TokenPage[T]) RawJSON() string { return r.JSON.raw } +func (r *TokenPage[T]) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// GetNextPage returns the next page as defined by this pagination style. When +// there is no next page, this function will return a 'nil' for the page value, but +// will not return an error +func (r *TokenPage[T]) GetNextPage() (res *TokenPage[T], err error) { + if len(r.Data) == 0 { + return nil, nil + } + + if r.JSON.HasMore.Valid() && r.HasMore == false { + return nil, nil + } + next := r.NextPage + if len(next) == 0 { + return nil, nil + } + cfg := r.cfg.Clone(r.cfg.Context) + err = cfg.Apply(option.WithQuery("page_token", next)) + if err != nil { + return nil, err + } + var raw *http.Response + cfg.ResponseInto = &raw + cfg.ResponseBodyInto = &res + err = cfg.Execute() + if err != nil { + return nil, err + } + res.SetPageConfig(cfg, raw) + return res, nil +} + +func (r *TokenPage[T]) SetPageConfig(cfg *requestconfig.RequestConfig, res *http.Response) { + if r == nil { + r = &TokenPage[T]{} + } + r.cfg = cfg + r.res = res +} + +type TokenPageAutoPager[T any] struct { + page *TokenPage[T] + cur T + idx int + run int + err error + paramObj +} + +func NewTokenPageAutoPager[T any](page *TokenPage[T], err error) *TokenPageAutoPager[T] { + return &TokenPageAutoPager[T]{ + page: page, + err: err, + } +} + +func (r *TokenPageAutoPager[T]) Next() bool { + if r.page == nil || len(r.page.Data) == 0 { + return false + } + if r.idx >= len(r.page.Data) { + r.idx = 0 + r.page, r.err = r.page.GetNextPage() + if r.err != nil || r.page == nil || len(r.page.Data) == 0 { + return false + } + } + r.cur = r.page.Data[r.idx] + r.run += 1 + r.idx += 1 + return true +} + +func (r *TokenPageAutoPager[T]) Current() T { + return r.cur +} + +func (r *TokenPageAutoPager[T]) Err() error { + return r.err +} + +func (r *TokenPageAutoPager[T]) Index() int { + return r.run +} + +type PageCursor[T any] struct { + Data []T `json:"data"` + HasMore bool `json:"has_more"` + NextPage string `json:"next_page,nullable"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Data respjson.Field + HasMore respjson.Field + NextPage respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` + cfg *requestconfig.RequestConfig + res *http.Response +} + +// Returns the unmodified JSON received from the API +func (r PageCursor[T]) RawJSON() string { return r.JSON.raw } +func (r *PageCursor[T]) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// GetNextPage returns the next page as defined by this pagination style. When +// there is no next page, this function will return a 'nil' for the page value, but +// will not return an error +func (r *PageCursor[T]) GetNextPage() (res *PageCursor[T], err error) { + if len(r.Data) == 0 { + return nil, nil + } + + if r.JSON.HasMore.Valid() && r.HasMore == false { + return nil, nil + } + next := r.NextPage + if len(next) == 0 { + return nil, nil + } + cfg := r.cfg.Clone(r.cfg.Context) + err = cfg.Apply(option.WithQuery("page", next)) + if err != nil { + return nil, err + } + var raw *http.Response + cfg.ResponseInto = &raw + cfg.ResponseBodyInto = &res + err = cfg.Execute() + if err != nil { + return nil, err + } + res.SetPageConfig(cfg, raw) + return res, nil +} + +func (r *PageCursor[T]) SetPageConfig(cfg *requestconfig.RequestConfig, res *http.Response) { + if r == nil { + r = &PageCursor[T]{} + } + r.cfg = cfg + r.res = res +} + +type PageCursorAutoPager[T any] struct { + page *PageCursor[T] + cur T + idx int + run int + err error + paramObj +} + +func NewPageCursorAutoPager[T any](page *PageCursor[T], err error) *PageCursorAutoPager[T] { + return &PageCursorAutoPager[T]{ + page: page, + err: err, + } +} + +func (r *PageCursorAutoPager[T]) Next() bool { + if r.page == nil || len(r.page.Data) == 0 { + return false + } + if r.idx >= len(r.page.Data) { + r.idx = 0 + r.page, r.err = r.page.GetNextPage() + if r.err != nil || r.page == nil || len(r.page.Data) == 0 { + return false + } + } + r.cur = r.page.Data[r.idx] + r.run += 1 + r.idx += 1 + return true +} + +func (r *PageCursorAutoPager[T]) Current() T { + return r.cur +} + +func (r *PageCursorAutoPager[T]) Err() error { + return r.err +} + +func (r *PageCursorAutoPager[T]) Index() int { + return r.run +} diff --git a/packages/param/encoder.go b/packages/param/encoder.go index bd884a4fd..c12732e67 100644 --- a/packages/param/encoder.go +++ b/packages/param/encoder.go @@ -83,6 +83,9 @@ func MarshalUnion[T ParamStruct](metadata T, variants ...any) ([]byte, error) { } } if nPresent == 0 || presentIdx == -1 { + if metadata.null() { + return []byte("null"), nil + } if ovr, ok := metadata.Overrides(); ok { return shimjson.Marshal(ovr) } diff --git a/packages/param/encoder_test.go b/packages/param/encoder_test.go index a6149a429..0f39bc848 100644 --- a/packages/param/encoder_test.go +++ b/packages/param/encoder_test.go @@ -363,3 +363,15 @@ func TestOverriddenUnion(t *testing.T) { }) } } + +func TestNullStructUnion(t *testing.T) { + nullUnion := param.NullStruct[PrimitiveUnion]() + + b, err := json.Marshal(nullUnion) + if err != nil { + t.Fatalf("didn't expect error %v", err) + } + if string(b) != "null" { + t.Fatalf("expected null, received %s", string(b)) + } +} diff --git a/packages/param/param.go b/packages/param/param.go index faccc1539..0d6196342 100644 --- a/packages/param/param.go +++ b/packages/param/param.go @@ -42,6 +42,19 @@ func Override[T ParamStruct, PtrT InferPtr[T]](v any) T { return *pt } +// SetJSON configures a param struct to serialize with the provided raw JSON data. +// Use this when you have existing JSON that you want to send as request parameters. +// +// var req example.NewUserParams +// var rawJSON = []byte(`{"name": "...", "age": 40}`) +// param.SetJSON(rawJSON, &req) +// res, err := client.Users.New(ctx, req) +// +// Note: The struct's existing fields will be ignored; only the provided JSON is serialized. +func SetJSON(rawJSON []byte, ptr anyParamStruct) { + ptr.setMetadata(json.RawMessage(rawJSON)) +} + // IsOmitted returns true if v is the zero value of its type. // // If IsOmitted is true, and the field uses a `json:"...,omitzero"` tag, @@ -92,6 +105,11 @@ type ParamStruct interface { extraFields() map[string]any } +// A pointer to ParamStruct +type anyParamStruct interface { + setMetadata(any) +} + // This is an implementation detail and should never be explicitly set. type InferPtr[T ParamStruct] interface { setMetadata(any) diff --git a/packages/respjson/respjson.go b/packages/respjson/respjson.go index cc0088ca3..9e61c5ca8 100644 --- a/packages/respjson/respjson.go +++ b/packages/respjson/respjson.go @@ -5,7 +5,7 @@ package respjson // Use [Field.Valid] to check if an optional value was null or omitted. // // A Field will always occur in the following structure, where it -// mirrors the original field in it's parent struct: +// mirrors the original field in its parent struct: // // type ExampleObject struct { // Foo bool `json:"foo"` diff --git a/paginationauto_test.go b/paginationauto_test.go index 5d96a228f..2d239ab93 100644 --- a/paginationauto_test.go +++ b/paginationauto_test.go @@ -27,7 +27,7 @@ func TestAutoPagination(t *testing.T) { iter := client.Beta.Messages.Batches.ListAutoPaging(context.TODO(), anthropic.BetaMessageBatchListParams{ Limit: anthropic.Int(20), }) - // Prism mock isn't going to give us real pagination + // The mock server isn't going to give us real pagination for i := 0; i < 3 && iter.Next(); i++ { batch := iter.Current() t.Logf("%+v\n", batch.ID) diff --git a/paginationmanual_test.go b/paginationmanual_test.go index 9e7d770a6..953808415 100644 --- a/paginationmanual_test.go +++ b/paginationmanual_test.go @@ -33,7 +33,7 @@ func TestManualPagination(t *testing.T) { for _, batch := range page.Data { t.Logf("%+v\n", batch.ID) } - // Prism mock isn't going to give us real pagination + // The mock server isn't going to give us real pagination page, err = page.GetNextPage() if err != nil { t.Fatalf("err should be nil: %s", err.Error()) diff --git a/schemautil.go b/schemautil.go new file mode 100644 index 000000000..0c27c1e32 --- /dev/null +++ b/schemautil.go @@ -0,0 +1,244 @@ +package anthropic + +import ( + "fmt" + "maps" + "slices" + "sort" + "strings" +) + +// BetaJSONSchemaOutputFormat creates a BetaJSONOutputFormatParam from a JSON schema map. +// It transforms the schema to ensure compatibility with Anthropic's JSON schema requirements. +// +// Example: +// +// schema := map[string]any{ +// "type": "object", +// "properties": map[string]any{ +// "name": map[string]any{"type": "string"}, +// "age": map[string]any{"type": "integer", "minimum": 0}, +// }, +// "required": []string{"name"}, +// } +// outputFormat := BetaJSONSchemaOutputFormat(schema) +// +// msg, _ := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{ +// Model: anthropic.Model("claude-sonnet-4-5"), +// Messages: anthropic.F([]anthropic.BetaMessageParam{...}), +// MaxTokens: 1024, +// OutputFormat: outputFormat, +// }) +func BetaJSONSchemaOutputFormat(jsonSchema map[string]any) BetaJSONOutputFormatParam { + return BetaJSONOutputFormatParam{Schema: transformSchema(jsonSchema)} +} + +// BetaToolInputSchema creates a BetaToolInputSchemaParam from a JSON schema map. +// It transforms the schema to ensure compatibility with Anthropic's tool calling requirements. +func BetaToolInputSchema(jsonSchema map[string]any) BetaToolInputSchemaParam { + return BetaToolInputSchemaParam{ExtraFields: transformSchema(jsonSchema)} +} + +var supportedStringFormats = []string{ + "date-time", + "time", + "date", + "duration", + "email", + "hostname", + "uri", + "ipv4", + "ipv6", + "uuid", +} +var supportedSchemaKeys = []string{ + // Top-level schema keys + "$ref", + "$defs", + "type", + "anyOf", + "oneOf", + "description", + "title", + + // Object-specific keys + "properties", + "additionalProperties", + "required", + + // Array-specific keys + "items", + "minItems", + + // String-specific keys + "format", +} + +// TransformSchema transforms a JSON schema to ensure it conforms to the Anthropic API's expectations. +// It returns nil if the transformed schema is empty. +// +// The transformation process: +// - Preserves $ref references +// - Transforms $defs recursively +// - Handles anyOf/oneOf by converting oneOf to anyOf +// - Ensures objects have additionalProperties: false +// - Filters string formats to only supported ones +// - Limits array minItems to 0 or 1 +// - Appends unsupported properties to the description +// +// Example: +// +// schema := map[string]any{ +// "type": "integer", +// "minimum": 1, +// "maximum": 10, +// "description": "A number", +// } +// transformed := TransformSchema(schema) +// // Result: {"type": "integer", "description": "A number\n\n{minimum: 1, maximum: 10}"} +func transformSchema(jsonSchema map[string]any) map[string]any { + if jsonSchema == nil { + return nil + } + + strictSchema := make(map[string]any) + + // Create a copy to avoid modifying the original + schemaCopy := make(map[string]any) + maps.Copy(schemaCopy, jsonSchema) + + // $ref is not supported alongside other properties + if ref, ok := schemaCopy["$ref"]; ok { + strictSchema["$ref"] = ref + return strictSchema + } + + for _, key := range supportedSchemaKeys { + value, exists := schemaCopy[key] + if exists { + delete(schemaCopy, key) + strictSchema[key] = value + } + } + + if defs, ok := strictSchema["$defs"]; ok { + if defsMap, ok := defs.(map[string]any); ok { + strictDefs := make(map[string]any) + strictSchema["$defs"] = strictDefs + + for name, schema := range defsMap { + if schemaMap, ok := schema.(map[string]any); ok { + strictDefs[name] = transformSchema(schemaMap) + } + } + } + } + + typeValue, _ := strictSchema["type"] + anyOf, _ := strictSchema["anyOf"] + oneOf, _ := strictSchema["oneOf"] + + if anyOfSlice, ok := anyOf.([]any); ok { + transformedVariants := make([]any, 0, len(anyOfSlice)) + for _, variant := range anyOfSlice { + variantMap, ok := variant.(map[string]any) + if !ok { + continue + } + if transformed := transformSchema(variantMap); transformed != nil { + transformedVariants = append(transformedVariants, transformed) + } + } + strictSchema["anyOf"] = transformedVariants + } else if oneOfSlice, ok := oneOf.([]any); ok { + transformedVariants := make([]any, 0, len(oneOfSlice)) + for _, variant := range oneOfSlice { + if variantMap, ok := variant.(map[string]any); ok { + if transformed := transformSchema(variantMap); transformed != nil { + transformedVariants = append(transformedVariants, transformed) + } + } + } + delete(strictSchema, "oneOf") + strictSchema["anyOf"] = transformedVariants + } else { + if typeValue == nil { + // schema is completely invalid, we have to bail + return nil + } + + strictSchema["type"] = typeValue + } + + typeStr, _ := typeValue.(string) + switch typeStr { + case "object": + if properties, ok := strictSchema["properties"]; ok { + if propsMap, ok := properties.(map[string]any); ok { + transformedProps := make(map[string]any) + for key, propSchema := range propsMap { + if propSchemaMap, ok := propSchema.(map[string]any); ok { + transformedProps[key] = transformSchema(propSchemaMap) + } + } + strictSchema["properties"] = transformedProps + } + } else { + strictSchema["properties"] = make(map[string]any) + } + + strictSchema["additionalProperties"] = false + + case "string": + if format, ok := strictSchema["format"]; ok { + if formatStr, ok := format.(string); ok { + if !slices.Contains(supportedStringFormats, formatStr) { + schemaCopy["format"] = format + delete(strictSchema, "format") + } + } + } + + case "array": + if items, ok := strictSchema["items"]; ok { + if itemsMap, ok := items.(map[string]any); ok { + strictSchema["items"] = transformSchema(itemsMap) + } + } + + if minItems, ok := strictSchema["minItems"]; ok { + if minItems != 0 && minItems != 1 { + schemaCopy["minItems"] = minItems + delete(strictSchema, "minItems") + } + } + + case "boolean", "integer", "number", "null": + // These types are supported as-is + } + + if len(schemaCopy) > 0 { + description := strictSchema["description"] + descStr, _ := description.(string) + + // Sort keys for deterministic output + keys := make([]string, 0, len(schemaCopy)) + for key := range schemaCopy { + keys = append(keys, key) + } + sort.Strings(keys) + + extraProps := make([]string, 0, len(keys)) + for _, key := range keys { + extraProps = append(extraProps, fmt.Sprintf("%s: %v", key, schemaCopy[key])) + } + + if descStr != "" { + strictSchema["description"] = descStr + "\n\n{" + strings.Join(extraProps, ", ") + "}" + } else { + strictSchema["description"] = "{" + strings.Join(extraProps, ", ") + "}" + } + } + + return strictSchema +} diff --git a/schemautil_test.go b/schemautil_test.go new file mode 100644 index 000000000..1b0143496 --- /dev/null +++ b/schemautil_test.go @@ -0,0 +1,234 @@ +package anthropic + +import ( + "encoding/json" + "reflect" + "testing" +) + +func TestTransformSchema(t *testing.T) { + tests := []struct { + name string + input map[string]any + expected map[string]any + }{ + { + name: "basic integer with unsupported properties", + input: map[string]any{ + "type": "integer", + "minimum": 1, + "maximum": 10, + "description": "A number", + }, + expected: map[string]any{ + "type": "integer", + "description": "A number\n\n{maximum: 10, minimum: 1}", + }, + }, + { + name: "object with properties", + input: map[string]any{ + "type": "object", + "properties": map[string]any{ + "name": map[string]any{ + "type": "string", + }, + "age": map[string]any{ + "type": "integer", + }, + }, + "required": []string{"name"}, + "additionalProperties": true, + }, + expected: map[string]any{ + "type": "object", + "properties": map[string]any{ + "name": map[string]any{ + "type": "string", + }, + "age": map[string]any{ + "type": "integer", + }, + }, + "required": []string{"name"}, + "additionalProperties": false, + }, + }, + { + name: "string with supported format", + input: map[string]any{ + "type": "string", + "format": "date-time", + }, + expected: map[string]any{ + "type": "string", + "format": "date-time", + }, + }, + { + name: "string with unsupported format", + input: map[string]any{ + "type": "string", + "format": "binary", + }, + expected: map[string]any{ + "type": "string", + "description": "{format: binary}", + }, + }, + { + name: "array with minItems 1", + input: map[string]any{ + "type": "array", + "items": map[string]any{ + "type": "string", + }, + "minItems": 1, + }, + expected: map[string]any{ + "type": "array", + "items": map[string]any{ + "type": "string", + }, + "minItems": 1, + }, + }, + { + name: "array with minItems 5", + input: map[string]any{ + "type": "array", + "items": map[string]any{ + "type": "string", + }, + "minItems": 5, + }, + expected: map[string]any{ + "type": "array", + "items": map[string]any{ + "type": "string", + }, + "description": "{minItems: 5}", + }, + }, + { + name: "schema with $ref", + input: map[string]any{ + "$ref": "#/definitions/Person", + "type": "object", + }, + expected: map[string]any{ + "$ref": "#/definitions/Person", + }, + }, + { + name: "schema with anyOf", + input: map[string]any{ + "anyOf": []any{ + map[string]any{ + "type": "string", + }, + map[string]any{ + "type": "number", + }, + }, + }, + expected: map[string]any{ + "anyOf": []any{ + map[string]any{ + "type": "string", + }, + map[string]any{ + "type": "number", + }, + }, + }, + }, + { + name: "schema with oneOf converted to anyOf", + input: map[string]any{ + "oneOf": []any{ + map[string]any{ + "type": "string", + }, + map[string]any{ + "type": "number", + }, + }, + }, + expected: map[string]any{ + "anyOf": []any{ + map[string]any{ + "type": "string", + }, + map[string]any{ + "type": "number", + }, + }, + }, + }, + { + name: "schema with $defs", + input: map[string]any{ + "type": "object", + "$defs": map[string]any{ + "Person": map[string]any{ + "type": "object", + "properties": map[string]any{ + "name": map[string]any{ + "type": "string", + }, + }, + }, + }, + "properties": map[string]any{ + "user": map[string]any{ + "$ref": "#/$defs/Person", + }, + }, + }, + expected: map[string]any{ + "type": "object", + "$defs": map[string]any{ + "Person": map[string]any{ + "type": "object", + "properties": map[string]any{ + "name": map[string]any{ + "type": "string", + }, + }, + "additionalProperties": false, + }, + }, + "properties": map[string]any{ + "user": map[string]any{ + "$ref": "#/$defs/Person", + }, + }, + "additionalProperties": false, + }, + }, + { + name: "nil schema returns nil", + input: nil, + expected: nil, + }, + { + name: "schema without type returns nil", + input: map[string]any{ + "description": "A schema without type", + }, + expected: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := transformSchema(tt.input) + if !reflect.DeepEqual(result, tt.expected) { + resultJSON, _ := json.MarshalIndent(result, "", " ") + expectedJSON, _ := json.MarshalIndent(tt.expected, "", " ") + t.Errorf("TransformSchema() mismatch:\ngot:\n%s\nwant:\n%s", resultJSON, expectedJSON) + } + }) + } +} diff --git a/scripts/detect-breaking-changes b/scripts/detect-breaking-changes index b38a2ed79..e0b2c7179 100755 --- a/scripts/detect-breaking-changes +++ b/scripts/detect-breaking-changes @@ -16,6 +16,8 @@ TEST_PATHS=( betamessage_test.go betamessagebatch_test.go betafile_test.go + betaskill_test.go + betaskillversion_test.go usage_test.go paginationauto_test.go paginationmanual_test.go diff --git a/shared/constant/constants.go b/shared/constant/constants.go index 497bd7b38..1808aac89 100644 --- a/shared/constant/constants.go +++ b/shared/constant/constants.go @@ -31,121 +31,142 @@ func ValueOf[T Constant[T]]() T { return t.Default() } -type ( - Any string // Always "any" - APIError string // Always "api_error" - ApplicationPDF string // Always "application/pdf" - Approximate string // Always "approximate" - Assistant string // Always "assistant" - AuthenticationError string // Always "authentication_error" - Auto string // Always "auto" - Base64 string // Always "base64" - Bash string // Always "bash" - Bash20241022 string // Always "bash_20241022" - Bash20250124 string // Always "bash_20250124" - BashCodeExecutionOutput string // Always "bash_code_execution_output" - BashCodeExecutionResult string // Always "bash_code_execution_result" - BashCodeExecutionToolResult string // Always "bash_code_execution_tool_result" - BashCodeExecutionToolResultError string // Always "bash_code_execution_tool_result_error" - BillingError string // Always "billing_error" - Canceled string // Always "canceled" - CharLocation string // Always "char_location" - CitationsDelta string // Always "citations_delta" - ClearToolUses20250919 string // Always "clear_tool_uses_20250919" - CodeExecution string // Always "code_execution" - CodeExecution20250522 string // Always "code_execution_20250522" - CodeExecution20250825 string // Always "code_execution_20250825" - CodeExecutionOutput string // Always "code_execution_output" - CodeExecutionResult string // Always "code_execution_result" - CodeExecutionToolResult string // Always "code_execution_tool_result" - CodeExecutionToolResultError string // Always "code_execution_tool_result_error" - Completion string // Always "completion" - Computer string // Always "computer" - Computer20241022 string // Always "computer_20241022" - Computer20250124 string // Always "computer_20250124" - ContainerUpload string // Always "container_upload" - Content string // Always "content" - ContentBlockDelta string // Always "content_block_delta" - ContentBlockLocation string // Always "content_block_location" - ContentBlockStart string // Always "content_block_start" - ContentBlockStop string // Always "content_block_stop" - Create string // Always "create" - Delete string // Always "delete" - Disabled string // Always "disabled" - Document string // Always "document" - Enabled string // Always "enabled" - Ephemeral string // Always "ephemeral" - Error string // Always "error" - Errored string // Always "errored" - Expired string // Always "expired" - File string // Always "file" - Image string // Always "image" - InputJSONDelta string // Always "input_json_delta" - InputTokens string // Always "input_tokens" - Insert string // Always "insert" - InvalidRequestError string // Always "invalid_request_error" - MCPToolResult string // Always "mcp_tool_result" - MCPToolUse string // Always "mcp_tool_use" - Memory string // Always "memory" - Memory20250818 string // Always "memory_20250818" - Message string // Always "message" - MessageBatch string // Always "message_batch" - MessageBatchDeleted string // Always "message_batch_deleted" - MessageDelta string // Always "message_delta" - MessageStart string // Always "message_start" - MessageStop string // Always "message_stop" - Model string // Always "model" - None string // Always "none" - NotFoundError string // Always "not_found_error" - Object string // Always "object" - OverloadedError string // Always "overloaded_error" - PageLocation string // Always "page_location" - PermissionError string // Always "permission_error" - RateLimitError string // Always "rate_limit_error" - RedactedThinking string // Always "redacted_thinking" - Rename string // Always "rename" - SearchResult string // Always "search_result" - SearchResultLocation string // Always "search_result_location" - ServerToolUse string // Always "server_tool_use" - SignatureDelta string // Always "signature_delta" - StrReplace string // Always "str_replace" - StrReplaceBasedEditTool string // Always "str_replace_based_edit_tool" - StrReplaceEditor string // Always "str_replace_editor" - Succeeded string // Always "succeeded" - Text string // Always "text" - TextDelta string // Always "text_delta" - TextEditor20241022 string // Always "text_editor_20241022" - TextEditor20250124 string // Always "text_editor_20250124" - TextEditor20250429 string // Always "text_editor_20250429" - TextEditor20250728 string // Always "text_editor_20250728" - TextEditorCodeExecutionCreateResult string // Always "text_editor_code_execution_create_result" - TextEditorCodeExecutionStrReplaceResult string // Always "text_editor_code_execution_str_replace_result" - TextEditorCodeExecutionToolResult string // Always "text_editor_code_execution_tool_result" - TextEditorCodeExecutionToolResultError string // Always "text_editor_code_execution_tool_result_error" - TextEditorCodeExecutionViewResult string // Always "text_editor_code_execution_view_result" - TextPlain string // Always "text/plain" - Thinking string // Always "thinking" - ThinkingDelta string // Always "thinking_delta" - TimeoutError string // Always "timeout_error" - Tool string // Always "tool" - ToolResult string // Always "tool_result" - ToolUse string // Always "tool_use" - ToolUses string // Always "tool_uses" - URL string // Always "url" - View string // Always "view" - WebFetch string // Always "web_fetch" - WebFetch20250910 string // Always "web_fetch_20250910" - WebFetchResult string // Always "web_fetch_result" - WebFetchToolResult string // Always "web_fetch_tool_result" - WebFetchToolResultError string // Always "web_fetch_tool_result_error" - WebSearch string // Always "web_search" - WebSearch20250305 string // Always "web_search_20250305" - WebSearchResult string // Always "web_search_result" - WebSearchResultLocation string // Always "web_search_result_location" - WebSearchToolResult string // Always "web_search_tool_result" - WebSearchToolResultError string // Always "web_search_tool_result_error" -) +type Adaptive string // Always "adaptive" +type All string // Always "all" +type Any string // Always "any" +type APIError string // Always "api_error" +type ApplicationPDF string // Always "application/pdf" +type Approximate string // Always "approximate" +type Assistant string // Always "assistant" +type AuthenticationError string // Always "authentication_error" +type Auto string // Always "auto" +type Base64 string // Always "base64" +type Bash string // Always "bash" +type Bash20241022 string // Always "bash_20241022" +type Bash20250124 string // Always "bash_20250124" +type BashCodeExecutionOutput string // Always "bash_code_execution_output" +type BashCodeExecutionResult string // Always "bash_code_execution_result" +type BashCodeExecutionToolResult string // Always "bash_code_execution_tool_result" +type BashCodeExecutionToolResultError string // Always "bash_code_execution_tool_result_error" +type BillingError string // Always "billing_error" +type Canceled string // Always "canceled" +type CharLocation string // Always "char_location" +type CitationsDelta string // Always "citations_delta" +type ClearThinking20251015 string // Always "clear_thinking_20251015" +type ClearToolUses20250919 string // Always "clear_tool_uses_20250919" +type CodeExecution string // Always "code_execution" +type CodeExecution20250522 string // Always "code_execution_20250522" +type CodeExecution20250825 string // Always "code_execution_20250825" +type CodeExecution20260120 string // Always "code_execution_20260120" +type CodeExecutionOutput string // Always "code_execution_output" +type CodeExecutionResult string // Always "code_execution_result" +type CodeExecutionToolResult string // Always "code_execution_tool_result" +type CodeExecutionToolResultError string // Always "code_execution_tool_result_error" +type Compact20260112 string // Always "compact_20260112" +type Compaction string // Always "compaction" +type CompactionDelta string // Always "compaction_delta" +type Completion string // Always "completion" +type Computer string // Always "computer" +type Computer20241022 string // Always "computer_20241022" +type Computer20250124 string // Always "computer_20250124" +type Computer20251124 string // Always "computer_20251124" +type ContainerUpload string // Always "container_upload" +type Content string // Always "content" +type ContentBlockDelta string // Always "content_block_delta" +type ContentBlockLocation string // Always "content_block_location" +type ContentBlockStart string // Always "content_block_start" +type ContentBlockStop string // Always "content_block_stop" +type Create string // Always "create" +type Delete string // Always "delete" +type Direct string // Always "direct" +type Disabled string // Always "disabled" +type Document string // Always "document" +type Enabled string // Always "enabled" +type EncryptedCodeExecutionResult string // Always "encrypted_code_execution_result" +type Ephemeral string // Always "ephemeral" +type Error string // Always "error" +type Errored string // Always "errored" +type Expired string // Always "expired" +type File string // Always "file" +type Image string // Always "image" +type InputJSONDelta string // Always "input_json_delta" +type InputTokens string // Always "input_tokens" +type Insert string // Always "insert" +type InvalidRequestError string // Always "invalid_request_error" +type JSONSchema string // Always "json_schema" +type MCPToolResult string // Always "mcp_tool_result" +type MCPToolUse string // Always "mcp_tool_use" +type MCPToolset string // Always "mcp_toolset" +type Memory string // Always "memory" +type Memory20250818 string // Always "memory_20250818" +type Message string // Always "message" +type MessageBatch string // Always "message_batch" +type MessageBatchDeleted string // Always "message_batch_deleted" +type MessageDelta string // Always "message_delta" +type MessageStart string // Always "message_start" +type MessageStop string // Always "message_stop" +type Model string // Always "model" +type None string // Always "none" +type NotFoundError string // Always "not_found_error" +type Object string // Always "object" +type OverloadedError string // Always "overloaded_error" +type PageLocation string // Always "page_location" +type PermissionError string // Always "permission_error" +type RateLimitError string // Always "rate_limit_error" +type RedactedThinking string // Always "redacted_thinking" +type Rename string // Always "rename" +type SearchResult string // Always "search_result" +type SearchResultLocation string // Always "search_result_location" +type ServerToolUse string // Always "server_tool_use" +type SignatureDelta string // Always "signature_delta" +type StrReplace string // Always "str_replace" +type StrReplaceBasedEditTool string // Always "str_replace_based_edit_tool" +type StrReplaceEditor string // Always "str_replace_editor" +type Succeeded string // Always "succeeded" +type Text string // Always "text" +type TextDelta string // Always "text_delta" +type TextEditor20241022 string // Always "text_editor_20241022" +type TextEditor20250124 string // Always "text_editor_20250124" +type TextEditor20250429 string // Always "text_editor_20250429" +type TextEditor20250728 string // Always "text_editor_20250728" +type TextEditorCodeExecutionCreateResult string // Always "text_editor_code_execution_create_result" +type TextEditorCodeExecutionStrReplaceResult string // Always "text_editor_code_execution_str_replace_result" +type TextEditorCodeExecutionToolResult string // Always "text_editor_code_execution_tool_result" +type TextEditorCodeExecutionToolResultError string // Always "text_editor_code_execution_tool_result_error" +type TextEditorCodeExecutionViewResult string // Always "text_editor_code_execution_view_result" +type TextPlain string // Always "text/plain" +type Thinking string // Always "thinking" +type ThinkingDelta string // Always "thinking_delta" +type ThinkingTurns string // Always "thinking_turns" +type TimeoutError string // Always "timeout_error" +type Tool string // Always "tool" +type ToolReference string // Always "tool_reference" +type ToolResult string // Always "tool_result" +type ToolSearchToolBm25 string // Always "tool_search_tool_bm25" +type ToolSearchToolRegex string // Always "tool_search_tool_regex" +type ToolSearchToolResult string // Always "tool_search_tool_result" +type ToolSearchToolResultError string // Always "tool_search_tool_result_error" +type ToolSearchToolSearchResult string // Always "tool_search_tool_search_result" +type ToolUse string // Always "tool_use" +type ToolUses string // Always "tool_uses" +type URL string // Always "url" +type View string // Always "view" +type WebFetch string // Always "web_fetch" +type WebFetch20250910 string // Always "web_fetch_20250910" +type WebFetch20260209 string // Always "web_fetch_20260209" +type WebFetchResult string // Always "web_fetch_result" +type WebFetchToolResult string // Always "web_fetch_tool_result" +type WebFetchToolResultError string // Always "web_fetch_tool_result_error" +type WebSearch string // Always "web_search" +type WebSearch20250305 string // Always "web_search_20250305" +type WebSearch20260209 string // Always "web_search_20260209" +type WebSearchResult string // Always "web_search_result" +type WebSearchResultLocation string // Always "web_search_result_location" +type WebSearchToolResult string // Always "web_search_tool_result" +type WebSearchToolResultError string // Always "web_search_tool_result_error" +func (c Adaptive) Default() Adaptive { return "adaptive" } +func (c All) Default() All { return "all" } func (c Any) Default() Any { return "any" } func (c APIError) Default() APIError { return "api_error" } func (c ApplicationPDF) Default() ApplicationPDF { return "application/pdf" } @@ -160,15 +181,12 @@ func (c Bash20250124) Default() Bash20250124 { return "bash_202501 func (c BashCodeExecutionOutput) Default() BashCodeExecutionOutput { return "bash_code_execution_output" } - func (c BashCodeExecutionResult) Default() BashCodeExecutionResult { return "bash_code_execution_result" } - func (c BashCodeExecutionToolResult) Default() BashCodeExecutionToolResult { return "bash_code_execution_tool_result" } - func (c BashCodeExecutionToolResultError) Default() BashCodeExecutionToolResultError { return "bash_code_execution_tool_result_error" } @@ -176,23 +194,28 @@ func (c BillingError) Default() BillingError { return "billing func (c Canceled) Default() Canceled { return "canceled" } func (c CharLocation) Default() CharLocation { return "char_location" } func (c CitationsDelta) Default() CitationsDelta { return "citations_delta" } +func (c ClearThinking20251015) Default() ClearThinking20251015 { return "clear_thinking_20251015" } func (c ClearToolUses20250919) Default() ClearToolUses20250919 { return "clear_tool_uses_20250919" } func (c CodeExecution) Default() CodeExecution { return "code_execution" } func (c CodeExecution20250522) Default() CodeExecution20250522 { return "code_execution_20250522" } func (c CodeExecution20250825) Default() CodeExecution20250825 { return "code_execution_20250825" } +func (c CodeExecution20260120) Default() CodeExecution20260120 { return "code_execution_20260120" } func (c CodeExecutionOutput) Default() CodeExecutionOutput { return "code_execution_output" } func (c CodeExecutionResult) Default() CodeExecutionResult { return "code_execution_result" } func (c CodeExecutionToolResult) Default() CodeExecutionToolResult { return "code_execution_tool_result" } - func (c CodeExecutionToolResultError) Default() CodeExecutionToolResultError { return "code_execution_tool_result_error" } +func (c Compact20260112) Default() Compact20260112 { return "compact_20260112" } +func (c Compaction) Default() Compaction { return "compaction" } +func (c CompactionDelta) Default() CompactionDelta { return "compaction_delta" } func (c Completion) Default() Completion { return "completion" } func (c Computer) Default() Computer { return "computer" } func (c Computer20241022) Default() Computer20241022 { return "computer_20241022" } func (c Computer20250124) Default() Computer20250124 { return "computer_20250124" } +func (c Computer20251124) Default() Computer20251124 { return "computer_20251124" } func (c ContainerUpload) Default() ContainerUpload { return "container_upload" } func (c Content) Default() Content { return "content" } func (c ContentBlockDelta) Default() ContentBlockDelta { return "content_block_delta" } @@ -201,9 +224,13 @@ func (c ContentBlockStart) Default() ContentBlockStart { return "content_b func (c ContentBlockStop) Default() ContentBlockStop { return "content_block_stop" } func (c Create) Default() Create { return "create" } func (c Delete) Default() Delete { return "delete" } +func (c Direct) Default() Direct { return "direct" } func (c Disabled) Default() Disabled { return "disabled" } func (c Document) Default() Document { return "document" } func (c Enabled) Default() Enabled { return "enabled" } +func (c EncryptedCodeExecutionResult) Default() EncryptedCodeExecutionResult { + return "encrypted_code_execution_result" +} func (c Ephemeral) Default() Ephemeral { return "ephemeral" } func (c Error) Default() Error { return "error" } func (c Errored) Default() Errored { return "errored" } @@ -214,8 +241,10 @@ func (c InputJSONDelta) Default() InputJSONDelta { return "input_jso func (c InputTokens) Default() InputTokens { return "input_tokens" } func (c Insert) Default() Insert { return "insert" } func (c InvalidRequestError) Default() InvalidRequestError { return "invalid_request_error" } +func (c JSONSchema) Default() JSONSchema { return "json_schema" } func (c MCPToolResult) Default() MCPToolResult { return "mcp_tool_result" } func (c MCPToolUse) Default() MCPToolUse { return "mcp_tool_use" } +func (c MCPToolset) Default() MCPToolset { return "mcp_toolset" } func (c Memory) Default() Memory { return "memory" } func (c Memory20250818) Default() Memory20250818 { return "memory_20250818" } func (c Message) Default() Message { return "message" } @@ -253,34 +282,42 @@ func (c TextEditor20250728) Default() TextEditor20250728 { return "text_editor_2 func (c TextEditorCodeExecutionCreateResult) Default() TextEditorCodeExecutionCreateResult { return "text_editor_code_execution_create_result" } - func (c TextEditorCodeExecutionStrReplaceResult) Default() TextEditorCodeExecutionStrReplaceResult { return "text_editor_code_execution_str_replace_result" } - func (c TextEditorCodeExecutionToolResult) Default() TextEditorCodeExecutionToolResult { return "text_editor_code_execution_tool_result" } - func (c TextEditorCodeExecutionToolResultError) Default() TextEditorCodeExecutionToolResultError { return "text_editor_code_execution_tool_result_error" } - func (c TextEditorCodeExecutionViewResult) Default() TextEditorCodeExecutionViewResult { return "text_editor_code_execution_view_result" } -func (c TextPlain) Default() TextPlain { return "text/plain" } -func (c Thinking) Default() Thinking { return "thinking" } -func (c ThinkingDelta) Default() ThinkingDelta { return "thinking_delta" } -func (c TimeoutError) Default() TimeoutError { return "timeout_error" } -func (c Tool) Default() Tool { return "tool" } -func (c ToolResult) Default() ToolResult { return "tool_result" } +func (c TextPlain) Default() TextPlain { return "text/plain" } +func (c Thinking) Default() Thinking { return "thinking" } +func (c ThinkingDelta) Default() ThinkingDelta { return "thinking_delta" } +func (c ThinkingTurns) Default() ThinkingTurns { return "thinking_turns" } +func (c TimeoutError) Default() TimeoutError { return "timeout_error" } +func (c Tool) Default() Tool { return "tool" } +func (c ToolReference) Default() ToolReference { return "tool_reference" } +func (c ToolResult) Default() ToolResult { return "tool_result" } +func (c ToolSearchToolBm25) Default() ToolSearchToolBm25 { return "tool_search_tool_bm25" } +func (c ToolSearchToolRegex) Default() ToolSearchToolRegex { return "tool_search_tool_regex" } +func (c ToolSearchToolResult) Default() ToolSearchToolResult { return "tool_search_tool_result" } +func (c ToolSearchToolResultError) Default() ToolSearchToolResultError { + return "tool_search_tool_result_error" +} +func (c ToolSearchToolSearchResult) Default() ToolSearchToolSearchResult { + return "tool_search_tool_search_result" +} func (c ToolUse) Default() ToolUse { return "tool_use" } func (c ToolUses) Default() ToolUses { return "tool_uses" } func (c URL) Default() URL { return "url" } func (c View) Default() View { return "view" } func (c WebFetch) Default() WebFetch { return "web_fetch" } func (c WebFetch20250910) Default() WebFetch20250910 { return "web_fetch_20250910" } +func (c WebFetch20260209) Default() WebFetch20260209 { return "web_fetch_20260209" } func (c WebFetchResult) Default() WebFetchResult { return "web_fetch_result" } func (c WebFetchToolResult) Default() WebFetchToolResult { return "web_fetch_tool_result" } func (c WebFetchToolResultError) Default() WebFetchToolResultError { @@ -288,6 +325,7 @@ func (c WebFetchToolResultError) Default() WebFetchToolResultError { } func (c WebSearch) Default() WebSearch { return "web_search" } func (c WebSearch20250305) Default() WebSearch20250305 { return "web_search_20250305" } +func (c WebSearch20260209) Default() WebSearch20260209 { return "web_search_20260209" } func (c WebSearchResult) Default() WebSearchResult { return "web_search_result" } func (c WebSearchResultLocation) Default() WebSearchResultLocation { return "web_search_result_location" @@ -297,6 +335,8 @@ func (c WebSearchToolResultError) Default() WebSearchToolResultError { return "web_search_tool_result_error" } +func (c Adaptive) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c All) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Any) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c APIError) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c ApplicationPDF) MarshalJSON() ([]byte, error) { return marshalString(c) } @@ -316,18 +356,24 @@ func (c BillingError) MarshalJSON() ([]byte, error) { ret func (c Canceled) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CharLocation) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CitationsDelta) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c ClearThinking20251015) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c ClearToolUses20250919) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CodeExecution) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CodeExecution20250522) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CodeExecution20250825) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c CodeExecution20260120) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CodeExecutionOutput) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CodeExecutionResult) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CodeExecutionToolResult) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c CodeExecutionToolResultError) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c Compact20260112) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c Compaction) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c CompactionDelta) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Completion) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Computer) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Computer20241022) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Computer20250124) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c Computer20251124) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c ContainerUpload) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Content) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c ContentBlockDelta) MarshalJSON() ([]byte, error) { return marshalString(c) } @@ -336,9 +382,11 @@ func (c ContentBlockStart) MarshalJSON() ([]byte, error) { ret func (c ContentBlockStop) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Create) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Delete) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c Direct) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Disabled) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Document) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Enabled) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c EncryptedCodeExecutionResult) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Ephemeral) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Error) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Errored) MarshalJSON() ([]byte, error) { return marshalString(c) } @@ -349,8 +397,10 @@ func (c InputJSONDelta) MarshalJSON() ([]byte, error) { ret func (c InputTokens) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Insert) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c InvalidRequestError) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c JSONSchema) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c MCPToolResult) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c MCPToolUse) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c MCPToolset) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Memory) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Memory20250818) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Message) MarshalJSON() ([]byte, error) { return marshalString(c) } @@ -395,20 +445,29 @@ func (c TextEditorCodeExecutionViewResult) MarshalJSON() ([]byte, error) { retur func (c TextPlain) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Thinking) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c ThinkingDelta) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c ThinkingTurns) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c TimeoutError) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c Tool) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c ToolReference) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c ToolResult) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c ToolSearchToolBm25) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c ToolSearchToolRegex) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c ToolSearchToolResult) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c ToolSearchToolResultError) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c ToolSearchToolSearchResult) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c ToolUse) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c ToolUses) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c URL) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c View) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebFetch) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebFetch20250910) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c WebFetch20260209) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebFetchResult) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebFetchToolResult) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebFetchToolResultError) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebSearch) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebSearch20250305) MarshalJSON() ([]byte, error) { return marshalString(c) } +func (c WebSearch20260209) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebSearchResult) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebSearchResultLocation) MarshalJSON() ([]byte, error) { return marshalString(c) } func (c WebSearchToolResult) MarshalJSON() ([]byte, error) { return marshalString(c) } diff --git a/toolrunner/runner_test.go b/toolrunner/runner_test.go new file mode 100644 index 000000000..2c771a5b5 --- /dev/null +++ b/toolrunner/runner_test.go @@ -0,0 +1,622 @@ +package toolrunner_test + +import ( + "context" + "encoding/json" + "fmt" + "sort" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + + anthropic "github.com/charmbracelet/anthropic-sdk-go" + "github.com/charmbracelet/anthropic-sdk-go/internal/testutil" + "github.com/charmbracelet/anthropic-sdk-go/option" + "github.com/charmbracelet/anthropic-sdk-go/toolrunner" +) + +// schemaToBytes converts a map schema to JSON bytes for use with NewBetaToolFromBytes. +func schemaToBytes(t *testing.T, schema map[string]any) []byte { + t.Helper() + bytes, err := json.Marshal(schema) + if err != nil { + t.Fatalf("marshal schema: %v", err) + } + return bytes +} + +// assistantText extracts concatenated assistant text blocks from a BetaMessage. +func assistantText(msg *anthropic.BetaMessage) string { + var b strings.Builder + for _, c := range msg.Content { + if tb, ok := c.AsAny().(anthropic.BetaTextBlock); ok { + b.WriteString(tb.Text) + } + } + return b.String() +} + +// Shared weather tool used by tests +type weatherRequest struct { + City string `json:"city"` + Units string `json:"units,omitempty"` +} + +var weatherSchema = map[string]any{ + "type": "object", + "properties": map[string]any{ + "city": map[string]any{"type": "string"}, + "units": map[string]any{"type": "string", "enum": []string{"celsius", "fahrenheit"}}, + }, + "required": []string{"city"}, +} + +func weatherTool(t *testing.T) anthropic.BetaTool { + t.Helper() + tool, err := toolrunner.NewBetaToolFromBytes("get_weather", "Get weather", schemaToBytes(t, weatherSchema), + func(ctx context.Context, req weatherRequest) (anthropic.BetaToolResultBlockParamContentUnion, error) { + temp := 20 + if req.Units == "fahrenheit" { + temp = 68 + } + return anthropic.BetaToolResultBlockParamContentUnion{ + OfText: &anthropic.BetaTextBlockParam{Text: fmt.Sprintf("The weather in %s is %d degrees %s.", req.City, temp, req.Units)}, + }, nil + }) + if err != nil { + t.Fatalf("create weather tool: %v", err) + } + return tool +} + +func newClientWithVCR(t *testing.T, cassette string) anthropic.Client { + t.Helper() + httpClient, _ := testutil.NewVCRHTTPClient(t, cassette) + return anthropic.NewClient(option.WithHTTPClient(httpClient)) +} + +// Test All() end-to-end + +func TestToolRunner_All_Basic(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_basic") + tool := weatherTool(t) + + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{tool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What's the weather in San Francisco? Use fahrenheit.")), + }, + }, + MaxIterations: 5, + }) + + ctx := context.Background() + var last *anthropic.BetaMessage + for msg, err := range runner.All(ctx) { + if err != nil { + t.Fatalf("runner error: %v", err) + } + last = msg + } + if last == nil { + t.Fatalf("no final message produced") + } + + // Extract assistant text content concisely + got := []byte(assistantText(last) + "\n") + testutil.CompareGolden(t, "testdata/snapshots/tool_runner_basic.golden", got) +} + +func TestToolRunner_RunToCompletion(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_run_to_completion") + tool := weatherTool(t) + + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{tool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What's the weather in San Francisco? Use fahrenheit.")), + }, + }, + MaxIterations: 5, + }) + + ctx := context.Background() + last, err := runner.RunToCompletion(ctx) + if err != nil { + t.Fatalf("RunToCompletion: %v", err) + } + + // Extract assistant text content concisely + got := []byte(assistantText(last) + "\n") + testutil.CompareGolden(t, "testdata/snapshots/tool_runner_run_to_completion.golden", got) +} + +// Test NextMessage step-wise, ensuring an intermediate tool_result is appended, then final answer + +func TestToolRunner_NextMessage_Step(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_next_message") + tool := weatherTool(t) + + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{tool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What's the weather in SF? Use celsius.")), + }, + }, + MaxIterations: 5, + }) + + ctx := context.Background() + // Turn 1: expect tool_use + msg, err := runner.NextMessage(ctx) + if err != nil { + t.Fatalf("NextMessage 1: %v", err) + } + if msg == nil { + t.Fatalf("expected first message") + } + + got := []byte(assistantText(msg) + "\n") + testutil.CompareGolden(t, "testdata/snapshots/tool_runner_next_message_step_1.golden", got) + // Turn 2: tool results sent, expect final assistant + msg, err = runner.NextMessage(ctx) + if err != nil { + t.Fatalf("NextMessage 2: %v", err) + } + if msg == nil { + t.Fatalf("expected final message") + } + + got = []byte(assistantText(msg) + "\n") + testutil.CompareGolden(t, "testdata/snapshots/tool_runner_next_message_step_2.golden", got) +} + +// Test AllStreaming end-to-end collects final text and compares + +func TestToolRunner_AllStreaming(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_streaming_all") + tool := weatherTool(t) + + runner := client.Beta.Messages.NewToolRunnerStreaming([]anthropic.BetaTool{tool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Weather in SF in fahrenheit?")), + }, + }, + MaxIterations: 5, + }) + + ctx := context.Background() + assistantMessages := []string{} + for iterator, err := range runner.AllStreaming(ctx) { + if err != nil { + t.Fatalf("stream err: %v", err) + } + stringBuilder := strings.Builder{} + for ev := range iterator { + switch evVariant := ev.AsAny().(type) { + case anthropic.BetaRawContentBlockDeltaEvent: + switch deltaVariant := evVariant.Delta.AsAny().(type) { + case anthropic.BetaTextDelta: + stringBuilder.WriteString(deltaVariant.Text) + } + } + } + assistantMessages = append(assistantMessages, stringBuilder.String()) + } + + got := []byte(strings.Join(assistantMessages, "\n")) + testutil.CompareGolden(t, "testdata/snapshots/tool_runner_streaming_all.golden", got) +} + +// Test NextStreaming for a single turn; verify event types set is stable + +func TestToolRunner_NextStreaming_EventTypes(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_next_streaming") + tool := weatherTool(t) + + runner := client.Beta.Messages.NewToolRunnerStreaming([]anthropic.BetaTool{tool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Weather in SF?")), + }, + }, + MaxIterations: 1, + }) + + ctx := context.Background() + events := runner.NextStreaming(ctx) + + eventsTypes := []string{} + for ev := range events { + eventsTypes = append(eventsTypes, ev.Type) + } + + sort.Strings(eventsTypes) + + got := []byte(strings.Join(eventsTypes, "\n") + "\n") + testutil.CompareGolden(t, "testdata/snapshots/tool_runner_next_streaming_types.golden", got) +} + +// Test that tool error is surfaced as a tool_result with is_error and the flow completes + +func TestToolRunner_ToolCallError_ThenSuccess(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_tool_call_error") + called := false + tool, err := toolrunner.NewBetaToolFromBytes("get_weather", "Get weather", schemaToBytes(t, weatherSchema), + func(ctx context.Context, req weatherRequest) (anthropic.BetaToolResultBlockParamContentUnion, error) { + if !called { + called = true + return anthropic.BetaToolResultBlockParamContentUnion{}, fmt.Errorf("Unexpected error, try again") + } + return anthropic.BetaToolResultBlockParamContentUnion{OfText: &anthropic.BetaTextBlockParam{Text: "Sunny 68°F"}}, nil + }) + if err != nil { + t.Fatalf("create tool: %v", err) + } + + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{tool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Weather in San Francisco?")), + }, + }, + }) + + ctx := context.Background() + msg, err := runner.RunToCompletion(ctx) + if err != nil { + t.Fatalf("RunToCompletion: %v", err) + } + + messages := runner.Messages() + if len(messages) == 0 { + t.Fatalf("expected messages in runner") + } + + // look through all the messages to find the tool results + // 1. should be an error + // 2. should be a success + toolResultBlocks := []*anthropic.BetaToolResultBlockParam{} + for _, msg := range messages { + for _, c := range msg.Content { + if tr := c.OfToolResult; tr != nil { + toolResultBlocks = append(toolResultBlocks, tr) + } + } + } + + if len(toolResultBlocks) != 2 { + t.Fatalf("expected 2 tool result blocks, got %d", len(toolResultBlocks)) + } + + errorToolResultBlock := toolResultBlocks[0] + if !errorToolResultBlock.IsError.Value { + t.Fatalf("expected first tool result to be an error") + } + errorText := errorToolResultBlock.Content[0].OfText.Text + if !strings.Contains(errorText, "Unexpected error") { + t.Fatalf("expected error message in tool result, got: %s", errorText) + } + + successToolResultBlock := toolResultBlocks[1] + if successToolResultBlock.IsError.Value { + t.Fatalf("expected second tool result to be a success") + } + successText := successToolResultBlock.Content[0].OfText.Text + if successText != "Sunny 68°F" { + t.Fatalf("expected success message in tool result, got: %s", successText) + } + + // Final assistant golden snapshot and iteration count + testutil.CompareGolden(t, "testdata/snapshots/tool_runner_tool_call_error_assistant.golden", []byte(assistantText(msg)+"\n")) + if runner.IterationCount() != 3 { + t.Fatalf("expected 3 iterations, got %d", runner.IterationCount()) + } +} + +// Test custom handling: intercept tool_use, push our own tool_result, and disable tools for next turn + +func TestToolRunner_CustomHandlingWithPushMessages(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_custom_handling") + tool := weatherTool(t) + + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{tool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What's the weather in SF in celsius?")), + }, + }, + }) + + ctx := context.Background() + // First assistant message with tool_use + msg, err := runner.NextMessage(ctx) + if err != nil || msg == nil { + t.Fatalf("turn 1: %v %v", msg, err) + } + // Find first tool_use id + var toolUseID string + for _, c := range msg.Content { + if tu, ok := c.AsAny().(anthropic.BetaToolUseBlock); ok { + toolUseID = tu.ID + break + } + } + if toolUseID == "" { + t.Fatalf("expected a tool_use block") + } + // Build a new runner with our custom tool_result appended to messages to avoid + // automatic execution for the prior assistant tool_use turn. + msgs := runner.Messages() + msgs = append(msgs, anthropic.NewBetaUserMessage( + anthropic.BetaContentBlockParamUnion{OfToolResult: &anthropic.BetaToolResultBlockParam{ToolUseID: toolUseID, Content: []anthropic.BetaToolResultBlockParamContentUnion{{OfText: &anthropic.BetaTextBlockParam{Text: "Celsius 20°C"}}}}}, + )) + + // No tools so the next turn is just the assistant producing final text + runner2 := client.Beta.Messages.NewToolRunner(nil, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: msgs, + }, + }) + + // Next turn should finalize with assistant text + msg, err = runner2.NextMessage(ctx) + if err != nil || msg == nil { + t.Fatalf("turn 2: %v %v", msg, err) + } +} + +// Test max iterations stops further calls + +func TestToolRunner_MaxIterations(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_max_iterations") + tool := weatherTool(t) + + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{tool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Check weather in SF and NY, step by step")), + }, + }, + MaxIterations: 2, + }) + + ctx := context.Background() + for { + msg, err := runner.NextMessage(ctx) + if msg == nil { + if err != nil { + t.Fatalf("runner error: %v", err) + } + break + } + } + if got := runner.IterationCount(); got != 2 { + t.Fatalf("expected 2 iterations, got %d", got) + } +} + +// Test concurrent tool execution (multiple tools in one message) + +func TestToolRunner_ConcurrentToolExecution(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_concurrent") + + // Track execution with timing to verify concurrency + var callCount atomic.Int32 + var executionTimes sync.Map + startTime := time.Now() + + weatherTool, err := toolrunner.NewBetaToolFromBytes("get_weather", "Get weather for a city", schemaToBytes(t, weatherSchema), + func(ctx context.Context, req weatherRequest) (anthropic.BetaToolResultBlockParamContentUnion, error) { + executionTimes.Store(req.City, time.Since(startTime)) + callCount.Add(1) + // Small delay - if sequential this would take 3x longer + time.Sleep(50 * time.Millisecond) + return anthropic.BetaToolResultBlockParamContentUnion{ + OfText: &anthropic.BetaTextBlockParam{Text: fmt.Sprintf("Weather in %s: Sunny 72°F", req.City)}, + }, nil + }) + if err != nil { + t.Fatalf("create weather tool: %v", err) + } + + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{weatherTool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock( + "What's the weather in San Francisco, New York, and London? Check all three cities at once.", + )), + }, + }, + MaxIterations: 5, + }) + + ctx := context.Background() + _, err = runner.RunToCompletion(ctx) + if err != nil { + t.Fatalf("RunToCompletion: %v", err) + } + + // Verify multiple tools were called + count := callCount.Load() + if count < 2 { + t.Fatalf("expected at least 2 concurrent tool calls, got %d", count) + } + + // Verify tool results are in the messages + messages := runner.Messages() + toolResultCount := 0 + for _, msg := range messages { + for _, c := range msg.Content { + if c.OfToolResult != nil { + toolResultCount++ + } + } + } + if toolResultCount < 2 { + t.Fatalf("expected at least 2 tool results, got %d", toolResultCount) + } +} + +// Test context cancellation during tool execution + +func TestToolRunner_ContextCancellation(t *testing.T) { + t.Parallel() + client := newClientWithVCR(t, "tool_runner_context_cancel") + + toolStarted := make(chan struct{}) + toolCompleted := make(chan struct{}) + + slowSchema := map[string]any{ + "type": "object", + "properties": map[string]any{"input": map[string]any{"type": "string"}}, + } + slowTool, err := toolrunner.NewBetaToolFromBytes("slow_tool", "A slow tool", schemaToBytes(t, slowSchema), + func(ctx context.Context, req struct{ Input string }) (anthropic.BetaToolResultBlockParamContentUnion, error) { + close(toolStarted) + // Wait for context cancellation or timeout + select { + case <-ctx.Done(): + return anthropic.BetaToolResultBlockParamContentUnion{}, ctx.Err() + case <-time.After(5 * time.Second): + close(toolCompleted) + return anthropic.BetaToolResultBlockParamContentUnion{ + OfText: &anthropic.BetaTextBlockParam{Text: "completed"}, + }, nil + } + }) + if err != nil { + t.Fatalf("create slow tool: %v", err) + } + + runner := client.Beta.Messages.NewToolRunner([]anthropic.BetaTool{slowTool}, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaude3_7SonnetLatest, + MaxTokens: 512, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("Call the slow_tool with input 'test'")), + }, + }, + MaxIterations: 5, + }) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Start the runner in a goroutine + done := make(chan struct{}) + go func() { + defer close(done) + runner.RunToCompletion(ctx) + }() + + // Wait for tool to start, then cancel + select { + case <-toolStarted: + cancel() + case <-time.After(10 * time.Second): + t.Fatal("tool never started") + } + + // Verify runner completes quickly after cancellation (not waiting 5 seconds) + select { + case <-done: + // Good - runner completed + case <-toolCompleted: + t.Fatal("tool completed without cancellation being respected") + case <-time.After(2 * time.Second): + t.Fatal("runner did not complete promptly after cancellation") + } +} + +// Test malformed JSON input error handling through Execute + +func TestToolRunner_MalformedJSONInput(t *testing.T) { + t.Parallel() + + type StrictInput struct { + RequiredField string `json:"required_field"` + NumberField int `json:"number_field"` + } + + strictSchema := map[string]any{ + "type": "object", + "properties": map[string]any{ + "required_field": map[string]any{"type": "string"}, + "number_field": map[string]any{"type": "integer"}, + }, + "required": []string{"required_field"}, + } + tool, err := toolrunner.NewBetaToolFromBytes("strict_tool", "A tool with strict input", schemaToBytes(t, strictSchema), + func(ctx context.Context, input StrictInput) (anthropic.BetaToolResultBlockParamContentUnion, error) { + return anthropic.BetaToolResultBlockParamContentUnion{ + OfText: &anthropic.BetaTextBlockParam{Text: "success"}, + }, nil + }) + if err != nil { + t.Fatalf("create tool: %v", err) + } + + // Test Execute with valid JSON + validJSON := json.RawMessage(`{"required_field": "test", "number_field": 42}`) + result, err := tool.Execute(context.Background(), validJSON) + if err != nil { + t.Fatalf("Execute valid JSON failed: %v", err) + } + if result.OfText == nil || result.OfText.Text != "success" { + t.Fatalf("Execute returned unexpected result: %+v", result) + } + + // Test Execute with malformed JSON (invalid syntax) + malformedJSON := json.RawMessage(`{"required_field": "test", "number_field": }`) + _, err = tool.Execute(context.Background(), malformedJSON) + if err == nil { + t.Fatal("expected error for malformed JSON, got nil") + } + + // Test Execute with type mismatch (string instead of int) + typeMismatchJSON := json.RawMessage(`{"required_field": "test", "number_field": "not a number"}`) + _, err = tool.Execute(context.Background(), typeMismatchJSON) + if err == nil { + t.Fatal("expected error for type mismatch, got nil") + } + + // Test Execute with invalid JSON propagates error + invalidJSON := json.RawMessage(`{invalid json}`) + _, err = tool.Execute(context.Background(), invalidJSON) + if err == nil { + t.Fatal("expected error for invalid JSON in Execute") + } +} diff --git a/toolrunner/testdata/cassettes/tool_runner_basic.yaml b/toolrunner/testdata/cassettes/tool_runner_basic.yaml new file mode 100644 index 000000000..4e2d9224c --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_basic.yaml @@ -0,0 +1,177 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in San Francisco? Use fahrenheit.","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01VLZuPg94y7NULJySZhEDJY","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll + get the current weather in San Francisco for you in Fahrenheit."},{"type":"tool_use","id":"toolu_01TZR6ZrLHdpAWdmhVPuDfjQ","name":"get_weather","input":{"city":"San + Francisco","units":"fahrenheit"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":402,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":89,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3997" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:35Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3946fe5f5e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:37 GMT + Request-Id: + - req_011CUdgeEZVNjY7M6qwNV9k6 + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1371" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in San Francisco? Use fahrenheit.","type":"text"}],"role":"user"},{"content":[{"text":"I''ll + get the current weather in San Francisco for you in Fahrenheit.","type":"text"},{"id":"toolu_01TZR6ZrLHdpAWdmhVPuDfjQ","input":{"city":"San + Francisco","units":"fahrenheit"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01TZR6ZrLHdpAWdmhVPuDfjQ","content":[{"text":"The + weather in San Francisco is 68 degrees fahrenheit.","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_014SddXAzPYwR72fa37nJ8N2","type":"message","role":"assistant","content":[{"type":"text","text":"The + current temperature in San Francisco is 68 degrees Fahrenheit."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":514,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":19,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3998" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c394fc8465e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:38 GMT + Request-Id: + - req_011CUdgeLbdAHJifhfifciof + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "711" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_concurrent.yaml b/toolrunner/testdata/cassettes/tool_runner_concurrent.yaml new file mode 100644 index 000000000..bff104c83 --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_concurrent.yaml @@ -0,0 +1,363 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in San Francisco, New York, and London? Check all three cities at once.","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather for a city"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.19.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.19.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.25.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01GhukHZbus69MS8zCp3tqTa","type":"message","role":"assistant","content":[{"type":"text","text":"I''d + be happy to check the weather for San Francisco, New York, and London for you. + I''ll need to look up each city individually."},{"type":"tool_use","id":"toolu_019dfQh1VSo4ykF3MUFvGpMg","name":"get_weather","input":{"city":"San + Francisco"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":414,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":85,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 4b663dca-f14e-490d-9965-801817fd453d + Anthropic-Ratelimit-Input-Tokens-Limit: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "39000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2026-01-23T07:42:01Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2026-01-23T07:42:02Z" + Anthropic-Ratelimit-Requests-Limit: + - "1000" + Anthropic-Ratelimit-Requests-Remaining: + - "998" + Anthropic-Ratelimit-Requests-Reset: + - "2026-01-23T07:42:00Z" + Anthropic-Ratelimit-Tokens-Limit: + - "56000" + Anthropic-Ratelimit-Tokens-Remaining: + - "55000" + Anthropic-Ratelimit-Tokens-Reset: + - "2026-01-23T07:42:01Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 9c25a6e2df5aa143-LAX + Content-Type: + - application/json + Date: + - Fri, 23 Jan 2026 07:42:01 GMT + Request-Id: + - req_011CXPw5fUs1tb4koxa1VUac + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1637" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in San Francisco, New York, and London? Check all three cities at once.","type":"text"}],"role":"user"},{"content":[{"text":"I''d + be happy to check the weather for San Francisco, New York, and London for you. + I''ll need to look up each city individually.","type":"text"},{"id":"toolu_019dfQh1VSo4ykF3MUFvGpMg","input":{"city":"San + Francisco"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_019dfQh1VSo4ykF3MUFvGpMg","content":[{"text":"Weather + in San Francisco: Sunny 72°F","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather for a city"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.19.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.19.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.25.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_0146jGKLKCa86wwR9aHbrEfe","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_015Sh8xNQBhJJnBCLz8x9F6f","name":"get_weather","input":{"city":"New + York"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":521,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":55,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 4b663dca-f14e-490d-9965-801817fd453d + Anthropic-Ratelimit-Input-Tokens-Limit: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2026-01-23T07:42:02Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2026-01-23T07:42:03Z" + Anthropic-Ratelimit-Requests-Limit: + - "1000" + Anthropic-Ratelimit-Requests-Remaining: + - "999" + Anthropic-Ratelimit-Requests-Reset: + - "2026-01-23T07:42:02Z" + Anthropic-Ratelimit-Tokens-Limit: + - "56000" + Anthropic-Ratelimit-Tokens-Remaining: + - "56000" + Anthropic-Ratelimit-Tokens-Reset: + - "2026-01-23T07:42:02Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 9c25a6edf8f7a143-LAX + Content-Type: + - application/json + Date: + - Fri, 23 Jan 2026 07:42:02 GMT + Request-Id: + - req_011CXPw5o5mF8wtv3QiE2tkd + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1008" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in San Francisco, New York, and London? Check all three cities at once.","type":"text"}],"role":"user"},{"content":[{"text":"I''d + be happy to check the weather for San Francisco, New York, and London for you. + I''ll need to look up each city individually.","type":"text"},{"id":"toolu_019dfQh1VSo4ykF3MUFvGpMg","input":{"city":"San + Francisco"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_019dfQh1VSo4ykF3MUFvGpMg","content":[{"text":"Weather + in San Francisco: Sunny 72°F","type":"text"}],"type":"tool_result"}],"role":"user"},{"content":[{"id":"toolu_015Sh8xNQBhJJnBCLz8x9F6f","input":{"city":"New + York"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_015Sh8xNQBhJJnBCLz8x9F6f","content":[{"text":"Weather + in New York: Sunny 72°F","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather for a city"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.19.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.19.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.25.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_018RyYEDtaKf3WyN2AVY7DVZ","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_019FKPTDNUQxrGzdjFtpP9Yp","name":"get_weather","input":{"city":"London"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":598,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":54,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 4b663dca-f14e-490d-9965-801817fd453d + Anthropic-Ratelimit-Input-Tokens-Limit: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2026-01-23T07:42:04Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2026-01-23T07:42:04Z" + Anthropic-Ratelimit-Requests-Limit: + - "1000" + Anthropic-Ratelimit-Requests-Remaining: + - "999" + Anthropic-Ratelimit-Requests-Reset: + - "2026-01-23T07:42:03Z" + Anthropic-Ratelimit-Tokens-Limit: + - "56000" + Anthropic-Ratelimit-Tokens-Remaining: + - "56000" + Anthropic-Ratelimit-Tokens-Reset: + - "2026-01-23T07:42:04Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 9c25a6f52a45a143-LAX + Content-Type: + - application/json + Date: + - Fri, 23 Jan 2026 07:42:04 GMT + Request-Id: + - req_011CXPw5t2fvWR46n9QUQ9Qm + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "945" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in San Francisco, New York, and London? Check all three cities at once.","type":"text"}],"role":"user"},{"content":[{"text":"I''d + be happy to check the weather for San Francisco, New York, and London for you. + I''ll need to look up each city individually.","type":"text"},{"id":"toolu_019dfQh1VSo4ykF3MUFvGpMg","input":{"city":"San + Francisco"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_019dfQh1VSo4ykF3MUFvGpMg","content":[{"text":"Weather + in San Francisco: Sunny 72°F","type":"text"}],"type":"tool_result"}],"role":"user"},{"content":[{"id":"toolu_015Sh8xNQBhJJnBCLz8x9F6f","input":{"city":"New + York"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_015Sh8xNQBhJJnBCLz8x9F6f","content":[{"text":"Weather + in New York: Sunny 72°F","type":"text"}],"type":"tool_result"}],"role":"user"},{"content":[{"id":"toolu_019FKPTDNUQxrGzdjFtpP9Yp","input":{"city":"London"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_019FKPTDNUQxrGzdjFtpP9Yp","content":[{"text":"Weather + in London: Sunny 72°F","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather for a city"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.19.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.19.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.25.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01U2itU4GfWtWJXqw43f4XB1","type":"message","role":"assistant","content":[{"type":"text","text":"Here''s + the current weather for all three cities:\n\n- San Francisco: Sunny 72°F\n- + New York: Sunny 72°F\n- London: Sunny 72°F\n\nWould you like me to check any + other cities or get the weather in Celsius instead?"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":673,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":65,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 4b663dca-f14e-490d-9965-801817fd453d + Anthropic-Ratelimit-Input-Tokens-Limit: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2026-01-23T07:42:05Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2026-01-23T07:42:05Z" + Anthropic-Ratelimit-Requests-Limit: + - "1000" + Anthropic-Ratelimit-Requests-Remaining: + - "999" + Anthropic-Ratelimit-Requests-Reset: + - "2026-01-23T07:42:04Z" + Anthropic-Ratelimit-Tokens-Limit: + - "56000" + Anthropic-Ratelimit-Tokens-Remaining: + - "56000" + Anthropic-Ratelimit-Tokens-Reset: + - "2026-01-23T07:42:05Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 9c25a6fbfae2a143-LAX + Content-Type: + - application/json + Date: + - Fri, 23 Jan 2026 07:42:05 GMT + Request-Id: + - req_011CXPw5xhTv4tqQceCdq8iZ + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1320" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_context_cancel.yaml b/toolrunner/testdata/cassettes/tool_runner_context_cancel.yaml new file mode 100644 index 000000000..6998723a1 --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_context_cancel.yaml @@ -0,0 +1,89 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Call the slow_tool with + input ''test''","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"input":{"type":"string"}},"type":"object"},"name":"slow_tool","description":"A + slow tool"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.19.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.19.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.25.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_0142PtqubSsNMQyL4EiyyEs6","type":"message","role":"assistant","content":[{"type":"text","text":"I + can help you call the slow_tool with the input ''test''. I''ll use the function + call now:"},{"type":"tool_use","id":"toolu_01CbQoxtE6Qg5V9pW5SX66i5","name":"slow_tool","input":{"input":"test"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":376,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":78,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 4b663dca-f14e-490d-9965-801817fd453d + Anthropic-Ratelimit-Input-Tokens-Limit: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "40000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2026-01-23T07:42:01Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "16000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2026-01-23T07:42:01Z" + Anthropic-Ratelimit-Requests-Limit: + - "1000" + Anthropic-Ratelimit-Requests-Remaining: + - "999" + Anthropic-Ratelimit-Requests-Reset: + - "2026-01-23T07:42:00Z" + Anthropic-Ratelimit-Tokens-Limit: + - "56000" + Anthropic-Ratelimit-Tokens-Remaining: + - "56000" + Anthropic-Ratelimit-Tokens-Reset: + - "2026-01-23T07:42:01Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 9c25a6e2df5ca143-LAX + Content-Type: + - application/json + Date: + - Fri, 23 Jan 2026 07:42:01 GMT + Request-Id: + - req_011CXPw5fUcysxR74k3PTTtN + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1425" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_custom_handling.yaml b/toolrunner/testdata/cassettes/tool_runner_custom_handling.yaml new file mode 100644 index 000000000..09f8e6234 --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_custom_handling.yaml @@ -0,0 +1,174 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in SF in celsius?","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01SKjgb16h4feir85VSwDQY3","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll + check the current weather in San Francisco for you in Celsius."},{"type":"tool_use","id":"toolu_01RemJnygsv2MuzBdGC1Amou","name":"get_weather","input":{"city":"SF","units":"celsius"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":399,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":86,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3995" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:35Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3946fe625e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:37 GMT + Request-Id: + - req_011CUdgeEayGXg3uus6w2iF3 + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1330" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in SF in celsius?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll + check the current weather in San Francisco for you in Celsius.","type":"text"},{"id":"toolu_01RemJnygsv2MuzBdGC1Amou","input":{"city":"SF","units":"celsius"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01RemJnygsv2MuzBdGC1Amou","content":[{"text":"Celsius + 20°C","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01AotAbnCJmEFVVkkw6rNfXP","type":"message","role":"assistant","content":[{"type":"text","text":"It''s + currently 20°C in San Francisco."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":119,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":15,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3999" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c394f88085e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:38 GMT + Request-Id: + - req_011CUdgeLTSmFd3yzdcPJc5d + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "788" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_max_iterations.yaml b/toolrunner/testdata/cassettes/tool_runner_max_iterations.yaml new file mode 100644 index 000000000..0435e5880 --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_max_iterations.yaml @@ -0,0 +1,180 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Check weather in SF + and NY, step by step","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01Q2mACVzNZQUHB5En8kt88w","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll + check the weather in San Francisco and New York step by step.\n\nFirst, let + me check the weather in San Francisco:"},{"type":"tool_use","id":"toolu_01CHZ5yWb5v7HP4EavruQtj8","name":"get_weather","input":{"city":"San + Francisco"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":400,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":82,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3994" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:35Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "280000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3946fe5e5e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:37 GMT + Request-Id: + - req_011CUdgeEaEDRiyx96pje4xj + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1748" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Check weather in SF + and NY, step by step","type":"text"}],"role":"user"},{"content":[{"text":"I''ll + check the weather in San Francisco and New York step by step.\n\nFirst, let + me check the weather in San Francisco:","type":"text"},{"id":"toolu_01CHZ5yWb5v7HP4EavruQtj8","input":{"city":"San + Francisco"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01CHZ5yWb5v7HP4EavruQtj8","content":[{"text":"The + weather in San Francisco is 20 degrees .","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01TF3a1zCD17o4pQHPZXJsdS","type":"message","role":"assistant","content":[{"type":"text","text":"Now, + let me check the weather in New York:"},{"type":"tool_use","id":"toolu_01FS9cCtrd1NyGHq5aHiBYTQ","name":"get_weather","input":{"city":"New + York"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":504,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":67,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:39Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3999" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "280000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c39523b215e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:39 GMT + Request-Id: + - req_011CUdgeNJpSrFv7D5t4RV3m + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1943" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_next_message.yaml b/toolrunner/testdata/cassettes/tool_runner_next_message.yaml new file mode 100644 index 000000000..b4e2ec29a --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_next_message.yaml @@ -0,0 +1,177 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in SF? Use celsius.","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01AMULp5HCeVjmUHkfitquk5","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll + check the weather in San Francisco for you using Celsius units."},{"type":"tool_use","id":"toolu_01Na4b3cjX4XZw88mccd5HyP","name":"get_weather","input":{"city":"San + Francisco","units":"celsius"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":400,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":87,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3995" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:35Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3946fe555e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:37 GMT + Request-Id: + - req_011CUdgeEZUym6SoQVcZV75Q + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1517" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in SF? Use celsius.","type":"text"}],"role":"user"},{"content":[{"text":"I''ll + check the weather in San Francisco for you using Celsius units.","type":"text"},{"id":"toolu_01Na4b3cjX4XZw88mccd5HyP","input":{"city":"San + Francisco","units":"celsius"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01Na4b3cjX4XZw88mccd5HyP","content":[{"text":"The + weather in San Francisco is 20 degrees celsius.","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01Y2wUmtAZCFJ2zbfZ37NZui","type":"message","role":"assistant","content":[{"type":"text","text":"The + current weather in San Francisco is 20 degrees Celsius."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":509,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":18,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3999" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3950b9785e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:38 GMT + Request-Id: + - req_011CUdgeMDLV8cZ2aqH8bTW3 + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1050" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_next_streaming.yaml b/toolrunner/testdata/cassettes/tool_runner_next_streaming.yaml new file mode 100644 index 000000000..c729e4a63 --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_next_streaming.yaml @@ -0,0 +1,161 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Weather in SF?","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}],"stream":true}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-3-7-sonnet-20250219","id":"msg_01P7nF1bmxyzFZjF8zwbUDBM","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":1,"service_tier":"standard"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"'"} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"d be"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" happy to check"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the weather"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" in"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" San Francisco for you."}} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Let"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" me get"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" that"}} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" information for you right"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" away"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"."} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: content_block_start + data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_017QoD96fYwGzCWvLfaPADWg","name":"get_weather","input":{}} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"city\": \"Sa"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"n Francis"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"co\"}"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":1 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":394,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":79} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3999" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Cache-Control: + - no-cache + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3946fe585e6a-EWR + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Thu, 30 Oct 2025 16:17:36 GMT + Request-Id: + - req_011CUdgeEggCMUt3Y8mNfvTP + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1133" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_run_to_completion.yaml b/toolrunner/testdata/cassettes/tool_runner_run_to_completion.yaml new file mode 100644 index 000000000..7a7a30e0b --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_run_to_completion.yaml @@ -0,0 +1,177 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in San Francisco? Use fahrenheit.","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_018ot5fJ8BmAG1WxW5B7WkJX","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll + get the current weather in San Francisco for you using Fahrenheit units."},{"type":"tool_use","id":"toolu_01RspNj5YbBdaKwpEEcKirBJ","name":"get_weather","input":{"city":"San + Francisco","units":"fahrenheit"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":402,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":90,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3998" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:35Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3946fe5d5e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:37 GMT + Request-Id: + - req_011CUdgeEZV6311MCdLraHEj + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1535" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"What''s the weather + in San Francisco? Use fahrenheit.","type":"text"}],"role":"user"},{"content":[{"text":"I''ll + get the current weather in San Francisco for you using Fahrenheit units.","type":"text"},{"id":"toolu_01RspNj5YbBdaKwpEEcKirBJ","input":{"city":"San + Francisco","units":"fahrenheit"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01RspNj5YbBdaKwpEEcKirBJ","content":[{"text":"The + weather in San Francisco is 68 degrees fahrenheit.","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01D2irNnbwPJPt2d5D6B4ovq","type":"message","role":"assistant","content":[{"type":"text","text":"The + weather in San Francisco is currently 68 degrees Fahrenheit."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":515,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":19,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3999" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3950d98c5e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:38 GMT + Request-Id: + - req_011CUdgeMJ3okUzCzuFRSRcg + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "588" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_streaming_all.yaml b/toolrunner/testdata/cassettes/tool_runner_streaming_all.yaml new file mode 100644 index 000000000..2085d5a9d --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_streaming_all.yaml @@ -0,0 +1,277 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Weather in SF in fahrenheit?","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}],"stream":true}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-3-7-sonnet-20250219","id":"msg_01H1pwRRkQxKbUGKi785gT4M","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":397,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"I'll"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" get"} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" the current weather in"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" San Francisco for you in"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Fahrenheit."} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0} + + event: content_block_start + data: {"type":"content_block_start","index":1,"content_block":{"type":"tool_use","id":"toolu_01RaX2WYWRWCbaeFHssmGJXG","name":"get_weather","input":{}} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":""} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"{\"city"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\": \"S"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"an F"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"ra"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"ncisco"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"\""}} + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":", \"units\""} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":": \"fahr"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"enhei"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":1,"delta":{"type":"input_json_delta","partial_json":"t\"}"} } + + event: content_block_stop + data: {"type":"content_block_stop","index":1 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"tool_use","stop_sequence":null},"usage":{"input_tokens":397,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":89} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:35Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3996" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:35Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:35Z" + Cache-Control: + - no-cache + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3946fe5c5e6a-EWR + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Thu, 30 Oct 2025 16:17:36 GMT + Request-Id: + - req_011CUdgeEaEXcfa9PDdxrNMk + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "344" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Weather in SF in fahrenheit?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll + get the current weather in San Francisco for you in Fahrenheit.","type":"text"},{"id":"toolu_01RaX2WYWRWCbaeFHssmGJXG","input":{"city":"San + Francisco","units":"fahrenheit"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01RaX2WYWRWCbaeFHssmGJXG","content":[{"text":"The + weather in San Francisco is 68 degrees fahrenheit.","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}],"stream":true}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: |+ + event: message_start + data: {"type":"message_start","message":{"model":"claude-3-7-sonnet-20250219","id":"msg_01Hh7yjeiaEaEREnpywjByCo","type":"message","role":"assistant","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":509,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":2,"service_tier":"standard"}} } + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"The"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" current weather"} } + + event: ping + data: {"type": "ping"} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" in San Francisco is "} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"68 degrees Fahren"} } + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"heit."} } + + event: content_block_stop + data: {"type":"content_block_stop","index":0 } + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":509,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":19} } + + event: message_stop + data: {"type":"message_stop" } + + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3999" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Cache-Control: + - no-cache + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c394fc8455e6a-EWR + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Thu, 30 Oct 2025 16:17:37 GMT + Request-Id: + - req_011CUdgeLebtjP3oqrQZ6wp1 + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "409" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/cassettes/tool_runner_tool_call_error.yaml b/toolrunner/testdata/cassettes/tool_runner_tool_call_error.yaml new file mode 100644 index 000000000..a858340f0 --- /dev/null +++ b/toolrunner/testdata/cassettes/tool_runner_tool_call_error.yaml @@ -0,0 +1,266 @@ +--- +version: 1 +interactions: +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Weather in San Francisco?","type":"text"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_014tfMBTf8yzH6aC9ohZ94k3","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll + check the current weather in San Francisco for you."},{"type":"tool_use","id":"toolu_01XKSJ1fM9PHM9vpwH1p7PDT","name":"get_weather","input":{"city":"San + Francisco"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":395,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":67,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3999" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:35Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:36Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c3946fe615e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:37 GMT + Request-Id: + - req_011CUdgeEYzbWH4BW7aH5Dbx + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1378" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Weather in San Francisco?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll + check the current weather in San Francisco for you.","type":"text"},{"id":"toolu_01XKSJ1fM9PHM9vpwH1p7PDT","input":{"city":"San + Francisco"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01XKSJ1fM9PHM9vpwH1p7PDT","is_error":true,"content":[{"text":"Error: + Unexpected error, try again","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01WkcabYzR3oCnHMEPgBcSAa","type":"message","role":"assistant","content":[{"type":"text","text":"I + apologize for the error. Let me try checking the weather in San Francisco again."},{"type":"tool_use","id":"toolu_01LELQc5n8mDyvS1bApN4qPi","name":"get_weather","input":{"city":"San + Francisco"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":489,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":74,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "199000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3998" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:37Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "279000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:37Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c394fd8575e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:38 GMT + Request-Id: + - req_011CUdgeLfMAoXNWKXy99k2B + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "1260" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" +- request: + body: '{"max_tokens":512,"messages":[{"content":[{"text":"Weather in San Francisco?","type":"text"}],"role":"user"},{"content":[{"text":"I''ll + check the current weather in San Francisco for you.","type":"text"},{"id":"toolu_01XKSJ1fM9PHM9vpwH1p7PDT","input":{"city":"San + Francisco"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01XKSJ1fM9PHM9vpwH1p7PDT","is_error":true,"content":[{"text":"Error: + Unexpected error, try again","type":"text"}],"type":"tool_result"}],"role":"user"},{"content":[{"text":"I + apologize for the error. Let me try checking the weather in San Francisco again.","type":"text"},{"id":"toolu_01LELQc5n8mDyvS1bApN4qPi","input":{"city":"San + Francisco"},"name":"get_weather","type":"tool_use"}],"role":"assistant"},{"content":[{"tool_use_id":"toolu_01LELQc5n8mDyvS1bApN4qPi","content":[{"text":"Sunny + 68°F","type":"text"}],"type":"tool_result"}],"role":"user"}],"model":"claude-3-7-sonnet-latest","tools":[{"input_schema":{"properties":{"city":{"type":"string"},"units":{"enum":["celsius","fahrenheit"],"type":"string"}},"required":["city"],"type":"object"},"name":"get_weather","description":"Get + weather"}]}' + form: {} + headers: + Accept: + - application/json + Anthropic-Version: + - "2023-06-01" + Content-Type: + - application/json + User-Agent: + - Anthropic/Go 1.16.0 + X-Api-Key: + - fake-api-key-for-testing-only + X-Stainless-Arch: + - arm64 + X-Stainless-Lang: + - go + X-Stainless-Os: + - MacOS + X-Stainless-Package-Version: + - 1.16.0 + X-Stainless-Retry-Count: + - "0" + X-Stainless-Runtime: + - go + X-Stainless-Runtime-Version: + - go1.24.5 + X-Stainless-Timeout: + - "600" + url: https://api.anthropic.com/v1/messages?beta=true + method: POST + response: + body: '{"model":"claude-3-7-sonnet-20250219","id":"msg_01BT54to51fGtyrvodmSUuUw","type":"message","role":"assistant","content":[{"type":"text","text":"The + current weather in San Francisco is sunny with a temperature of 68°F."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":580,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":21,"service_tier":"standard"}}' + headers: + Anthropic-Organization-Id: + - 1577a8a6-174a-4705-916c-6b22ae7a49e6 + Anthropic-Ratelimit-Input-Tokens-Limit: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Remaining: + - "200000" + Anthropic-Ratelimit-Input-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Output-Tokens-Limit: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Remaining: + - "80000" + Anthropic-Ratelimit-Output-Tokens-Reset: + - "2025-10-30T16:17:39Z" + Anthropic-Ratelimit-Requests-Limit: + - "4000" + Anthropic-Ratelimit-Requests-Remaining: + - "3999" + Anthropic-Ratelimit-Requests-Reset: + - "2025-10-30T16:17:38Z" + Anthropic-Ratelimit-Tokens-Limit: + - "280000" + Anthropic-Ratelimit-Tokens-Remaining: + - "280000" + Anthropic-Ratelimit-Tokens-Reset: + - "2025-10-30T16:17:38Z" + Cf-Cache-Status: + - DYNAMIC + Cf-Ray: + - 996c39580aab5e6a-EWR + Content-Type: + - application/json + Date: + - Thu, 30 Oct 2025 16:17:39 GMT + Request-Id: + - req_011CUdgeSDTmEigNbh79UCJo + Server: + - cloudflare + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + X-Envoy-Upstream-Service-Time: + - "605" + X-Robots-Tag: + - none + status: 200 OK + code: 200 + duration: "" diff --git a/toolrunner/testdata/snapshots/tool_runner_basic.golden b/toolrunner/testdata/snapshots/tool_runner_basic.golden new file mode 100644 index 000000000..9a6f32791 --- /dev/null +++ b/toolrunner/testdata/snapshots/tool_runner_basic.golden @@ -0,0 +1 @@ +The current temperature in San Francisco is 68 degrees Fahrenheit. diff --git a/toolrunner/testdata/snapshots/tool_runner_next_message_step_1.golden b/toolrunner/testdata/snapshots/tool_runner_next_message_step_1.golden new file mode 100644 index 000000000..74ece49af --- /dev/null +++ b/toolrunner/testdata/snapshots/tool_runner_next_message_step_1.golden @@ -0,0 +1 @@ +I'll check the weather in San Francisco for you using Celsius units. diff --git a/toolrunner/testdata/snapshots/tool_runner_next_message_step_2.golden b/toolrunner/testdata/snapshots/tool_runner_next_message_step_2.golden new file mode 100644 index 000000000..c8f0ad904 --- /dev/null +++ b/toolrunner/testdata/snapshots/tool_runner_next_message_step_2.golden @@ -0,0 +1 @@ +The current weather in San Francisco is 20 degrees Celsius. diff --git a/toolrunner/testdata/snapshots/tool_runner_next_streaming_types.golden b/toolrunner/testdata/snapshots/tool_runner_next_streaming_types.golden new file mode 100644 index 000000000..607bbb36b --- /dev/null +++ b/toolrunner/testdata/snapshots/tool_runner_next_streaming_types.golden @@ -0,0 +1,24 @@ +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_delta +content_block_start +content_block_start +content_block_stop +content_block_stop +message_delta +message_start +message_stop diff --git a/toolrunner/testdata/snapshots/tool_runner_run_to_completion.golden b/toolrunner/testdata/snapshots/tool_runner_run_to_completion.golden new file mode 100644 index 000000000..119416607 --- /dev/null +++ b/toolrunner/testdata/snapshots/tool_runner_run_to_completion.golden @@ -0,0 +1 @@ +The weather in San Francisco is currently 68 degrees Fahrenheit. diff --git a/toolrunner/testdata/snapshots/tool_runner_streaming_all.golden b/toolrunner/testdata/snapshots/tool_runner_streaming_all.golden new file mode 100644 index 000000000..756571a6a --- /dev/null +++ b/toolrunner/testdata/snapshots/tool_runner_streaming_all.golden @@ -0,0 +1,2 @@ +I'll get the current weather in San Francisco for you in Fahrenheit. +The current weather in San Francisco is 68 degrees Fahrenheit. diff --git a/toolrunner/testdata/snapshots/tool_runner_tool_call_error_assistant.golden b/toolrunner/testdata/snapshots/tool_runner_tool_call_error_assistant.golden new file mode 100644 index 000000000..d7c982631 --- /dev/null +++ b/toolrunner/testdata/snapshots/tool_runner_tool_call_error_assistant.golden @@ -0,0 +1 @@ +The current weather in San Francisco is sunny with a temperature of 68°F. diff --git a/toolrunner/tool.go b/toolrunner/tool.go new file mode 100644 index 000000000..a38ca3dcb --- /dev/null +++ b/toolrunner/tool.go @@ -0,0 +1,132 @@ +package toolrunner + +import ( + "context" + "encoding/json" + "fmt" + + anthropic "github.com/charmbracelet/anthropic-sdk-go" + "github.com/invopop/jsonschema" +) + +// betaTool is the internal generic implementation of anthropic.BetaTool. +// Users never see this type directly - they work with the BetaTool interface. +// The generic type parameter T is used internally for type-safe JSON unmarshaling. +type betaTool[T any] struct { + name string + description string + schema anthropic.BetaToolInputSchemaParam + handler func(context.Context, T) (anthropic.BetaToolResultBlockParamContentUnion, error) +} + +func (t *betaTool[T]) Name() string { return t.name } +func (t *betaTool[T]) Description() string { return t.description } +func (t *betaTool[T]) InputSchema() anthropic.BetaToolInputSchemaParam { return t.schema } + +func (t *betaTool[T]) Execute(ctx context.Context, input json.RawMessage) (anthropic.BetaToolResultBlockParamContentUnion, error) { + parsed, err := t.parse(input) + if err != nil { + return anthropic.BetaToolResultBlockParamContentUnion{}, fmt.Errorf("failed to parse tool input: %w", err) + } + return t.handler(ctx, parsed) +} + +// parse validates and parses the input according to the tool's schema. +// This method handles special cases for json.RawMessage and []byte type parameters. +func (t *betaTool[T]) parse(input json.RawMessage) (T, error) { + var parsed T + + switch any(parsed).(type) { + case json.RawMessage: + // If T is json.RawMessage, return the input as is + if result, ok := any(input).(T); ok { + return result, nil + } + return parsed, fmt.Errorf("type assertion failed for json.RawMessage") + case []byte: + // If T is []byte, return the raw JSON input as bytes + if result, ok := any([]byte(input)).(T); ok { + return result, nil + } + return parsed, fmt.Errorf("type assertion failed for []byte") + default: + // For all other types (structs), unmarshal the input + if err := json.Unmarshal(input, &parsed); err != nil { + return parsed, err + } + return parsed, nil + } +} + +func parseSchemaMap(s map[string]any) (anthropic.BetaToolInputSchemaParam, error) { + bytes, err := json.Marshal(s) + if err != nil { + return anthropic.BetaToolInputSchemaParam{}, fmt.Errorf("failed to marshal schema: %w", err) + } + + var schema anthropic.BetaToolInputSchemaParam + if err := json.Unmarshal(bytes, &schema); err != nil { + return anthropic.BetaToolInputSchemaParam{}, fmt.Errorf("failed to unmarshal schema: %w", err) + } + + return schema, nil +} + +// NewBetaToolFromBytes creates a BetaTool from JSON schema bytes. +func NewBetaToolFromBytes[T any]( + name, description string, + schemaJSON []byte, + handler func(context.Context, T) (anthropic.BetaToolResultBlockParamContentUnion, error), +) (anthropic.BetaTool, error) { + var schema anthropic.BetaToolInputSchemaParam + if err := schema.UnmarshalJSON(schemaJSON); err != nil { + return nil, fmt.Errorf("failed to unmarshal schema: %w", err) + } + return NewBetaTool(name, description, schema, handler), nil +} + +// NewBetaToolFromJSONSchema creates a BetaTool by inferring the schema from struct type T using reflection. +// The struct should use jsonschema tags to define the schema (e.g., `jsonschema:"required,description=..."`). +func NewBetaToolFromJSONSchema[T any]( + name, description string, + handler func(context.Context, T) (anthropic.BetaToolResultBlockParamContentUnion, error), +) (anthropic.BetaTool, error) { + var zeroValue T + reflector := jsonschema.Reflector{ + AllowAdditionalProperties: false, + RequiredFromJSONSchemaTags: true, + DoNotReference: true, + } + + schema := reflector.Reflect(zeroValue) + + schemaBytes, err := json.Marshal(schema) + if err != nil { + return nil, err + } + var schemaMap map[string]any + if err := json.Unmarshal(schemaBytes, &schemaMap); err != nil { + return nil, err + } + + inputSchema, err := parseSchemaMap(schemaMap) + if err != nil { + return nil, err + } + + return NewBetaTool(name, description, inputSchema, handler), nil +} + +// NewBetaTool creates a BetaTool with a BetaToolInputSchemaParam directly. +func NewBetaTool[T any]( + name, description string, + schema anthropic.BetaToolInputSchemaParam, + handler func(context.Context, T) (anthropic.BetaToolResultBlockParamContentUnion, error), +) anthropic.BetaTool { + return &betaTool[T]{ + name: name, + description: description, + schema: schema, + handler: handler, + } +} diff --git a/tools.md b/tools.md new file mode 100644 index 000000000..53b576992 --- /dev/null +++ b/tools.md @@ -0,0 +1,292 @@ +# Tool Helpers + +The SDK provides helper functions for defining tools and automatically running the conversation loop between Claude and your tools until Claude produces a final response. + +## Defining Tools + +Use the `toolrunner` package to create a `BetaTool` that combines the tool definition with its execution handler. There are three ways to create tools: + +- `NewBetaToolFromJSONSchema` - Automatically generates schema from a struct with `jsonschema` tags (recommended) +- `NewBetaToolFromBytes` - Creates a tool from JSON schema bytes +- `NewBetaTool` - Creates a tool from an explicit `BetaToolInputSchemaParam` + +The generic type parameter is automatically inferred from your handler function's signature, so you don't need to specify it explicitly. + +### Automatic Schema Generation from Structs (Recommended) + +The easiest approach is to use `NewBetaToolFromJSONSchema`, which automatically generates the schema from your struct using `jsonschema` tags: + +```go +type GetWeatherInput struct { + City string `json:"city" jsonschema:"required,description=The city name"` + Units string `json:"units,omitempty" jsonschema:"enum=celsius,enum=fahrenheit,description=Temperature units"` +} + +weatherTool, err := toolrunner.NewBetaToolFromJSONSchema( + "get_weather", + "Get current weather for a city", + func(ctx context.Context, input GetWeatherInput) (anthropic.BetaToolResultBlockParamContentUnion, error) { + return anthropic.BetaToolResultBlockParamContentUnion{ + OfText: &anthropic.BetaTextBlockParam{ + Text: fmt.Sprintf("Weather in %s: 72°F, sunny", input.City), + }, + }, nil + }, +) +``` + +### Using JSON Bytes + +You can provide the schema as JSON bytes using `NewBetaToolFromBytes`: + +```go +type GetWeatherInput struct { + City string `json:"city"` +} + +weatherTool, err := toolrunner.NewBetaToolFromBytes( + "get_weather", + "Get current weather for a city", + []byte(`{ + "type": "object", + "properties": { + "city": {"type": "string", "description": "The city name"} + }, + "required": ["city"] + }`), + func(ctx context.Context, input GetWeatherInput) (anthropic.BetaToolResultBlockParamContentUnion, error) { + // Your handler here + }, +) +``` + +### Using an Explicit Schema + +For full control, use `NewBetaTool` with a `BetaToolInputSchemaParam` directly: + +```go +weatherTool := toolrunner.NewBetaTool( + "get_weather", + "Get current weather for a city", + anthropic.BetaToolInputSchemaParam{ + Properties: map[string]any{ + "city": map[string]any{ + "type": "string", + "description": "The city name", + }, + }, + }, + handler, +) +``` + +### Raw JSON Input + +If you prefer to handle JSON parsing yourself, use `json.RawMessage` or `[]byte` as the input type: + +```go +rawTool, err := toolrunner.NewBetaToolFromBytes( + "process_data", + "Process raw JSON data", + schemaBytes, + func(ctx context.Context, input json.RawMessage) (anthropic.BetaToolResultBlockParamContentUnion, error) { + // Parse the JSON yourself + var data map[string]any + json.Unmarshal(input, &data) + // ... + }, +) + +## Tool Runner + +The `BetaToolRunner` automatically handles the conversation loop between Claude and your tools. On each iteration, it: + +1. Sends the current messages to Claude +2. If Claude responds with tool calls, executes them in parallel +3. Adds the tool results to the conversation +4. Repeats until Claude produces a final response (no tool calls) + +### Basic Usage + +```go +tools := []anthropic.BetaTool{weatherTool} + +runner := client.Beta.Messages.NewToolRunner(tools, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaudeSonnet4_20250514, + MaxTokens: 1024, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What's the weather in Tokyo?")), + }, + }, +}) + +// Run the entire conversation to completion +message, err := runner.RunToCompletion(context.Background()) +``` + +### Iterating Over Messages + +Use `All()` to iterate over each message in the conversation: + +```go +for message, err := range runner.All(ctx) { + if err != nil { + log.Fatal(err) + } + for _, block := range message.Content { + switch b := block.AsAny().(type) { + case anthropic.BetaTextBlock: + fmt.Println("[assistant]:", b.Text) + case anthropic.BetaToolUseBlock: + fmt.Printf("[tool call]: %s(%v)\n", b.Name, b.Input) + } + } +} +``` + +### Step-by-Step Iteration + +For more control, use `NextMessage()` to advance one turn at a time: + +```go +for { + message, err := runner.NextMessage(ctx) + if err != nil { + log.Fatal(err) + } + if message == nil { + break // Conversation complete + } + // Process the message... +} +``` + +### Streaming + +Use `BetaToolRunnerStreaming` via `NewToolRunnerStreaming()` for streaming responses: + +```go +runner := client.Beta.Messages.NewToolRunnerStreaming(tools, anthropic.BetaToolRunnerParams{ + BetaMessageNewParams: anthropic.BetaMessageNewParams{ + Model: anthropic.ModelClaudeSonnet4_20250514, + MaxTokens: 1024, + Messages: []anthropic.BetaMessageParam{ + anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What's the weather in Tokyo?")), + }, + }, +}) + +for eventsIterator := range runner.AllStreaming(ctx) { + for event, err := range eventsIterator { + if err != nil { + log.Fatal(err) + } + switch e := event.AsAny().(type) { + case anthropic.BetaRawContentBlockDeltaEvent: + switch delta := e.Delta.AsAny().(type) { + case anthropic.BetaTextDelta: + fmt.Print(delta.Text) + } + } + } +} +``` + +Or use `NextStreaming()` for step-by-step streaming: + +```go +for !runner.IsCompleted() { + for event, err := range runner.NextStreaming(ctx) { + // Handle streaming events... + } +} +``` + +## Configuration + +### Max Iterations + +Limit the number of API calls to prevent runaway loops. When set to 0 (the default), there is no limit and the runner continues until the model stops using tools: + +```go +runner := client.Beta.Messages.NewToolRunner(tools, anthropic.BetaToolRunnerParams{ + // ... + MaxIterations: 10, // Stop after 10 API calls (0 = no limit) +}) +``` + +### Modifying Parameters Mid-Conversation + +The `Params` field is exported, so you can modify parameters directly: + +```go +// Update maximum tokens +runner.Params.MaxTokens = 2048 + +// Update maximum iterations +runner.Params.MaxIterations = 10 + +// Update system prompt +runner.Params.System = []anthropic.BetaTextBlockParam{ + {Text: "You are a helpful assistant."}, +} + +// Add messages to the conversation (direct field access) +runner.Params.Messages = append(runner.Params.Messages, anthropic.NewBetaUserMessage( + anthropic.NewBetaTextBlock("Now check the weather in London too"), +)) + +// Or use the convenience method +runner.AppendMessages(anthropic.NewBetaUserMessage( + anthropic.NewBetaTextBlock("Now check the weather in London too"), +)) +``` + +### Inspecting State + +```go +// Get most recent assistant message +lastMsg := runner.LastMessage() + +// Get full conversation history (returns a copy) +messages := runner.Messages() + +// Check iteration count +count := runner.IterationCount() + +// Check if completed +if runner.IsCompleted() { + // ... +} +``` + +## Error Handling + +Tool execution errors are automatically converted to error results and sent back to Claude, allowing it to recover or try a different approach: + +```go +func handler(ctx context.Context, input MyInput) (anthropic.BetaToolResultBlockParamContentUnion, error) { + if input.City == "" { + return anthropic.BetaToolResultBlockParamContentUnion{}, errors.New("city is required") + } + // ... +} +``` + +The error message will be sent to Claude as a tool result with `is_error: true`. + +## Parallel Tool Execution + +When Claude requests multiple tool calls in a single message, they are executed in parallel using an `errgroup`. This provides: + +- Concurrent execution for better performance +- Proper context cancellation handling +- Results returned in the correct order + +## Examples + +See the [examples](./examples) directory for complete working examples: + +- [examples/tool-runner](./examples/tool-runner) - Basic tool runner usage +- [examples/tool-runner-streaming](./examples/tool-runner-streaming) - Streaming with tool runner diff --git a/usage_test.go b/usage_test.go index b1bfcfcf5..efd04fe14 100644 --- a/usage_test.go +++ b/usage_test.go @@ -28,13 +28,13 @@ func TestUsage(t *testing.T) { MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ - OfText: &anthropic.TextBlockParam{Text: "What is a quaternion?", CacheControl: anthropic.CacheControlEphemeralParam{TTL: anthropic.CacheControlEphemeralTTLTTL5m}, Citations: []anthropic.TextCitationParamUnion{{ - OfCharLocation: &anthropic.CitationCharLocationParam{CitedText: "cited_text", DocumentIndex: 0, DocumentTitle: anthropic.String("x"), EndCharIndex: 0, StartCharIndex: 0}, - }}}, + OfText: &anthropic.TextBlockParam{ + Text: "x", + }, }}, Role: anthropic.MessageParamRoleUser, }}, - Model: anthropic.ModelClaude3_7SonnetLatest, + Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err != nil { t.Fatalf("err should be nil: %s", err.Error())