Repository: anthropics/anthropic-sdk-go Branch: main Commit: 017d9ffaa3f1 Files: 164 Total size: 1.8 MB Directory structure: gitextract_ngkaakcw/ ├── .devcontainer/ │ └── devcontainer.json ├── .github/ │ ├── CODEOWNERS │ └── workflows/ │ ├── ci.yml │ ├── claude.yml │ ├── create-releases.yml │ └── detect-breaking-changes.yml ├── .gitignore ├── .release-please-manifest.json ├── .stats.yml ├── Brewfile ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── aliases.go ├── api.md ├── bedrock/ │ ├── bedrock.go │ └── bedrock_test.go ├── beta.go ├── betafile.go ├── betafile_test.go ├── betamessage.go ├── betamessage_test.go ├── betamessagebatch.go ├── betamessagebatch_test.go ├── betamessageutil.go ├── betamodel.go ├── betamodel_test.go ├── betaskill.go ├── betaskill_test.go ├── betaskillversion.go ├── betaskillversion_test.go ├── betatoolrunner.go ├── client.go ├── client_test.go ├── completion.go ├── completion_test.go ├── examples/ │ ├── .keep │ ├── bedrock/ │ │ └── main.go │ ├── bedrock-bearer-token/ │ │ └── main.go │ ├── bedrock-streaming/ │ │ └── main.go │ ├── file-upload/ │ │ ├── file.txt │ │ └── main.go │ ├── go.mod │ ├── go.sum │ ├── message/ │ │ └── main.go │ ├── message-mcp-streaming/ │ │ └── main.go │ ├── message-streaming/ │ │ └── main.go │ ├── multimodal/ │ │ └── main.go │ ├── structured-outputs/ │ │ └── main.go │ ├── tool-runner/ │ │ └── main.go │ ├── tool-runner-streaming/ │ │ └── main.go │ ├── tools/ │ │ └── main.go │ ├── tools-streaming/ │ │ └── main.go │ ├── tools-streaming-jsonschema/ │ │ └── main.go │ ├── vertex/ │ │ └── main.go │ └── vertex-streaming/ │ └── main.go ├── field.go ├── go.mod ├── go.sum ├── internal/ │ ├── apierror/ │ │ └── apierror.go │ ├── apiform/ │ │ ├── encoder.go │ │ ├── form.go │ │ ├── form_test.go │ │ ├── richparam.go │ │ └── tag.go │ ├── apijson/ │ │ ├── decodeparam_test.go │ │ ├── decoder.go │ │ ├── decoderesp_test.go │ │ ├── encoder.go │ │ ├── enum.go │ │ ├── enum_test.go │ │ ├── field.go │ │ ├── json_test.go │ │ ├── port.go │ │ ├── port_test.go │ │ ├── registry.go │ │ ├── subfield.go │ │ ├── tag.go │ │ └── union.go │ ├── apiquery/ │ │ ├── encoder.go │ │ ├── query.go │ │ ├── query_test.go │ │ ├── richparam.go │ │ └── tag.go │ ├── encoding/ │ │ └── json/ │ │ ├── decode.go │ │ ├── encode.go │ │ ├── fold.go │ │ ├── indent.go │ │ ├── scanner.go │ │ ├── sentinel/ │ │ │ ├── null.go │ │ │ └── sentinel_test.go │ │ ├── shims/ │ │ │ └── shims.go │ │ ├── stream.go │ │ ├── tables.go │ │ ├── tags.go │ │ └── time.go │ ├── paramutil/ │ │ ├── field.go │ │ └── union.go │ ├── requestconfig/ │ │ ├── requestconfig.go │ │ └── requestconfig_test.go │ ├── testutil/ │ │ ├── golden.go │ │ ├── testutil.go │ │ └── vcr.go │ └── version.go ├── lib/ │ └── .keep ├── message.go ├── message_test.go ├── messagebatch.go ├── messagebatch_test.go ├── messageutil.go ├── messageutil_test.go ├── model.go ├── model_test.go ├── option/ │ ├── middleware.go │ └── requestoption.go ├── packages/ │ ├── jsonl/ │ │ └── jsonl.go │ ├── pagination/ │ │ └── pagination.go │ ├── param/ │ │ ├── encoder.go │ │ ├── encoder_test.go │ │ ├── null.go │ │ ├── null_test.go │ │ ├── option.go │ │ └── param.go │ ├── respjson/ │ │ ├── decoder_test.go │ │ └── respjson.go │ └── ssestream/ │ └── ssestream.go ├── paginationauto_test.go ├── paginationmanual_test.go ├── release-please-config.json ├── schemautil.go ├── schemautil_test.go ├── scripts/ │ ├── bootstrap │ ├── detect-breaking-changes │ ├── format │ ├── lint │ ├── mock │ ├── test │ └── utils/ │ └── upload-artifact.sh ├── shared/ │ ├── constant/ │ │ └── constants.go │ └── shared.go ├── toolrunner/ │ ├── runner_test.go │ ├── testdata/ │ │ ├── cassettes/ │ │ │ ├── tool_runner_basic.yaml │ │ │ ├── tool_runner_concurrent.yaml │ │ │ ├── tool_runner_context_cancel.yaml │ │ │ ├── tool_runner_custom_handling.yaml │ │ │ ├── tool_runner_max_iterations.yaml │ │ │ ├── tool_runner_next_message.yaml │ │ │ ├── tool_runner_next_streaming.yaml │ │ │ ├── tool_runner_run_to_completion.yaml │ │ │ ├── tool_runner_streaming_all.yaml │ │ │ └── tool_runner_tool_call_error.yaml │ │ └── snapshots/ │ │ ├── tool_runner_basic.golden │ │ ├── tool_runner_next_message_step_1.golden │ │ ├── tool_runner_next_message_step_2.golden │ │ ├── tool_runner_next_streaming_types.golden │ │ ├── tool_runner_run_to_completion.golden │ │ ├── tool_runner_streaming_all.golden │ │ └── tool_runner_tool_call_error_assistant.golden │ └── tool.go ├── tools.md ├── usage_test.go └── vertex/ └── vertex.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .devcontainer/devcontainer.json ================================================ // For format details, see https://aka.ms/devcontainer.json. For config options, see the // README at: https://github.com/devcontainers/templates/tree/main/src/debian { "name": "Development", "image": "mcr.microsoft.com/devcontainers/go:1.23-bookworm", "postCreateCommand": "go mod tidy" } ================================================ FILE: .github/CODEOWNERS ================================================ # This file is used to automatically assign reviewers to PRs # For more information see: https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners * @anthropics/sdk ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: push: branches: - '**' - '!integrated/**' - '!stl-preview-head/**' - '!stl-preview-base/**' - '!generated' - '!codegen/**' - 'codegen/stl/**' pull_request: branches-ignore: - 'stl-preview-head/**' - 'stl-preview-base/**' jobs: build: timeout-minutes: 10 name: build permissions: contents: read id-token: write runs-on: ${{ github.repository == 'stainless-sdks/anthropic-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: |- github.repository == 'stainless-sdks/anthropic-go' && (github.event_name == 'push' || github.event.pull_request.head.repo.fork) steps: - uses: actions/checkout@v6 - name: Get GitHub OIDC Token if: |- github.repository == 'stainless-sdks/anthropic-go' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); - name: Upload tarball if: |- github.repository == 'stainless-sdks/anthropic-go' && !startsWith(github.ref, 'refs/heads/stl/') env: URL: https://pkg.stainless.com/s AUTH: ${{ steps.github-oidc.outputs.github_token }} SHA: ${{ github.sha }} run: ./scripts/utils/upload-artifact.sh lint: timeout-minutes: 10 name: lint 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@v6 - name: Setup go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Run lints run: ./scripts/lint test: timeout-minutes: 10 name: test 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@v6 - name: Setup go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Bootstrap run: ./scripts/bootstrap - name: Run tests run: ./scripts/test ================================================ FILE: .github/workflows/claude.yml ================================================ 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:*)' ================================================ FILE: .github/workflows/create-releases.yml ================================================ name: Create releases on: schedule: - cron: '0 5 * * *' # every day at 5am UTC push: branches: - main jobs: release: name: release if: github.ref == 'refs/heads/main' && github.repository == 'anthropics/anthropic-sdk-go' runs-on: ubuntu-latest environment: production-release steps: - uses: actions/checkout@v6 - uses: stainless-api/trigger-release-please@v1 id: release with: repo: ${{ github.event.repository.full_name }} stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} - name: Generate godocs if: ${{ steps.release.outputs.releases_created }} run: | # x-release-please-start-version version=$(jq -r '. | to_entries[0] | .value' .release-please-manifest.json) curl -X POST https://pkg.go.dev/fetch/github.com/anthropics/anthropic-sdk-go@v${version} # x-release-please-end ================================================ FILE: .github/workflows/detect-breaking-changes.yml ================================================ name: CI on: pull_request: branches: - main - next jobs: detect_breaking_changes: runs-on: 'ubuntu-latest' name: detect-breaking-changes if: github.repository == 'anthropics/anthropic-sdk-go' steps: - name: Calculate fetch-depth run: | echo "FETCH_DEPTH=$(expr ${{ github.event.pull_request.commits }} + 1)" >> $GITHUB_ENV - uses: actions/checkout@v6 with: # Ensure we can check out the pull request base in the script below. fetch-depth: ${{ env.FETCH_DEPTH }} - name: Setup go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Detect breaking changes run: | # Try to check out previous versions of the breaking change detection script. This ensures that # we still detect breaking changes when entire files and their tests are removed. git checkout "${{ github.event.pull_request.base.sha }}" -- ./scripts/detect-breaking-changes 2>/dev/null || true ./scripts/detect-breaking-changes ${{ github.event.pull_request.base.sha }} ================================================ FILE: .gitignore ================================================ .prism.log codegen.log Brewfile.lock.json .idea/ ================================================ FILE: .release-please-manifest.json ================================================ { ".": "1.27.1" } ================================================ FILE: .stats.yml ================================================ configured_endpoints: 34 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-dd2dcd00a757075370a7e4a7f469a1e2d067c2118684c3b70d7906a8f5cf518b.yml openapi_spec_hash: ebeeaa9a9bf7603f0bbcce30389e27ca config_hash: f292746941a1c02183ee7646c37753af ================================================ FILE: Brewfile ================================================ brew "go" ================================================ FILE: CHANGELOG.md ================================================ # Changelog ## 1.27.1 (2026-03-18) Full Changelog: [v1.27.0...v1.27.1](https://github.com/anthropics/anthropic-sdk-go/compare/v1.27.0...v1.27.1) ### Chores * **internal:** regenerate SDK with no functional changes ([c963fd0](https://github.com/anthropics/anthropic-sdk-go/commit/c963fd0fd1e591bfd572f100a3a444ba40fe4ad4)) * **internal:** tweak CI branches ([95e3410](https://github.com/anthropics/anthropic-sdk-go/commit/95e3410a6892afae8b1b4631d05b5bfd4bf12eb2)) ## 1.27.0 (2026-03-16) Full Changelog: [v1.26.0...v1.27.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.26.0...v1.27.0) ### Features * **api:** change array_format to brackets ([ca5ae6e](https://github.com/anthropics/anthropic-sdk-go/commit/ca5ae6eaf8243aece877d33eb88653db2e439a36)) * **api:** chore(config): clean up model enum list ([#31](https://github.com/anthropics/anthropic-sdk-go/issues/31)) ([1db4ea7](https://github.com/anthropics/anthropic-sdk-go/commit/1db4ea7956259bb217bc2523a5244b6029c4bd15)) * **api:** GA thinking-display-setting ([1924af2](https://github.com/anthropics/anthropic-sdk-go/commit/1924af22e00fad68ccf31a3809c8cab8d442c048)) * **api:** remove publishing section from cli target ([514282e](https://github.com/anthropics/anthropic-sdk-go/commit/514282e1728881f7ef4c6782f3000ca0ec632d53)) * **tests:** update mock server ([cf24ced](https://github.com/anthropics/anthropic-sdk-go/commit/cf24ced2844da5d0f645e7a2afbabb936c891892)) ### Bug Fixes * allow canceling a request while it is waiting to retry ([32ee053](https://github.com/anthropics/anthropic-sdk-go/commit/32ee05317970d99df3147c65c2055efabe354472)) * **client:** update model reference from claude-3-7-sonnet-latest to claude-sonnet-4-5 ([2f42e73](https://github.com/anthropics/anthropic-sdk-go/commit/2f42e7336295d898d18c66ddd6f9f70bab108cc6)) ### Chores * **client:** reorganize code in Messages files to lead to less conflicts ([c677bb5](https://github.com/anthropics/anthropic-sdk-go/commit/c677bb58a3da8f17f0dbc630b5b28faed995aa6b)) * **internal:** codegen related update ([c978aac](https://github.com/anthropics/anthropic-sdk-go/commit/c978aacf53bbcf6555ba97bdc6bdfc9be9d8f98d)) * **internal:** codegen related update ([4ac31a2](https://github.com/anthropics/anthropic-sdk-go/commit/4ac31a2fb9dc45a41bcbaa25dfbf8848119768ec)) * **internal:** codegen related update ([5b2b2fa](https://github.com/anthropics/anthropic-sdk-go/commit/5b2b2fa276ad9365ddcb53270f307db05e5b6363)) * **internal:** codegen related update ([9678c6c](https://github.com/anthropics/anthropic-sdk-go/commit/9678c6c5d375f66cb569a537a0766a5ed4d8f7f0)) * **internal:** codegen related update ([f6035d2](https://github.com/anthropics/anthropic-sdk-go/commit/f6035d2bb0c50cf97cea78fb3fe854289b11a34c)) * **internal:** codegen related update ([9246bbb](https://github.com/anthropics/anthropic-sdk-go/commit/9246bbb15553cee531b5caef2c7876e84a8fe8f2)) * **internal:** move custom custom `json` tags to `api` ([4392627](https://github.com/anthropics/anthropic-sdk-go/commit/4392627107c43726c242923c16b0f5ac2b432082)) * **tests:** unskip tests that are now supported in steady ([b0ca374](https://github.com/anthropics/anthropic-sdk-go/commit/b0ca37403486c65ae171d2b330ff82c938fe9b58)) ### Documentation * streamline README, centralize documentation at docs.anthropic.com ([33f6943](https://github.com/anthropics/anthropic-sdk-go/commit/33f69431abd96025134d8967c20a1f313af3382d)), closes [#587](https://github.com/anthropics/anthropic-sdk-go/issues/587) ## 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) ### Features * **api:** manual updates ([3eac8aa](https://github.com/anthropics/anthropic-sdk-go/commit/3eac8aaee0dbb3f4a5e30b039d60503614365a82)) ### Chores * **client:** add context-management-2025-06-27 beta header ([eeba6fa](https://github.com/anthropics/anthropic-sdk-go/commit/eeba6fa95ca9eedf16897b413950fc5f80d0d8cb)) * **client:** add model-context-window-exceeded-2025-08-26 beta header ([7d5a37d](https://github.com/anthropics/anthropic-sdk-go/commit/7d5a37d895b769739d23b6e91f6c0a806cade710)) ## 1.13.0 (2025-09-29) Full Changelog: [v1.12.0...v1.13.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.12.0...v1.13.0) ### Features * **api:** adds support for Claude Sonnet 4.5 and context management features ([3d5d51a](https://github.com/anthropics/anthropic-sdk-go/commit/3d5d51ad6ee64b34c7cc361a9dfd6f45966987dd)) ### Bug Fixes * bugfix for setting JSON keys with special characters ([c868b92](https://github.com/anthropics/anthropic-sdk-go/commit/c868b921190f8d371cc93d12e019daf5a7463306)) * **internal:** unmarshal correctly when there are multiple discriminators ([ecc3ce3](https://github.com/anthropics/anthropic-sdk-go/commit/ecc3ce31a9ed98b8f2b66b5e1489fce510528f77)) * use slices.Concat instead of sometimes modifying r.Options ([88e7186](https://github.com/anthropics/anthropic-sdk-go/commit/88e7186cad944290498a3381c829df36d26a1cce)) ### Chores * bump minimum go version to 1.22 ([87af8f3](https://github.com/anthropics/anthropic-sdk-go/commit/87af8f397ae68ce72a76a07a735d21495aad8799)) * do not install brew dependencies in ./scripts/bootstrap by default ([c689348](https://github.com/anthropics/anthropic-sdk-go/commit/c689348cc4b5ec7ab3512261e4e3cc50d208a02c)) * **internal:** fix tests ([bfc6eaf](https://github.com/anthropics/anthropic-sdk-go/commit/bfc6eafeff58664f0d6f155f96286f3993e60f89)) * update more docs for 1.22 ([d67c50d](https://github.com/anthropics/anthropic-sdk-go/commit/d67c50d49082b4b28bdabc44943853431cd5205c)) ## 1.12.0 (2025-09-10) Full Changelog: [v1.11.0...v1.12.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.11.0...v1.12.0) ### Features * **api:** adds support for web_fetch_20250910 tool ([6d5e237](https://github.com/anthropics/anthropic-sdk-go/commit/6d5e2370e14e1d125ebebcf741b721e88dc0e810)) ### Chores * tmp ([07b65e9](https://github.com/anthropics/anthropic-sdk-go/commit/07b65e9b178a1c280fc96e3f2a7bf30bd9932329)) ## 1.11.0 (2025-09-05) Full Changelog: [v1.10.0...v1.11.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.10.0...v1.11.0) ### Features * **api:** adds support for Documents in tool results ([7161c2c](https://github.com/anthropics/anthropic-sdk-go/commit/7161c2ce9843b80374186dc83fd84a8dfebda45f)) ### Bug Fixes * **client:** fix issue in Go with nested document content params ([b442cc3](https://github.com/anthropics/anthropic-sdk-go/commit/b442cc3fd41ee53a18f8ccec868ae1057dae53a8)) * use release please annotations on more places ([31a09b0](https://github.com/anthropics/anthropic-sdk-go/commit/31a09b07991cc92d38517c80320d154246779a76)) ## 1.10.0 (2025-09-02) Full Changelog: [v1.9.1...v1.10.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.9.1...v1.10.0) ### Features * **api:** makes 1 hour TTL Cache Control generally available ([c28a9a3](https://github.com/anthropics/anthropic-sdk-go/commit/c28a9a3272acb1973f2a2fb768157ab27a8f440d)) * **client:** adds support for code-execution-2025-08-26 tool ([066a126](https://github.com/anthropics/anthropic-sdk-go/commit/066a126a92a8e09f10742f13e0db36724a96c788)) * use custom decoder for []ContentBlockParamUnion ([#464](https://github.com/anthropics/anthropic-sdk-go/issues/464)) ([4731597](https://github.com/anthropics/anthropic-sdk-go/commit/473159792468018c709da311d7ac27139cf851e6)) ### Bug Fixes * close body before retrying ([c970e10](https://github.com/anthropics/anthropic-sdk-go/commit/c970e10ff45c04c38a5a2c87fe85a8c191e06f80)) ### Chores * deprecate older claude-3-5 sonnet models ([#453](https://github.com/anthropics/anthropic-sdk-go/issues/453)) ([e49d59b](https://github.com/anthropics/anthropic-sdk-go/commit/e49d59b14be89dcfb858b565e5183ecf9c1e246b)) ## 1.9.1 (2025-08-12) Full Changelog: [v1.9.0...v1.9.1](https://github.com/anthropics/anthropic-sdk-go/compare/v1.9.0...v1.9.1) ## 1.9.0 (2025-08-12) Full Changelog: [v1.8.0...v1.9.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.8.0...v1.9.0) ### Features * **betas:** add context-1m-2025-08-07 ([c086118](https://github.com/anthropics/anthropic-sdk-go/commit/c086118c9acd55ec711b29a08f165b358e56332b)) ### Chores * **internal:** detect breaking changes when removing endpoints ([91ea519](https://github.com/anthropics/anthropic-sdk-go/commit/91ea5197646ffd3d807610f11bab8726092e7a4b)) * **internal:** update comment in script ([de412b0](https://github.com/anthropics/anthropic-sdk-go/commit/de412b007a097ce7d3231e0ccdf7d57572f78199)) * update @stainless-api/prism-cli to v5.15.0 ([555556f](https://github.com/anthropics/anthropic-sdk-go/commit/555556f4ce77d406e904733b30c782039dacb837)) ## 1.8.0 (2025-08-08) Full Changelog: [v1.7.0...v1.8.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.7.0...v1.8.0) ### Features * **api:** search result content blocks ([0907804](https://github.com/anthropics/anthropic-sdk-go/commit/0907804ae58405abc4f4c0acb76464da3abdd00b)) * **client:** support optional json html escaping ([8da877c](https://github.com/anthropics/anthropic-sdk-go/commit/8da877cb04c62d081d36a1f8cb5eea7922a396ce)) ## 1.7.0 (2025-08-05) Full Changelog: [v1.6.2...v1.7.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.6.2...v1.7.0) ### Features * **api:** add claude-opus-4-1-20250805 ([72c9d29](https://github.com/anthropics/anthropic-sdk-go/commit/72c9d29255cb59d11b132062df00889a63dd609e)) * **api:** adds support for text_editor_20250728 tool ([be56278](https://github.com/anthropics/anthropic-sdk-go/commit/be56278e456ff5eb034852e17a4642be612e30a2)) * **api:** removed older deprecated models ([88a397a](https://github.com/anthropics/anthropic-sdk-go/commit/88a397acb01a7557fbd6852f85ece295a7c2a2b7)) * **docs:** add File Upload example ([bade71b](https://github.com/anthropics/anthropic-sdk-go/commit/bade71b64850e8fa4410c404f263d4252cdbb82d)) * update streaming error message to say 'required' not 'recommended' ([0fb3d30](https://github.com/anthropics/anthropic-sdk-go/commit/0fb3d30814f8aead1237283a994f405c1103aff2)) * update streaming error message to say 'required' not 'recommended' ([b23f6df](https://github.com/anthropics/anthropic-sdk-go/commit/b23f6df73098c6fe3aa599beb73973b699c4b2a4)) ### Bug Fixes * **client:** process custom base url ahead of time ([2165b1a](https://github.com/anthropics/anthropic-sdk-go/commit/2165b1ac1c78491be85fdc6b49c63ab027caeed6)) ### Chores * **client:** add TextEditor_20250429 tool ([20424fc](https://github.com/anthropics/anthropic-sdk-go/commit/20424fc340b4f10b208f5ba8ee2d2b4a6f9e546d)) * **internal:** version bump ([e03b3bd](https://github.com/anthropics/anthropic-sdk-go/commit/e03b3bdd13e207925a9da2b12b830ce9bb6ed88b)) ## 1.6.2 (2025-07-18) Full Changelog: [v1.6.1...v1.6.2](https://github.com/anthropics/anthropic-sdk-go/compare/v1.6.1...v1.6.2) ### Chores * **internal:** version bump ([defc645](https://github.com/anthropics/anthropic-sdk-go/commit/defc6458496679762e07ce8dc9838335e4bd8268)) ## 1.6.1 (2025-07-18) Full Changelog: [v1.6.0...v1.6.1](https://github.com/anthropics/anthropic-sdk-go/compare/v1.6.0...v1.6.1) ### Chores * **internal:** version bump ([459dd39](https://github.com/anthropics/anthropic-sdk-go/commit/459dd391b281273af9027a23e39b78c422dace0b)) ## 1.6.0 (2025-07-18) Full Changelog: [v1.5.0...v1.6.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.5.0...v1.6.0) ### Features * **client:** expand max streaming buffer size ([8b206e2](https://github.com/anthropics/anthropic-sdk-go/commit/8b206e2267b83af7e9f7f56f029497bd403608fe)) ### Bug Fixes * **api:** revert change to NewToolResultBlock ([b4167e7](https://github.com/anthropics/anthropic-sdk-go/commit/b4167e7b3bb80927b3f397c0b6fb00f7340272a0)) * **client:** fix default timeout logic to match other languages ([47e47f5](https://github.com/anthropics/anthropic-sdk-go/commit/47e47f54f8bd1a58413c82137713bedf88e2d4d2)) * **tests:** make sure to build examples in scripts/lint ([69bcb13](https://github.com/anthropics/anthropic-sdk-go/commit/69bcb139fcf661bff527d345e9876c26c784befc)) ### Chores * **api:** update BetaCitationSearchResultLocation ([5d040a7](https://github.com/anthropics/anthropic-sdk-go/commit/5d040a7698b11ee059c175ce4a806509a9ae8e5b)) * **internal:** fix lint script for tests ([f54301d](https://github.com/anthropics/anthropic-sdk-go/commit/f54301d9f251fa6e409852605f2d301c50d3466d)) * **internal:** restructure things to avoid conflicts ([5f1bead](https://github.com/anthropics/anthropic-sdk-go/commit/5f1bead6fd696504d63ebbbf21c1a55c707a3df7)) * lint tests ([4a64d14](https://github.com/anthropics/anthropic-sdk-go/commit/4a64d14e7988ba0c2343d7abc65f15da41bafb24)) * lint tests in subpackages ([4ae61a6](https://github.com/anthropics/anthropic-sdk-go/commit/4ae61a601cf94e459bc431e07c9b7e25557af493)) ### Documentation * model in examples ([da9d5af](https://github.com/anthropics/anthropic-sdk-go/commit/da9d5af61544a6f25d9284ee6eee25f5d1364e8a)) * model in examples ([fe2da16](https://github.com/anthropics/anthropic-sdk-go/commit/fe2da16e4bf05ee7029b1be33059bf3a4e76c300)) ## 1.5.0 (2025-07-03) Full Changelog: [v1.4.0...v1.5.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.4.0...v1.5.0) ### Features * add RequestID to API errors ([884f13b](https://github.com/anthropics/anthropic-sdk-go/commit/884f13b87969c94bd3ed1343c17c84e69b676de8)) * **api:** add support for Search Result Content Blocks ([1f6ab8a](https://github.com/anthropics/anthropic-sdk-go/commit/1f6ab8aa2f3a29ca92920545933fc028b4701d20)) * **api:** api update ([27a18f2](https://github.com/anthropics/anthropic-sdk-go/commit/27a18f25697da82de75d5800a9077353bb5319a6)) * **api:** manual updates ([926b094](https://github.com/anthropics/anthropic-sdk-go/commit/926b094724c0443e8c2d19fc2c885d296254c01a)) * **client:** add debug log helper ([e427bb3](https://github.com/anthropics/anthropic-sdk-go/commit/e427bb35859880729e16cca16499accc3bb19a1b)) * **client:** add escape hatch for null slice & maps ([9e3ded0](https://github.com/anthropics/anthropic-sdk-go/commit/9e3ded03652bfd8fc5e63095f0849995907537fb)) * **vertex:** support global region endpoint ([3c0b86d](https://github.com/anthropics/anthropic-sdk-go/commit/3c0b86dc60bd05d12e854b8ec0fac79418532c78)) ### Bug Fixes * **client:** deprecate BetaBase64PDFBlock in favor of BetaRequestDocumentBlock ([5d8fd96](https://github.com/anthropics/anthropic-sdk-go/commit/5d8fd9661585c1894aeb4e80670d577ab1cc3582)) * don't try to deserialize as json when ResponseBodyInto is []byte ([0e7ce7b](https://github.com/anthropics/anthropic-sdk-go/commit/0e7ce7b16f5af7afc94333cdef6958a08875a71d)) * **pagination:** check if page data is empty in GetNextPage ([d64dc0a](https://github.com/anthropics/anthropic-sdk-go/commit/d64dc0a334da95f82a665f9cef9f6a2f58f39878)) ### Chores * **api:** mark claude-3-opus-20240229 as deprecated ([1472af8](https://github.com/anthropics/anthropic-sdk-go/commit/1472af8504ae2f48b562e4122e641b9207240d30)) * **ci:** enable for pull requests ([cdb1340](https://github.com/anthropics/anthropic-sdk-go/commit/cdb134079026cfa467d5f0299ee5e551fb50628a)) * **ci:** only run for pushes and fork pull requests ([d7d44ff](https://github.com/anthropics/anthropic-sdk-go/commit/d7d44ffb621e183f611fabe3ac6f0df06d99d459)) * fix documentation of null map ([c79ab28](https://github.com/anthropics/anthropic-sdk-go/commit/c79ab28a977f1bbda336bfffdd9fdc7ee6adccaf)) * **internal:** add breaking change detection ([49a1855](https://github.com/anthropics/anthropic-sdk-go/commit/49a1855d3d3f107ea69dc6c4e28a82dd36a9e2af)) ### Documentation * simplify message creation syntax in README example ([#203](https://github.com/anthropics/anthropic-sdk-go/issues/203)) ([c4aef2e](https://github.com/anthropics/anthropic-sdk-go/commit/c4aef2e9c75a6cdfdfd8928bbc164b384051fc53)) * update models and non-beta ([a7bc60e](https://github.com/anthropics/anthropic-sdk-go/commit/a7bc60e1beb087c6cc0843e99d3d3e4b51b1859d)) ### Refactors * improve Error() method to avoid code duplication ([43651c2](https://github.com/anthropics/anthropic-sdk-go/commit/43651c2804801454d24674baf62e05fc9e27e366)) ## 1.4.0 (2025-06-04) Full Changelog: [v1.3.0...v1.4.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.3.0...v1.4.0) ### Features * **client:** allow overriding unions ([079149c](https://github.com/anthropics/anthropic-sdk-go/commit/079149c673981891ecd35906cd610f8d4a4b69a9)) ### Chores * **internal:** codegen related update ([853ba1f](https://github.com/anthropics/anthropic-sdk-go/commit/853ba1f46d2b6c476ee04d9c061368e708cc9e18)) ## 1.3.0 (2025-06-03) Full Changelog: [v1.2.2...v1.3.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.2.2...v1.3.0) ### Features * **client:** add support for new text_editor_20250429 tool ([b33c543](https://github.com/anthropics/anthropic-sdk-go/commit/b33c543f7dc3b74c3322b6f84c189b81f67b6154)) ## 1.2.2 (2025-06-02) Full Changelog: [v1.2.1...v1.2.2](https://github.com/anthropics/anthropic-sdk-go/compare/v1.2.1...v1.2.2) ### Bug Fixes * **client:** access subunions properly ([f29c162](https://github.com/anthropics/anthropic-sdk-go/commit/f29c1627fe94c6371937659d02f1af7b55583d60)) * fix error ([bbc002c](https://github.com/anthropics/anthropic-sdk-go/commit/bbc002ccbbf9df681201d9b8ba806c37338c0fd3)) ### Chores * make go mod tidy continue on error ([ac184b4](https://github.com/anthropics/anthropic-sdk-go/commit/ac184b4f7afee4015d133a05ce819a8dac35be52)) ## 1.2.1 (2025-05-23) Full Changelog: [v1.2.0...v1.2.1](https://github.com/anthropics/anthropic-sdk-go/compare/v1.2.0...v1.2.1) ### Chores * **examples:** clean up MCP example ([66f406a](https://github.com/anthropics/anthropic-sdk-go/commit/66f406a04b9756281e7716e9b635c3e3f29397fb)) * **internal:** fix release workflows ([6a0ff4c](https://github.com/anthropics/anthropic-sdk-go/commit/6a0ff4cad1c1b4ab6435df80fccd945d6ce07be7)) ## 1.2.0 (2025-05-22) Full Changelog: [v1.1.0...v1.2.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.1.0...v1.2.0) ### Features * **api:** add claude 4 models, files API, code execution tool, MCP connector and more ([b2e5cbf](https://github.com/anthropics/anthropic-sdk-go/commit/b2e5cbffd9d05228c2c2569974a6fa260c3f46be)) ### Bug Fixes * **tests:** fix model testing for anthropic.CalculateNonStreamingTimeout ([9956842](https://github.com/anthropics/anthropic-sdk-go/commit/995684240b77284a4590b1b9ae34a85e525d1e52)) ## 1.1.0 (2025-05-22) Full Changelog: [v1.0.0...v1.1.0](https://github.com/anthropics/anthropic-sdk-go/compare/v1.0.0...v1.1.0) ### Features * **api:** add claude 4 models, files API, code execution tool, MCP connector and more ([2740935](https://github.com/anthropics/anthropic-sdk-go/commit/2740935f444de2d46103a7c777ea75e7e214872e)) ### Bug Fixes * **tests:** fix model testing for anthropic.CalculateNonStreamingTimeout ([f1aa0a1](https://github.com/anthropics/anthropic-sdk-go/commit/f1aa0a1a32d1ca87b87a7d688daab31f2a36071c)) ## 1.0.0 (2025-05-21) Full Changelog: [v0.2.0-beta.4...v1.0.0](https://github.com/anthropics/anthropic-sdk-go/compare/v0.2.0-beta.4...v1.0.0) ### ⚠ BREAKING CHANGES * **client:** rename variant constructors * **client:** remove is present ### Features * **client:** improve variant constructor names ([227c96b](https://github.com/anthropics/anthropic-sdk-go/commit/227c96bf50e14827e112c31ad0f512354477a409)) * **client:** rename variant constructors ([078fad6](https://github.com/anthropics/anthropic-sdk-go/commit/078fad6558642a20b5fb3e82186b03c2efc0ab47)) ### Bug Fixes * **client:** correctly set stream key for multipart ([f17bfe0](https://github.com/anthropics/anthropic-sdk-go/commit/f17bfe0aac0fb8228d9cad87ccca0deb7449a824)) * **client:** don't panic on marshal with extra null field ([d67a151](https://github.com/anthropics/anthropic-sdk-go/commit/d67a151a6ef0870918c5eaf84ce996cb5b1860b7)) * **client:** elide nil citations array ([09cadec](https://github.com/anthropics/anthropic-sdk-go/commit/09cadec3c076d74bda74e67c345a1aee1fdb7ce4)) * **client:** fix bug with empty tool inputs and citation deltas in Accumulate ([f4ac348](https://github.com/anthropics/anthropic-sdk-go/commit/f4ac348658fb83485d6555c63f90920599c98d99)) * **client:** increase max stream buffer size ([18a6ccf](https://github.com/anthropics/anthropic-sdk-go/commit/18a6ccf1961922a342467800c737fa000bdd254e)) * **client:** remove is present ([385d99f](https://github.com/anthropics/anthropic-sdk-go/commit/385d99fa225c755d9af737425ad2ef4d66ad5ba9)) * **client:** resolve naming collisions in union variants ([2cb6904](https://github.com/anthropics/anthropic-sdk-go/commit/2cb69048a6b583954934bc2926186564b5c74bf6)) * **client:** use scanner for streaming ([82a2840](https://github.com/anthropics/anthropic-sdk-go/commit/82a2840ce0f8aa8bd63f7697c566f437c06bb132)) ### Chores * **examples:** remove fmt ([872e055](https://github.com/anthropics/anthropic-sdk-go/commit/872e0550171942c405786c7eedb23b8270f6e8de)) * formatting ([1ce0ee8](https://github.com/anthropics/anthropic-sdk-go/commit/1ce0ee863c5df658909d81b138dc1ebedb78844a)) * improve devcontainer setup ([9021490](https://github.com/anthropics/anthropic-sdk-go/commit/90214901d77ba57901e77d6ea31aafb06c120f2c)) ### Documentation * upgrade security note to warning ([#346](https://github.com/anthropics/anthropic-sdk-go/issues/346)) ([83e70de](https://github.com/anthropics/anthropic-sdk-go/commit/83e70decfb5da14a1ecf78402302f7f0600515ea)) ## 0.2.0-beta.4 (2025-05-18) Full Changelog: [v0.2.0-beta.3...v0.2.0-beta.4](https://github.com/anthropics/anthropic-sdk-go/compare/v0.2.0-beta.3...v0.2.0-beta.4) ### ⚠ BREAKING CHANGES * **client:** clearer array variant names * **client:** rename resp package * **client:** improve core function names * **client:** improve union variant names * **client:** improve param subunions & deduplicate types ### Features * **api:** adds web search capabilities to the Claude API ([9ca314a](https://github.com/anthropics/anthropic-sdk-go/commit/9ca314a74998f24b5f17427698a8fa709b103581)) * **api:** extract ContentBlockDelta events into their own schemas ([#165](https://github.com/anthropics/anthropic-sdk-go/issues/165)) ([6d75486](https://github.com/anthropics/anthropic-sdk-go/commit/6d75486e9f524f5511f787181106a679e3414498)) * **api:** manual updates ([d405f97](https://github.com/anthropics/anthropic-sdk-go/commit/d405f97373cd7ae863a7400441d1d79c85f0ddd5)) * **api:** manual updates ([e1326cd](https://github.com/anthropics/anthropic-sdk-go/commit/e1326cdd756beb871e939af8be8b45fd3d5fdc9a)) * **api:** manual updates ([a92a382](https://github.com/anthropics/anthropic-sdk-go/commit/a92a382976d595dd32208109b480bf26dbbdc00f)) * **api:** manual updates ([59bd507](https://github.com/anthropics/anthropic-sdk-go/commit/59bd5071282403373ddca9333fafc9efc90a16d6)) * **client:** add dynamic streaming buffer to handle large lines ([510e099](https://github.com/anthropics/anthropic-sdk-go/commit/510e099e19fa71411502650eb387f1fee79f5d0d)) * **client:** add escape hatch to omit required param fields ([#175](https://github.com/anthropics/anthropic-sdk-go/issues/175)) ([6df8184](https://github.com/anthropics/anthropic-sdk-go/commit/6df8184947d6568260fa0bc22a89a27d10eaacd0)) * **client:** add helper method to generate constant structs ([015e8bc](https://github.com/anthropics/anthropic-sdk-go/commit/015e8bc7f74582fb5a3d69021ad3d61e96d65b36)) * **client:** add support for endpoint-specific base URLs in python ([44645c9](https://github.com/anthropics/anthropic-sdk-go/commit/44645c9fd0b883db4deeb88bfee6922ec9845ace)) * **client:** add support for reading base URL from environment variable ([835e632](https://github.com/anthropics/anthropic-sdk-go/commit/835e6326b658cd40590cd8bbed0932ab219e6d2d)) * **client:** clearer array variant names ([1fdea8f](https://github.com/anthropics/anthropic-sdk-go/commit/1fdea8f9fedc470a917d12607b3b7ebe3f0f6439)) * **client:** experimental support for unmarshalling into param structs ([94c8fa4](https://github.com/anthropics/anthropic-sdk-go/commit/94c8fa41ecb4792cb7da043bde2c0f5ddafe84b0)) * **client:** improve param subunions & deduplicate types ([8daacf6](https://github.com/anthropics/anthropic-sdk-go/commit/8daacf6866e8bc706ec29e17046e53d4ed100364)) * **client:** make response union's AsAny method type safe ([#174](https://github.com/anthropics/anthropic-sdk-go/issues/174)) ([f410ed0](https://github.com/anthropics/anthropic-sdk-go/commit/f410ed025ee57a05b0cec8d72a1cb43d30e564a6)) * **client:** rename resp package ([8e7d278](https://github.com/anthropics/anthropic-sdk-go/commit/8e7d2788e9be7b954d07de731e7b27ad2e2a9e8e)) * **client:** support custom http clients ([#177](https://github.com/anthropics/anthropic-sdk-go/issues/177)) ([ff7a793](https://github.com/anthropics/anthropic-sdk-go/commit/ff7a793b43b99dc148b30e408edfdc19e19c28b2)) * **client:** support more time formats ([af2df86](https://github.com/anthropics/anthropic-sdk-go/commit/af2df86f24acbe6b9cdcc4e055c3ff754303e0ef)) * **client:** support param struct overrides ([#167](https://github.com/anthropics/anthropic-sdk-go/issues/167)) ([e0d5eb0](https://github.com/anthropics/anthropic-sdk-go/commit/e0d5eb098c6441e99d53c6d997c7bcca460a238b)) * **client:** support unions in query and forms ([#171](https://github.com/anthropics/anthropic-sdk-go/issues/171)) ([6bf1ce3](https://github.com/anthropics/anthropic-sdk-go/commit/6bf1ce36f0155dba20afd4b63bf96c4527e2baa5)) ### Bug Fixes * **client:** clean up reader resources ([2234386](https://github.com/anthropics/anthropic-sdk-go/commit/223438673ade3be3435bebf7063fd34ddf3dfb8e)) * **client:** correctly update body in WithJSONSet ([f531c77](https://github.com/anthropics/anthropic-sdk-go/commit/f531c77c15859b1f2e61d654f4d9956cdfafa082)) * **client:** deduplicate stop reason type ([#155](https://github.com/anthropics/anthropic-sdk-go/issues/155)) ([0f985ad](https://github.com/anthropics/anthropic-sdk-go/commit/0f985ad54ef47849d7d478c84d34c7350a4349b5)) * **client:** fix bug where types occasionally wouldn't generate ([8988713](https://github.com/anthropics/anthropic-sdk-go/commit/8988713904ce73d3c82de635d98da48b98532366)) * **client:** improve core function names ([0a2777f](https://github.com/anthropics/anthropic-sdk-go/commit/0a2777fd597a5eb74bcf6b1da48a9ff1988059de)) * **client:** improve union variant names ([92718fd](https://github.com/anthropics/anthropic-sdk-go/commit/92718fd4058fd8535fd888a56f83fc2d3ec505ef)) * **client:** include path for type names in example code ([5bbe836](https://github.com/anthropics/anthropic-sdk-go/commit/5bbe83639793878aa0ea52e8ff06b1d9ee72ed7c)) * **client:** resolve issue with optional multipart files ([e2af94c](https://github.com/anthropics/anthropic-sdk-go/commit/e2af94c840a8f9da566c781fc99c57084e490ec1)) * **client:** return error on bad custom url instead of panic ([#169](https://github.com/anthropics/anthropic-sdk-go/issues/169)) ([b086b55](https://github.com/anthropics/anthropic-sdk-go/commit/b086b55f4886474282d4e2ea9ee3495cbf25ec6b)) * **client:** support multipart encoding array formats ([#170](https://github.com/anthropics/anthropic-sdk-go/issues/170)) ([611a25a](https://github.com/anthropics/anthropic-sdk-go/commit/611a25a427fc5303bb311fa4a2fec836d55b0933)) * **client:** time format encoding fix ([d589846](https://github.com/anthropics/anthropic-sdk-go/commit/d589846c1a08ad56d639d60736e2b8e190f7f2b1)) * **client:** unmarshal responses properly ([8344a1c](https://github.com/anthropics/anthropic-sdk-go/commit/8344a1c58dd497abbed8e9e689efca544256eaa8)) * **client:** unmarshal stream events into fresh memory ([#168](https://github.com/anthropics/anthropic-sdk-go/issues/168)) ([9cc1257](https://github.com/anthropics/anthropic-sdk-go/commit/9cc1257a67340e446ac415ec9ddddded24bb1f9a)) * handle empty bodies in WithJSONSet ([0bad01e](https://github.com/anthropics/anthropic-sdk-go/commit/0bad01e40a2a4b5b376ba27513d7e16d604459d9)) * **internal:** fix type changes ([d8ef353](https://github.com/anthropics/anthropic-sdk-go/commit/d8ef3531840ac1dc0541d3b1cf0015d1db29e2b6)) * **pagination:** handle errors when applying options ([2381476](https://github.com/anthropics/anthropic-sdk-go/commit/2381476e64991e781b696890c98f78001e256b3b)) ### Chores * **ci:** add timeout thresholds for CI jobs ([335e9f0](https://github.com/anthropics/anthropic-sdk-go/commit/335e9f0af2275f1af21aa7062afb50bee81771b6)) * **ci:** only use depot for staging repos ([6818451](https://github.com/anthropics/anthropic-sdk-go/commit/68184515143aa1e4473208f794fa593668c94df4)) * **ci:** run on more branches and use depot runners ([b0ca09d](https://github.com/anthropics/anthropic-sdk-go/commit/b0ca09d1d39a8de390c47be804847a7647ca3c67)) * **client:** use new opt conversion ([#184](https://github.com/anthropics/anthropic-sdk-go/issues/184)) ([58dc74f](https://github.com/anthropics/anthropic-sdk-go/commit/58dc74f951aa6a0eb4355a0213c8695bfa7cb0ed)) * **docs:** doc improvements ([#173](https://github.com/anthropics/anthropic-sdk-go/issues/173)) ([aebe8f6](https://github.com/anthropics/anthropic-sdk-go/commit/aebe8f68afa3de4460cda6e4032c7859e13cda81)) * **docs:** document pre-request options ([8f5eb18](https://github.com/anthropics/anthropic-sdk-go/commit/8f5eb188146bd46ba990558a7e2348c8697d6405)) * **docs:** readme improvements ([#176](https://github.com/anthropics/anthropic-sdk-go/issues/176)) ([b5769ff](https://github.com/anthropics/anthropic-sdk-go/commit/b5769ffcf5ef5345659ae848b875227718ea2425)) * **docs:** update file uploads in README ([#166](https://github.com/anthropics/anthropic-sdk-go/issues/166)) ([a4a36bf](https://github.com/anthropics/anthropic-sdk-go/commit/a4a36bfbefa5a166774c23d8c5428fb55c1b4abe)) * **docs:** update respjson package name ([28910b5](https://github.com/anthropics/anthropic-sdk-go/commit/28910b57821cab670561a25bee413375187ed747)) * **internal:** expand CI branch coverage ([#178](https://github.com/anthropics/anthropic-sdk-go/issues/178)) ([900e2df](https://github.com/anthropics/anthropic-sdk-go/commit/900e2df3eb2d3e1309d85fdcf807998f701bea8a)) * **internal:** reduce CI branch coverage ([343f6c6](https://github.com/anthropics/anthropic-sdk-go/commit/343f6c6c295dc3d39f65aae481bc10969dbb5694)) * **internal:** remove CI condition ([#160](https://github.com/anthropics/anthropic-sdk-go/issues/160)) ([adfa1e2](https://github.com/anthropics/anthropic-sdk-go/commit/adfa1e2e349842aa88262af70b209d1a59dbb419)) * **internal:** update config ([#157](https://github.com/anthropics/anthropic-sdk-go/issues/157)) ([46f0194](https://github.com/anthropics/anthropic-sdk-go/commit/46f019497bd9533390c4b9f0ebee6863263ce009)) * **readme:** improve formatting ([66be9bb](https://github.com/anthropics/anthropic-sdk-go/commit/66be9bbb17ccc9d878e79b3c39605da3e2846297)) ### Documentation * remove or fix invalid readme examples ([142576c](https://github.com/anthropics/anthropic-sdk-go/commit/142576c73b4dab5b84a2bf2481506ad642ad31cc)) * update documentation links to be more uniform ([457122b](https://github.com/anthropics/anthropic-sdk-go/commit/457122b79646dc17fa8752c98dbf4991edffc548)) ## 0.2.0-beta.3 (2025-03-27) Full Changelog: [v0.2.0-beta.2...v0.2.0-beta.3](https://github.com/anthropics/anthropic-sdk-go/compare/v0.2.0-beta.2...v0.2.0-beta.3) ### Chores * add hash of OpenAPI spec/config inputs to .stats.yml ([#154](https://github.com/anthropics/anthropic-sdk-go/issues/154)) ([76b91b5](https://github.com/anthropics/anthropic-sdk-go/commit/76b91b56fbf42fe8982e7b861885db179b1bdcc5)) * fix typos ([#152](https://github.com/anthropics/anthropic-sdk-go/issues/152)) ([1cf6a6a](https://github.com/anthropics/anthropic-sdk-go/commit/1cf6a6ae25231b88d2eedbe0758f1281cbe439d8)) ## 0.2.0-beta.2 (2025-03-25) Full Changelog: [v0.2.0-beta.1...v0.2.0-beta.2](https://github.com/anthropics/anthropic-sdk-go/compare/v0.2.0-beta.1...v0.2.0-beta.2) ### Bug Fixes * **client:** use raw json for tool input ([1013c2b](https://github.com/anthropics/anthropic-sdk-go/commit/1013c2bdb87a27d2420dbe0dcadc57d1fe3589f2)) ### Chores * add request options to client tests ([#150](https://github.com/anthropics/anthropic-sdk-go/issues/150)) ([7c70ae1](https://github.com/anthropics/anthropic-sdk-go/commit/7c70ae134a345aff775694abcad255c76e7dfcba)) ## 0.2.0-beta.1 (2025-03-25) Full Changelog: [v0.2.0-alpha.13...v0.2.0-beta.1](https://github.com/anthropics/anthropic-sdk-go/compare/v0.2.0-alpha.13...v0.2.0-beta.1) ### ⚠ BREAKING CHANGES * **api:** migrate to v2 ### Features * add SKIP_BREW env var to ./scripts/bootstrap ([#137](https://github.com/anthropics/anthropic-sdk-go/issues/137)) ([4057111](https://github.com/anthropics/anthropic-sdk-go/commit/40571110129d5c66f171ead36f5d725663262bc4)) * **api:** migrate to v2 ([fcd95eb](https://github.com/anthropics/anthropic-sdk-go/commit/fcd95eb8f45d0ffedcd1e47cd0879d7e66783540)) * **client:** accept RFC6838 JSON content types ([#139](https://github.com/anthropics/anthropic-sdk-go/issues/139)) ([78d17cd](https://github.com/anthropics/anthropic-sdk-go/commit/78d17cd4122893ba62b1e14714a1da004c128344)) * **client:** allow custom baseurls without trailing slash ([#135](https://github.com/anthropics/anthropic-sdk-go/issues/135)) ([9b30fce](https://github.com/anthropics/anthropic-sdk-go/commit/9b30fce0a71a35910315e02cd3a2f2afc1fd7962)) * **client:** improve default client options support ([07f82a6](https://github.com/anthropics/anthropic-sdk-go/commit/07f82a6f9e07bf9aadf4ca150287887cb9e75bc4)) * **client:** improve default client options support ([#142](https://github.com/anthropics/anthropic-sdk-go/issues/142)) ([f261355](https://github.com/anthropics/anthropic-sdk-go/commit/f261355e497748bcb112eecb67a95d7c7c5075c0)) * **client:** support v2 ([#147](https://github.com/anthropics/anthropic-sdk-go/issues/147)) ([6b3af98](https://github.com/anthropics/anthropic-sdk-go/commit/6b3af98e02a9b6126bd715d43f83b8adf8b861e8)) ### Chores * **docs:** clarify breaking changes ([#146](https://github.com/anthropics/anthropic-sdk-go/issues/146)) ([a2586b4](https://github.com/anthropics/anthropic-sdk-go/commit/a2586b4beb2b9a0ad252e90223fbb471e6c25bc1)) * **internal:** codegen metadata ([ce0eca2](https://github.com/anthropics/anthropic-sdk-go/commit/ce0eca25c6a83fca9ececccb41faf04e74566e2d)) * **internal:** remove extra empty newlines ([#143](https://github.com/anthropics/anthropic-sdk-go/issues/143)) ([2ed1584](https://github.com/anthropics/anthropic-sdk-go/commit/2ed1584c7d80fddf2ef5143eabbd33b8f1a4603d)) ### Refactors * tidy up dependencies ([#140](https://github.com/anthropics/anthropic-sdk-go/issues/140)) ([289cc1b](https://github.com/anthropics/anthropic-sdk-go/commit/289cc1b007094421305dfc4ef01ae68bb2d50ee5)) ================================================ FILE: CONTRIBUTING.md ================================================ ## Contributing to documentation The documentation for this SDK lives at [platform.claude.com/docs/en/api/sdks/go](https://platform.claude.com/docs/en/api/sdks/go). To suggest changes, open an issue. ## Setting up the environment To set up the repository, run: ```sh $ ./scripts/bootstrap $ ./scripts/lint ``` This will install all the required dependencies and build the SDK. You can also [install go 1.22+ manually](https://go.dev/doc/install). ## Modifying/Adding code Most of the SDK is generated code. Modifications to code will be persisted between generations, but may result in merge conflicts between manual patches and changes from the generator. The generator will never modify the contents of the `lib/` and `examples/` directories. ## Adding and running examples All files in the `examples/` directory are not modified by the generator and can be freely edited or added to. ```go # add an example to examples//main.go package main func main() { // ... } ``` ```sh $ go run ./examples/ ``` ## Using the repository from source To use a local version of this library from source in another project, edit the `go.mod` with a replace directive. This can be done through the CLI with the following: ```sh $ go mod edit -replace github.com/anthropics/anthropic-sdk-go=/path/to/anthropic-sdk-go ``` ## Running tests Most tests require you to [set up a mock server](https://github.com/dgellow/steady) against the OpenAPI spec to run the tests. ```sh $ ./scripts/mock ``` ```sh $ ./scripts/test ``` ## Formatting This library uses the standard gofmt code formatter: ```sh $ ./scripts/format ``` ================================================ FILE: LICENSE ================================================ Copyright 2023 Anthropic, PBC. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Claude SDK for Go Go Reference The Claude SDK for Go provides access to the [Claude API](https://docs.anthropic.com/en/api/) from Go applications. ## Documentation Full documentation is available at **[platform.claude.com/docs/en/api/sdks/go](https://platform.claude.com/docs/en/api/sdks/go)**. ## Installation ```go import ( "github.com/anthropics/anthropic-sdk-go" // imported as anthropic ) ``` Or explicitly add the dependency: ```sh go get -u 'github.com/anthropics/anthropic-sdk-go@v1.27.1' ``` ## Getting started ```go package main import ( "context" "fmt" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/option" ) func main() { client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), // defaults to os.LookupEnv("ANTHROPIC_API_KEY") ) message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock("What is a quaternion?")), }, Model: anthropic.ModelClaudeOpus4_6, }) if err != nil { panic(err.Error()) } fmt.Printf("%+v\n", message.Content) } ``` ## Requirements Go 1.22+ ## Contributing See [CONTRIBUTING.md](./CONTRIBUTING.md). ## License This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Reporting Security Issues This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. To report a security issue, please contact the Stainless team at security@stainless.com. ## Responsible Disclosure We appreciate the efforts of security researchers and individuals who help us maintain the security of SDKs we generate. If you believe you have found a security vulnerability, please adhere to responsible disclosure practices by allowing us a reasonable amount of time to investigate and address the issue before making any information public. ## Reporting Non-SDK Related Security Issues If you encounter security issues that are not directly related to SDKs but pertain to the services or products provided by Anthropic, please follow the respective company's security reporting guidelines. ### Anthropic Terms and Policies Please contact support@anthropic.com for any questions or concerns regarding the security of our services. --- Thank you for helping us keep the SDKs and systems they interact with secure. ================================================ FILE: aliases.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic import ( "github.com/anthropics/anthropic-sdk-go/internal/apierror" "github.com/anthropics/anthropic-sdk-go/packages/param" "github.com/anthropics/anthropic-sdk-go/shared" ) // aliased to make [param.APIUnion] private when embedding type paramUnion = param.APIUnion // aliased to make [param.APIObject] private when embedding type paramObj = param.APIObject type Error = apierror.Error // This is an alias to an internal type. type APIErrorObject = shared.APIErrorObject // This is an alias to an internal type. type AuthenticationError = shared.AuthenticationError // This is an alias to an internal type. type BillingError = shared.BillingError // This is an alias to an internal type. type ErrorObjectUnion = shared.ErrorObjectUnion // This is an alias to an internal type. type ErrorResponse = shared.ErrorResponse // This is an alias to an internal type. type GatewayTimeoutError = shared.GatewayTimeoutError // This is an alias to an internal type. type InvalidRequestError = shared.InvalidRequestError // This is an alias to an internal type. type NotFoundError = shared.NotFoundError // This is an alias to an internal type. type OverloadedError = shared.OverloadedError // This is an alias to an internal type. 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 ================================================ FILE: api.md ================================================ # Shared Response Types - shared.APIErrorObject - shared.AuthenticationError - shared.BillingError - shared.ErrorObjectUnion - shared.ErrorResponse - shared.GatewayTimeoutError - shared.InvalidRequestError - shared.NotFoundError - shared.OverloadedError - shared.PermissionError - shared.RateLimitError # Messages Params Types: - anthropic.Base64ImageSourceParam - anthropic.Base64PDFSourceParam - anthropic.BashCodeExecutionOutputBlockParam - anthropic.BashCodeExecutionResultBlockParam - anthropic.BashCodeExecutionToolResultBlockParam - anthropic.BashCodeExecutionToolResultErrorCode - anthropic.BashCodeExecutionToolResultErrorParam - anthropic.CacheControlEphemeralParam - anthropic.CitationCharLocationParam - anthropic.CitationContentBlockLocationParam - anthropic.CitationPageLocationParam - 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 - anthropic.ToolParam - anthropic.ToolBash20250124Param - anthropic.ToolChoiceUnionParam - anthropic.ToolChoiceAnyParam - 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 - anthropic.ToolUnionParam - anthropic.ToolUseBlockParam - anthropic.URLImageSourceParam - anthropic.URLPDFSourceParam - anthropic.UserLocationParam - anthropic.WebFetchBlockParam - anthropic.WebFetchTool20250910Param - anthropic.WebFetchTool20260209Param - anthropic.WebFetchTool20260309Param - 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 - anthropic.ContentBlockStopEvent - anthropic.MessageDeltaEvent - anthropic.MessageStartEvent - anthropic.MessageStopEvent - anthropic.MessageStreamEventUnion - anthropic.RedactedThinkingBlock - anthropic.ServerToolCaller - anthropic.ServerToolCaller20260120 - anthropic.ServerToolUsage - anthropic.ServerToolUseBlock - anthropic.SignatureDelta - anthropic.StopReason - 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) ## Batches Response Types: - anthropic.DeletedMessageBatch - anthropic.MessageBatch - anthropic.MessageBatchCanceledResult - anthropic.MessageBatchErroredResult - anthropic.MessageBatchExpiredResult - anthropic.MessageBatchIndividualResponse - anthropic.MessageBatchRequestCounts - anthropic.MessageBatchResultUnion - anthropic.MessageBatchSucceededResult 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) # Models Response Types: - anthropic.CapabilitySupport - anthropic.ContextManagementCapability - anthropic.EffortCapability - anthropic.ModelCapabilities - anthropic.ModelInfo - anthropic.ThinkingCapability - anthropic.ThinkingTypes 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) # Beta Params Types: - anthropic.AnthropicBeta Response Types: - anthropic.BetaAPIError - anthropic.BetaAuthenticationError - anthropic.BetaBillingError - anthropic.BetaErrorUnion - anthropic.BetaErrorResponse - anthropic.BetaGatewayTimeoutError - anthropic.BetaInvalidRequestError - anthropic.BetaNotFoundError - anthropic.BetaOverloadedError - anthropic.BetaPermissionError - anthropic.BetaRateLimitError ## Models Response Types: - anthropic.BetaCapabilitySupport - anthropic.BetaContextManagementCapability - anthropic.BetaEffortCapability - anthropic.BetaModelCapabilities - anthropic.BetaModelInfo - anthropic.BetaThinkingCapability - anthropic.BetaThinkingTypes 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) ## Messages Params Types: - anthropic.BetaAllThinkingTurnsParam - anthropic.BetaBase64ImageSourceParam - anthropic.BetaBase64PDFSourceParam - anthropic.BetaBashCodeExecutionOutputBlockParam - anthropic.BetaBashCodeExecutionResultBlockParam - anthropic.BetaBashCodeExecutionToolResultBlockParam - anthropic.BetaBashCodeExecutionToolResultErrorParam - anthropic.BetaCacheControlEphemeralParam - anthropic.BetaCitationCharLocationParam - anthropic.BetaCitationContentBlockLocationParam - anthropic.BetaCitationPageLocationParam - 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 - anthropic.BetaRequestMCPServerToolConfigurationParam - anthropic.BetaRequestMCPServerURLDefinitionParam - anthropic.BetaRequestMCPToolResultBlockParam - anthropic.BetaSearchResultBlockParam - anthropic.BetaServerToolCallerParam - anthropic.BetaServerToolCaller20260120Param - anthropic.BetaServerToolUseBlockParam - anthropic.BetaSkillParams - anthropic.BetaTextBlockParam - anthropic.BetaTextCitationParamUnion - anthropic.BetaTextEditorCodeExecutionCreateResultBlockParam - anthropic.BetaTextEditorCodeExecutionStrReplaceResultBlockParam - anthropic.BetaTextEditorCodeExecutionToolResultBlockParam - anthropic.BetaTextEditorCodeExecutionToolResultErrorParam - anthropic.BetaTextEditorCodeExecutionViewResultBlockParam - anthropic.BetaThinkingBlockParam - anthropic.BetaThinkingConfigAdaptiveParam - anthropic.BetaThinkingConfigDisabledParam - anthropic.BetaThinkingConfigEnabledParam - anthropic.BetaThinkingConfigParamUnion - anthropic.BetaThinkingTurnsParam - anthropic.BetaToolParam - anthropic.BetaToolBash20241022Param - anthropic.BetaToolBash20250124Param - anthropic.BetaToolChoiceUnionParam - anthropic.BetaToolChoiceAnyParam - anthropic.BetaToolChoiceAutoParam - anthropic.BetaToolChoiceNoneParam - 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 - anthropic.BetaToolTextEditor20250728Param - anthropic.BetaToolUnionParam - anthropic.BetaToolUseBlockParam - anthropic.BetaToolUsesKeepParam - anthropic.BetaToolUsesTriggerParam - anthropic.BetaURLImageSourceParam - anthropic.BetaURLPDFSourceParam - anthropic.BetaUserLocationParam - anthropic.BetaWebFetchBlockParam - anthropic.BetaWebFetchTool20250910Param - anthropic.BetaWebFetchTool20260209Param - anthropic.BetaWebFetchTool20260309Param - anthropic.BetaWebFetchToolResultBlockParam - anthropic.BetaWebFetchToolResultErrorBlockParam - anthropic.BetaWebFetchToolResultErrorCode - anthropic.BetaWebSearchResultBlockParam - anthropic.BetaWebSearchTool20250305Param - anthropic.BetaWebSearchTool20260209Param - anthropic.BetaWebSearchToolRequestErrorParam - anthropic.BetaWebSearchToolResultBlockParam - anthropic.BetaWebSearchToolResultBlockParamContentUnion - anthropic.BetaWebSearchToolResultErrorCode Response Types: - anthropic.BetaBase64PDFSource - anthropic.BetaBashCodeExecutionOutputBlock - anthropic.BetaBashCodeExecutionResultBlock - anthropic.BetaBashCodeExecutionToolResultBlock - anthropic.BetaBashCodeExecutionToolResultError - anthropic.BetaCacheCreation - anthropic.BetaCitationCharLocation - anthropic.BetaCitationConfig - anthropic.BetaCitationContentBlockLocation - anthropic.BetaCitationPageLocation - anthropic.BetaCitationSearchResultLocation - anthropic.BetaCitationsDelta - anthropic.BetaCitationsWebSearchResultLocation - anthropic.BetaClearThinking20251015EditResponse - anthropic.BetaClearToolUses20250919EditResponse - anthropic.BetaCodeExecutionOutputBlock - anthropic.BetaCodeExecutionResultBlock - anthropic.BetaCodeExecutionToolResultBlock - 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 - anthropic.BetaMemoryTool20250818CreateCommand - anthropic.BetaMemoryTool20250818DeleteCommand - anthropic.BetaMemoryTool20250818InsertCommand - anthropic.BetaMemoryTool20250818RenameCommand - anthropic.BetaMemoryTool20250818StrReplaceCommand - anthropic.BetaMemoryTool20250818ViewCommand - anthropic.BetaMessage - anthropic.BetaMessageDeltaUsage - anthropic.BetaMessageIterationUsage - anthropic.BetaMessageTokensCount - anthropic.BetaPlainTextSource - anthropic.BetaRawContentBlockDeltaUnion - anthropic.BetaRawContentBlockDeltaEvent - anthropic.BetaRawContentBlockStartEvent - anthropic.BetaRawContentBlockStopEvent - anthropic.BetaRawMessageDeltaEvent - anthropic.BetaRawMessageStartEvent - anthropic.BetaRawMessageStopEvent - anthropic.BetaRawMessageStreamEventUnion - anthropic.BetaRedactedThinkingBlock - anthropic.BetaServerToolCaller - anthropic.BetaServerToolCaller20260120 - anthropic.BetaServerToolUsage - anthropic.BetaServerToolUseBlock - anthropic.BetaSignatureDelta - anthropic.BetaSkill - anthropic.BetaStopReason - anthropic.BetaTextBlock - anthropic.BetaTextCitationUnion - anthropic.BetaTextDelta - anthropic.BetaTextEditorCodeExecutionCreateResultBlock - anthropic.BetaTextEditorCodeExecutionStrReplaceResultBlock - anthropic.BetaTextEditorCodeExecutionToolResultBlock - anthropic.BetaTextEditorCodeExecutionToolResultError - anthropic.BetaTextEditorCodeExecutionViewResultBlock - anthropic.BetaThinkingBlock - anthropic.BetaThinkingDelta - anthropic.BetaToolReferenceBlock - anthropic.BetaToolSearchToolResultBlock - anthropic.BetaToolSearchToolResultError - anthropic.BetaToolSearchToolSearchResultBlock - anthropic.BetaToolUseBlock - anthropic.BetaUsage - anthropic.BetaWebFetchBlock - anthropic.BetaWebFetchToolResultBlock - anthropic.BetaWebFetchToolResultErrorBlock - anthropic.BetaWebFetchToolResultErrorCode - anthropic.BetaWebSearchResultBlock - anthropic.BetaWebSearchToolResultBlock - anthropic.BetaWebSearchToolResultBlockContentUnion - anthropic.BetaWebSearchToolResultError - anthropic.BetaWebSearchToolResultErrorCode 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) ### Batches Response Types: - anthropic.BetaDeletedMessageBatch - anthropic.BetaMessageBatch - anthropic.BetaMessageBatchCanceledResult - anthropic.BetaMessageBatchErroredResult - anthropic.BetaMessageBatchExpiredResult - anthropic.BetaMessageBatchIndividualResponse - anthropic.BetaMessageBatchRequestCounts - anthropic.BetaMessageBatchResultUnion - anthropic.BetaMessageBatchSucceededResult 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) ## Files Response Types: - anthropic.DeletedFile - anthropic.FileMetadata 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) ## 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) ================================================ FILE: bedrock/bedrock.go ================================================ package bedrock import ( "bytes" "context" "crypto/sha256" "encoding/base64" "encoding/hex" "encoding/json" "fmt" "io" "net/http" "net/url" "os" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream" "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" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/ssestream" ) const DefaultVersion = "bedrock-2023-05-31" var DefaultEndpoints = map[string]bool{ "/v1/complete": true, "/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"` } type eventstreamDecoder struct { eventstream.Decoder rc io.ReadCloser evt ssestream.Event err error } func (e *eventstreamDecoder) Close() error { return e.rc.Close() } func (e *eventstreamDecoder) Err() error { return e.err } func (e *eventstreamDecoder) Next() bool { if e.err != nil { return false } msg, err := e.Decoder.Decode(e.rc, nil) if err != nil { e.err = err return false } messageType := msg.Headers.Get(eventstreamapi.MessageTypeHeader) if messageType == nil { e.err = fmt.Errorf("%s event header not present", eventstreamapi.MessageTypeHeader) return false } switch messageType.String() { case eventstreamapi.EventMessageType: eventType := msg.Headers.Get(eventstreamapi.EventTypeHeader) if eventType == nil { e.err = fmt.Errorf("%s event header not present", eventstreamapi.EventTypeHeader) return false } if eventType.String() == "chunk" { chunk := eventstreamChunk{} err = json.Unmarshal(msg.Payload, &chunk) if err != nil { e.err = err return false } decoded, err := base64.StdEncoding.DecodeString(chunk.Bytes) if err != nil { e.err = err return false } e.evt = ssestream.Event{ Type: gjson.GetBytes(decoded, "type").String(), Data: decoded, } } case eventstreamapi.ExceptionMessageType: // See https://github.com/aws/aws-sdk-go-v2/blob/885de40869f9bcee29ad11d60967aa0f1b571d46/service/iotsitewise/deserializers.go#L15511C1-L15567C2 exceptionType := msg.Headers.Get(eventstreamapi.ExceptionTypeHeader) if exceptionType == nil { e.err = fmt.Errorf("%s event header not present", eventstreamapi.ExceptionTypeHeader) return false } // See https://github.com/aws/aws-sdk-go-v2/blob/885de40869f9bcee29ad11d60967aa0f1b571d46/aws/protocol/restjson/decoder_util.go#L15-L48k var errInfo struct { Code string Type string `json:"__type"` Message string } err = json.Unmarshal(msg.Payload, &errInfo) if err != nil && err != io.EOF { e.err = fmt.Errorf("received exception %s: parsing exception payload failed: %w", exceptionType.String(), err) return false } errorCode := "UnknownError" errorMessage := errorCode if ev := exceptionType.String(); len(ev) > 0 { errorCode = ev } else if len(errInfo.Code) > 0 { errorCode = errInfo.Code } else if len(errInfo.Type) > 0 { errorCode = errInfo.Type } if len(errInfo.Message) > 0 { errorMessage = errInfo.Message } e.err = fmt.Errorf("received exception %s: %s", errorCode, errorMessage) return false case eventstreamapi.ErrorMessageType: errorCode := "UnknownError" errorMessage := errorCode if header := msg.Headers.Get(eventstreamapi.ErrorCodeHeader); header != nil { errorCode = header.String() } if header := msg.Headers.Get(eventstreamapi.ErrorMessageHeader); header != nil { errorMessage = header.String() } e.err = fmt.Errorf("received error %s: %s", errorCode, errorMessage) return false } return true } func (e *eventstreamDecoder) Event() ssestream.Event { return e.evt } var ( _ ssestream.Decoder = &eventstreamDecoder{} ) func init() { ssestream.RegisterDecoder("application/vnd.amazon.eventstream", func(rc io.ReadCloser) ssestream.Decoder { return &eventstreamDecoder{rc: rc} }) } // WithLoadDefaultConfig returns a request option which loads the default config for Amazon and registers // middleware that intercepts request to the Messages API so that this SDK can be used with Amazon Bedrock. // // If you already have an [aws.Config], it is recommended that you instead call [WithConfig] directly. func WithLoadDefaultConfig(ctx context.Context, optFns ...func(*config.LoadOptions) error) option.RequestOption { cfg, err := config.LoadDefaultConfig(ctx, optFns...) if err != nil { panic(err) } return WithConfig(cfg) } // 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), ) }) } func bedrockMiddleware(signer *v4.Signer, cfg aws.Config) option.Middleware { return func(r *http.Request, next option.MiddlewareNext) (res *http.Response, err error) { var body []byte if r.Body != nil { body, err = io.ReadAll(r.Body) if err != nil { return nil, err } r.Body.Close() if !gjson.GetBytes(body, "anthropic_version").Exists() { 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() body, _ = sjson.DeleteBytes(body, "model") body, _ = sjson.DeleteBytes(body, "stream") var method string if stream { method = "invoke-with-response-stream" } else { method = "invoke" } r.URL.Path = fmt.Sprintf("/model/%s/%s", model, method) r.URL.RawPath = fmt.Sprintf("/model/%s/%s", url.QueryEscape(model), method) } reader := bytes.NewReader(body) r.Body = io.NopCloser(reader) r.GetBody = func() (io.ReadCloser, error) { _, err := reader.Seek(0, 0) return io.NopCloser(reader), err } r.ContentLength = int64(len(body)) } // Use bearer token authentication if configured, otherwise fall back to SigV4 if cfg.BearerAuthTokenProvider != nil { token, err := cfg.BearerAuthTokenProvider.RetrieveBearerToken(r.Context()) if err != nil { return nil, err } r.Header.Set("Authorization", "Bearer "+token.Value) } else { ctx := r.Context() credentials, err := cfg.Credentials.Retrieve(ctx) if err != nil { return nil, err } hash := sha256.Sum256(body) err = signer.SignHTTP(ctx, credentials, r, hex.EncodeToString(hash[:]), "bedrock", cfg.Region, time.Now()) if err != nil { return nil, err } } return next(r) } } ================================================ FILE: bedrock/bedrock_test.go ================================================ package bedrock import ( "bytes" "encoding/json" "fmt" "io" "net/http" "testing" "github.com/aws/aws-sdk-go-v2/aws" v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/credentials" ) func TestBedrockURLEncoding(t *testing.T) { testCases := []struct { name string model string stream bool expectedPath string expectedRawPath string }{ { name: "regular model name", model: "claude-3-sonnet", stream: false, expectedPath: "/model/claude-3-sonnet/invoke", expectedRawPath: "/model/claude-3-sonnet/invoke", }, { name: "regular model name with streaming", model: "claude-3-sonnet", stream: true, expectedPath: "/model/claude-3-sonnet/invoke-with-response-stream", expectedRawPath: "/model/claude-3-sonnet/invoke-with-response-stream", }, { name: "inference profile ARN with slashes", model: "arn:aws:bedrock:us-east-1:947123456126:application-inference-profile/xv9example4b", stream: false, expectedPath: "/model/arn:aws:bedrock:us-east-1:947123456126:application-inference-profile/xv9example4b/invoke", expectedRawPath: "/model/arn%3Aaws%3Abedrock%3Aus-east-1%3A947123456126%3Aapplication-inference-profile%2Fxv9example4b/invoke", }, { name: "inference profile ARN with streaming", model: "arn:aws:bedrock:us-east-1:947123456126:application-inference-profile/xv9example4b", stream: true, expectedPath: "/model/arn:aws:bedrock:us-east-1:947123456126:application-inference-profile/xv9example4b/invoke-with-response-stream", expectedRawPath: "/model/arn%3Aaws%3Abedrock%3Aus-east-1%3A947123456126%3Aapplication-inference-profile%2Fxv9example4b/invoke-with-response-stream", }, { name: "foundation model ARN with colons", model: "arn:aws:bedrock:us-east-1:123456789012:foundation-model/anthropic.claude-3-sonnet-20240229-v1:0", stream: false, expectedPath: "/model/arn:aws:bedrock:us-east-1:123456789012:foundation-model/anthropic.claude-3-sonnet-20240229-v1:0/invoke", expectedRawPath: "/model/arn%3Aaws%3Abedrock%3Aus-east-1%3A123456789012%3Afoundation-model%2Fanthropic.claude-3-sonnet-20240229-v1%3A0/invoke", }, } for _, tc := range testCases { t.Run(tc.name, func(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 request body requestBody := map[string]any{ "model": tc.model, "stream": tc.stream, "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) } // Create HTTP request req, err := http.NewRequest("POST", "https://bedrock-runtime.us-east-1.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") // Apply middleware _, err = middleware(req, func(r *http.Request) (*http.Response, error) { // Verify the URL paths are set correctly if r.URL.Path != tc.expectedPath { t.Errorf("Expected Path %q, got %q", tc.expectedPath, r.URL.Path) } if r.URL.RawPath != tc.expectedRawPath { t.Errorf("Expected RawPath %q, got %q", tc.expectedRawPath, r.URL.RawPath) } // Verify that the URL string contains the properly encoded path urlString := r.URL.String() expectedURL := fmt.Sprintf("https://bedrock-runtime.us-east-1.amazonaws.com%s", tc.expectedRawPath) if urlString != expectedURL { t.Errorf("Expected URL %q, got %q", expectedURL, urlString) } // Return a dummy response return &http.Response{ StatusCode: 200, Body: http.NoBody, }, nil }) if err != nil { t.Fatalf("Middleware failed: %v", err) } }) } } 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) } } ================================================ FILE: beta.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic import ( "encoding/json" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/respjson" "github.com/anthropics/anthropic-sdk-go/shared/constant" ) // BetaService 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 [NewBetaService] method instead. type BetaService struct { Options []option.RequestOption Models BetaModelService Messages BetaMessageService Files BetaFileService Skills BetaSkillService } // NewBetaService 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 NewBetaService(opts ...option.RequestOption) (r BetaService) { r = BetaService{} r.Options = opts r.Models = NewBetaModelService(opts...) r.Messages = NewBetaMessageService(opts...) r.Files = NewBetaFileService(opts...) r.Skills = NewBetaSkillService(opts...) return } type AnthropicBeta = string const ( AnthropicBetaMessageBatches2024_09_24 AnthropicBeta = "message-batches-2024-09-24" AnthropicBetaPromptCaching2024_07_31 AnthropicBeta = "prompt-caching-2024-07-31" AnthropicBetaComputerUse2024_10_22 AnthropicBeta = "computer-use-2024-10-22" AnthropicBetaComputerUse2025_01_24 AnthropicBeta = "computer-use-2025-01-24" AnthropicBetaPDFs2024_09_25 AnthropicBeta = "pdfs-2024-09-25" AnthropicBetaTokenCounting2024_11_01 AnthropicBeta = "token-counting-2024-11-01" AnthropicBetaTokenEfficientTools2025_02_19 AnthropicBeta = "token-efficient-tools-2025-02-19" 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" AnthropicBetaExtendedCacheTTL2025_04_11 AnthropicBeta = "extended-cache-ttl-2025-04-11" 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 { Message string `json:"message" api:"required"` Type constant.APIError `json:"type" api:"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 BetaAPIError) RawJSON() string { return r.JSON.raw } func (r *BetaAPIError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaAuthenticationError struct { Message string `json:"message" api:"required"` Type constant.AuthenticationError `json:"type" api:"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 BetaAuthenticationError) RawJSON() string { return r.JSON.raw } func (r *BetaAuthenticationError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaBillingError struct { Message string `json:"message" api:"required"` Type constant.BillingError `json:"type" api:"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 BetaBillingError) RawJSON() string { return r.JSON.raw } func (r *BetaBillingError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaErrorUnion contains all possible properties and values from // [BetaInvalidRequestError], [BetaAuthenticationError], [BetaBillingError], // [BetaPermissionError], [BetaNotFoundError], [BetaRateLimitError], // [BetaGatewayTimeoutError], [BetaAPIError], [BetaOverloadedError]. // // Use the [BetaErrorUnion.AsAny] method to switch on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaErrorUnion struct { Message string `json:"message"` // Any of "invalid_request_error", "authentication_error", "billing_error", // "permission_error", "not_found_error", "rate_limit_error", "timeout_error", // "api_error", "overloaded_error". Type string `json:"type"` JSON struct { Message respjson.Field Type respjson.Field raw string } `json:"-"` } // anyBetaError is implemented by each variant of [BetaErrorUnion] to add type // safety for the return type of [BetaErrorUnion.AsAny] type anyBetaError interface { implBetaErrorUnion() } func (BetaInvalidRequestError) implBetaErrorUnion() {} func (BetaAuthenticationError) implBetaErrorUnion() {} func (BetaBillingError) implBetaErrorUnion() {} func (BetaPermissionError) implBetaErrorUnion() {} func (BetaNotFoundError) implBetaErrorUnion() {} func (BetaRateLimitError) implBetaErrorUnion() {} func (BetaGatewayTimeoutError) implBetaErrorUnion() {} func (BetaAPIError) implBetaErrorUnion() {} func (BetaOverloadedError) implBetaErrorUnion() {} // Use the following switch statement to find the correct variant // // switch variant := BetaErrorUnion.AsAny().(type) { // case anthropic.BetaInvalidRequestError: // case anthropic.BetaAuthenticationError: // case anthropic.BetaBillingError: // case anthropic.BetaPermissionError: // case anthropic.BetaNotFoundError: // case anthropic.BetaRateLimitError: // case anthropic.BetaGatewayTimeoutError: // case anthropic.BetaAPIError: // case anthropic.BetaOverloadedError: // default: // fmt.Errorf("no variant present") // } func (u BetaErrorUnion) AsAny() anyBetaError { switch u.Type { case "invalid_request_error": return u.AsInvalidRequestError() case "authentication_error": return u.AsAuthenticationError() case "billing_error": return u.AsBillingError() case "permission_error": return u.AsPermissionError() case "not_found_error": return u.AsNotFoundError() case "rate_limit_error": return u.AsRateLimitError() case "timeout_error": return u.AsTimeoutError() case "api_error": return u.AsAPIError() case "overloaded_error": return u.AsOverloadedError() } return nil } func (u BetaErrorUnion) AsInvalidRequestError() (v BetaInvalidRequestError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaErrorUnion) AsAuthenticationError() (v BetaAuthenticationError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaErrorUnion) AsBillingError() (v BetaBillingError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaErrorUnion) AsPermissionError() (v BetaPermissionError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaErrorUnion) AsNotFoundError() (v BetaNotFoundError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaErrorUnion) AsRateLimitError() (v BetaRateLimitError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaErrorUnion) AsTimeoutError() (v BetaGatewayTimeoutError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaErrorUnion) AsAPIError() (v BetaAPIError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaErrorUnion) AsOverloadedError() (v BetaOverloadedError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaErrorUnion) RawJSON() string { return u.JSON.raw } func (r *BetaErrorUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaErrorResponse struct { Error BetaErrorUnion `json:"error" api:"required"` RequestID string `json:"request_id" api:"required"` Type constant.Error `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Error respjson.Field RequestID respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaGatewayTimeoutError struct { Message string `json:"message" api:"required"` Type constant.TimeoutError `json:"type" api:"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 BetaGatewayTimeoutError) RawJSON() string { return r.JSON.raw } func (r *BetaGatewayTimeoutError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaInvalidRequestError struct { Message string `json:"message" api:"required"` Type constant.InvalidRequestError `json:"type" api:"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 BetaInvalidRequestError) RawJSON() string { return r.JSON.raw } func (r *BetaInvalidRequestError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaNotFoundError struct { Message string `json:"message" api:"required"` Type constant.NotFoundError `json:"type" api:"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 BetaNotFoundError) RawJSON() string { return r.JSON.raw } func (r *BetaNotFoundError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaOverloadedError struct { Message string `json:"message" api:"required"` Type constant.OverloadedError `json:"type" api:"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 BetaOverloadedError) RawJSON() string { return r.JSON.raw } func (r *BetaOverloadedError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaPermissionError struct { Message string `json:"message" api:"required"` Type constant.PermissionError `json:"type" api:"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 BetaPermissionError) RawJSON() string { return r.JSON.raw } func (r *BetaPermissionError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRateLimitError struct { Message string `json:"message" api:"required"` Type constant.RateLimitError `json:"type" api:"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 BetaRateLimitError) RawJSON() string { return r.JSON.raw } func (r *BetaRateLimitError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } ================================================ FILE: betafile.go ================================================ // 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" "time" "github.com/anthropics/anthropic-sdk-go/internal/apiform" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/internal/apiquery" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/pagination" "github.com/anthropics/anthropic-sdk-go/packages/param" "github.com/anthropics/anthropic-sdk-go/packages/respjson" "github.com/anthropics/anthropic-sdk-go/shared/constant" ) // BetaFileService 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 [NewBetaFileService] method instead. type BetaFileService struct { Options []option.RequestOption } // NewBetaFileService 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 NewBetaFileService(opts ...option.RequestOption) (r BetaFileService) { r = BetaFileService{} r.Options = opts return } // List Files func (r *BetaFileService) List(ctx context.Context, params BetaFileListParams, opts ...option.RequestOption) (res *pagination.Page[FileMetadata], err error) { var raw *http.Response for _, v := range params.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14"), option.WithResponseInto(&raw)}, opts...) path := "v1/files?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 Files func (r *BetaFileService) ListAutoPaging(ctx context.Context, params BetaFileListParams, opts ...option.RequestOption) *pagination.PageAutoPager[FileMetadata] { return pagination.NewPageAutoPager(r.List(ctx, params, opts...)) } // Delete File func (r *BetaFileService) Delete(ctx context.Context, fileID string, body BetaFileDeleteParams, opts ...option.RequestOption) (res *DeletedFile, err error) { for _, v := range body.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14")}, opts...) if fileID == "" { err = errors.New("missing required file_id parameter") return nil, err } path := fmt.Sprintf("v1/files/%s?beta=true", fileID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) return res, err } // Download File func (r *BetaFileService) Download(ctx context.Context, fileID string, query BetaFileDownloadParams, opts ...option.RequestOption) (res *http.Response, err error) { for _, v := range query.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } 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...) if fileID == "" { err = errors.New("missing required file_id parameter") return nil, err } path := fmt.Sprintf("v1/files/%s/content?beta=true", fileID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) return res, err } // Get File Metadata func (r *BetaFileService) GetMetadata(ctx context.Context, fileID string, query BetaFileGetMetadataParams, opts ...option.RequestOption) (res *FileMetadata, err error) { for _, v := range query.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14")}, opts...) if fileID == "" { err = errors.New("missing required file_id parameter") return nil, err } path := fmt.Sprintf("v1/files/%s?beta=true", fileID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) return res, err } // Upload File func (r *BetaFileService) Upload(ctx context.Context, params BetaFileUploadParams, opts ...option.RequestOption) (res *FileMetadata, err error) { for _, v := range params.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "files-api-2025-04-14")}, opts...) path := "v1/files?beta=true" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return res, err } type DeletedFile struct { // ID of the deleted file. ID string `json:"id" api:"required"` // Deleted object type. // // For file deletion, this is always `"file_deleted"`. // // Any of "file_deleted". Type DeletedFileType `json:"type"` // 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 DeletedFile) RawJSON() string { return r.JSON.raw } func (r *DeletedFile) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Deleted object type. // // For file deletion, this is always `"file_deleted"`. type DeletedFileType string const ( DeletedFileTypeFileDeleted DeletedFileType = "file_deleted" ) type FileMetadata struct { // Unique object identifier. // // The format and length of IDs may change over time. ID string `json:"id" api:"required"` // RFC 3339 datetime string representing when the file was created. CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Original filename of the uploaded file. Filename string `json:"filename" api:"required"` // MIME type of the file. MimeType string `json:"mime_type" api:"required"` // Size of the file in bytes. SizeBytes int64 `json:"size_bytes" api:"required"` // Object type. // // For files, this is always `"file"`. Type constant.File `json:"type" api:"required"` // Whether the file can be downloaded. Downloadable bool `json:"downloadable"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field CreatedAt respjson.Field Filename respjson.Field MimeType respjson.Field SizeBytes respjson.Field Type respjson.Field Downloadable respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r FileMetadata) RawJSON() string { return r.JSON.raw } func (r *FileMetadata) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaFileListParams struct { // ID of the object to use as a cursor for pagination. When provided, returns the // page of results immediately after this object. AfterID param.Opt[string] `query:"after_id,omitzero" json:"-"` // ID of the object to use as a cursor for pagination. When provided, returns the // page of results immediately before this object. BeforeID param.Opt[string] `query:"before_id,omitzero" json:"-"` // Number of items to return per page. // // Defaults to `20`. Ranges from `1` to `1000`. 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 [BetaFileListParams]'s query parameters as `url.Values`. func (r BetaFileListParams) URLQuery() (v url.Values, err error) { return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ ArrayFormat: apiquery.ArrayQueryFormatComma, NestedFormat: apiquery.NestedQueryFormatBrackets, }) } type BetaFileDeleteParams struct { // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } type BetaFileDownloadParams struct { // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } type BetaFileGetMetadataParams struct { // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } type BetaFileUploadParams struct { // The file to upload File io.Reader `json:"file,omitzero" api:"required" format:"binary"` // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } func (r BetaFileUploadParams) 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 } ================================================ FILE: betafile_test.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic_test import ( "bytes" "context" "errors" "io" "net/http" "net/http/httptest" "os" "testing" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/internal/testutil" "github.com/anthropics/anthropic-sdk-go/option" ) func TestBetaFileListWithOptionalParams(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.Files.List(context.TODO(), anthropic.BetaFileListParams{ AfterID: anthropic.String("after_id"), BeforeID: anthropic.String("before_id"), Limit: anthropic.Int(1), 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 TestBetaFileDeleteWithOptionalParams(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.Files.Delete( context.TODO(), "file_id", anthropic.BetaFileDeleteParams{ 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 TestBetaFileDownloadWithOptionalParams(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) w.Write([]byte("abc")) })) defer server.Close() baseURL := server.URL client := anthropic.NewClient( option.WithBaseURL(baseURL), option.WithAPIKey("my-anthropic-api-key"), ) resp, err := client.Beta.Files.Download( context.TODO(), "file_id", anthropic.BetaFileDownloadParams{ 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()) } defer resp.Body.Close() b, err := io.ReadAll(resp.Body) 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()) } if !bytes.Equal(b, []byte("abc")) { t.Fatalf("return value not %s: %s", "abc", b) } } func TestBetaFileGetMetadataWithOptionalParams(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.Files.GetMetadata( context.TODO(), "file_id", anthropic.BetaFileGetMetadataParams{ 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 TestBetaFileUploadWithOptionalParams(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.Files.Upload(context.TODO(), anthropic.BetaFileUploadParams{ File: io.Reader(bytes.NewBuffer([]byte("Example data"))), 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()) } } ================================================ FILE: betamessage.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic import ( "context" "encoding/json" "fmt" "net/http" "slices" "time" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/internal/paramutil" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/param" "github.com/anthropics/anthropic-sdk-go/packages/respjson" "github.com/anthropics/anthropic-sdk-go/packages/ssestream" "github.com/anthropics/anthropic-sdk-go/shared/constant" ) // BetaMessageService 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 [NewBetaMessageService] method instead. type BetaMessageService struct { Options []option.RequestOption Batches BetaMessageBatchService } // NewBetaMessageService 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 NewBetaMessageService(opts ...option.RequestOption) (r BetaMessageService) { r = BetaMessageService{} r.Options = opts r.Batches = NewBetaMessageBatchService(opts...) return } // Send a structured list of input messages with text and/or image content, and the // model will generate the next message in the conversation. // // 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](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("%v", v))) } opts = slices.Concat(r.Options, opts) // For non-streaming requests, calculate the appropriate timeout based on maxTokens // and check against model-specific limits timeout, timeoutErr := CalculateNonStreamingTimeout(int(params.MaxTokens), params.Model, opts) if timeoutErr != nil { return nil, timeoutErr } opts = append(opts, option.WithRequestTimeout(timeout)) path := "v1/messages?beta=true" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return res, err } // Send a structured list of input messages with text and/or image content, and the // model will generate the next message in the conversation. // // 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](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]) { var ( raw *http.Response 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(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) } // Count the number of tokens in a Message. // // The Token Count API can be used to count the number of tokens in a Message, // including tools, images, and documents, without creating it. // // Learn more about token counting in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/token-counting) func (r *BetaMessageService) CountTokens(ctx context.Context, params BetaMessageCountTokensParams, opts ...option.RequestOption) (res *BetaMessageTokensCount, err error) { for _, v := range params.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } 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 } 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" api:"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. type BetaBase64ImageSourceParam struct { Data string `json:"data" api:"required" format:"byte"` // Any of "image/jpeg", "image/png", "image/gif", "image/webp". MediaType BetaBase64ImageSourceMediaType `json:"media_type,omitzero" api:"required"` // This field can be elided, and will marshal its zero value as "base64". Type constant.Base64 `json:"type" api:"required"` paramObj } 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) } type BetaBase64ImageSourceMediaType string const ( BetaBase64ImageSourceMediaTypeImageJPEG BetaBase64ImageSourceMediaType = "image/jpeg" BetaBase64ImageSourceMediaTypeImagePNG BetaBase64ImageSourceMediaType = "image/png" BetaBase64ImageSourceMediaTypeImageGIF BetaBase64ImageSourceMediaType = "image/gif" BetaBase64ImageSourceMediaTypeImageWebP BetaBase64ImageSourceMediaType = "image/webp" ) type BetaBase64PDFSource struct { Data string `json:"data" api:"required" format:"byte"` MediaType constant.ApplicationPDF `json:"media_type" api:"required"` Type constant.Base64 `json:"type" api:"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 BetaBase64PDFSource) RawJSON() string { return r.JSON.raw } func (r *BetaBase64PDFSource) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // ToParam converts this BetaBase64PDFSource to a BetaBase64PDFSourceParam. // // 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 // BetaBase64PDFSourceParam.Overrides() func (r BetaBase64PDFSource) ToParam() BetaBase64PDFSourceParam { return param.Override[BetaBase64PDFSourceParam](json.RawMessage(r.RawJSON())) } // The properties Data, MediaType, Type are required. type BetaBase64PDFSourceParam struct { Data string `json:"data" api:"required" format:"byte"` // This field can be elided, and will marshal its zero value as "application/pdf". MediaType constant.ApplicationPDF `json:"media_type" api:"required"` // This field can be elided, and will marshal its zero value as "base64". Type constant.Base64 `json:"type" api:"required"` paramObj } 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) } type BetaBashCodeExecutionOutputBlock struct { FileID string `json:"file_id" api:"required"` Type constant.BashCodeExecutionOutput `json:"type" api:"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 BetaBashCodeExecutionOutputBlock) RawJSON() string { return r.JSON.raw } func (r *BetaBashCodeExecutionOutputBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties FileID, Type are required. type BetaBashCodeExecutionOutputBlockParam struct { FileID string `json:"file_id" api:"required"` // This field can be elided, and will marshal its zero value as // "bash_code_execution_output". Type constant.BashCodeExecutionOutput `json:"type" api:"required"` paramObj } func (r BetaBashCodeExecutionOutputBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaBashCodeExecutionOutputBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaBashCodeExecutionOutputBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaBashCodeExecutionResultBlock struct { Content []BetaBashCodeExecutionOutputBlock `json:"content" api:"required"` ReturnCode int64 `json:"return_code" api:"required"` Stderr string `json:"stderr" api:"required"` Stdout string `json:"stdout" api:"required"` Type constant.BashCodeExecutionResult `json:"type" api:"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 BetaBashCodeExecutionResultBlock) RawJSON() string { return r.JSON.raw } func (r *BetaBashCodeExecutionResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Content, ReturnCode, Stderr, Stdout, Type are required. type BetaBashCodeExecutionResultBlockParam struct { Content []BetaBashCodeExecutionOutputBlockParam `json:"content,omitzero" api:"required"` ReturnCode int64 `json:"return_code" api:"required"` Stderr string `json:"stderr" api:"required"` Stdout string `json:"stdout" api:"required"` // This field can be elided, and will marshal its zero value as // "bash_code_execution_result". Type constant.BashCodeExecutionResult `json:"type" api:"required"` paramObj } func (r BetaBashCodeExecutionResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaBashCodeExecutionResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaBashCodeExecutionResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaBashCodeExecutionToolResultBlock struct { Content BetaBashCodeExecutionToolResultBlockContentUnion `json:"content" api:"required"` ToolUseID string `json:"tool_use_id" api:"required"` Type constant.BashCodeExecutionToolResult `json:"type" api:"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 BetaBashCodeExecutionToolResultBlock) RawJSON() string { return r.JSON.raw } func (r *BetaBashCodeExecutionToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaBashCodeExecutionToolResultBlockContentUnion contains all possible // properties and values from [BetaBashCodeExecutionToolResultError], // [BetaBashCodeExecutionResultBlock]. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaBashCodeExecutionToolResultBlockContentUnion struct { // This field is from variant [BetaBashCodeExecutionToolResultError]. ErrorCode BetaBashCodeExecutionToolResultErrorErrorCode `json:"error_code"` Type string `json:"type"` // This field is from variant [BetaBashCodeExecutionResultBlock]. Content []BetaBashCodeExecutionOutputBlock `json:"content"` // This field is from variant [BetaBashCodeExecutionResultBlock]. ReturnCode int64 `json:"return_code"` // This field is from variant [BetaBashCodeExecutionResultBlock]. Stderr string `json:"stderr"` // This field is from variant [BetaBashCodeExecutionResultBlock]. 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 BetaBashCodeExecutionToolResultBlockContentUnion) AsResponseBashCodeExecutionToolResultError() (v BetaBashCodeExecutionToolResultError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaBashCodeExecutionToolResultBlockContentUnion) AsResponseBashCodeExecutionResultBlock() (v BetaBashCodeExecutionResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaBashCodeExecutionToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } func (r *BetaBashCodeExecutionToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Content, ToolUseID, Type are required. type BetaBashCodeExecutionToolResultBlockParam struct { Content BetaBashCodeExecutionToolResultBlockParamContentUnion `json:"content,omitzero" api:"required"` ToolUseID string `json:"tool_use_id" api:"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 // "bash_code_execution_tool_result". Type constant.BashCodeExecutionToolResult `json:"type" api:"required"` paramObj } func (r BetaBashCodeExecutionToolResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaBashCodeExecutionToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaBashCodeExecutionToolResultBlockParam) 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 BetaBashCodeExecutionToolResultBlockParamContentUnion struct { OfRequestBashCodeExecutionToolResultError *BetaBashCodeExecutionToolResultErrorParam `json:",omitzero,inline"` OfRequestBashCodeExecutionResultBlock *BetaBashCodeExecutionResultBlockParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaBashCodeExecutionToolResultBlockParamContentUnion) 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 BetaBashCodeExecutionToolResultBlockParamContentUnion) 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 BetaBashCodeExecutionToolResultBlockParamContentUnion) GetContent() []BetaBashCodeExecutionOutputBlockParam { if vt := u.OfRequestBashCodeExecutionResultBlock; vt != nil { return vt.Content } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaBashCodeExecutionToolResultBlockParamContentUnion) 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 BetaBashCodeExecutionToolResultBlockParamContentUnion) 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 BetaBashCodeExecutionToolResultBlockParamContentUnion) 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 BetaBashCodeExecutionToolResultBlockParamContentUnion) 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 BetaBashCodeExecutionToolResultError struct { // Any of "invalid_tool_input", "unavailable", "too_many_requests", // "execution_time_exceeded", "output_file_too_large". ErrorCode BetaBashCodeExecutionToolResultErrorErrorCode `json:"error_code" api:"required"` Type constant.BashCodeExecutionToolResultError `json:"type" api:"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 BetaBashCodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } func (r *BetaBashCodeExecutionToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaBashCodeExecutionToolResultErrorErrorCode string const ( BetaBashCodeExecutionToolResultErrorErrorCodeInvalidToolInput BetaBashCodeExecutionToolResultErrorErrorCode = "invalid_tool_input" BetaBashCodeExecutionToolResultErrorErrorCodeUnavailable BetaBashCodeExecutionToolResultErrorErrorCode = "unavailable" BetaBashCodeExecutionToolResultErrorErrorCodeTooManyRequests BetaBashCodeExecutionToolResultErrorErrorCode = "too_many_requests" BetaBashCodeExecutionToolResultErrorErrorCodeExecutionTimeExceeded BetaBashCodeExecutionToolResultErrorErrorCode = "execution_time_exceeded" BetaBashCodeExecutionToolResultErrorErrorCodeOutputFileTooLarge BetaBashCodeExecutionToolResultErrorErrorCode = "output_file_too_large" ) // The properties ErrorCode, Type are required. type BetaBashCodeExecutionToolResultErrorParam struct { // Any of "invalid_tool_input", "unavailable", "too_many_requests", // "execution_time_exceeded", "output_file_too_large". ErrorCode BetaBashCodeExecutionToolResultErrorParamErrorCode `json:"error_code,omitzero" api:"required"` // This field can be elided, and will marshal its zero value as // "bash_code_execution_tool_result_error". Type constant.BashCodeExecutionToolResultError `json:"type" api:"required"` paramObj } func (r BetaBashCodeExecutionToolResultErrorParam) MarshalJSON() (data []byte, err error) { type shadow BetaBashCodeExecutionToolResultErrorParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaBashCodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaBashCodeExecutionToolResultErrorParamErrorCode string const ( BetaBashCodeExecutionToolResultErrorParamErrorCodeInvalidToolInput BetaBashCodeExecutionToolResultErrorParamErrorCode = "invalid_tool_input" BetaBashCodeExecutionToolResultErrorParamErrorCodeUnavailable BetaBashCodeExecutionToolResultErrorParamErrorCode = "unavailable" BetaBashCodeExecutionToolResultErrorParamErrorCodeTooManyRequests BetaBashCodeExecutionToolResultErrorParamErrorCode = "too_many_requests" BetaBashCodeExecutionToolResultErrorParamErrorCodeExecutionTimeExceeded BetaBashCodeExecutionToolResultErrorParamErrorCode = "execution_time_exceeded" BetaBashCodeExecutionToolResultErrorParamErrorCodeOutputFileTooLarge BetaBashCodeExecutionToolResultErrorParamErrorCode = "output_file_too_large" ) func NewBetaCacheControlEphemeralParam() BetaCacheControlEphemeralParam { return BetaCacheControlEphemeralParam{ Type: "ephemeral", } } // This struct has a constant value, construct it with // [NewBetaCacheControlEphemeralParam]. type BetaCacheControlEphemeralParam struct { // The time-to-live for the cache control breakpoint. // // This may be one the following values: // // - `5m`: 5 minutes // - `1h`: 1 hour // // Defaults to `5m`. // // Any of "5m", "1h". TTL BetaCacheControlEphemeralTTL `json:"ttl,omitzero"` Type constant.Ephemeral `json:"type" api:"required"` paramObj } 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) } // The time-to-live for the cache control breakpoint. // // This may be one the following values: // // - `5m`: 5 minutes // - `1h`: 1 hour // // Defaults to `5m`. type BetaCacheControlEphemeralTTL string const ( BetaCacheControlEphemeralTTLTTL5m BetaCacheControlEphemeralTTL = "5m" BetaCacheControlEphemeralTTLTTL1h BetaCacheControlEphemeralTTL = "1h" ) type BetaCacheCreation struct { // The number of input tokens used to create the 1 hour cache entry. Ephemeral1hInputTokens int64 `json:"ephemeral_1h_input_tokens" api:"required"` // The number of input tokens used to create the 5 minute cache entry. Ephemeral5mInputTokens int64 `json:"ephemeral_5m_input_tokens" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Ephemeral1hInputTokens respjson.Field Ephemeral5mInputTokens respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaCitationCharLocation struct { CitedText string `json:"cited_text" api:"required"` DocumentIndex int64 `json:"document_index" api:"required"` DocumentTitle string `json:"document_title" api:"required"` EndCharIndex int64 `json:"end_char_index" api:"required"` FileID string `json:"file_id" api:"required"` StartCharIndex int64 `json:"start_char_index" api:"required"` Type constant.CharLocation `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { CitedText respjson.Field DocumentIndex respjson.Field DocumentTitle respjson.Field EndCharIndex respjson.Field FileID respjson.Field StartCharIndex respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } // The properties CitedText, DocumentIndex, DocumentTitle, EndCharIndex, // StartCharIndex, Type are required. type BetaCitationCharLocationParam struct { DocumentTitle param.Opt[string] `json:"document_title,omitzero" api:"required"` CitedText string `json:"cited_text" api:"required"` DocumentIndex int64 `json:"document_index" api:"required"` EndCharIndex int64 `json:"end_char_index" api:"required"` StartCharIndex int64 `json:"start_char_index" api:"required"` // This field can be elided, and will marshal its zero value as "char_location". Type constant.CharLocation `json:"type" api:"required"` paramObj } 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) } type BetaCitationConfig struct { Enabled bool `json:"enabled" api:"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 BetaCitationConfig) RawJSON() string { return r.JSON.raw } func (r *BetaCitationConfig) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaCitationContentBlockLocation struct { CitedText string `json:"cited_text" api:"required"` DocumentIndex int64 `json:"document_index" api:"required"` DocumentTitle string `json:"document_title" api:"required"` EndBlockIndex int64 `json:"end_block_index" api:"required"` FileID string `json:"file_id" api:"required"` StartBlockIndex int64 `json:"start_block_index" api:"required"` Type constant.ContentBlockLocation `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { CitedText respjson.Field DocumentIndex respjson.Field DocumentTitle respjson.Field EndBlockIndex respjson.Field FileID respjson.Field StartBlockIndex respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } // The properties CitedText, DocumentIndex, DocumentTitle, EndBlockIndex, // StartBlockIndex, Type are required. type BetaCitationContentBlockLocationParam struct { DocumentTitle param.Opt[string] `json:"document_title,omitzero" api:"required"` CitedText string `json:"cited_text" api:"required"` DocumentIndex int64 `json:"document_index" api:"required"` EndBlockIndex int64 `json:"end_block_index" api:"required"` StartBlockIndex int64 `json:"start_block_index" api:"required"` // This field can be elided, and will marshal its zero value as // "content_block_location". Type constant.ContentBlockLocation `json:"type" api:"required"` paramObj } func (r BetaCitationContentBlockLocationParam) MarshalJSON() (data []byte, err error) { type shadow BetaCitationContentBlockLocationParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaCitationContentBlockLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaCitationPageLocation struct { CitedText string `json:"cited_text" api:"required"` DocumentIndex int64 `json:"document_index" api:"required"` DocumentTitle string `json:"document_title" api:"required"` EndPageNumber int64 `json:"end_page_number" api:"required"` FileID string `json:"file_id" api:"required"` StartPageNumber int64 `json:"start_page_number" api:"required"` Type constant.PageLocation `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { CitedText respjson.Field DocumentIndex respjson.Field DocumentTitle respjson.Field EndPageNumber respjson.Field FileID respjson.Field StartPageNumber respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } // The properties CitedText, DocumentIndex, DocumentTitle, EndPageNumber, // StartPageNumber, Type are required. type BetaCitationPageLocationParam struct { DocumentTitle param.Opt[string] `json:"document_title,omitzero" api:"required"` CitedText string `json:"cited_text" api:"required"` DocumentIndex int64 `json:"document_index" api:"required"` EndPageNumber int64 `json:"end_page_number" api:"required"` StartPageNumber int64 `json:"start_page_number" api:"required"` // This field can be elided, and will marshal its zero value as "page_location". Type constant.PageLocation `json:"type" api:"required"` paramObj } 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) } type BetaCitationSearchResultLocation struct { CitedText string `json:"cited_text" api:"required"` EndBlockIndex int64 `json:"end_block_index" api:"required"` SearchResultIndex int64 `json:"search_result_index" api:"required"` Source string `json:"source" api:"required"` StartBlockIndex int64 `json:"start_block_index" api:"required"` Title string `json:"title" api:"required"` Type constant.SearchResultLocation `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { CitedText respjson.Field EndBlockIndex respjson.Field SearchResultIndex respjson.Field Source respjson.Field StartBlockIndex 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 BetaCitationSearchResultLocation) RawJSON() string { return r.JSON.raw } func (r *BetaCitationSearchResultLocation) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties CitedText, EndBlockIndex, SearchResultIndex, Source, // StartBlockIndex, Title, Type are required. type BetaCitationSearchResultLocationParam struct { Title param.Opt[string] `json:"title,omitzero" api:"required"` CitedText string `json:"cited_text" api:"required"` EndBlockIndex int64 `json:"end_block_index" api:"required"` SearchResultIndex int64 `json:"search_result_index" api:"required"` Source string `json:"source" api:"required"` StartBlockIndex int64 `json:"start_block_index" api:"required"` // This field can be elided, and will marshal its zero value as // "search_result_location". Type constant.SearchResultLocation `json:"type" api:"required"` paramObj } func (r BetaCitationSearchResultLocationParam) MarshalJSON() (data []byte, err error) { type shadow BetaCitationSearchResultLocationParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaCitationSearchResultLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties CitedText, EncryptedIndex, Title, Type, URL are required. type BetaCitationWebSearchResultLocationParam struct { Title param.Opt[string] `json:"title,omitzero" api:"required"` CitedText string `json:"cited_text" api:"required"` EncryptedIndex string `json:"encrypted_index" api:"required"` URL string `json:"url" api:"required"` // This field can be elided, and will marshal its zero value as // "web_search_result_location". Type constant.WebSearchResultLocation `json:"type" api:"required"` paramObj } func (r BetaCitationWebSearchResultLocationParam) MarshalJSON() (data []byte, err error) { type shadow BetaCitationWebSearchResultLocationParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaCitationWebSearchResultLocationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaCitationsConfigParam struct { Enabled param.Opt[bool] `json:"enabled,omitzero"` paramObj } 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) } type BetaCitationsDelta struct { Citation BetaCitationsDeltaCitationUnion `json:"citation" api:"required"` Type constant.CitationsDelta `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Citation respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } // BetaCitationsDeltaCitationUnion contains all possible properties and values from // [BetaCitationCharLocation], [BetaCitationPageLocation], // [BetaCitationContentBlockLocation], [BetaCitationsWebSearchResultLocation], // [BetaCitationSearchResultLocation]. // // Use the [BetaCitationsDeltaCitationUnion.AsAny] method to switch on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaCitationsDeltaCitationUnion struct { CitedText string `json:"cited_text"` DocumentIndex int64 `json:"document_index"` DocumentTitle string `json:"document_title"` // This field is from variant [BetaCitationCharLocation]. EndCharIndex int64 `json:"end_char_index"` FileID string `json:"file_id"` // This field is from variant [BetaCitationCharLocation]. 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 [BetaCitationPageLocation]. EndPageNumber int64 `json:"end_page_number"` // This field is from variant [BetaCitationPageLocation]. StartPageNumber int64 `json:"start_page_number"` EndBlockIndex int64 `json:"end_block_index"` StartBlockIndex int64 `json:"start_block_index"` // This field is from variant [BetaCitationsWebSearchResultLocation]. EncryptedIndex string `json:"encrypted_index"` Title string `json:"title"` // This field is from variant [BetaCitationsWebSearchResultLocation]. URL string `json:"url"` // This field is from variant [BetaCitationSearchResultLocation]. SearchResultIndex int64 `json:"search_result_index"` // This field is from variant [BetaCitationSearchResultLocation]. 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:"-"` } // anyBetaCitationsDeltaCitation is implemented by each variant of // [BetaCitationsDeltaCitationUnion] to add type safety for the return type of // [BetaCitationsDeltaCitationUnion.AsAny] type anyBetaCitationsDeltaCitation interface { implBetaCitationsDeltaCitationUnion() } func (BetaCitationCharLocation) implBetaCitationsDeltaCitationUnion() {} func (BetaCitationPageLocation) implBetaCitationsDeltaCitationUnion() {} func (BetaCitationContentBlockLocation) implBetaCitationsDeltaCitationUnion() {} func (BetaCitationsWebSearchResultLocation) implBetaCitationsDeltaCitationUnion() {} func (BetaCitationSearchResultLocation) implBetaCitationsDeltaCitationUnion() {} // Use the following switch statement to find the correct variant // // switch variant := BetaCitationsDeltaCitationUnion.AsAny().(type) { // case anthropic.BetaCitationCharLocation: // case anthropic.BetaCitationPageLocation: // case anthropic.BetaCitationContentBlockLocation: // case anthropic.BetaCitationsWebSearchResultLocation: // case anthropic.BetaCitationSearchResultLocation: // default: // fmt.Errorf("no variant present") // } func (u BetaCitationsDeltaCitationUnion) AsAny() anyBetaCitationsDeltaCitation { 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 BetaCitationsDeltaCitationUnion) AsCharLocation() (v BetaCitationCharLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaCitationsDeltaCitationUnion) AsPageLocation() (v BetaCitationPageLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaCitationsDeltaCitationUnion) AsContentBlockLocation() (v BetaCitationContentBlockLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaCitationsDeltaCitationUnion) AsWebSearchResultLocation() (v BetaCitationsWebSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaCitationsDeltaCitationUnion) AsSearchResultLocation() (v BetaCitationSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaCitationsDeltaCitationUnion) RawJSON() string { return u.JSON.raw } func (r *BetaCitationsDeltaCitationUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaCitationsWebSearchResultLocation struct { CitedText string `json:"cited_text" api:"required"` EncryptedIndex string `json:"encrypted_index" api:"required"` Title string `json:"title" api:"required"` Type constant.WebSearchResultLocation `json:"type" api:"required"` URL string `json:"url" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { CitedText respjson.Field EncryptedIndex respjson.Field Title respjson.Field Type respjson.Field URL respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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" api:"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" api:"required"` // Number of thinking turns that were cleared. ClearedThinkingTurns int64 `json:"cleared_thinking_turns" api:"required"` // The type of context management edit applied. Type constant.ClearThinking20251015 `json:"type" api:"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) ClearToolInputs BetaClearToolUses20250919EditClearToolInputsUnionParam `json:"clear_tool_inputs,omitzero"` // Tool names whose uses are preserved from clearing ExcludeTools []string `json:"exclude_tools,omitzero"` // Minimum number of tokens that must be cleared when triggered. Context will only // be modified if at least this many tokens can be removed. ClearAtLeast BetaInputTokensClearAtLeastParam `json:"clear_at_least,omitzero"` // Number of tool uses to retain in the conversation Keep BetaToolUsesKeepParam `json:"keep,omitzero"` // Condition that triggers the context management strategy Trigger BetaClearToolUses20250919EditTriggerUnionParam `json:"trigger,omitzero"` // This field can be elided, and will marshal its zero value as // "clear_tool_uses_20250919". Type constant.ClearToolUses20250919 `json:"type" api:"required"` paramObj } func (r BetaClearToolUses20250919EditParam) MarshalJSON() (data []byte, err error) { type shadow BetaClearToolUses20250919EditParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaClearToolUses20250919EditParam) 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 BetaClearToolUses20250919EditClearToolInputsUnionParam struct { OfBool param.Opt[bool] `json:",omitzero,inline"` OfStringArray []string `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaClearToolUses20250919EditClearToolInputsUnionParam) asAny() any { if !param.IsOmitted(u.OfBool) { return &u.OfBool.Value } else if !param.IsOmitted(u.OfStringArray) { return &u.OfStringArray } return nil } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaClearToolUses20250919EditTriggerUnionParam struct { OfInputTokens *BetaInputTokensTriggerParam `json:",omitzero,inline"` OfToolUses *BetaToolUsesTriggerParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaClearToolUses20250919EditTriggerUnionParam) asAny() any { if !param.IsOmitted(u.OfInputTokens) { return u.OfInputTokens } else if !param.IsOmitted(u.OfToolUses) { return u.OfToolUses } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaClearToolUses20250919EditTriggerUnionParam) GetType() *string { if vt := u.OfInputTokens; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfToolUses; vt != nil { return (*string)(&vt.Type) } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaClearToolUses20250919EditTriggerUnionParam) GetValue() *int64 { if vt := u.OfInputTokens; vt != nil { return (*int64)(&vt.Value) } else if vt := u.OfToolUses; vt != nil { return (*int64)(&vt.Value) } return nil } 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"), apijson.Discriminator[BetaCompactionBlockParam]("compaction"), ) } func init() { apijson.RegisterUnion[BetaContextManagementConfigEditUnionParam]( "type", apijson.Discriminator[BetaClearToolUses20250919EditParam]("clear_tool_uses_20250919"), apijson.Discriminator[BetaClearThinking20251015EditParam]("clear_thinking_20251015"), apijson.Discriminator[BetaCompact20260112EditParam]("compact_20260112"), ) } func init() { apijson.RegisterUnion[BetaImageBlockParamSourceUnion]( "type", apijson.Discriminator[BetaBase64ImageSourceParam]("base64"), apijson.Discriminator[BetaURLImageSourceParam]("url"), apijson.Discriminator[BetaFileImageSourceParam]("file"), ) } func init() { apijson.RegisterUnion[BetaRequestDocumentBlockSourceUnionParam]( "type", apijson.Discriminator[BetaBase64PDFSourceParam]("base64"), apijson.Discriminator[BetaPlainTextSourceParam]("text"), apijson.Discriminator[BetaContentBlockSourceParam]("content"), apijson.Discriminator[BetaURLPDFSourceParam]("url"), apijson.Discriminator[BetaFileDocumentSourceParam]("file"), ) } func init() { apijson.RegisterUnion[BetaServerToolUseBlockParamCallerUnion]( "type", apijson.Discriminator[BetaDirectCallerParam]("direct"), apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), apijson.Discriminator[BetaServerToolCaller20260120Param]("code_execution_20260120"), ) } func init() { apijson.RegisterUnion[BetaTextCitationParamUnion]( "type", apijson.Discriminator[BetaCitationCharLocationParam]("char_location"), apijson.Discriminator[BetaCitationPageLocationParam]("page_location"), apijson.Discriminator[BetaCitationContentBlockLocationParam]("content_block_location"), apijson.Discriminator[BetaCitationWebSearchResultLocationParam]("web_search_result_location"), apijson.Discriminator[BetaCitationSearchResultLocationParam]("search_result_location"), ) } func init() { apijson.RegisterUnion[BetaThinkingConfigParamUnion]( "type", apijson.Discriminator[BetaThinkingConfigEnabledParam]("enabled"), apijson.Discriminator[BetaThinkingConfigDisabledParam]("disabled"), apijson.Discriminator[BetaThinkingConfigAdaptiveParam]("adaptive"), ) } func init() { apijson.RegisterUnion[BetaToolChoiceUnionParam]( "type", apijson.Discriminator[BetaToolChoiceAutoParam]("auto"), apijson.Discriminator[BetaToolChoiceAnyParam]("any"), apijson.Discriminator[BetaToolChoiceToolParam]("tool"), apijson.Discriminator[BetaToolChoiceNoneParam]("none"), ) } func init() { apijson.RegisterUnion[BetaToolResultBlockParamContentUnion]( "type", apijson.Discriminator[BetaTextBlockParam]("text"), 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"), apijson.Discriminator[BetaServerToolCaller20260120Param]("code_execution_20260120"), ) } func init() { apijson.RegisterUnion[BetaWebFetchToolResultBlockParamCallerUnion]( "type", apijson.Discriminator[BetaDirectCallerParam]("direct"), apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), apijson.Discriminator[BetaServerToolCaller20260120Param]("code_execution_20260120"), ) } func init() { apijson.RegisterUnion[BetaWebSearchToolResultBlockParamCallerUnion]( "type", apijson.Discriminator[BetaDirectCallerParam]("direct"), apijson.Discriminator[BetaServerToolCallerParam]("code_execution_20250825"), apijson.Discriminator[BetaServerToolCaller20260120Param]("code_execution_20260120"), ) } type BetaClearToolUses20250919EditResponse struct { // Number of input tokens cleared by this edit. ClearedInputTokens int64 `json:"cleared_input_tokens" api:"required"` // Number of tool uses that were cleared. ClearedToolUses int64 `json:"cleared_tool_uses" api:"required"` // The type of context management edit applied. Type constant.ClearToolUses20250919 `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ClearedInputTokens respjson.Field ClearedToolUses respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaCodeExecutionOutputBlock struct { FileID string `json:"file_id" api:"required"` Type constant.CodeExecutionOutput `json:"type" api:"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 BetaCodeExecutionOutputBlock) RawJSON() string { return r.JSON.raw } func (r *BetaCodeExecutionOutputBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties FileID, Type are required. type BetaCodeExecutionOutputBlockParam struct { FileID string `json:"file_id" api:"required"` // This field can be elided, and will marshal its zero value as // "code_execution_output". Type constant.CodeExecutionOutput `json:"type" api:"required"` paramObj } 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) } type BetaCodeExecutionResultBlock struct { Content []BetaCodeExecutionOutputBlock `json:"content" api:"required"` ReturnCode int64 `json:"return_code" api:"required"` Stderr string `json:"stderr" api:"required"` Stdout string `json:"stdout" api:"required"` Type constant.CodeExecutionResult `json:"type" api:"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 BetaCodeExecutionResultBlock) RawJSON() string { return r.JSON.raw } func (r *BetaCodeExecutionResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Content, ReturnCode, Stderr, Stdout, Type are required. type BetaCodeExecutionResultBlockParam struct { Content []BetaCodeExecutionOutputBlockParam `json:"content,omitzero" api:"required"` ReturnCode int64 `json:"return_code" api:"required"` Stderr string `json:"stderr" api:"required"` Stdout string `json:"stdout" api:"required"` // This field can be elided, and will marshal its zero value as // "code_execution_result". Type constant.CodeExecutionResult `json:"type" api:"required"` paramObj } 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. // // 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" api:"required"` // This field can be elided, and will marshal its zero value as // "code_execution_20250522". Type constant.CodeExecution20250522 `json:"type" api:"required"` paramObj } func (r BetaCodeExecutionTool20250522Param) MarshalJSON() (data []byte, err error) { 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. // // 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" api:"required"` // This field can be elided, and will marshal its zero value as // "code_execution_20250825". Type constant.CodeExecution20250825 `json:"type" api:"required"` paramObj } func (r BetaCodeExecutionTool20250825Param) MarshalJSON() (data []byte, err error) { 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" api:"required"` // This field can be elided, and will marshal its zero value as // "code_execution_20260120". Type constant.CodeExecution20260120 `json:"type" api:"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" api:"required"` ToolUseID string `json:"tool_use_id" api:"required"` Type constant.CodeExecutionToolResult `json:"type" api:"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 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], [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"` Content []BetaCodeExecutionOutputBlock `json:"content"` ReturnCode int64 `json:"return_code"` Stderr string `json:"stderr"` // This field is from variant [BetaCodeExecutionResultBlock]. Stdout string `json:"stdout"` // 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 } func (u BetaCodeExecutionToolResultBlockContentUnion) AsResponseCodeExecutionResultBlock() (v BetaCodeExecutionResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &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 func (u BetaCodeExecutionToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } func (r *BetaCodeExecutionToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // 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" api:"required"` ToolUseID string `json:"tool_use_id" api:"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 // "code_execution_tool_result". Type constant.CodeExecutionToolResult `json:"type" api:"required"` paramObj } func (r BetaCodeExecutionToolResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaCodeExecutionToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaCodeExecutionToolResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } func BetaNewCodeExecutionToolRequestError(errorCode BetaCodeExecutionToolResultErrorCode) BetaCodeExecutionToolResultBlockParamContentUnion { var variant BetaCodeExecutionToolResultErrorParam variant.ErrorCode = errorCode return BetaCodeExecutionToolResultBlockParamContentUnion{OfError: &variant} } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaCodeExecutionToolResultBlockParamContentUnion struct { 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, u.OfRequestEncryptedCodeExecutionResultBlock) } func (u *BetaCodeExecutionToolResultBlockParamContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } func (u *BetaCodeExecutionToolResultBlockParamContentUnion) asAny() any { if !param.IsOmitted(u.OfError) { return u.OfError } else if !param.IsOmitted(u.OfResultBlock) { return u.OfResultBlock } else if !param.IsOmitted(u.OfRequestEncryptedCodeExecutionResultBlock) { return u.OfRequestEncryptedCodeExecutionResultBlock } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetErrorCode() *string { if vt := u.OfError; vt != nil { return (*string)(&vt.ErrorCode) } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaCodeExecutionToolResultBlockParamContentUnion) GetStdout() *string { if vt := u.OfResultBlock; vt != nil { return &vt.Stdout } return nil } // Returns a pointer to the underlying variant's property, if present. 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) 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) GetReturnCode() *int64 { if vt := u.OfResultBlock; 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 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 } type BetaCodeExecutionToolResultError struct { // Any of "invalid_tool_input", "unavailable", "too_many_requests", // "execution_time_exceeded". ErrorCode BetaCodeExecutionToolResultErrorCode `json:"error_code" api:"required"` Type constant.CodeExecutionToolResultError `json:"type" api:"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 BetaCodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } func (r *BetaCodeExecutionToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaCodeExecutionToolResultErrorCode string const ( BetaCodeExecutionToolResultErrorCodeInvalidToolInput BetaCodeExecutionToolResultErrorCode = "invalid_tool_input" BetaCodeExecutionToolResultErrorCodeUnavailable BetaCodeExecutionToolResultErrorCode = "unavailable" BetaCodeExecutionToolResultErrorCodeTooManyRequests BetaCodeExecutionToolResultErrorCode = "too_many_requests" BetaCodeExecutionToolResultErrorCodeExecutionTimeExceeded BetaCodeExecutionToolResultErrorCode = "execution_time_exceeded" ) // The properties ErrorCode, Type are required. type BetaCodeExecutionToolResultErrorParam struct { // Any of "invalid_tool_input", "unavailable", "too_many_requests", // "execution_time_exceeded". ErrorCode BetaCodeExecutionToolResultErrorCode `json:"error_code,omitzero" api:"required"` // This field can be elided, and will marshal its zero value as // "code_execution_tool_result_error". Type constant.CodeExecutionToolResultError `json:"type" api:"required"` paramObj } func (r BetaCodeExecutionToolResultErrorParam) MarshalJSON() (data []byte, err error) { type shadow BetaCodeExecutionToolResultErrorParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaCodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // 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" api:"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" api:"required"` Type constant.Compaction `json:"type" api:"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" api:"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" api:"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" api:"required"` Type constant.CompactionDelta `json:"type" api:"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" api:"required"` // The number of input tokens used to create the cache entry. CacheCreationInputTokens int64 `json:"cache_creation_input_tokens" api:"required"` // The number of input tokens read from the cache. CacheReadInputTokens int64 `json:"cache_read_input_tokens" api:"required"` // The number of input tokens which were used. InputTokens int64 `json:"input_tokens" api:"required"` // The number of output tokens which were used. OutputTokens int64 `json:"output_tokens" api:"required"` // Usage for a compaction iteration Type constant.Compaction `json:"type" api:"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" api:"required"` // The time at which the container will expire. ExpiresAt time.Time `json:"expires_at" api:"required" format:"date-time"` // Skills loaded in the container Skills []BetaSkill `json:"skills" api:"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:"-"` } // 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" api:"required"` Type constant.ContainerUpload `json:"type" api:"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 BetaContainerUploadBlock) RawJSON() string { return r.JSON.raw } func (r *BetaContainerUploadBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // 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. // // The properties FileID, Type are required. type BetaContainerUploadBlockParam struct { FileID string `json:"file_id" api:"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 "container_upload". Type constant.ContainerUpload `json:"type" api:"required"` paramObj } 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) } // BetaContentBlockUnion contains all possible properties and values from // [BetaTextBlock], [BetaThinkingBlock], [BetaRedactedThinkingBlock], // [BetaToolUseBlock], [BetaServerToolUseBlock], [BetaWebSearchToolResultBlock], // [BetaWebFetchToolResultBlock], [BetaCodeExecutionToolResultBlock], // [BetaBashCodeExecutionToolResultBlock], // [BetaTextEditorCodeExecutionToolResultBlock], [BetaToolSearchToolResultBlock], // [BetaMCPToolUseBlock], [BetaMCPToolResultBlock], [BetaContainerUploadBlock], // [BetaCompactionBlock]. // // Use the [BetaContentBlockUnion.AsAny] method to switch on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaContentBlockUnion struct { // This field is from variant [BetaTextBlock]. Citations []BetaTextCitationUnion `json:"citations"` // This field is from variant [BetaTextBlock]. 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", "mcp_tool_use", "mcp_tool_result", // "container_upload", "compaction". Type string `json:"type"` // This field is from variant [BetaThinkingBlock]. Signature string `json:"signature"` // This field is from variant [BetaThinkingBlock]. Thinking string `json:"thinking"` // This field is from variant [BetaRedactedThinkingBlock]. Data string `json:"data"` ID string `json:"id"` // 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], // [BetaToolSearchToolResultBlockContentUnion], // [BetaMCPToolResultBlockContentUnion], [string] Content BetaContentBlockUnionContent `json:"content"` ToolUseID string `json:"tool_use_id"` // This field is from variant [BetaMCPToolUseBlock]. ServerName string `json:"server_name"` // This field is from variant [BetaMCPToolResultBlock]. IsError bool `json:"is_error"` // This field is from variant [BetaContainerUploadBlock]. 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 Input respjson.Field Name respjson.Field Caller respjson.Field Content respjson.Field ToolUseID respjson.Field ServerName respjson.Field IsError respjson.Field FileID respjson.Field raw string } `json:"-"` } // 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() {} func (BetaThinkingBlock) implBetaContentBlockUnion() {} func (BetaRedactedThinkingBlock) implBetaContentBlockUnion() {} func (BetaToolUseBlock) implBetaContentBlockUnion() {} func (BetaServerToolUseBlock) implBetaContentBlockUnion() {} func (BetaWebSearchToolResultBlock) implBetaContentBlockUnion() {} 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 // // switch variant := BetaContentBlockUnion.AsAny().(type) { // case anthropic.BetaTextBlock: // case anthropic.BetaThinkingBlock: // case anthropic.BetaRedactedThinkingBlock: // case anthropic.BetaToolUseBlock: // case anthropic.BetaServerToolUseBlock: // case anthropic.BetaWebSearchToolResultBlock: // case anthropic.BetaWebFetchToolResultBlock: // 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") // } func (u BetaContentBlockUnion) AsAny() anyBetaContentBlock { 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 "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 } func (u BetaContentBlockUnion) AsThinking() (v BetaThinkingBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsRedactedThinking() (v BetaRedactedThinkingBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsToolUse() (v BetaToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsServerToolUse() (v BetaServerToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsWebSearchToolResult() (v BetaWebSearchToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsWebFetchToolResult() (v BetaWebFetchToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsCodeExecutionToolResult() (v BetaCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsBashCodeExecutionToolResult() (v BetaBashCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsTextEditorCodeExecutionToolResult() (v BetaTextEditorCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &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 } func (u BetaContentBlockUnion) AsMCPToolResult() (v BetaMCPToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaContentBlockUnion) AsContainerUpload() (v BetaContainerUploadBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &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 func (u BetaContentBlockUnion) RawJSON() string { return u.JSON.raw } 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. // // For type safety it is recommended to directly use a variant of the // [BetaContentBlockUnion]. // // If the underlying value is not a json object, one of the following properties // will be valid: OfBetaWebSearchResultBlockArray OfString // OfBetaMCPToolResultBlockContent] type BetaContentBlockUnionContent struct { // This field will be present if the value is a [[]BetaWebSearchResultBlock] // instead of an object. OfBetaWebSearchResultBlockArray []BetaWebSearchResultBlock `json:",inline"` // This field will be present if the value is a [string] instead of an object. OfString string `json:",inline"` // This field will be present if the value is a [[]BetaTextBlock] instead of an // object. OfBetaMCPToolResultBlockContent []BetaTextBlock `json:",inline"` ErrorCode string `json:"error_code"` Type string `json:"type"` // This field is a union of [BetaDocumentBlock], [[]BetaCodeExecutionOutputBlock], // [[]BetaCodeExecutionOutputBlock], [[]BetaBashCodeExecutionOutputBlock], [string] Content BetaContentBlockUnionContentContent `json:"content"` // This field is from variant [BetaWebFetchToolResultBlockContentUnion]. RetrievedAt string `json:"retrieved_at"` // This field is from variant [BetaWebFetchToolResultBlockContentUnion]. URL string `json:"url"` ReturnCode int64 `json:"return_code"` Stderr string `json:"stderr"` Stdout string `json:"stdout"` // 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"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. NumLines int64 `json:"num_lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. StartLine int64 `json:"start_line"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. TotalLines int64 `json:"total_lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. IsFileUpdate bool `json:"is_file_update"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. Lines []string `json:"lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. NewLines int64 `json:"new_lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. NewStart int64 `json:"new_start"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. OldLines int64 `json:"old_lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. OldStart int64 `json:"old_start"` // This field is from variant [BetaToolSearchToolResultBlockContentUnion]. ToolReferences []BetaToolReferenceBlock `json:"tool_references"` JSON struct { OfBetaWebSearchResultBlockArray respjson.Field OfString respjson.Field OfBetaMCPToolResultBlockContent 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 *BetaContentBlockUnionContent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaContentBlockUnionContentContent is an implicit subunion of // [BetaContentBlockUnion]. BetaContentBlockUnionContentContent provides convenient // access to the sub-properties of the union. // // For type safety it is recommended to directly use a variant of the // [BetaContentBlockUnion]. // // If the underlying value is not a json object, one of the following properties // will be valid: OfContent OfString] type BetaContentBlockUnionContentContent struct { // This field will be present if the value is a [[]BetaCodeExecutionOutputBlock] // instead of an object. OfContent []BetaCodeExecutionOutputBlock `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 [BetaDocumentBlock]. Citations BetaCitationConfig `json:"citations"` // This field is from variant [BetaDocumentBlock]. Source BetaDocumentBlockSourceUnion `json:"source"` // This field is from variant [BetaDocumentBlock]. Title string `json:"title"` // This field is from variant [BetaDocumentBlock]. 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 *BetaContentBlockUnionContentContent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } func NewBetaTextBlock(text string) BetaContentBlockParamUnion { var variant BetaTextBlockParam variant.Text = text return BetaContentBlockParamUnion{OfText: &variant} } func NewBetaImageBlock[ T BetaBase64ImageSourceParam | BetaURLImageSourceParam | BetaFileImageSourceParam, ](source T) BetaContentBlockParamUnion { var image BetaImageBlockParam switch v := any(source).(type) { case BetaBase64ImageSourceParam: image.Source.OfBase64 = &v case BetaURLImageSourceParam: image.Source.OfURL = &v case BetaFileImageSourceParam: image.Source.OfFile = &v } return BetaContentBlockParamUnion{OfImage: &image} } func NewBetaDocumentBlock[ T BetaBase64PDFSourceParam | BetaPlainTextSourceParam | BetaContentBlockSourceParam | BetaURLPDFSourceParam | BetaFileDocumentSourceParam, ](source T) BetaContentBlockParamUnion { var document BetaRequestDocumentBlockParam switch v := any(source).(type) { case BetaBase64PDFSourceParam: document.Source.OfBase64 = &v case BetaPlainTextSourceParam: document.Source.OfText = &v case BetaContentBlockSourceParam: document.Source.OfContent = &v case BetaURLPDFSourceParam: document.Source.OfURL = &v case BetaFileDocumentSourceParam: document.Source.OfFile = &v } return BetaContentBlockParamUnion{OfDocument: &document} } func NewBetaSearchResultBlock(content []BetaTextBlockParam, source string, title string) BetaContentBlockParamUnion { var searchResult BetaSearchResultBlockParam searchResult.Content = content searchResult.Source = source searchResult.Title = title return BetaContentBlockParamUnion{OfSearchResult: &searchResult} } func NewBetaThinkingBlock(signature string, thinking string) BetaContentBlockParamUnion { var variant BetaThinkingBlockParam variant.Signature = signature variant.Thinking = thinking return BetaContentBlockParamUnion{OfThinking: &variant} } func NewBetaRedactedThinkingBlock(data string) BetaContentBlockParamUnion { var redactedThinking BetaRedactedThinkingBlockParam redactedThinking.Data = data return BetaContentBlockParamUnion{OfRedactedThinking: &redactedThinking} } func NewBetaToolUseBlock(id string, input any, name string) BetaContentBlockParamUnion { var toolUse BetaToolUseBlockParam toolUse.ID = id toolUse.Input = input toolUse.Name = name return BetaContentBlockParamUnion{OfToolUse: &toolUse} } 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 { var serverToolUse BetaServerToolUseBlockParam serverToolUse.ID = id serverToolUse.Input = input serverToolUse.Name = name return BetaContentBlockParamUnion{OfServerToolUse: &serverToolUse} } func NewBetaWebSearchToolResultBlock[ T []BetaWebSearchResultBlockParam | BetaWebSearchToolRequestErrorParam, ](content T, toolUseID string) BetaContentBlockParamUnion { var webSearchToolResult BetaWebSearchToolResultBlockParam switch v := any(content).(type) { case []BetaWebSearchResultBlockParam: webSearchToolResult.Content.OfResultBlock = v case BetaWebSearchToolRequestErrorParam: webSearchToolResult.Content.OfError = &v } webSearchToolResult.ToolUseID = toolUseID return BetaContentBlockParamUnion{OfWebSearchToolResult: &webSearchToolResult} } func NewBetaWebFetchToolResultBlock[ T BetaWebFetchToolResultErrorBlockParam | BetaWebFetchBlockParam, ](content T, toolUseID string) BetaContentBlockParamUnion { var webFetchToolResult BetaWebFetchToolResultBlockParam switch v := any(content).(type) { case BetaWebFetchToolResultErrorBlockParam: webFetchToolResult.Content.OfRequestWebFetchToolResultError = &v case BetaWebFetchBlockParam: webFetchToolResult.Content.OfRequestWebFetchResultBlock = &v } webFetchToolResult.ToolUseID = toolUseID return BetaContentBlockParamUnion{OfWebFetchToolResult: &webFetchToolResult} } func NewBetaCodeExecutionToolResultBlock[ T BetaCodeExecutionToolResultErrorParam | BetaCodeExecutionResultBlockParam | BetaEncryptedCodeExecutionResultBlockParam, ](content T, toolUseID string) BetaContentBlockParamUnion { var codeExecutionToolResult BetaCodeExecutionToolResultBlockParam switch v := any(content).(type) { case BetaCodeExecutionToolResultErrorParam: codeExecutionToolResult.Content.OfError = &v case BetaCodeExecutionResultBlockParam: codeExecutionToolResult.Content.OfResultBlock = &v case BetaEncryptedCodeExecutionResultBlockParam: codeExecutionToolResult.Content.OfRequestEncryptedCodeExecutionResultBlock = &v } codeExecutionToolResult.ToolUseID = toolUseID return BetaContentBlockParamUnion{OfCodeExecutionToolResult: &codeExecutionToolResult} } func NewBetaBashCodeExecutionToolResultBlock[ T BetaBashCodeExecutionToolResultErrorParam | BetaBashCodeExecutionResultBlockParam, ](content T, toolUseID string) BetaContentBlockParamUnion { var bashCodeExecutionToolResult BetaBashCodeExecutionToolResultBlockParam switch v := any(content).(type) { case BetaBashCodeExecutionToolResultErrorParam: bashCodeExecutionToolResult.Content.OfRequestBashCodeExecutionToolResultError = &v case BetaBashCodeExecutionResultBlockParam: bashCodeExecutionToolResult.Content.OfRequestBashCodeExecutionResultBlock = &v } bashCodeExecutionToolResult.ToolUseID = toolUseID return BetaContentBlockParamUnion{OfBashCodeExecutionToolResult: &bashCodeExecutionToolResult} } func NewBetaTextEditorCodeExecutionToolResultBlock[ T BetaTextEditorCodeExecutionToolResultErrorParam | BetaTextEditorCodeExecutionViewResultBlockParam | BetaTextEditorCodeExecutionCreateResultBlockParam | BetaTextEditorCodeExecutionStrReplaceResultBlockParam, ](content T, toolUseID string) BetaContentBlockParamUnion { var textEditorCodeExecutionToolResult BetaTextEditorCodeExecutionToolResultBlockParam switch v := any(content).(type) { case BetaTextEditorCodeExecutionToolResultErrorParam: textEditorCodeExecutionToolResult.Content.OfRequestTextEditorCodeExecutionToolResultError = &v case BetaTextEditorCodeExecutionViewResultBlockParam: textEditorCodeExecutionToolResult.Content.OfRequestTextEditorCodeExecutionViewResultBlock = &v case BetaTextEditorCodeExecutionCreateResultBlockParam: textEditorCodeExecutionToolResult.Content.OfRequestTextEditorCodeExecutionCreateResultBlock = &v case BetaTextEditorCodeExecutionStrReplaceResultBlockParam: textEditorCodeExecutionToolResult.Content.OfRequestTextEditorCodeExecutionStrReplaceResultBlock = &v } textEditorCodeExecutionToolResult.ToolUseID = toolUseID 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 return BetaContentBlockParamUnion{OfMCPToolResult: &mcpToolResult} } func NewBetaContainerUploadBlock(fileID string) BetaContentBlockParamUnion { var containerUpload BetaContainerUploadBlockParam containerUpload.FileID = fileID 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. type BetaContentBlockParamUnion struct { OfText *BetaTextBlockParam `json:",omitzero,inline"` OfImage *BetaImageBlockParam `json:",omitzero,inline"` OfDocument *BetaRequestDocumentBlockParam `json:",omitzero,inline"` OfSearchResult *BetaSearchResultBlockParam `json:",omitzero,inline"` OfThinking *BetaThinkingBlockParam `json:",omitzero,inline"` OfRedactedThinking *BetaRedactedThinkingBlockParam `json:",omitzero,inline"` OfToolUse *BetaToolUseBlockParam `json:",omitzero,inline"` OfToolResult *BetaToolResultBlockParam `json:",omitzero,inline"` OfServerToolUse *BetaServerToolUseBlockParam `json:",omitzero,inline"` OfWebSearchToolResult *BetaWebSearchToolResultBlockParam `json:",omitzero,inline"` OfWebFetchToolResult *BetaWebFetchToolResultBlockParam `json:",omitzero,inline"` 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 } func (u BetaContentBlockParamUnion) 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.OfMCPToolUse, u.OfMCPToolResult, u.OfContainerUpload, u.OfCompaction) } func (u *BetaContentBlockParamUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } func (u *BetaContentBlockParamUnion) 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 } 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.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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaContentBlockParamUnion) 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 BetaContentBlockParamUnion) 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 BetaContentBlockParamUnion) 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 BetaContentBlockParamUnion) 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 BetaContentBlockParamUnion) 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 BetaContentBlockParamUnion) GetServerName() *string { if vt := u.OfMCPToolUse; vt != nil { return &vt.ServerName } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaContentBlockParamUnion) 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 BetaContentBlockParamUnion) 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 { 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.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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaContentBlockParamUnion) 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 BetaContentBlockParamUnion) GetID() *string { if vt := u.OfToolUse; vt != nil { return (*string)(&vt.ID) } else if vt := u.OfServerToolUse; vt != nil { return (*string)(&vt.ID) } else if vt := u.OfMCPToolUse; vt != nil { return (*string)(&vt.ID) } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaContentBlockParamUnion) GetName() *string { if vt := u.OfToolUse; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfServerToolUse; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfMCPToolUse; vt != nil { return (*string)(&vt.Name) } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaContentBlockParamUnion) 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) } else if vt := u.OfMCPToolResult; vt != nil { return (*string)(&vt.ToolUseID) } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaContentBlockParamUnion) GetIsError() *bool { if vt := u.OfToolResult; vt != nil && vt.IsError.Valid() { return &vt.IsError.Value } else if vt := u.OfMCPToolResult; vt != nil && vt.IsError.Valid() { return &vt.IsError.Value } return nil } // Returns a pointer to the underlying variant's CacheControl property, if present. func (u BetaContentBlockParamUnion) GetCacheControl() *BetaCacheControlEphemeralParam { 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.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 } // Returns a subunion which exports methods to access subproperties // // Or use AsAny() to get the underlying value func (u BetaContentBlockParamUnion) GetCitations() (res betaContentBlockParamUnionCitations) { 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 } // Can have the runtime types [*[]BetaTextCitationParamUnion], // [*BetaCitationsConfigParam] type betaContentBlockParamUnionCitations struct{ any } // Use the following switch statement to get the type of the union: // // switch u.AsAny().(type) { // case *[]anthropic.BetaTextCitationParamUnion: // case *anthropic.BetaCitationsConfigParam: // default: // fmt.Errorf("not present") // } func (u betaContentBlockParamUnionCitations) AsAny() any { return u.any } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionCitations) GetEnabled() *bool { switch vt := u.any.(type) { case *BetaCitationsConfigParam: 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 BetaContentBlockParamUnion) GetSource() (res betaContentBlockParamUnionSource) { 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 [*BetaBase64ImageSourceParam], // [*BetaURLImageSourceParam], [*BetaFileImageSourceParam], // [*BetaBase64PDFSourceParam], [*BetaPlainTextSourceParam], // [*BetaContentBlockSourceParam], [*BetaURLPDFSourceParam], // [*BetaFileDocumentSourceParam], [*string] type betaContentBlockParamUnionSource struct{ any } // Use the following switch statement to get the type of the union: // // switch u.AsAny().(type) { // case *anthropic.BetaBase64ImageSourceParam: // case *anthropic.BetaURLImageSourceParam: // case *anthropic.BetaFileImageSourceParam: // case *anthropic.BetaBase64PDFSourceParam: // case *anthropic.BetaPlainTextSourceParam: // case *anthropic.BetaContentBlockSourceParam: // case *anthropic.BetaURLPDFSourceParam: // case *anthropic.BetaFileDocumentSourceParam: // case *string: // default: // fmt.Errorf("not present") // } func (u betaContentBlockParamUnionSource) AsAny() any { return u.any } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionSource) GetContent() *BetaContentBlockSourceContentUnionParam { switch vt := u.any.(type) { case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetContent() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionSource) GetData() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetData() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetData() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionSource) GetMediaType() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetMediaType() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetMediaType() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionSource) GetType() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetType() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetType() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionSource) GetURL() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetURL() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetURL() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionSource) GetFileID() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetFileID() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetFileID() } return nil } // Returns a subunion which exports methods to access subproperties // // Or use AsAny() to get the underlying value func (u BetaContentBlockParamUnion) GetContent() (res betaContentBlockParamUnionContent) { 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() } 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 } // Can have the runtime types [_[]BetaTextBlockParam], // [_[]BetaToolResultBlockParamContentUnion], [*[]BetaWebSearchResultBlockParam], // [*BetaWebFetchToolResultErrorBlockParam], [*BetaWebFetchBlockParam], // [*BetaCodeExecutionToolResultErrorParam], [*BetaCodeExecutionResultBlockParam], // [*BetaEncryptedCodeExecutionResultBlockParam], // [*BetaBashCodeExecutionToolResultErrorParam], // [*BetaBashCodeExecutionResultBlockParam], // [*BetaTextEditorCodeExecutionToolResultErrorParam], // [*BetaTextEditorCodeExecutionViewResultBlockParam], // [*BetaTextEditorCodeExecutionCreateResultBlockParam], // [*BetaTextEditorCodeExecutionStrReplaceResultBlockParam], // [*BetaToolSearchToolResultErrorParam], // [*BetaToolSearchToolSearchResultBlockParam], [*string] type betaContentBlockParamUnionContent struct{ any } // Use the following switch statement to get the type of the union: // // switch u.AsAny().(type) { // case *[]anthropic.BetaTextBlockParam: // case *[]anthropic.BetaToolResultBlockParamContentUnion: // case *[]anthropic.BetaWebSearchResultBlockParam: // case *anthropic.BetaWebFetchToolResultErrorBlockParam: // 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") // } func (u betaContentBlockParamUnionContent) AsAny() any { return u.any } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetURL() *string { switch vt := u.any.(type) { case *BetaWebFetchToolResultBlockParamContentUnion: return vt.GetURL() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetRetrievedAt() *string { switch vt := u.any.(type) { case *BetaWebFetchToolResultBlockParamContentUnion: return vt.GetRetrievedAt() } 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) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetErrorMessage() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetFileType() *string { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetFileType() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetNumLines() *int64 { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetNumLines() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetStartLine() *int64 { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetStartLine() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetTotalLines() *int64 { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetTotalLines() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetIsFileUpdate() *bool { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetIsFileUpdate() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetLines() []string { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetLines() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetNewLines() *int64 { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetNewLines() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetNewStart() *int64 { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetNewStart() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetOldLines() *int64 { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetOldLines() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetOldStart() *int64 { switch vt := u.any.(type) { case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetOldStart() } 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) { case *BetaWebSearchToolResultBlockParamContentUnion: if vt.OfError != nil { return (*string)(&vt.OfError.ErrorCode) } case *BetaWebFetchToolResultBlockParamContentUnion: return vt.GetErrorCode() case *BetaCodeExecutionToolResultBlockParamContentUnion: return vt.GetErrorCode() case *BetaBashCodeExecutionToolResultBlockParamContentUnion: return vt.GetErrorCode() case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetErrorCode() case *BetaToolSearchToolResultBlockParamContentUnion: return vt.GetErrorCode() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetType() *string { switch vt := u.any.(type) { case *BetaWebSearchToolResultBlockParamContentUnion: if vt.OfError != nil { return (*string)(&vt.OfError.Type) } case *BetaWebFetchToolResultBlockParamContentUnion: return vt.GetType() case *BetaCodeExecutionToolResultBlockParamContentUnion: return vt.GetType() case *BetaBashCodeExecutionToolResultBlockParamContentUnion: return vt.GetType() case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: return vt.GetType() case *BetaToolSearchToolResultBlockParamContentUnion: return vt.GetType() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetReturnCode() *int64 { switch vt := u.any.(type) { case *BetaCodeExecutionToolResultBlockParamContentUnion: return vt.GetReturnCode() case *BetaBashCodeExecutionToolResultBlockParamContentUnion: return vt.GetReturnCode() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetStderr() *string { switch vt := u.any.(type) { case *BetaCodeExecutionToolResultBlockParamContentUnion: return vt.GetStderr() case *BetaBashCodeExecutionToolResultBlockParamContentUnion: return vt.GetStderr() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaContentBlockParamUnionContent) GetStdout() *string { switch vt := u.any.(type) { case *BetaCodeExecutionToolResultBlockParamContentUnion: return vt.GetStdout() case *BetaBashCodeExecutionToolResultBlockParamContentUnion: return vt.GetStdout() } return nil } // Returns a subunion which exports methods to access subproperties // // Or use AsAny() to get the underlying value func (u betaContentBlockParamUnionContent) GetContent() (res betaContentBlockParamUnionContentContent) { switch vt := u.any.(type) { case *BetaWebFetchToolResultBlockParamContentUnion: res.any = vt.GetContent() case *BetaCodeExecutionToolResultBlockParamContentUnion: res.any = vt.GetContent() case *BetaBashCodeExecutionToolResultBlockParamContentUnion: res.any = vt.GetContent() case *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion: res.any = vt.GetContent() } return res } // Can have the runtime types [*BetaRequestDocumentBlockParam], // [_[]BetaCodeExecutionOutputBlockParam], // [_[]BetaBashCodeExecutionOutputBlockParam], [*string] type betaContentBlockParamUnionContentContent struct{ any } // Use the following switch statement to get the type of the union: // // switch u.AsAny().(type) { // case *anthropic.BetaRequestDocumentBlockParam: // case *[]anthropic.BetaCodeExecutionOutputBlockParam: // case *[]anthropic.BetaBashCodeExecutionOutputBlockParam: // case *string: // default: // fmt.Errorf("not present") // } func (u betaContentBlockParamUnionContentContent) AsAny() any { return u.any } // Returns a pointer to the underlying variant's Input property, if present. func (u BetaContentBlockParamUnion) GetInput() *any { if vt := u.OfToolUse; vt != nil { return &vt.Input } else if vt := u.OfServerToolUse; vt != nil { return &vt.Input } else if vt := u.OfMCPToolUse; vt != nil { return &vt.Input } 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" api:"required"` // This field can be elided, and will marshal its zero value as "content". Type constant.Content `json:"type" api:"required"` paramObj } 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) } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaContentBlockSourceContentUnionParam struct { OfString param.Opt[string] `json:",omitzero,inline"` OfBetaContentBlockSourceContent []BetaContentBlockSourceContentUnionParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaContentBlockSourceContentUnionParam) asAny() any { if !param.IsOmitted(u.OfString) { return &u.OfString.Value } else if !param.IsOmitted(u.OfBetaContentBlockSourceContent) { return &u.OfBetaContentBlockSourceContent } return nil } type BetaContextManagementConfigParam struct { // List of context management edits to apply Edits []BetaContextManagementConfigEditUnionParam `json:"edits,omitzero"` paramObj } 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) } // 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 } func (u BetaContextManagementConfigEditUnionParam) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfClearToolUses20250919, u.OfClearThinking20251015, u.OfCompact20260112) } func (u *BetaContextManagementConfigEditUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } 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 } // 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 } // 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 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 } // 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 } // 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" api:"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" api:"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" api:"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" api:"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" api:"required"` Source BetaDocumentBlockSourceUnion `json:"source" api:"required"` // The title of the document Title string `json:"title" api:"required"` Type constant.Document `json:"type" api:"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. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaDocumentBlockSourceUnion struct { Data string `json:"data"` MediaType string `json:"media_type"` // Any of "base64", "text". Type string `json:"type"` JSON struct { Data respjson.Field MediaType respjson.Field Type respjson.Field raw string } `json:"-"` } // anyBetaDocumentBlockSource is implemented by each variant of // [BetaDocumentBlockSourceUnion] to add type safety for the return type of // [BetaDocumentBlockSourceUnion.AsAny] type anyBetaDocumentBlockSource interface { implBetaDocumentBlockSourceUnion() } func (BetaBase64PDFSource) implBetaDocumentBlockSourceUnion() {} func (BetaPlainTextSource) implBetaDocumentBlockSourceUnion() {} // Use the following switch statement to find the correct variant // // switch variant := BetaDocumentBlockSourceUnion.AsAny().(type) { // case anthropic.BetaBase64PDFSource: // case anthropic.BetaPlainTextSource: // default: // fmt.Errorf("no variant present") // } func (u BetaDocumentBlockSourceUnion) AsAny() anyBetaDocumentBlockSource { switch u.Type { case "base64": return u.AsBase64() case "text": return u.AsText() } return nil } func (u BetaDocumentBlockSourceUnion) AsBase64() (v BetaBase64PDFSource) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaDocumentBlockSourceUnion) AsText() (v BetaPlainTextSource) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaDocumentBlockSourceUnion) RawJSON() string { return u.JSON.raw } 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" api:"required"` EncryptedStdout string `json:"encrypted_stdout" api:"required"` ReturnCode int64 `json:"return_code" api:"required"` Stderr string `json:"stderr" api:"required"` Type constant.EncryptedCodeExecutionResult `json:"type" api:"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" api:"required"` EncryptedStdout string `json:"encrypted_stdout" api:"required"` ReturnCode int64 `json:"return_code" api:"required"` Stderr string `json:"stderr" api:"required"` // This field can be elided, and will marshal its zero value as // "encrypted_code_execution_result". Type constant.EncryptedCodeExecutionResult `json:"type" api:"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" api:"required"` // This field can be elided, and will marshal its zero value as "file". Type constant.File `json:"type" api:"required"` paramObj } 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) } // The properties FileID, Type are required. type BetaFileImageSourceParam struct { FileID string `json:"file_id" api:"required"` // This field can be elided, and will marshal its zero value as "file". Type constant.File `json:"type" api:"required"` paramObj } 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) } // The properties Source, Type are required. type BetaImageBlockParam struct { Source BetaImageBlockParamSourceUnion `json:"source,omitzero" api:"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 "image". Type constant.Image `json:"type" api:"required"` paramObj } 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) } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaImageBlockParamSourceUnion struct { OfBase64 *BetaBase64ImageSourceParam `json:",omitzero,inline"` OfURL *BetaURLImageSourceParam `json:",omitzero,inline"` OfFile *BetaFileImageSourceParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaImageBlockParamSourceUnion) asAny() any { if !param.IsOmitted(u.OfBase64) { return u.OfBase64 } else if !param.IsOmitted(u.OfURL) { return u.OfURL } else if !param.IsOmitted(u.OfFile) { return u.OfFile } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaImageBlockParamSourceUnion) 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 BetaImageBlockParamSourceUnion) 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 BetaImageBlockParamSourceUnion) 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 BetaImageBlockParamSourceUnion) GetFileID() *string { if vt := u.OfFile; vt != nil { return &vt.FileID } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaImageBlockParamSourceUnion) GetType() *string { if vt := u.OfBase64; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfURL; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfFile; vt != nil { return (*string)(&vt.Type) } return nil } type BetaInputJSONDelta struct { PartialJSON string `json:"partial_json" api:"required"` Type constant.InputJSONDelta `json:"type" api:"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 BetaInputJSONDelta) RawJSON() string { return r.JSON.raw } func (r *BetaInputJSONDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Type, Value are required. type BetaInputTokensClearAtLeastParam struct { Value int64 `json:"value" api:"required"` // This field can be elided, and will marshal its zero value as "input_tokens". Type constant.InputTokens `json:"type" api:"required"` paramObj } 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) } // The properties Type, Value are required. type BetaInputTokensTriggerParam struct { Value int64 `json:"value" api:"required"` // This field can be elided, and will marshal its zero value as "input_tokens". Type constant.InputTokens `json:"type" api:"required"` paramObj } 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 [BetaIterationsUsageItemUnion.AsAny] method to switch on the variant. // // 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"` // Any of "message", "compaction". 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:"-"` } // anyBetaIterationsUsageItem is implemented by each variant of // [BetaIterationsUsageItemUnion] to add type safety for the return type of // [BetaIterationsUsageItemUnion.AsAny] type anyBetaIterationsUsageItem interface { implBetaIterationsUsageItemUnion() } func (BetaMessageIterationUsage) implBetaIterationsUsageItemUnion() {} func (BetaCompactionIterationUsage) implBetaIterationsUsageItemUnion() {} // Use the following switch statement to find the correct variant // // switch variant := BetaIterationsUsageItemUnion.AsAny().(type) { // case anthropic.BetaMessageIterationUsage: // case anthropic.BetaCompactionIterationUsage: // default: // fmt.Errorf("no variant present") // } func (u BetaIterationsUsageItemUnion) AsAny() anyBetaIterationsUsageItem { switch u.Type { case "message": return u.AsMessage() case "compaction": return u.AsCompaction() } return nil } func (u BetaIterationsUsageItemUnion) AsMessage() (v BetaMessageIterationUsage) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaIterationsUsageItemUnion) AsCompaction() (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" api:"required"` // This field can be elided, and will marshal its zero value as "json_schema". Type constant.JSONSchema `json:"type" api:"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" api:"required"` IsError bool `json:"is_error" api:"required"` ToolUseID string `json:"tool_use_id" api:"required"` Type constant.MCPToolResult `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Content respjson.Field IsError 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 BetaMCPToolResultBlock) RawJSON() string { return r.JSON.raw } func (r *BetaMCPToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaMCPToolResultBlockContentUnion contains all possible properties and values // from [string], [[]BetaTextBlock]. // // Use the methods beginning with 'As' to cast the union to one of its variants. // // If the underlying value is not a json object, one of the following properties // will be valid: OfString OfBetaMCPToolResultBlockContent] type BetaMCPToolResultBlockContentUnion struct { // This field will be present if the value is a [string] instead of an object. OfString string `json:",inline"` // This field will be present if the value is a [[]BetaTextBlock] instead of an // object. OfBetaMCPToolResultBlockContent []BetaTextBlock `json:",inline"` JSON struct { OfString respjson.Field OfBetaMCPToolResultBlockContent respjson.Field raw string } `json:"-"` } func (u BetaMCPToolResultBlockContentUnion) AsString() (v string) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMCPToolResultBlockContentUnion) AsBetaMCPToolResultBlockContent() (v []BetaTextBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaMCPToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } func (r *BetaMCPToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMCPToolUseBlock struct { ID string `json:"id" api:"required"` Input any `json:"input" api:"required"` // The name of the MCP tool Name string `json:"name" api:"required"` // The name of the MCP server ServerName string `json:"server_name" api:"required"` Type constant.MCPToolUse `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field Input respjson.Field Name respjson.Field ServerName respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } // The properties ID, Input, Name, ServerName, Type are required. type BetaMCPToolUseBlockParam struct { ID string `json:"id" api:"required"` Input any `json:"input,omitzero" api:"required"` Name string `json:"name" api:"required"` // The name of the MCP server ServerName string `json:"server_name" api:"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 "mcp_tool_use". Type constant.MCPToolUse `json:"type" api:"required"` paramObj } 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" api:"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" api:"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"` 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" api:"required"` // This field can be elided, and will marshal its zero value as "memory_20250818". Type constant.Memory20250818 `json:"type" api:"required"` paramObj } 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) } // BetaMemoryTool20250818CommandUnion contains all possible properties and values // from [BetaMemoryTool20250818ViewCommand], [BetaMemoryTool20250818CreateCommand], // [BetaMemoryTool20250818StrReplaceCommand], // [BetaMemoryTool20250818InsertCommand], [BetaMemoryTool20250818DeleteCommand], // [BetaMemoryTool20250818RenameCommand]. // // Use the [BetaMemoryTool20250818CommandUnion.AsAny] method to switch on the // variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaMemoryTool20250818CommandUnion struct { // Any of "view", "create", "str_replace", "insert", "delete", "rename". Command string `json:"command"` Path string `json:"path"` // This field is from variant [BetaMemoryTool20250818ViewCommand]. ViewRange []int64 `json:"view_range"` // This field is from variant [BetaMemoryTool20250818CreateCommand]. FileText string `json:"file_text"` // This field is from variant [BetaMemoryTool20250818StrReplaceCommand]. NewStr string `json:"new_str"` // This field is from variant [BetaMemoryTool20250818StrReplaceCommand]. OldStr string `json:"old_str"` // This field is from variant [BetaMemoryTool20250818InsertCommand]. InsertLine int64 `json:"insert_line"` // This field is from variant [BetaMemoryTool20250818InsertCommand]. InsertText string `json:"insert_text"` // This field is from variant [BetaMemoryTool20250818RenameCommand]. NewPath string `json:"new_path"` // This field is from variant [BetaMemoryTool20250818RenameCommand]. OldPath string `json:"old_path"` JSON struct { Command respjson.Field Path respjson.Field ViewRange respjson.Field FileText respjson.Field NewStr respjson.Field OldStr respjson.Field InsertLine respjson.Field InsertText respjson.Field NewPath respjson.Field OldPath respjson.Field raw string } `json:"-"` } // anyBetaMemoryTool20250818Command is implemented by each variant of // [BetaMemoryTool20250818CommandUnion] to add type safety for the return type of // [BetaMemoryTool20250818CommandUnion.AsAny] type anyBetaMemoryTool20250818Command interface { implBetaMemoryTool20250818CommandUnion() } func (BetaMemoryTool20250818ViewCommand) implBetaMemoryTool20250818CommandUnion() {} func (BetaMemoryTool20250818CreateCommand) implBetaMemoryTool20250818CommandUnion() {} func (BetaMemoryTool20250818StrReplaceCommand) implBetaMemoryTool20250818CommandUnion() {} func (BetaMemoryTool20250818InsertCommand) implBetaMemoryTool20250818CommandUnion() {} func (BetaMemoryTool20250818DeleteCommand) implBetaMemoryTool20250818CommandUnion() {} func (BetaMemoryTool20250818RenameCommand) implBetaMemoryTool20250818CommandUnion() {} // Use the following switch statement to find the correct variant // // switch variant := BetaMemoryTool20250818CommandUnion.AsAny().(type) { // case anthropic.BetaMemoryTool20250818ViewCommand: // case anthropic.BetaMemoryTool20250818CreateCommand: // case anthropic.BetaMemoryTool20250818StrReplaceCommand: // case anthropic.BetaMemoryTool20250818InsertCommand: // case anthropic.BetaMemoryTool20250818DeleteCommand: // case anthropic.BetaMemoryTool20250818RenameCommand: // default: // fmt.Errorf("no variant present") // } func (u BetaMemoryTool20250818CommandUnion) AsAny() anyBetaMemoryTool20250818Command { switch u.Command { case "view": return u.AsView() case "create": return u.AsCreate() case "str_replace": return u.AsStrReplace() case "insert": return u.AsInsert() case "delete": return u.AsDelete() case "rename": return u.AsRename() } return nil } func (u BetaMemoryTool20250818CommandUnion) AsView() (v BetaMemoryTool20250818ViewCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMemoryTool20250818CommandUnion) AsCreate() (v BetaMemoryTool20250818CreateCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMemoryTool20250818CommandUnion) AsStrReplace() (v BetaMemoryTool20250818StrReplaceCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMemoryTool20250818CommandUnion) AsInsert() (v BetaMemoryTool20250818InsertCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMemoryTool20250818CommandUnion) AsDelete() (v BetaMemoryTool20250818DeleteCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMemoryTool20250818CommandUnion) AsRename() (v BetaMemoryTool20250818RenameCommand) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaMemoryTool20250818CommandUnion) RawJSON() string { return u.JSON.raw } func (r *BetaMemoryTool20250818CommandUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMemoryTool20250818CreateCommand struct { // Command type identifier Command constant.Create `json:"command" api:"required"` // Content to write to the file FileText string `json:"file_text" api:"required"` // Path where the file should be created Path string `json:"path" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Command respjson.Field FileText respjson.Field Path respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaMemoryTool20250818DeleteCommand struct { // Command type identifier Command constant.Delete `json:"command" api:"required"` // Path to the file or directory to delete Path string `json:"path" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Command respjson.Field Path respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaMemoryTool20250818InsertCommand struct { // Command type identifier Command constant.Insert `json:"command" api:"required"` // Line number where text should be inserted InsertLine int64 `json:"insert_line" api:"required"` // Text to insert at the specified line InsertText string `json:"insert_text" api:"required"` // Path to the file where text should be inserted Path string `json:"path" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Command respjson.Field InsertLine respjson.Field InsertText respjson.Field Path respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaMemoryTool20250818RenameCommand struct { // Command type identifier Command constant.Rename `json:"command" api:"required"` // New path for the file or directory NewPath string `json:"new_path" api:"required"` // Current path of the file or directory OldPath string `json:"old_path" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Command respjson.Field NewPath respjson.Field OldPath respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaMemoryTool20250818StrReplaceCommand struct { // Command type identifier Command constant.StrReplace `json:"command" api:"required"` // Text to replace with NewStr string `json:"new_str" api:"required"` // Text to search for and replace OldStr string `json:"old_str" api:"required"` // Path to the file where text should be replaced Path string `json:"path" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Command respjson.Field NewStr respjson.Field OldStr respjson.Field Path respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaMemoryTool20250818ViewCommand struct { // Command type identifier Command constant.View `json:"command" api:"required"` // Path to directory or file to view Path string `json:"path" api:"required"` // Optional line range for viewing specific lines ViewRange []int64 `json:"view_range"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Command respjson.Field Path respjson.Field ViewRange respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaMessage struct { // Unique object identifier. // // The format and length of IDs may change over time. ID string `json:"id" api:"required"` // Information about the container used in the request (for the code execution // tool) Container BetaContainer `json:"container" api:"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 []BetaContentBlockUnion `json:"content" api:"required"` // Context management response. // // Information about context management strategies applied during the request. ContextManagement BetaContextManagementResponse `json:"context_management" api:"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" api:"required"` // Conversational role of the generated message. // // This will always be `"assistant"`. Role constant.Assistant `json:"role" api:"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", // "compaction", "refusal", "model_context_window_exceeded". StopReason BetaStopReason `json:"stop_reason" api:"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" api:"required"` // Object type. // // For Messages, this is always `"message"`. Type constant.Message `json:"type" api:"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 BetaUsage `json:"usage" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field Container respjson.Field Content respjson.Field ContextManagement 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 BetaMessage) RawJSON() string { return r.JSON.raw } func (r *BetaMessage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMessageDeltaUsage struct { // The cumulative number of input tokens used to create the cache entry. CacheCreationInputTokens int64 `json:"cache_creation_input_tokens" api:"required"` // The cumulative number of input tokens read from the cache. CacheReadInputTokens int64 `json:"cache_read_input_tokens" api:"required"` // The cumulative number of input tokens which were used. InputTokens int64 `json:"input_tokens" api:"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" api:"required"` // The cumulative number of output tokens which were used. OutputTokens int64 `json:"output_tokens" api:"required"` // The number of server tool requests. ServerToolUse BetaServerToolUsage `json:"server_tool_use" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { CacheCreationInputTokens respjson.Field CacheReadInputTokens respjson.Field InputTokens respjson.Field Iterations 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 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" api:"required"` // The number of input tokens used to create the cache entry. CacheCreationInputTokens int64 `json:"cache_creation_input_tokens" api:"required"` // The number of input tokens read from the cache. CacheReadInputTokens int64 `json:"cache_read_input_tokens" api:"required"` // The number of input tokens which were used. InputTokens int64 `json:"input_tokens" api:"required"` // The number of output tokens which were used. OutputTokens int64 `json:"output_tokens" api:"required"` // Usage for a sampling iteration Type constant.Message `json:"type" api:"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" api:"required"` // Any of "user", "assistant". Role BetaMessageParamRole `json:"role,omitzero" api:"required"` paramObj } func NewBetaUserMessage(blocks ...BetaContentBlockParamUnion) BetaMessageParam { return BetaMessageParam{ Role: BetaMessageParamRoleUser, Content: blocks, } } 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) } type BetaMessageParamRole string const ( BetaMessageParamRoleUser BetaMessageParamRole = "user" BetaMessageParamRoleAssistant BetaMessageParamRole = "assistant" ) type BetaMessageTokensCount struct { // Information about context management applied to the message. ContextManagement BetaCountTokensContextManagementResponse `json:"context_management" api:"required"` // The total number of tokens across the provided list of messages, system prompt, // and tools. InputTokens int64 `json:"input_tokens" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ContextManagement respjson.Field InputTokens respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } type BetaMetadataParam 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 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" api:"required"` MediaType constant.TextPlain `json:"media_type" api:"required"` Type constant.Text `json:"type" api:"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 BetaPlainTextSource) RawJSON() string { return r.JSON.raw } func (r *BetaPlainTextSource) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // ToParam converts this BetaPlainTextSource to a BetaPlainTextSourceParam. // // 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 // BetaPlainTextSourceParam.Overrides() func (r BetaPlainTextSource) ToParam() BetaPlainTextSourceParam { return param.Override[BetaPlainTextSourceParam](json.RawMessage(r.RawJSON())) } // The properties Data, MediaType, Type are required. type BetaPlainTextSourceParam struct { Data string `json:"data" api:"required"` // This field can be elided, and will marshal its zero value as "text/plain". MediaType constant.TextPlain `json:"media_type" api:"required"` // This field can be elided, and will marshal its zero value as "text". Type constant.Text `json:"type" api:"required"` paramObj } 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], [BetaCompactionContentBlockDelta]. // // Use the [BetaRawContentBlockDeltaUnion.AsAny] method to switch on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. 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", "compaction_delta". Type string `json:"type"` // This field is from variant [BetaInputJSONDelta]. PartialJSON string `json:"partial_json"` // This field is from variant [BetaCitationsDelta]. Citation BetaCitationsDeltaCitationUnion `json:"citation"` // This field is from variant [BetaThinkingDelta]. Thinking string `json:"thinking"` // This field is from variant [BetaSignatureDelta]. Signature string `json:"signature"` // 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:"-"` } // anyBetaRawContentBlockDelta is implemented by each variant of // [BetaRawContentBlockDeltaUnion] to add type safety for the return type of // [BetaRawContentBlockDeltaUnion.AsAny] type anyBetaRawContentBlockDelta interface { 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 // // switch variant := BetaRawContentBlockDeltaUnion.AsAny().(type) { // case anthropic.BetaTextDelta: // case anthropic.BetaInputJSONDelta: // case anthropic.BetaCitationsDelta: // case anthropic.BetaThinkingDelta: // case anthropic.BetaSignatureDelta: // case anthropic.BetaCompactionContentBlockDelta: // default: // fmt.Errorf("no variant present") // } func (u BetaRawContentBlockDeltaUnion) AsAny() anyBetaRawContentBlockDelta { 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() case "compaction_delta": return u.AsCompactionDelta() } return nil } func (u BetaRawContentBlockDeltaUnion) AsTextDelta() (v BetaTextDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockDeltaUnion) AsInputJSONDelta() (v BetaInputJSONDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockDeltaUnion) AsCitationsDelta() (v BetaCitationsDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockDeltaUnion) AsThinkingDelta() (v BetaThinkingDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockDeltaUnion) AsSignatureDelta() (v BetaSignatureDelta) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &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 func (u BetaRawContentBlockDeltaUnion) RawJSON() string { return u.JSON.raw } func (r *BetaRawContentBlockDeltaUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRawContentBlockDeltaEvent struct { Delta BetaRawContentBlockDeltaUnion `json:"delta" api:"required"` Index int64 `json:"index" api:"required"` Type constant.ContentBlockDelta `json:"type" api:"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 BetaRawContentBlockDeltaEvent) RawJSON() string { return r.JSON.raw } func (r *BetaRawContentBlockDeltaEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRawContentBlockStartEvent struct { // Response model for a file uploaded to the container. ContentBlock BetaRawContentBlockStartEventContentBlockUnion `json:"content_block" api:"required"` Index int64 `json:"index" api:"required"` Type constant.ContentBlockStart `json:"type" api:"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 BetaRawContentBlockStartEvent) RawJSON() string { return r.JSON.raw } func (r *BetaRawContentBlockStartEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaRawContentBlockStartEventContentBlockUnion contains all possible properties // and values from [BetaTextBlock], [BetaThinkingBlock], // [BetaRedactedThinkingBlock], [BetaToolUseBlock], [BetaServerToolUseBlock], // [BetaWebSearchToolResultBlock], [BetaWebFetchToolResultBlock], // [BetaCodeExecutionToolResultBlock], [BetaBashCodeExecutionToolResultBlock], // [BetaTextEditorCodeExecutionToolResultBlock], [BetaToolSearchToolResultBlock], // [BetaMCPToolUseBlock], [BetaMCPToolResultBlock], [BetaContainerUploadBlock], // [BetaCompactionBlock]. // // Use the [BetaRawContentBlockStartEventContentBlockUnion.AsAny] method to switch // on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaRawContentBlockStartEventContentBlockUnion struct { // This field is from variant [BetaTextBlock]. Citations []BetaTextCitationUnion `json:"citations"` // This field is from variant [BetaTextBlock]. 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", "mcp_tool_use", "mcp_tool_result", // "container_upload", "compaction". Type string `json:"type"` // This field is from variant [BetaThinkingBlock]. Signature string `json:"signature"` // This field is from variant [BetaThinkingBlock]. Thinking string `json:"thinking"` // This field is from variant [BetaRedactedThinkingBlock]. Data string `json:"data"` 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], // [BetaToolSearchToolResultBlockContentUnion], // [BetaMCPToolResultBlockContentUnion], [string] Content BetaRawContentBlockStartEventContentBlockUnionContent `json:"content"` ToolUseID string `json:"tool_use_id"` // This field is from variant [BetaMCPToolUseBlock]. ServerName string `json:"server_name"` // This field is from variant [BetaMCPToolResultBlock]. IsError bool `json:"is_error"` // This field is from variant [BetaContainerUploadBlock]. 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 Input respjson.Field Name respjson.Field Caller respjson.Field Content respjson.Field ToolUseID respjson.Field ServerName respjson.Field IsError respjson.Field FileID respjson.Field raw string } `json:"-"` } // anyBetaRawContentBlockStartEventContentBlock is implemented by each variant of // [BetaRawContentBlockStartEventContentBlockUnion] to add type safety for the // return type of [BetaRawContentBlockStartEventContentBlockUnion.AsAny] type anyBetaRawContentBlockStartEventContentBlock interface { implBetaRawContentBlockStartEventContentBlockUnion() } func (BetaTextBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaThinkingBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaRedactedThinkingBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaToolUseBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaServerToolUseBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaWebSearchToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaWebFetchToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaCodeExecutionToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaBashCodeExecutionToolResultBlock) implBetaRawContentBlockStartEventContentBlockUnion() {} func (BetaTextEditorCodeExecutionToolResultBlock) 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 // // switch variant := BetaRawContentBlockStartEventContentBlockUnion.AsAny().(type) { // case anthropic.BetaTextBlock: // case anthropic.BetaThinkingBlock: // case anthropic.BetaRedactedThinkingBlock: // case anthropic.BetaToolUseBlock: // case anthropic.BetaServerToolUseBlock: // case anthropic.BetaWebSearchToolResultBlock: // case anthropic.BetaWebFetchToolResultBlock: // 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") // } func (u BetaRawContentBlockStartEventContentBlockUnion) AsAny() anyBetaRawContentBlockStartEventContentBlock { 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 "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 } func (u BetaRawContentBlockStartEventContentBlockUnion) AsThinking() (v BetaThinkingBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsRedactedThinking() (v BetaRedactedThinkingBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsToolUse() (v BetaToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsServerToolUse() (v BetaServerToolUseBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsWebSearchToolResult() (v BetaWebSearchToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsWebFetchToolResult() (v BetaWebFetchToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsCodeExecutionToolResult() (v BetaCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsBashCodeExecutionToolResult() (v BetaBashCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsTextEditorCodeExecutionToolResult() (v BetaTextEditorCodeExecutionToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &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 } func (u BetaRawContentBlockStartEventContentBlockUnion) AsMCPToolResult() (v BetaMCPToolResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawContentBlockStartEventContentBlockUnion) AsContainerUpload() (v BetaContainerUploadBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &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 func (u BetaRawContentBlockStartEventContentBlockUnion) RawJSON() string { return u.JSON.raw } func (r *BetaRawContentBlockStartEventContentBlockUnion) UnmarshalJSON(data []byte) error { 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 // to the sub-properties of the union. // // For type safety it is recommended to directly use a variant of the // [BetaRawContentBlockStartEventContentBlockUnion]. // // If the underlying value is not a json object, one of the following properties // will be valid: OfBetaWebSearchResultBlockArray OfString // OfBetaMCPToolResultBlockContent] type BetaRawContentBlockStartEventContentBlockUnionContent struct { // This field will be present if the value is a [[]BetaWebSearchResultBlock] // instead of an object. OfBetaWebSearchResultBlockArray []BetaWebSearchResultBlock `json:",inline"` // This field will be present if the value is a [string] instead of an object. OfString string `json:",inline"` // This field will be present if the value is a [[]BetaTextBlock] instead of an // object. OfBetaMCPToolResultBlockContent []BetaTextBlock `json:",inline"` ErrorCode string `json:"error_code"` Type string `json:"type"` // This field is a union of [BetaDocumentBlock], [[]BetaCodeExecutionOutputBlock], // [[]BetaCodeExecutionOutputBlock], [[]BetaBashCodeExecutionOutputBlock], [string] Content BetaRawContentBlockStartEventContentBlockUnionContentContent `json:"content"` // This field is from variant [BetaWebFetchToolResultBlockContentUnion]. RetrievedAt string `json:"retrieved_at"` // This field is from variant [BetaWebFetchToolResultBlockContentUnion]. URL string `json:"url"` ReturnCode int64 `json:"return_code"` Stderr string `json:"stderr"` Stdout string `json:"stdout"` // 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"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. NumLines int64 `json:"num_lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. StartLine int64 `json:"start_line"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. TotalLines int64 `json:"total_lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. IsFileUpdate bool `json:"is_file_update"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. Lines []string `json:"lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. NewLines int64 `json:"new_lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. NewStart int64 `json:"new_start"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. OldLines int64 `json:"old_lines"` // This field is from variant // [BetaTextEditorCodeExecutionToolResultBlockContentUnion]. OldStart int64 `json:"old_start"` // This field is from variant [BetaToolSearchToolResultBlockContentUnion]. ToolReferences []BetaToolReferenceBlock `json:"tool_references"` JSON struct { OfBetaWebSearchResultBlockArray respjson.Field OfString respjson.Field OfBetaMCPToolResultBlockContent 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 *BetaRawContentBlockStartEventContentBlockUnionContent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaRawContentBlockStartEventContentBlockUnionContentContent is an implicit // subunion of [BetaRawContentBlockStartEventContentBlockUnion]. // BetaRawContentBlockStartEventContentBlockUnionContentContent provides convenient // access to the sub-properties of the union. // // For type safety it is recommended to directly use a variant of the // [BetaRawContentBlockStartEventContentBlockUnion]. // // If the underlying value is not a json object, one of the following properties // will be valid: OfContent OfString] type BetaRawContentBlockStartEventContentBlockUnionContentContent struct { // This field will be present if the value is a [[]BetaCodeExecutionOutputBlock] // instead of an object. OfContent []BetaCodeExecutionOutputBlock `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 [BetaDocumentBlock]. Citations BetaCitationConfig `json:"citations"` // This field is from variant [BetaDocumentBlock]. Source BetaDocumentBlockSourceUnion `json:"source"` // This field is from variant [BetaDocumentBlock]. Title string `json:"title"` // This field is from variant [BetaDocumentBlock]. 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 *BetaRawContentBlockStartEventContentBlockUnionContentContent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRawContentBlockStopEvent struct { Index int64 `json:"index" api:"required"` Type constant.ContentBlockStop `json:"type" api:"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 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 strategies applied during the request ContextManagement BetaContextManagementResponse `json:"context_management" api:"required"` Delta BetaRawMessageDeltaEventDelta `json:"delta" api:"required"` Type constant.MessageDelta `json:"type" api:"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 BetaMessageDeltaUsage `json:"usage" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ContextManagement respjson.Field 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 BetaRawMessageDeltaEvent) RawJSON() string { return r.JSON.raw } func (r *BetaRawMessageDeltaEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRawMessageDeltaEventDelta struct { // Information about the container used in the request (for the code execution // tool) Container BetaContainer `json:"container" api:"required"` // Any of "end_turn", "max_tokens", "stop_sequence", "tool_use", "pause_turn", // "compaction", "refusal", "model_context_window_exceeded". StopReason BetaStopReason `json:"stop_reason" api:"required"` StopSequence string `json:"stop_sequence" api:"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 BetaRawMessageDeltaEventDelta) RawJSON() string { return r.JSON.raw } func (r *BetaRawMessageDeltaEventDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRawMessageStartEvent struct { Message BetaMessage `json:"message" api:"required"` Type constant.MessageStart `json:"type" api:"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 BetaRawMessageStartEvent) RawJSON() string { return r.JSON.raw } func (r *BetaRawMessageStartEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRawMessageStopEvent struct { Type constant.MessageStop `json:"type" api:"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 BetaRawMessageStopEvent) RawJSON() string { return r.JSON.raw } func (r *BetaRawMessageStopEvent) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaRawMessageStreamEventUnion contains all possible properties and values from // [BetaRawMessageStartEvent], [BetaRawMessageDeltaEvent], // [BetaRawMessageStopEvent], [BetaRawContentBlockStartEvent], // [BetaRawContentBlockDeltaEvent], [BetaRawContentBlockStopEvent]. // // Use the [BetaRawMessageStreamEventUnion.AsAny] method to switch on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaRawMessageStreamEventUnion struct { // This field is from variant [BetaRawMessageStartEvent]. Message BetaMessage `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 from variant [BetaRawMessageDeltaEvent]. ContextManagement BetaContextManagementResponse `json:"context_management"` // This field is a union of [BetaRawMessageDeltaEventDelta], // [BetaRawContentBlockDeltaUnion] Delta BetaRawMessageStreamEventUnionDelta `json:"delta"` // This field is from variant [BetaRawMessageDeltaEvent]. Usage BetaMessageDeltaUsage `json:"usage"` // This field is from variant [BetaRawContentBlockStartEvent]. ContentBlock BetaRawContentBlockStartEventContentBlockUnion `json:"content_block"` Index int64 `json:"index"` JSON struct { Message respjson.Field Type respjson.Field ContextManagement respjson.Field Delta respjson.Field Usage respjson.Field ContentBlock respjson.Field Index respjson.Field raw string } `json:"-"` } // anyBetaRawMessageStreamEvent is implemented by each variant of // [BetaRawMessageStreamEventUnion] to add type safety for the return type of // [BetaRawMessageStreamEventUnion.AsAny] type anyBetaRawMessageStreamEvent interface { implBetaRawMessageStreamEventUnion() } func (BetaRawMessageStartEvent) implBetaRawMessageStreamEventUnion() {} func (BetaRawMessageDeltaEvent) implBetaRawMessageStreamEventUnion() {} func (BetaRawMessageStopEvent) implBetaRawMessageStreamEventUnion() {} func (BetaRawContentBlockStartEvent) implBetaRawMessageStreamEventUnion() {} func (BetaRawContentBlockDeltaEvent) implBetaRawMessageStreamEventUnion() {} func (BetaRawContentBlockStopEvent) implBetaRawMessageStreamEventUnion() {} // Use the following switch statement to find the correct variant // // switch variant := BetaRawMessageStreamEventUnion.AsAny().(type) { // case anthropic.BetaRawMessageStartEvent: // case anthropic.BetaRawMessageDeltaEvent: // case anthropic.BetaRawMessageStopEvent: // case anthropic.BetaRawContentBlockStartEvent: // case anthropic.BetaRawContentBlockDeltaEvent: // case anthropic.BetaRawContentBlockStopEvent: // default: // fmt.Errorf("no variant present") // } func (u BetaRawMessageStreamEventUnion) AsAny() anyBetaRawMessageStreamEvent { 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 BetaRawMessageStreamEventUnion) AsMessageStart() (v BetaRawMessageStartEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawMessageStreamEventUnion) AsMessageDelta() (v BetaRawMessageDeltaEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawMessageStreamEventUnion) AsMessageStop() (v BetaRawMessageStopEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawMessageStreamEventUnion) AsContentBlockStart() (v BetaRawContentBlockStartEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawMessageStreamEventUnion) AsContentBlockDelta() (v BetaRawContentBlockDeltaEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaRawMessageStreamEventUnion) AsContentBlockStop() (v BetaRawContentBlockStopEvent) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaRawMessageStreamEventUnion) RawJSON() string { return u.JSON.raw } func (r *BetaRawMessageStreamEventUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaRawMessageStreamEventUnionDelta is an implicit subunion of // [BetaRawMessageStreamEventUnion]. BetaRawMessageStreamEventUnionDelta provides // convenient access to the sub-properties of the union. // // For type safety it is recommended to directly use a variant of the // [BetaRawMessageStreamEventUnion]. type BetaRawMessageStreamEventUnionDelta struct { // This field is from variant [BetaRawMessageDeltaEventDelta]. Container BetaContainer `json:"container"` // This field is from variant [BetaRawMessageDeltaEventDelta]. StopReason BetaStopReason `json:"stop_reason"` // This field is from variant [BetaRawMessageDeltaEventDelta]. StopSequence string `json:"stop_sequence"` // This field is from variant [BetaRawContentBlockDeltaUnion]. Text string `json:"text"` Type string `json:"type"` // This field is from variant [BetaRawContentBlockDeltaUnion]. PartialJSON string `json:"partial_json"` // This field is from variant [BetaRawContentBlockDeltaUnion]. Citation BetaCitationsDeltaCitationUnion `json:"citation"` // This field is from variant [BetaRawContentBlockDeltaUnion]. Thinking string `json:"thinking"` // This field is from variant [BetaRawContentBlockDeltaUnion]. Signature string `json:"signature"` // This field is from variant [BetaRawContentBlockDeltaUnion]. Content string `json:"content"` 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 Content respjson.Field raw string } `json:"-"` } func (r *BetaRawMessageStreamEventUnionDelta) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaRedactedThinkingBlock struct { Data string `json:"data" api:"required"` Type constant.RedactedThinking `json:"type" api:"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 BetaRedactedThinkingBlock) RawJSON() string { return r.JSON.raw } func (r *BetaRedactedThinkingBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Data, Type are required. type BetaRedactedThinkingBlockParam struct { Data string `json:"data" api:"required"` // This field can be elided, and will marshal its zero value as // "redacted_thinking". Type constant.RedactedThinking `json:"type" api:"required"` paramObj } 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) } // The properties Source, Type are required. type BetaRequestDocumentBlockParam struct { Source BetaRequestDocumentBlockSourceUnionParam `json:"source,omitzero" api:"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 BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` Citations BetaCitationsConfigParam `json:"citations,omitzero"` // This field can be elided, and will marshal its zero value as "document". Type constant.Document `json:"type" api:"required"` paramObj } 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) } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaRequestDocumentBlockSourceUnionParam struct { OfBase64 *BetaBase64PDFSourceParam `json:",omitzero,inline"` OfText *BetaPlainTextSourceParam `json:",omitzero,inline"` OfContent *BetaContentBlockSourceParam `json:",omitzero,inline"` OfURL *BetaURLPDFSourceParam `json:",omitzero,inline"` OfFile *BetaFileDocumentSourceParam `json:",omitzero,inline"` paramUnion } func (u BetaRequestDocumentBlockSourceUnionParam) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfBase64, u.OfText, u.OfContent, u.OfURL, u.OfFile) } func (u *BetaRequestDocumentBlockSourceUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } func (u *BetaRequestDocumentBlockSourceUnionParam) 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 } else if !param.IsOmitted(u.OfFile) { return u.OfFile } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaRequestDocumentBlockSourceUnionParam) GetContent() *BetaContentBlockSourceContentUnionParam { if vt := u.OfContent; vt != nil { return &vt.Content } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaRequestDocumentBlockSourceUnionParam) 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 BetaRequestDocumentBlockSourceUnionParam) GetFileID() *string { if vt := u.OfFile; vt != nil { return &vt.FileID } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaRequestDocumentBlockSourceUnionParam) 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 BetaRequestDocumentBlockSourceUnionParam) 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 BetaRequestDocumentBlockSourceUnionParam) 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) } else if vt := u.OfFile; vt != nil { return (*string)(&vt.Type) } return nil } type BetaRequestMCPServerToolConfigurationParam struct { Enabled param.Opt[bool] `json:"enabled,omitzero"` AllowedTools []string `json:"allowed_tools,omitzero"` paramObj } func (r BetaRequestMCPServerToolConfigurationParam) MarshalJSON() (data []byte, err error) { type shadow BetaRequestMCPServerToolConfigurationParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaRequestMCPServerToolConfigurationParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Name, Type, URL are required. type BetaRequestMCPServerURLDefinitionParam struct { Name string `json:"name" api:"required"` URL string `json:"url" api:"required"` AuthorizationToken param.Opt[string] `json:"authorization_token,omitzero"` ToolConfiguration BetaRequestMCPServerToolConfigurationParam `json:"tool_configuration,omitzero"` // This field can be elided, and will marshal its zero value as "url". Type constant.URL `json:"type" api:"required"` paramObj } func (r BetaRequestMCPServerURLDefinitionParam) MarshalJSON() (data []byte, err error) { type shadow BetaRequestMCPServerURLDefinitionParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaRequestMCPServerURLDefinitionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties ToolUseID, Type are required. type BetaRequestMCPToolResultBlockParam struct { ToolUseID string `json:"tool_use_id" api:"required"` IsError param.Opt[bool] `json:"is_error,omitzero"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` Content BetaRequestMCPToolResultBlockParamContentUnion `json:"content,omitzero"` // This field can be elided, and will marshal its zero value as "mcp_tool_result". Type constant.MCPToolResult `json:"type" api:"required"` paramObj } func (r BetaRequestMCPToolResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaRequestMCPToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaRequestMCPToolResultBlockParam) 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 BetaRequestMCPToolResultBlockParamContentUnion struct { OfString param.Opt[string] `json:",omitzero,inline"` OfBetaMCPToolResultBlockContent []BetaTextBlockParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaRequestMCPToolResultBlockParamContentUnion) asAny() any { if !param.IsOmitted(u.OfString) { return &u.OfString.Value } else if !param.IsOmitted(u.OfBetaMCPToolResultBlockContent) { return &u.OfBetaMCPToolResultBlockContent } return nil } // The properties Content, Source, Title, Type are required. type BetaSearchResultBlockParam struct { Content []BetaTextBlockParam `json:"content,omitzero" api:"required"` Source string `json:"source" api:"required"` Title string `json:"title" api:"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" api:"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" api:"required"` Type constant.CodeExecution20250825 `json:"type" api:"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" api:"required"` // This field can be elided, and will marshal its zero value as // "code_execution_20250825". Type constant.CodeExecution20250825 `json:"type" api:"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" api:"required"` Type constant.CodeExecution20260120 `json:"type" api:"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" api:"required"` // This field can be elided, and will marshal its zero value as // "code_execution_20260120". Type constant.CodeExecution20260120 `json:"type" api:"required"` paramObj } func (r BetaServerToolCaller20260120Param) MarshalJSON() (data []byte, err error) { type shadow BetaServerToolCaller20260120Param return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaServerToolCaller20260120Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaServerToolUsage struct { // The number of web fetch tool requests. WebFetchRequests int64 `json:"web_fetch_requests" api:"required"` // The number of web search tool requests. WebSearchRequests int64 `json:"web_search_requests" api:"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 BetaServerToolUsage) RawJSON() string { return r.JSON.raw } func (r *BetaServerToolUsage) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaServerToolUseBlock struct { ID string `json:"id" api:"required"` Input any `json:"input" api:"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 BetaServerToolUseBlockName `json:"name" api:"required"` Type constant.ServerToolUse `json:"type" api:"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:"-"` } // 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) } type BetaServerToolUseBlockName string const ( BetaServerToolUseBlockNameWebSearch BetaServerToolUseBlockName = "web_search" BetaServerToolUseBlockNameWebFetch BetaServerToolUseBlockName = "web_fetch" 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" api:"required"` Input any `json:"input,omitzero" api:"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 BetaServerToolUseBlockParamName `json:"name,omitzero" api:"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" api:"required"` paramObj } 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) } type BetaServerToolUseBlockParamName string const ( BetaServerToolUseBlockParamNameWebSearch BetaServerToolUseBlockParamName = "web_search" BetaServerToolUseBlockParamNameWebFetch BetaServerToolUseBlockParamName = "web_fetch" 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 } type BetaSignatureDelta struct { Signature string `json:"signature" api:"required"` Type constant.SignatureDelta `json:"type" api:"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 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" api:"required"` // Type of skill - either 'anthropic' (built-in) or 'custom' (user-defined) // // Any of "anthropic", "custom". Type BetaSkillType `json:"type" api:"required"` // Skill version or 'latest' for most recent version Version string `json:"version" api:"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" api:"required"` // Type of skill - either 'anthropic' (built-in) or 'custom' (user-defined) // // Any of "anthropic", "custom". Type BetaSkillParamsType `json:"type,omitzero" api:"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 ( BetaStopReasonEndTurn BetaStopReason = "end_turn" BetaStopReasonMaxTokens BetaStopReason = "max_tokens" BetaStopReasonStopSequence BetaStopReason = "stop_sequence" BetaStopReasonToolUse BetaStopReason = "tool_use" BetaStopReasonPauseTurn BetaStopReason = "pause_turn" BetaStopReasonCompaction BetaStopReason = "compaction" BetaStopReasonRefusal BetaStopReason = "refusal" BetaStopReasonModelContextWindowExceeded BetaStopReason = "model_context_window_exceeded" ) type BetaTextBlock 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 []BetaTextCitationUnion `json:"citations" api:"required"` Text string `json:"text" api:"required"` Type constant.Text `json:"type" api:"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 BetaTextBlock) RawJSON() string { return r.JSON.raw } func (r *BetaTextBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Text, Type are required. type BetaTextBlockParam struct { Text string `json:"text" api:"required"` Citations []BetaTextCitationParamUnion `json:"citations,omitzero"` // 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 "text". Type constant.Text `json:"type" api:"required"` paramObj } 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) } // BetaTextCitationUnion contains all possible properties and values from // [BetaCitationCharLocation], [BetaCitationPageLocation], // [BetaCitationContentBlockLocation], [BetaCitationsWebSearchResultLocation], // [BetaCitationSearchResultLocation]. // // Use the [BetaTextCitationUnion.AsAny] method to switch on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaTextCitationUnion struct { CitedText string `json:"cited_text"` DocumentIndex int64 `json:"document_index"` DocumentTitle string `json:"document_title"` // This field is from variant [BetaCitationCharLocation]. EndCharIndex int64 `json:"end_char_index"` FileID string `json:"file_id"` // This field is from variant [BetaCitationCharLocation]. 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 [BetaCitationPageLocation]. EndPageNumber int64 `json:"end_page_number"` // This field is from variant [BetaCitationPageLocation]. StartPageNumber int64 `json:"start_page_number"` EndBlockIndex int64 `json:"end_block_index"` StartBlockIndex int64 `json:"start_block_index"` // This field is from variant [BetaCitationsWebSearchResultLocation]. EncryptedIndex string `json:"encrypted_index"` Title string `json:"title"` // This field is from variant [BetaCitationsWebSearchResultLocation]. URL string `json:"url"` // This field is from variant [BetaCitationSearchResultLocation]. SearchResultIndex int64 `json:"search_result_index"` // This field is from variant [BetaCitationSearchResultLocation]. 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:"-"` } // anyBetaTextCitation is implemented by each variant of [BetaTextCitationUnion] to // add type safety for the return type of [BetaTextCitationUnion.AsAny] type anyBetaTextCitation interface { implBetaTextCitationUnion() toParamUnion() BetaTextCitationParamUnion } func (BetaCitationCharLocation) implBetaTextCitationUnion() {} func (BetaCitationPageLocation) implBetaTextCitationUnion() {} func (BetaCitationContentBlockLocation) implBetaTextCitationUnion() {} func (BetaCitationsWebSearchResultLocation) implBetaTextCitationUnion() {} func (BetaCitationSearchResultLocation) implBetaTextCitationUnion() {} // Use the following switch statement to find the correct variant // // switch variant := BetaTextCitationUnion.AsAny().(type) { // case anthropic.BetaCitationCharLocation: // case anthropic.BetaCitationPageLocation: // case anthropic.BetaCitationContentBlockLocation: // case anthropic.BetaCitationsWebSearchResultLocation: // case anthropic.BetaCitationSearchResultLocation: // default: // fmt.Errorf("no variant present") // } func (u BetaTextCitationUnion) AsAny() anyBetaTextCitation { 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 BetaTextCitationUnion) AsCharLocation() (v BetaCitationCharLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaTextCitationUnion) AsPageLocation() (v BetaCitationPageLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaTextCitationUnion) AsContentBlockLocation() (v BetaCitationContentBlockLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaTextCitationUnion) AsWebSearchResultLocation() (v BetaCitationsWebSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaTextCitationUnion) AsSearchResultLocation() (v BetaCitationSearchResultLocation) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaTextCitationUnion) RawJSON() string { return u.JSON.raw } func (r *BetaTextCitationUnion) 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 BetaTextCitationParamUnion struct { OfCharLocation *BetaCitationCharLocationParam `json:",omitzero,inline"` OfPageLocation *BetaCitationPageLocationParam `json:",omitzero,inline"` OfContentBlockLocation *BetaCitationContentBlockLocationParam `json:",omitzero,inline"` OfWebSearchResultLocation *BetaCitationWebSearchResultLocationParam `json:",omitzero,inline"` OfSearchResultLocation *BetaCitationSearchResultLocationParam `json:",omitzero,inline"` paramUnion } func (u BetaTextCitationParamUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfCharLocation, u.OfPageLocation, u.OfContentBlockLocation, u.OfWebSearchResultLocation, u.OfSearchResultLocation) } func (u *BetaTextCitationParamUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } func (u *BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextCitationParamUnion) 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 BetaTextDelta struct { Text string `json:"text" api:"required"` Type constant.TextDelta `json:"type" api:"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:"-"` } // 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) } type BetaTextEditorCodeExecutionCreateResultBlock struct { IsFileUpdate bool `json:"is_file_update" api:"required"` Type constant.TextEditorCodeExecutionCreateResult `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { IsFileUpdate respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } // The properties IsFileUpdate, Type are required. type BetaTextEditorCodeExecutionCreateResultBlockParam struct { IsFileUpdate bool `json:"is_file_update" api:"required"` // This field can be elided, and will marshal its zero value as // "text_editor_code_execution_create_result". Type constant.TextEditorCodeExecutionCreateResult `json:"type" api:"required"` paramObj } func (r BetaTextEditorCodeExecutionCreateResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaTextEditorCodeExecutionCreateResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaTextEditorCodeExecutionCreateResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaTextEditorCodeExecutionStrReplaceResultBlock struct { Lines []string `json:"lines" api:"required"` NewLines int64 `json:"new_lines" api:"required"` NewStart int64 `json:"new_start" api:"required"` OldLines int64 `json:"old_lines" api:"required"` OldStart int64 `json:"old_start" api:"required"` Type constant.TextEditorCodeExecutionStrReplaceResult `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { 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 } `json:"-"` } // 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) } // The property Type is required. type BetaTextEditorCodeExecutionStrReplaceResultBlockParam 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" api:"required"` paramObj } func (r BetaTextEditorCodeExecutionStrReplaceResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaTextEditorCodeExecutionStrReplaceResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaTextEditorCodeExecutionStrReplaceResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaTextEditorCodeExecutionToolResultBlock struct { Content BetaTextEditorCodeExecutionToolResultBlockContentUnion `json:"content" api:"required"` ToolUseID string `json:"tool_use_id" api:"required"` Type constant.TextEditorCodeExecutionToolResult `json:"type" api:"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 BetaTextEditorCodeExecutionToolResultBlock) RawJSON() string { return r.JSON.raw } func (r *BetaTextEditorCodeExecutionToolResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaTextEditorCodeExecutionToolResultBlockContentUnion contains all possible // properties and values from [BetaTextEditorCodeExecutionToolResultError], // [BetaTextEditorCodeExecutionViewResultBlock], // [BetaTextEditorCodeExecutionCreateResultBlock], // [BetaTextEditorCodeExecutionStrReplaceResultBlock]. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaTextEditorCodeExecutionToolResultBlockContentUnion struct { // This field is from variant [BetaTextEditorCodeExecutionToolResultError]. ErrorCode BetaTextEditorCodeExecutionToolResultErrorErrorCode `json:"error_code"` // This field is from variant [BetaTextEditorCodeExecutionToolResultError]. ErrorMessage string `json:"error_message"` Type string `json:"type"` // This field is from variant [BetaTextEditorCodeExecutionViewResultBlock]. Content string `json:"content"` // This field is from variant [BetaTextEditorCodeExecutionViewResultBlock]. FileType BetaTextEditorCodeExecutionViewResultBlockFileType `json:"file_type"` // This field is from variant [BetaTextEditorCodeExecutionViewResultBlock]. NumLines int64 `json:"num_lines"` // This field is from variant [BetaTextEditorCodeExecutionViewResultBlock]. StartLine int64 `json:"start_line"` // This field is from variant [BetaTextEditorCodeExecutionViewResultBlock]. TotalLines int64 `json:"total_lines"` // This field is from variant [BetaTextEditorCodeExecutionCreateResultBlock]. IsFileUpdate bool `json:"is_file_update"` // This field is from variant [BetaTextEditorCodeExecutionStrReplaceResultBlock]. Lines []string `json:"lines"` // This field is from variant [BetaTextEditorCodeExecutionStrReplaceResultBlock]. NewLines int64 `json:"new_lines"` // This field is from variant [BetaTextEditorCodeExecutionStrReplaceResultBlock]. NewStart int64 `json:"new_start"` // This field is from variant [BetaTextEditorCodeExecutionStrReplaceResultBlock]. OldLines int64 `json:"old_lines"` // This field is from variant [BetaTextEditorCodeExecutionStrReplaceResultBlock]. OldStart int64 `json:"old_start"` JSON struct { ErrorCode respjson.Field ErrorMessage respjson.Field Type 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:"-"` } func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionToolResultError() (v BetaTextEditorCodeExecutionToolResultError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionViewResultBlock() (v BetaTextEditorCodeExecutionViewResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionCreateResultBlock() (v BetaTextEditorCodeExecutionCreateResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) AsResponseTextEditorCodeExecutionStrReplaceResultBlock() (v BetaTextEditorCodeExecutionStrReplaceResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaTextEditorCodeExecutionToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } func (r *BetaTextEditorCodeExecutionToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Content, ToolUseID, Type are required. type BetaTextEditorCodeExecutionToolResultBlockParam struct { Content BetaTextEditorCodeExecutionToolResultBlockParamContentUnion `json:"content,omitzero" api:"required"` ToolUseID string `json:"tool_use_id" api:"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 // "text_editor_code_execution_tool_result". Type constant.TextEditorCodeExecutionToolResult `json:"type" api:"required"` paramObj } func (r BetaTextEditorCodeExecutionToolResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaTextEditorCodeExecutionToolResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaTextEditorCodeExecutionToolResultBlockParam) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion struct { OfRequestTextEditorCodeExecutionToolResultError *BetaTextEditorCodeExecutionToolResultErrorParam `json:",omitzero,inline"` OfRequestTextEditorCodeExecutionViewResultBlock *BetaTextEditorCodeExecutionViewResultBlockParam `json:",omitzero,inline"` OfRequestTextEditorCodeExecutionCreateResultBlock *BetaTextEditorCodeExecutionCreateResultBlockParam `json:",omitzero,inline"` OfRequestTextEditorCodeExecutionStrReplaceResultBlock *BetaTextEditorCodeExecutionStrReplaceResultBlockParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) GetErrorCode() *string { if vt := u.OfRequestTextEditorCodeExecutionToolResultError; vt != nil { return (*string)(&vt.ErrorCode) } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) GetErrorMessage() *string { if vt := u.OfRequestTextEditorCodeExecutionToolResultError; vt != nil && vt.ErrorMessage.Valid() { return &vt.ErrorMessage.Value } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultBlockParamContentUnion) 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 BetaTextEditorCodeExecutionToolResultError struct { // Any of "invalid_tool_input", "unavailable", "too_many_requests", // "execution_time_exceeded", "file_not_found". ErrorCode BetaTextEditorCodeExecutionToolResultErrorErrorCode `json:"error_code" api:"required"` ErrorMessage string `json:"error_message" api:"required"` Type constant.TextEditorCodeExecutionToolResultError `json:"type" api:"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 BetaTextEditorCodeExecutionToolResultError) RawJSON() string { return r.JSON.raw } func (r *BetaTextEditorCodeExecutionToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaTextEditorCodeExecutionToolResultErrorErrorCode string const ( BetaTextEditorCodeExecutionToolResultErrorErrorCodeInvalidToolInput BetaTextEditorCodeExecutionToolResultErrorErrorCode = "invalid_tool_input" BetaTextEditorCodeExecutionToolResultErrorErrorCodeUnavailable BetaTextEditorCodeExecutionToolResultErrorErrorCode = "unavailable" BetaTextEditorCodeExecutionToolResultErrorErrorCodeTooManyRequests BetaTextEditorCodeExecutionToolResultErrorErrorCode = "too_many_requests" BetaTextEditorCodeExecutionToolResultErrorErrorCodeExecutionTimeExceeded BetaTextEditorCodeExecutionToolResultErrorErrorCode = "execution_time_exceeded" BetaTextEditorCodeExecutionToolResultErrorErrorCodeFileNotFound BetaTextEditorCodeExecutionToolResultErrorErrorCode = "file_not_found" ) // The properties ErrorCode, Type are required. type BetaTextEditorCodeExecutionToolResultErrorParam struct { // Any of "invalid_tool_input", "unavailable", "too_many_requests", // "execution_time_exceeded", "file_not_found". ErrorCode BetaTextEditorCodeExecutionToolResultErrorParamErrorCode `json:"error_code,omitzero" api:"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" api:"required"` paramObj } func (r BetaTextEditorCodeExecutionToolResultErrorParam) MarshalJSON() (data []byte, err error) { type shadow BetaTextEditorCodeExecutionToolResultErrorParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaTextEditorCodeExecutionToolResultErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaTextEditorCodeExecutionToolResultErrorParamErrorCode string const ( BetaTextEditorCodeExecutionToolResultErrorParamErrorCodeInvalidToolInput BetaTextEditorCodeExecutionToolResultErrorParamErrorCode = "invalid_tool_input" BetaTextEditorCodeExecutionToolResultErrorParamErrorCodeUnavailable BetaTextEditorCodeExecutionToolResultErrorParamErrorCode = "unavailable" BetaTextEditorCodeExecutionToolResultErrorParamErrorCodeTooManyRequests BetaTextEditorCodeExecutionToolResultErrorParamErrorCode = "too_many_requests" BetaTextEditorCodeExecutionToolResultErrorParamErrorCodeExecutionTimeExceeded BetaTextEditorCodeExecutionToolResultErrorParamErrorCode = "execution_time_exceeded" BetaTextEditorCodeExecutionToolResultErrorParamErrorCodeFileNotFound BetaTextEditorCodeExecutionToolResultErrorParamErrorCode = "file_not_found" ) type BetaTextEditorCodeExecutionViewResultBlock struct { Content string `json:"content" api:"required"` // Any of "text", "image", "pdf". FileType BetaTextEditorCodeExecutionViewResultBlockFileType `json:"file_type" api:"required"` NumLines int64 `json:"num_lines" api:"required"` StartLine int64 `json:"start_line" api:"required"` TotalLines int64 `json:"total_lines" api:"required"` Type constant.TextEditorCodeExecutionViewResult `json:"type" api:"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 (r BetaTextEditorCodeExecutionViewResultBlock) RawJSON() string { return r.JSON.raw } func (r *BetaTextEditorCodeExecutionViewResultBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaTextEditorCodeExecutionViewResultBlockFileType string const ( BetaTextEditorCodeExecutionViewResultBlockFileTypeText BetaTextEditorCodeExecutionViewResultBlockFileType = "text" BetaTextEditorCodeExecutionViewResultBlockFileTypeImage BetaTextEditorCodeExecutionViewResultBlockFileType = "image" BetaTextEditorCodeExecutionViewResultBlockFileTypePDF BetaTextEditorCodeExecutionViewResultBlockFileType = "pdf" ) // The properties Content, FileType, Type are required. type BetaTextEditorCodeExecutionViewResultBlockParam struct { Content string `json:"content" api:"required"` // Any of "text", "image", "pdf". FileType BetaTextEditorCodeExecutionViewResultBlockParamFileType `json:"file_type,omitzero" api:"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" api:"required"` paramObj } func (r BetaTextEditorCodeExecutionViewResultBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaTextEditorCodeExecutionViewResultBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaTextEditorCodeExecutionViewResultBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaTextEditorCodeExecutionViewResultBlockParamFileType string const ( BetaTextEditorCodeExecutionViewResultBlockParamFileTypeText BetaTextEditorCodeExecutionViewResultBlockParamFileType = "text" BetaTextEditorCodeExecutionViewResultBlockParamFileTypeImage BetaTextEditorCodeExecutionViewResultBlockParamFileType = "image" BetaTextEditorCodeExecutionViewResultBlockParamFileTypePDF BetaTextEditorCodeExecutionViewResultBlockParamFileType = "pdf" ) type BetaThinkingBlock struct { Signature string `json:"signature" api:"required"` Thinking string `json:"thinking" api:"required"` Type constant.Thinking `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Signature respjson.Field Thinking respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } // The properties Signature, Thinking, Type are required. type BetaThinkingBlockParam struct { Signature string `json:"signature" api:"required"` Thinking string `json:"thinking" api:"required"` // This field can be elided, and will marshal its zero value as "thinking". Type constant.Thinking `json:"type" api:"required"` paramObj } 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) } // The property Type is required. type BetaThinkingConfigAdaptiveParam struct { // Controls how thinking content appears in the response. When set to `summarized`, // thinking is returned normally. When set to `omitted`, thinking content is // redacted but a signature is returned for multi-turn continuity. Defaults to // `summarized`. // // Any of "summarized", "omitted". Display BetaThinkingConfigAdaptiveDisplay `json:"display,omitzero"` // This field can be elided, and will marshal its zero value as "adaptive". Type constant.Adaptive `json:"type" api:"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) } // Controls how thinking content appears in the response. When set to `summarized`, // thinking is returned normally. When set to `omitted`, thinking content is // redacted but a signature is returned for multi-turn continuity. Defaults to // `summarized`. type BetaThinkingConfigAdaptiveDisplay string const ( BetaThinkingConfigAdaptiveDisplaySummarized BetaThinkingConfigAdaptiveDisplay = "summarized" BetaThinkingConfigAdaptiveDisplayOmitted BetaThinkingConfigAdaptiveDisplay = "omitted" ) func NewBetaThinkingConfigDisabledParam() BetaThinkingConfigDisabledParam { return BetaThinkingConfigDisabledParam{ Type: "disabled", } } // This struct has a constant value, construct it with // [NewBetaThinkingConfigDisabledParam]. type BetaThinkingConfigDisabledParam struct { Type constant.Disabled `json:"type" api:"required"` paramObj } 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) } // The properties BudgetTokens, Type are required. type BetaThinkingConfigEnabledParam 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" api:"required"` // Controls how thinking content appears in the response. When set to `summarized`, // thinking is returned normally. When set to `omitted`, thinking content is // redacted but a signature is returned for multi-turn continuity. Defaults to // `summarized`. // // Any of "summarized", "omitted". Display BetaThinkingConfigEnabledDisplay `json:"display,omitzero"` // This field can be elided, and will marshal its zero value as "enabled". Type constant.Enabled `json:"type" api:"required"` paramObj } 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) } // Controls how thinking content appears in the response. When set to `summarized`, // thinking is returned normally. When set to `omitted`, thinking content is // redacted but a signature is returned for multi-turn continuity. Defaults to // `summarized`. type BetaThinkingConfigEnabledDisplay string const ( BetaThinkingConfigEnabledDisplaySummarized BetaThinkingConfigEnabledDisplay = "summarized" BetaThinkingConfigEnabledDisplayOmitted BetaThinkingConfigEnabledDisplay = "omitted" ) func BetaThinkingConfigParamOfEnabled(budgetTokens int64) BetaThinkingConfigParamUnion { var enabled BetaThinkingConfigEnabledParam enabled.BudgetTokens = budgetTokens return BetaThinkingConfigParamUnion{OfEnabled: &enabled} } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. 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, u.OfAdaptive) } func (u *BetaThinkingConfigParamUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } func (u *BetaThinkingConfigParamUnion) 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 BetaThinkingConfigParamUnion) 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 BetaThinkingConfigParamUnion) 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaThinkingConfigParamUnion) GetDisplay() *string { if vt := u.OfEnabled; vt != nil { return (*string)(&vt.Display) } else if vt := u.OfAdaptive; vt != nil { return (*string)(&vt.Display) } return nil } type BetaThinkingDelta struct { Thinking string `json:"thinking" api:"required"` Type constant.ThinkingDelta `json:"type" api:"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 } `json:"-"` } // 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" api:"required"` // This field can be elided, and will marshal its zero value as "thinking_turns". Type constant.ThinkingTurns `json:"type" api:"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. // // This defines the shape of the `input` that your tool accepts and that the model // will produce. InputSchema BetaToolInputSchemaParam `json:"input_schema,omitzero" api:"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" api:"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 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"` InputExamples []map[string]any `json:"input_examples,omitzero"` paramObj } 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) } // [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 BetaToolInputSchemaParam 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" api:"required"` ExtraFields map[string]any `json:"-"` paramObj } 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) } type BetaToolType string const ( BetaToolTypeCustom BetaToolType = "custom" ) // 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"` 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" api:"required"` // This field can be elided, and will marshal its zero value as "bash_20241022". Type constant.Bash20241022 `json:"type" api:"required"` paramObj } 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"` 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" api:"required"` // This field can be elided, and will marshal its zero value as "bash_20250124". Type constant.Bash20250124 `json:"type" api:"required"` paramObj } 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) } func BetaToolChoiceParamOfTool(name string) BetaToolChoiceUnionParam { var tool BetaToolChoiceToolParam tool.Name = name return BetaToolChoiceUnionParam{OfTool: &tool} } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaToolChoiceUnionParam struct { OfAuto *BetaToolChoiceAutoParam `json:",omitzero,inline"` OfAny *BetaToolChoiceAnyParam `json:",omitzero,inline"` OfTool *BetaToolChoiceToolParam `json:",omitzero,inline"` OfNone *BetaToolChoiceNoneParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaToolChoiceUnionParam) 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 a pointer to the underlying variant's property, if present. func (u BetaToolChoiceUnionParam) GetName() *string { if vt := u.OfTool; vt != nil { return &vt.Name } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolChoiceUnionParam) 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolChoiceUnionParam) 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 nil } // The model will use any available tools. // // The property Type is required. type BetaToolChoiceAnyParam 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" api:"required"` paramObj } 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) } // The model will automatically decide whether to use tools. // // The property Type is required. type BetaToolChoiceAutoParam 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" api:"required"` paramObj } 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) } func NewBetaToolChoiceNoneParam() BetaToolChoiceNoneParam { return BetaToolChoiceNoneParam{ Type: "none", } } // The model will not be allowed to use tools. // // This struct has a constant value, construct it with // [NewBetaToolChoiceNoneParam]. type BetaToolChoiceNoneParam struct { Type constant.None `json:"type" api:"required"` paramObj } 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) } // The model will use the specified tool with `tool_choice.name`. // // The properties Name, Type are required. type BetaToolChoiceToolParam struct { // The name of the tool to use. Name string `json:"name" api:"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" api:"required"` paramObj } 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) } // The properties DisplayHeightPx, DisplayWidthPx, Name, Type are required. type BetaToolComputerUse20241022Param struct { // The height of the display in pixels. DisplayHeightPx int64 `json:"display_height_px" api:"required"` // The width of the display in pixels. DisplayWidthPx int64 `json:"display_width_px" api:"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"` 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" api:"required"` // This field can be elided, and will marshal its zero value as // "computer_20241022". Type constant.Computer20241022 `json:"type" api:"required"` paramObj } 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) } // The properties DisplayHeightPx, DisplayWidthPx, Name, Type are required. type BetaToolComputerUse20250124Param struct { // The height of the display in pixels. DisplayHeightPx int64 `json:"display_height_px" api:"required"` // The width of the display in pixels. DisplayWidthPx int64 `json:"display_width_px" api:"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"` 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" api:"required"` // This field can be elided, and will marshal its zero value as // "computer_20250124". Type constant.Computer20250124 `json:"type" api:"required"` paramObj } 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" api:"required"` // The width of the display in pixels. DisplayWidthPx int64 `json:"display_width_px" api:"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" api:"required"` // This field can be elided, and will marshal its zero value as // "computer_20251124". Type constant.Computer20251124 `json:"type" api:"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" api:"required"` Type constant.ToolReference `json:"type" api:"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" api:"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" api:"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" api:"required"` IsError param.Opt[bool] `json:"is_error,omitzero"` // Create a cache control breakpoint at this content block. CacheControl BetaCacheControlEphemeralParam `json:"cache_control,omitzero"` Content []BetaToolResultBlockParamContentUnion `json:"content,omitzero"` // This field can be elided, and will marshal its zero value as "tool_result". Type constant.ToolResult `json:"type" api:"required"` paramObj } 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"` OfToolReference *BetaToolReferenceBlockParam `json:",omitzero,inline"` paramUnion } func (u BetaToolResultBlockParamContentUnion) MarshalJSON() ([]byte, error) { 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) } func (u *BetaToolResultBlockParamContentUnion) 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 BetaToolResultBlockParamContentUnion) 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 BetaToolResultBlockParamContentUnion) GetContent() []BetaTextBlockParam { if vt := u.OfSearchResult; vt != nil { return vt.Content } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolResultBlockParamContentUnion) 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 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 { 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 BetaToolResultBlockParamContentUnion) 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 BetaToolResultBlockParamContentUnion) GetCacheControl() *BetaCacheControlEphemeralParam { 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 BetaToolResultBlockParamContentUnion) GetCitations() (res betaToolResultBlockParamContentUnionCitations) { 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 [*[]BetaTextCitationParamUnion], // [*BetaCitationsConfigParam] type betaToolResultBlockParamContentUnionCitations struct{ any } // Use the following switch statement to get the type of the union: // // switch u.AsAny().(type) { // case *[]anthropic.BetaTextCitationParamUnion: // case *anthropic.BetaCitationsConfigParam: // default: // fmt.Errorf("not present") // } func (u betaToolResultBlockParamContentUnionCitations) AsAny() any { return u.any } // Returns a pointer to the underlying variant's property, if present. func (u betaToolResultBlockParamContentUnionCitations) GetEnabled() *bool { switch vt := u.any.(type) { case *BetaCitationsConfigParam: 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 BetaToolResultBlockParamContentUnion) GetSource() (res betaToolResultBlockParamContentUnionSource) { 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 } // Can have the runtime types [*BetaBase64ImageSourceParam], // [*BetaURLImageSourceParam], [*BetaFileImageSourceParam], [*string], // [*BetaBase64PDFSourceParam], [*BetaPlainTextSourceParam], // [*BetaContentBlockSourceParam], [*BetaURLPDFSourceParam], // [*BetaFileDocumentSourceParam] type betaToolResultBlockParamContentUnionSource struct{ any } // Use the following switch statement to get the type of the union: // // switch u.AsAny().(type) { // case *anthropic.BetaBase64ImageSourceParam: // case *anthropic.BetaURLImageSourceParam: // case *anthropic.BetaFileImageSourceParam: // case *string: // case *anthropic.BetaBase64PDFSourceParam: // case *anthropic.BetaPlainTextSourceParam: // case *anthropic.BetaContentBlockSourceParam: // case *anthropic.BetaURLPDFSourceParam: // case *anthropic.BetaFileDocumentSourceParam: // default: // fmt.Errorf("not present") // } func (u betaToolResultBlockParamContentUnionSource) AsAny() any { return u.any } // Returns a pointer to the underlying variant's property, if present. func (u betaToolResultBlockParamContentUnionSource) GetContent() *BetaContentBlockSourceContentUnionParam { switch vt := u.any.(type) { case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetContent() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaToolResultBlockParamContentUnionSource) GetData() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetData() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetData() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaToolResultBlockParamContentUnionSource) GetMediaType() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetMediaType() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetMediaType() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaToolResultBlockParamContentUnionSource) GetType() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetType() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetType() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaToolResultBlockParamContentUnionSource) GetURL() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetURL() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetURL() } return nil } // Returns a pointer to the underlying variant's property, if present. func (u betaToolResultBlockParamContentUnionSource) GetFileID() *string { switch vt := u.any.(type) { case *BetaImageBlockParamSourceUnion: return vt.GetFileID() case *BetaRequestDocumentBlockSourceUnionParam: return vt.GetFileID() } return nil } // The properties Name, Type are required. type BetaToolSearchToolBm25_20251119Param struct { // Any of "tool_search_tool_bm25_20251119", "tool_search_tool_bm25". Type BetaToolSearchToolBm25_20251119Type `json:"type,omitzero" api:"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" api:"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" api:"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" api:"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" api:"required"` ToolUseID string `json:"tool_use_id" api:"required"` Type constant.ToolSearchToolResult `json:"type" api:"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" api:"required"` ToolUseID string `json:"tool_use_id" api:"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" api:"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" api:"required"` ErrorMessage string `json:"error_message" api:"required"` Type constant.ToolSearchToolResultError `json:"type" api:"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" api:"required"` // This field can be elided, and will marshal its zero value as // "tool_search_tool_result_error". Type constant.ToolSearchToolResultError `json:"type" api:"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" api:"required"` Type constant.ToolSearchToolSearchResult `json:"type" api:"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" api:"required"` // This field can be elided, and will marshal its zero value as // "tool_search_tool_search_result". Type constant.ToolSearchToolSearchResult `json:"type" api:"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. // // This field can be elided, and will marshal its zero value as // "str_replace_editor". Name constant.StrReplaceEditor `json:"name" api:"required"` // This field can be elided, and will marshal its zero value as // "text_editor_20241022". Type constant.TextEditor20241022 `json:"type" api:"required"` paramObj } 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"` 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_editor". Name constant.StrReplaceEditor `json:"name" api:"required"` // This field can be elided, and will marshal its zero value as // "text_editor_20250124". Type constant.TextEditor20250124 `json:"type" api:"required"` paramObj } 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"` 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" api:"required"` // This field can be elided, and will marshal its zero value as // "text_editor_20250429". Type constant.TextEditor20250429 `json:"type" api:"required"` paramObj } 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) } // The properties Name, Type are required. 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"` 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" api:"required"` // This field can be elided, and will marshal its zero value as // "text_editor_20250728". Type constant.TextEditor20250728 `json:"type" api:"required"` paramObj } 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) } func BetaToolUnionParamOfTool(inputSchema BetaToolInputSchemaParam, name string) BetaToolUnionParam { var variant BetaToolParam variant.InputSchema = inputSchema variant.Name = name return BetaToolUnionParam{OfTool: &variant} } func BetaToolUnionParamOfComputerUseTool20241022(displayHeightPx int64, displayWidthPx int64) BetaToolUnionParam { var variant BetaToolComputerUse20241022Param variant.DisplayHeightPx = displayHeightPx variant.DisplayWidthPx = displayWidthPx return BetaToolUnionParam{OfComputerUseTool20241022: &variant} } func BetaToolUnionParamOfComputerUseTool20250124(displayHeightPx int64, displayWidthPx int64) BetaToolUnionParam { var variant BetaToolComputerUse20250124Param variant.DisplayHeightPx = displayHeightPx variant.DisplayWidthPx = displayWidthPx 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"` 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"` OfWebFetchTool20260309 *BetaWebFetchTool20260309Param `json:",omitzero,inline"` OfToolSearchToolBm25_20251119 *BetaToolSearchToolBm25_20251119Param `json:",omitzero,inline"` OfToolSearchToolRegex20251119 *BetaToolSearchToolRegex20251119Param `json:",omitzero,inline"` OfMCPToolset *BetaMCPToolsetParam `json:",omitzero,inline"` paramUnion } func (u BetaToolUnionParam) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfTool, u.OfBashTool20241022, 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.OfWebSearchTool20260209, u.OfWebFetchTool20260209, u.OfWebFetchTool20260309, u.OfToolSearchToolBm25_20251119, u.OfToolSearchToolRegex20251119, u.OfMCPToolset) } func (u *BetaToolUnionParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } func (u *BetaToolUnionParam) asAny() any { if !param.IsOmitted(u.OfTool) { return u.OfTool } else if !param.IsOmitted(u.OfBashTool20241022) { return u.OfBashTool20241022 } 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.OfComputerUseTool20241022) { return u.OfComputerUseTool20241022 } else if !param.IsOmitted(u.OfMemoryTool20250818) { return u.OfMemoryTool20250818 } else if !param.IsOmitted(u.OfComputerUseTool20250124) { 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) { 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.OfWebFetchTool20260309) { return u.OfWebFetchTool20260309 } 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) GetInputSchema() *BetaToolInputSchemaParam { if vt := u.OfTool; vt != nil { return &vt.InputSchema } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) 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 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() { return &vt.MaxCharacters.Value } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) GetUseCache() *bool { if vt := u.OfWebFetchTool20260309; vt != nil && vt.UseCache.Valid() { return &vt.UseCache.Value } return nil } // Returns a pointer to the underlying variant's property, if present. 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) 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) GetDefaultConfig() *BetaMCPToolDefaultConfigParam { if vt := u.OfMCPToolset; vt != nil { return &vt.DefaultConfig } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) GetName() *string { if vt := u.OfTool; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfBashTool20241022; 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.OfComputerUseTool20241022; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfMemoryTool20250818; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfComputerUseTool20250124; vt != nil { 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 { 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.OfWebFetchTool20260309; 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.OfWebFetchTool20260309; 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.OfWebFetchTool20260309; 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 BetaToolUnionParam) GetType() *string { if vt := u.OfTool; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfBashTool20241022; 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.OfComputerUseTool20241022; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfMemoryTool20250818; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfComputerUseTool20250124; vt != nil { 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 { 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.OfWebFetchTool20260309; 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) GetDisplayHeightPx() *int64 { if vt := u.OfComputerUseTool20241022; vt != nil { 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) GetDisplayWidthPx() *int64 { if vt := u.OfComputerUseTool20241022; vt != nil { 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) GetDisplayNumber() *int64 { if vt := u.OfComputerUseTool20241022; vt != nil && vt.DisplayNumber.Valid() { 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaToolUnionParam) 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 } else if vt := u.OfWebFetchTool20260309; 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 } else if vt := u.OfWebFetchTool20260309; 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.OfWebFetchTool20260309; 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 BetaToolUnionParam) GetCacheControl() *BetaCacheControlEphemeralParam { if vt := u.OfTool; vt != nil { return &vt.CacheControl } else if vt := u.OfBashTool20241022; 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.OfComputerUseTool20241022; vt != nil { return &vt.CacheControl } else if vt := u.OfMemoryTool20250818; vt != nil { return &vt.CacheControl } else if vt := u.OfComputerUseTool20250124; vt != nil { 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 { 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.OfWebFetchTool20260309; 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 } // Returns a pointer to the underlying variant's AllowedDomains property, if // present. func (u BetaToolUnionParam) 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 } else if vt := u.OfWebFetchTool20260309; vt != nil { return vt.AllowedDomains } return nil } // Returns a pointer to the underlying variant's BlockedDomains property, if // present. func (u BetaToolUnionParam) 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 } else if vt := u.OfWebFetchTool20260309; 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 } else if vt := u.OfWebFetchTool20260309; vt != nil { return &vt.Citations } return nil } type BetaToolUseBlock struct { ID string `json:"id" api:"required"` Input any `json:"input" api:"required"` Name string `json:"name" api:"required"` Type constant.ToolUse `json:"type" api:"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:"-"` } // 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) } // 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. type BetaToolUseBlockParam struct { ID string `json:"id" api:"required"` Input any `json:"input,omitzero" api:"required"` Name string `json:"name" api:"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" api:"required"` paramObj } 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 } // The properties Type, Value are required. type BetaToolUsesKeepParam struct { Value int64 `json:"value" api:"required"` // This field can be elided, and will marshal its zero value as "tool_uses". Type constant.ToolUses `json:"type" api:"required"` paramObj } 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) } // The properties Type, Value are required. type BetaToolUsesTriggerParam struct { Value int64 `json:"value" api:"required"` // This field can be elided, and will marshal its zero value as "tool_uses". Type constant.ToolUses `json:"type" api:"required"` paramObj } 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) } // The properties Type, URL are required. type BetaURLImageSourceParam struct { URL string `json:"url" api:"required"` // This field can be elided, and will marshal its zero value as "url". Type constant.URL `json:"type" api:"required"` paramObj } 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) } // The properties Type, URL are required. type BetaURLPDFSourceParam struct { URL string `json:"url" api:"required"` // This field can be elided, and will marshal its zero value as "url". Type constant.URL `json:"type" api:"required"` paramObj } 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) } type BetaUsage struct { // Breakdown of cached tokens by TTL CacheCreation BetaCacheCreation `json:"cache_creation" api:"required"` // The number of input tokens used to create the cache entry. CacheCreationInputTokens int64 `json:"cache_creation_input_tokens" api:"required"` // The number of input tokens read from the cache. CacheReadInputTokens int64 `json:"cache_read_input_tokens" api:"required"` // The geographic region where inference was performed for this request. InferenceGeo string `json:"inference_geo" api:"required"` // The number of input tokens which were used. InputTokens int64 `json:"input_tokens" api:"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" api:"required"` // The number of output tokens which were used. OutputTokens int64 `json:"output_tokens" api:"required"` // The number of server tool requests. ServerToolUse BetaServerToolUsage `json:"server_tool_use" api:"required"` // If the request used the priority, standard, or batch tier. // // Any of "standard", "priority", "batch". ServiceTier BetaUsageServiceTier `json:"service_tier" api:"required"` // The inference speed mode used for this request. // // Any of "standard", "fast". Speed BetaUsageSpeed `json:"speed" api:"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:"-"` } // 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) } // If the request used the priority, standard, or batch tier. type BetaUsageServiceTier string const ( BetaUsageServiceTierStandard BetaUsageServiceTier = "standard" BetaUsageServiceTierPriority BetaUsageServiceTier = "priority" 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" api:"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" api:"required"` // ISO 8601 timestamp when the content was retrieved RetrievedAt string `json:"retrieved_at" api:"required"` Type constant.WebFetchResult `json:"type" api:"required"` // Fetched content URL URL string `json:"url" api:"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:"-"` } // 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) } // The properties Content, Type, URL are required. type BetaWebFetchBlockParam struct { Content BetaRequestDocumentBlockParam `json:"content,omitzero" api:"required"` // Fetched content URL URL string `json:"url" api:"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" api:"required"` paramObj } 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) } // The properties Name, Type are required. type BetaWebFetchTool20250910Param 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" api:"required"` // This field can be elided, and will marshal its zero value as // "web_fetch_20250910". Type constant.WebFetch20250910 `json:"type" api:"required"` paramObj } 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" api:"required"` // This field can be elided, and will marshal its zero value as // "web_fetch_20260209". Type constant.WebFetch20260209 `json:"type" api:"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) } // Web fetch tool with use_cache parameter for bypassing cached content. // // The properties Name, Type are required. type BetaWebFetchTool20260309Param 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"` // Whether to use cached content. Set to false to bypass the cache and fetch fresh // content. Only set to false when the user explicitly requests fresh content or // when fetching rapidly-changing sources. UseCache param.Opt[bool] `json:"use_cache,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" api:"required"` // This field can be elided, and will marshal its zero value as // "web_fetch_20260309". Type constant.WebFetch20260309 `json:"type" api:"required"` paramObj } func (r BetaWebFetchTool20260309Param) MarshalJSON() (data []byte, err error) { type shadow BetaWebFetchTool20260309Param return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaWebFetchTool20260309Param) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaWebFetchToolResultBlock struct { Content BetaWebFetchToolResultBlockContentUnion `json:"content" api:"required"` ToolUseID string `json:"tool_use_id" api:"required"` Type constant.WebFetchToolResult `json:"type" api:"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:"-"` } // 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) } // BetaWebFetchToolResultBlockContentUnion contains all possible properties and // values from [BetaWebFetchToolResultErrorBlock], [BetaWebFetchBlock]. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaWebFetchToolResultBlockContentUnion struct { // This field is from variant [BetaWebFetchToolResultErrorBlock]. ErrorCode BetaWebFetchToolResultErrorCode `json:"error_code"` Type string `json:"type"` // This field is from variant [BetaWebFetchBlock]. Content BetaDocumentBlock `json:"content"` // This field is from variant [BetaWebFetchBlock]. RetrievedAt string `json:"retrieved_at"` // This field is from variant [BetaWebFetchBlock]. URL string `json:"url"` JSON struct { ErrorCode respjson.Field Type respjson.Field Content respjson.Field RetrievedAt respjson.Field URL respjson.Field raw string } `json:"-"` } func (u BetaWebFetchToolResultBlockContentUnion) AsResponseWebFetchToolResultError() (v BetaWebFetchToolResultErrorBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaWebFetchToolResultBlockContentUnion) AsResponseWebFetchResultBlock() (v BetaWebFetchBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaWebFetchToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } func (r *BetaWebFetchToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { 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" api:"required"` ToolUseID string `json:"tool_use_id" api:"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" api:"required"` paramObj } 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) } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaWebFetchToolResultBlockParamContentUnion struct { OfRequestWebFetchToolResultError *BetaWebFetchToolResultErrorBlockParam `json:",omitzero,inline"` OfRequestWebFetchResultBlock *BetaWebFetchBlockParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaWebFetchToolResultBlockParamContentUnion) 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 BetaWebFetchToolResultBlockParamContentUnion) GetErrorCode() *string { if vt := u.OfRequestWebFetchToolResultError; vt != nil { return (*string)(&vt.ErrorCode) } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaWebFetchToolResultBlockParamContentUnion) GetContent() *BetaRequestDocumentBlockParam { if vt := u.OfRequestWebFetchResultBlock; vt != nil { return &vt.Content } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaWebFetchToolResultBlockParamContentUnion) GetURL() *string { if vt := u.OfRequestWebFetchResultBlock; vt != nil { return &vt.URL } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaWebFetchToolResultBlockParamContentUnion) GetRetrievedAt() *string { if vt := u.OfRequestWebFetchResultBlock; vt != nil && vt.RetrievedAt.Valid() { return &vt.RetrievedAt.Value } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaWebFetchToolResultBlockParamContentUnion) 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 } // 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 } type BetaWebFetchToolResultErrorBlock 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 BetaWebFetchToolResultErrorCode `json:"error_code" api:"required"` Type constant.WebFetchToolResultError `json:"type" api:"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 BetaWebFetchToolResultErrorBlock) RawJSON() string { return r.JSON.raw } func (r *BetaWebFetchToolResultErrorBlock) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties ErrorCode, Type are required. type BetaWebFetchToolResultErrorBlockParam 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 BetaWebFetchToolResultErrorCode `json:"error_code,omitzero" api:"required"` // This field can be elided, and will marshal its zero value as // "web_fetch_tool_result_error". Type constant.WebFetchToolResultError `json:"type" api:"required"` paramObj } func (r BetaWebFetchToolResultErrorBlockParam) MarshalJSON() (data []byte, err error) { type shadow BetaWebFetchToolResultErrorBlockParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaWebFetchToolResultErrorBlockParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaWebFetchToolResultErrorCode string const ( BetaWebFetchToolResultErrorCodeInvalidToolInput BetaWebFetchToolResultErrorCode = "invalid_tool_input" BetaWebFetchToolResultErrorCodeURLTooLong BetaWebFetchToolResultErrorCode = "url_too_long" BetaWebFetchToolResultErrorCodeURLNotAllowed BetaWebFetchToolResultErrorCode = "url_not_allowed" BetaWebFetchToolResultErrorCodeURLNotAccessible BetaWebFetchToolResultErrorCode = "url_not_accessible" BetaWebFetchToolResultErrorCodeUnsupportedContentType BetaWebFetchToolResultErrorCode = "unsupported_content_type" BetaWebFetchToolResultErrorCodeTooManyRequests BetaWebFetchToolResultErrorCode = "too_many_requests" BetaWebFetchToolResultErrorCodeMaxUsesExceeded BetaWebFetchToolResultErrorCode = "max_uses_exceeded" BetaWebFetchToolResultErrorCodeUnavailable BetaWebFetchToolResultErrorCode = "unavailable" ) type BetaWebSearchResultBlock struct { EncryptedContent string `json:"encrypted_content" api:"required"` PageAge string `json:"page_age" api:"required"` Title string `json:"title" api:"required"` Type constant.WebSearchResult `json:"type" api:"required"` URL string `json:"url" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { EncryptedContent respjson.Field PageAge respjson.Field Title respjson.Field Type respjson.Field URL respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // 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) } // The properties EncryptedContent, Title, Type, URL are required. type BetaWebSearchResultBlockParam struct { EncryptedContent string `json:"encrypted_content" api:"required"` Title string `json:"title" api:"required"` URL string `json:"url" api:"required"` PageAge param.Opt[string] `json:"page_age,omitzero"` // This field can be elided, and will marshal its zero value as // "web_search_result". Type constant.WebSearchResult `json:"type" api:"required"` paramObj } 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) } // The properties Name, Type are required. 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"` // 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" api:"required"` // This field can be elided, and will marshal its zero value as // "web_search_20250305". Type constant.WebSearch20250305 `json:"type" api:"required"` paramObj } 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) } // 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" api:"required"` // This field can be elided, and will marshal its zero value as // "web_search_20260209". Type constant.WebSearch20260209 `json:"type" api:"required"` paramObj } func (r BetaWebSearchTool20260209Param) MarshalJSON() (data []byte, err error) { type shadow BetaWebSearchTool20260209Param return param.MarshalObject(r, (*shadow)(&r)) } 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", "request_too_large". ErrorCode BetaWebSearchToolResultErrorCode `json:"error_code,omitzero" api:"required"` // This field can be elided, and will marshal its zero value as // "web_search_tool_result_error". Type constant.WebSearchToolResultError `json:"type" api:"required"` paramObj } func (r BetaWebSearchToolRequestErrorParam) MarshalJSON() (data []byte, err error) { type shadow BetaWebSearchToolRequestErrorParam return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaWebSearchToolRequestErrorParam) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaWebSearchToolResultBlock struct { Content BetaWebSearchToolResultBlockContentUnion `json:"content" api:"required"` ToolUseID string `json:"tool_use_id" api:"required"` Type constant.WebSearchToolResult `json:"type" api:"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:"-"` } // 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]. // // Use the methods beginning with 'As' to cast the union to one of its variants. // // If the underlying value is not a json object, one of the following properties // will be valid: OfBetaWebSearchResultBlockArray] type BetaWebSearchToolResultBlockContentUnion struct { // This field will be present if the value is a [[]BetaWebSearchResultBlock] // instead of an object. OfBetaWebSearchResultBlockArray []BetaWebSearchResultBlock `json:",inline"` // This field is from variant [BetaWebSearchToolResultError]. ErrorCode BetaWebSearchToolResultErrorCode `json:"error_code"` // This field is from variant [BetaWebSearchToolResultError]. Type constant.WebSearchToolResultError `json:"type"` JSON struct { OfBetaWebSearchResultBlockArray respjson.Field ErrorCode respjson.Field Type respjson.Field raw string } `json:"-"` } func (u BetaWebSearchToolResultBlockContentUnion) AsResponseWebSearchToolResultError() (v BetaWebSearchToolResultError) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaWebSearchToolResultBlockContentUnion) AsBetaWebSearchResultBlockArray() (v []BetaWebSearchResultBlock) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaWebSearchToolResultBlockContentUnion) RawJSON() string { return u.JSON.raw } func (r *BetaWebSearchToolResultBlockContentUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties Content, ToolUseID, Type are required. type BetaWebSearchToolResultBlockParam struct { Content BetaWebSearchToolResultBlockParamContentUnion `json:"content,omitzero" api:"required"` ToolUseID string `json:"tool_use_id" api:"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" api:"required"` paramObj } 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 BetaNewWebSearchToolRequestError(errorCode BetaWebSearchToolResultErrorCode) BetaWebSearchToolResultBlockParamContentUnion { var variant BetaWebSearchToolRequestErrorParam variant.ErrorCode = errorCode return BetaWebSearchToolResultBlockParamContentUnion{OfError: &variant} } // Only one field can be non-zero. // // Use [param.IsOmitted] to confirm if a field is set. type BetaWebSearchToolResultBlockParamContentUnion struct { OfResultBlock []BetaWebSearchResultBlockParam `json:",omitzero,inline"` OfError *BetaWebSearchToolRequestErrorParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaWebSearchToolResultBlockParamContentUnion) asAny() any { if !param.IsOmitted(u.OfResultBlock) { return &u.OfResultBlock } else if !param.IsOmitted(u.OfError) { return u.OfError } return nil } type BetaWebSearchToolResultError struct { // Any of "invalid_tool_input", "unavailable", "max_uses_exceeded", // "too_many_requests", "query_too_long", "request_too_large". ErrorCode BetaWebSearchToolResultErrorCode `json:"error_code" api:"required"` Type constant.WebSearchToolResultError `json:"type" api:"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 BetaWebSearchToolResultError) RawJSON() string { return r.JSON.raw } func (r *BetaWebSearchToolResultError) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaWebSearchToolResultErrorCode string const ( BetaWebSearchToolResultErrorCodeInvalidToolInput BetaWebSearchToolResultErrorCode = "invalid_tool_input" BetaWebSearchToolResultErrorCodeUnavailable BetaWebSearchToolResultErrorCode = "unavailable" BetaWebSearchToolResultErrorCodeMaxUsesExceeded BetaWebSearchToolResultErrorCode = "max_uses_exceeded" BetaWebSearchToolResultErrorCodeTooManyRequests BetaWebSearchToolResultErrorCode = "too_many_requests" BetaWebSearchToolResultErrorCodeQueryTooLong BetaWebSearchToolResultErrorCode = "query_too_long" BetaWebSearchToolResultErrorCodeRequestTooLarge BetaWebSearchToolResultErrorCode = "request_too_large" ) type BetaMessageNewParams struct { // The maximum number of tokens to generate before stopping. // // Note that our models may stop _before_ reaching this maximum. This parameter // only specifies the absolute maximum number of tokens to generate. // // Different models have different maximum values for this parameter. See // [models](https://docs.claude.com/en/docs/models-overview) for details. MaxTokens int64 `json:"max_tokens" api:"required"` // Input messages. // // Our models are trained to operate on alternating `user` and `assistant` // conversational turns. When creating a new `Message`, you specify the prior // conversational turns with the `messages` parameter, and the model then generates // the next `Message` in the conversation. Consecutive `user` or `assistant` turns // in your request will be combined into a single turn. // // Each input message must be an object with a `role` and `content`. You can // specify a single `user`-role message, or you can include multiple `user` and // `assistant` messages. // // If the final message uses the `assistant` role, the response content will // continue immediately from the content in that message. This can be used to // constrain part of the model's response. // // Example with a single `user` message: // // ```json // [{ "role": "user", "content": "Hello, Claude" }] // ``` // // Example with multiple conversational turns: // // ```json // [ // // { "role": "user", "content": "Hello there." }, // { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, // { "role": "user", "content": "Can you explain LLMs in plain English?" } // // ] // ``` // // Example with a partially-filled response from Claude: // // ```json // [ // // { // "role": "user", // "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" // }, // { "role": "assistant", "content": "The best answer is (" } // // ] // ``` // // Each input message `content` may be either a single `string` or an array of // content blocks, where each block has a specific `type`. Using a `string` for // `content` is shorthand for an array of one content block of type `"text"`. The // following input messages are equivalent: // // ```json // { "role": "user", "content": "Hello, Claude" } // ``` // // ```json // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a // [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" api:"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,omitzero" api:"required"` // 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` // for analytical / multiple choice, and closer to `1.0` for creative and // generative tasks. // // Note that even with `temperature` of `0.0`, the results will not be fully // deterministic. Temperature param.Opt[float64] `json:"temperature,omitzero"` // Only sample from the top K options for each subsequent token. // // Used to remove "long tail" low probability responses. // [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). // // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopK param.Opt[int64] `json:"top_k,omitzero"` // Use nucleus sampling. // // In nucleus sampling, we compute the cumulative distribution over all the options // for each subsequent token in decreasing probability order and cut it off once it // reaches a particular probability specified by `top_p`. You should either alter // `temperature` or `top_p`, but not both. // // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopP param.Opt[float64] `json:"top_p,omitzero"` // 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.claude.com/en/api/service-tiers) for details. // // Any of "auto", "standard_only". ServiceTier BetaMessageNewParamsServiceTier `json:"service_tier,omitzero"` // Custom text sequences that will cause the model to stop generating. // // Our models will normally stop when they have naturally completed their turn, // which will result in a response `stop_reason` of `"end_turn"`. // // If you want the model to stop generating when it encounters custom strings of // text, you can use the `stop_sequences` parameter. If the model encounters one of // the custom sequences, the response `stop_reason` value will be `"stop_sequence"` // and the response `stop_sequence` value will contain the matched stop sequence. StopSequences []string `json:"stop_sequences,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.claude.com/en/docs/system-prompts). System []BetaTextBlockParam `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // // When enabled, responses include `thinking` content blocks showing Claude's // thinking process before the final answer. Requires a minimum budget of 1,024 // tokens and counts towards your `max_tokens` limit. // // See // [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, // any available tool, decide by itself, or not use tools at all. ToolChoice BetaToolChoiceUnionParam `json:"tool_choice,omitzero"` // Definitions of tools that the model may use. // // If you include `tools` in your API request, the model may return `tool_use` // content blocks that represent the model's use of those tools. You can then run // those tools using the tool input generated by the model and then optionally // return results back to the model using `tool_result` content blocks. // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For // [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.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // // - `name`: Name of the tool. // - `description`: Optional, but strongly-recommended description of the tool. // - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the // tool `input` shape that the model will produce in `tool_use` output content // blocks. // // For example, if you defined `tools` as: // // ```json // [ // // { // "name": "get_stock_price", // "description": "Get the current stock price for a given ticker symbol.", // "input_schema": { // "type": "object", // "properties": { // "ticker": { // "type": "string", // "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." // } // }, // "required": ["ticker"] // } // } // // ] // ``` // // And then asked the model "What's the S&P 500 at today?", the model might produce // `tool_use` content blocks in the response like this: // // ```json // [ // // { // "type": "tool_use", // "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", // "name": "get_stock_price", // "input": { "ticker": "^GSPC" } // } // // ] // ``` // // You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an // input, and return the following back to the model in a subsequent `user` // message: // // ```json // [ // // { // "type": "tool_result", // "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", // "content": "259.75 USD" // } // // ] // ``` // // Tools can be used for workflows that include running client-side tools and // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // // 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:"-"` paramObj } 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.claude.com/en/api/service-tiers) for details. type BetaMessageNewParamsServiceTier string const ( BetaMessageNewParamsServiceTierAuto BetaMessageNewParamsServiceTier = "auto" 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. // // Our models are trained to operate on alternating `user` and `assistant` // conversational turns. When creating a new `Message`, you specify the prior // conversational turns with the `messages` parameter, and the model then generates // the next `Message` in the conversation. Consecutive `user` or `assistant` turns // in your request will be combined into a single turn. // // Each input message must be an object with a `role` and `content`. You can // specify a single `user`-role message, or you can include multiple `user` and // `assistant` messages. // // If the final message uses the `assistant` role, the response content will // continue immediately from the content in that message. This can be used to // constrain part of the model's response. // // Example with a single `user` message: // // ```json // [{ "role": "user", "content": "Hello, Claude" }] // ``` // // Example with multiple conversational turns: // // ```json // [ // // { "role": "user", "content": "Hello there." }, // { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, // { "role": "user", "content": "Can you explain LLMs in plain English?" } // // ] // ``` // // Example with a partially-filled response from Claude: // // ```json // [ // // { // "role": "user", // "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" // }, // { "role": "assistant", "content": "The best answer is (" } // // ] // ``` // // Each input message `content` may be either a single `string` or an array of // content blocks, where each block has a specific `type`. Using a `string` for // `content` is shorthand for an array of one content block of type `"text"`. The // following input messages are equivalent: // // ```json // { "role": "user", "content": "Hello, Claude" } // ``` // // ```json // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a // [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" api:"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,omitzero" api:"required"` // 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.claude.com/en/docs/system-prompts). System BetaMessageCountTokensParamsSystemUnion `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // // When enabled, responses include `thinking` content blocks showing Claude's // thinking process before the final answer. Requires a minimum budget of 1,024 // tokens and counts towards your `max_tokens` limit. // // See // [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, // any available tool, decide by itself, or not use tools at all. ToolChoice BetaToolChoiceUnionParam `json:"tool_choice,omitzero"` // Definitions of tools that the model may use. // // If you include `tools` in your API request, the model may return `tool_use` // content blocks that represent the model's use of those tools. You can then run // those tools using the tool input generated by the model and then optionally // return results back to the model using `tool_result` content blocks. // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For // [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.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // // - `name`: Name of the tool. // - `description`: Optional, but strongly-recommended description of the tool. // - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the // tool `input` shape that the model will produce in `tool_use` output content // blocks. // // For example, if you defined `tools` as: // // ```json // [ // // { // "name": "get_stock_price", // "description": "Get the current stock price for a given ticker symbol.", // "input_schema": { // "type": "object", // "properties": { // "ticker": { // "type": "string", // "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." // } // }, // "required": ["ticker"] // } // } // // ] // ``` // // And then asked the model "What's the S&P 500 at today?", the model might produce // `tool_use` content blocks in the response like this: // // ```json // [ // // { // "type": "tool_use", // "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", // "name": "get_stock_price", // "input": { "ticker": "^GSPC" } // } // // ] // ``` // // You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an // input, and return the following back to the model in a subsequent `user` // message: // // ```json // [ // // { // "type": "tool_result", // "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", // "content": "259.75 USD" // } // // ] // ``` // // Tools can be used for workflows that include running client-side tools and // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // // 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:"-"` paramObj } 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. type BetaMessageCountTokensParamsSystemUnion struct { OfString param.Opt[string] `json:",omitzero,inline"` OfBetaTextBlockArray []BetaTextBlockParam `json:",omitzero,inline"` paramUnion } 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) } func (u *BetaMessageCountTokensParamsSystemUnion) asAny() any { if !param.IsOmitted(u.OfString) { return &u.OfString.Value } else if !param.IsOmitted(u.OfBetaTextBlockArray) { return &u.OfBetaTextBlockArray } return nil } // Only one field can be non-zero. // // 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"` 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"` OfWebFetchTool20260309 *BetaWebFetchTool20260309Param `json:",omitzero,inline"` OfToolSearchToolBm25_20251119 *BetaToolSearchToolBm25_20251119Param `json:",omitzero,inline"` OfToolSearchToolRegex20251119 *BetaToolSearchToolRegex20251119Param `json:",omitzero,inline"` OfMCPToolset *BetaMCPToolsetParam `json:",omitzero,inline"` paramUnion } func (u BetaMessageCountTokensParamsToolUnion) MarshalJSON() ([]byte, error) { return param.MarshalUnion(u, u.OfTool, u.OfBashTool20241022, 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.OfWebSearchTool20260209, u.OfWebFetchTool20260209, u.OfWebFetchTool20260309, u.OfToolSearchToolBm25_20251119, u.OfToolSearchToolRegex20251119, u.OfMCPToolset) } func (u *BetaMessageCountTokensParamsToolUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, u) } func (u *BetaMessageCountTokensParamsToolUnion) asAny() any { if !param.IsOmitted(u.OfTool) { return u.OfTool } else if !param.IsOmitted(u.OfBashTool20241022) { return u.OfBashTool20241022 } 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.OfComputerUseTool20241022) { return u.OfComputerUseTool20241022 } else if !param.IsOmitted(u.OfMemoryTool20250818) { return u.OfMemoryTool20250818 } else if !param.IsOmitted(u.OfComputerUseTool20250124) { 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) { 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.OfWebFetchTool20260309) { return u.OfWebFetchTool20260309 } 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) GetInputSchema() *BetaToolInputSchemaParam { if vt := u.OfTool; vt != nil { return &vt.InputSchema } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) 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 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() { return &vt.MaxCharacters.Value } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) GetUseCache() *bool { if vt := u.OfWebFetchTool20260309; vt != nil && vt.UseCache.Valid() { return &vt.UseCache.Value } return nil } // Returns a pointer to the underlying variant's property, if present. 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) 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) GetDefaultConfig() *BetaMCPToolDefaultConfigParam { if vt := u.OfMCPToolset; vt != nil { return &vt.DefaultConfig } return nil } // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) GetName() *string { if vt := u.OfTool; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfBashTool20241022; 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.OfComputerUseTool20241022; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfMemoryTool20250818; vt != nil { return (*string)(&vt.Name) } else if vt := u.OfComputerUseTool20250124; vt != nil { 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 { 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.OfWebFetchTool20260309; 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.OfWebFetchTool20260309; 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.OfWebFetchTool20260309; 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 BetaMessageCountTokensParamsToolUnion) GetType() *string { if vt := u.OfTool; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfBashTool20241022; 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.OfComputerUseTool20241022; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfMemoryTool20250818; vt != nil { return (*string)(&vt.Type) } else if vt := u.OfComputerUseTool20250124; vt != nil { 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 { 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.OfWebFetchTool20260309; 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) GetDisplayHeightPx() *int64 { if vt := u.OfComputerUseTool20241022; vt != nil { 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) GetDisplayWidthPx() *int64 { if vt := u.OfComputerUseTool20241022; vt != nil { 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) GetDisplayNumber() *int64 { if vt := u.OfComputerUseTool20241022; vt != nil && vt.DisplayNumber.Valid() { 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 } // Returns a pointer to the underlying variant's property, if present. func (u BetaMessageCountTokensParamsToolUnion) 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 } else if vt := u.OfWebFetchTool20260309; 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 } else if vt := u.OfWebFetchTool20260309; 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.OfWebFetchTool20260309; 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 BetaMessageCountTokensParamsToolUnion) GetCacheControl() *BetaCacheControlEphemeralParam { if vt := u.OfTool; vt != nil { return &vt.CacheControl } else if vt := u.OfBashTool20241022; 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.OfComputerUseTool20241022; vt != nil { return &vt.CacheControl } else if vt := u.OfMemoryTool20250818; vt != nil { return &vt.CacheControl } else if vt := u.OfComputerUseTool20250124; vt != nil { 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 { 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.OfWebFetchTool20260309; 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 } // Returns a pointer to the underlying variant's AllowedDomains property, if // present. func (u BetaMessageCountTokensParamsToolUnion) 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 } else if vt := u.OfWebFetchTool20260309; vt != nil { return vt.AllowedDomains } return nil } // Returns a pointer to the underlying variant's BlockedDomains property, if // present. func (u BetaMessageCountTokensParamsToolUnion) 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 } else if vt := u.OfWebFetchTool20260309; 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 } else if vt := u.OfWebFetchTool20260309; vt != nil { return &vt.Citations } return nil } ================================================ FILE: betamessage_test.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic_test import ( "context" "encoding/json" "errors" "os" "testing" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/internal/testutil" "github.com/anthropics/anthropic-sdk-go/option" ) func TestBetaMessageNewWithOptionalParams(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.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{ MaxTokens: 1024, Messages: []anthropic.BetaMessageParam{{ Content: []anthropic.BetaContentBlockParamUnion{{ 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.ModelClaudeOpus4_6, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, Container: anthropic.BetaMessageNewParamsContainerUnion{ OfContainers: &anthropic.BetaContainerParams{ ID: anthropic.String("id"), Skills: []anthropic.BetaSkillParams{{ SkillID: "pdf", Type: anthropic.BetaSkillParamsTypeAnthropic, Version: anthropic.String("latest"), }}, }, }, ContextManagement: anthropic.BetaContextManagementConfigParam{ 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", AuthorizationToken: anthropic.String("authorization_token"), ToolConfiguration: anthropic.BetaRequestMCPServerToolConfigurationParam{ AllowedTools: []string{"string"}, Enabled: anthropic.Bool(true), }, }}, 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: "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{ OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{ Display: anthropic.BetaThinkingConfigAdaptiveDisplaySummarized, }, }, ToolChoice: anthropic.BetaToolChoiceUnionParam{ OfAuto: &anthropic.BetaToolChoiceAutoParam{ DisableParallelToolUse: anthropic.Bool(true), }, }, Tools: []anthropic.BetaToolUnionParam{{ OfTool: &anthropic.BetaToolParam{ InputSchema: anthropic.BetaToolInputSchemaParam{ Properties: map[string]any{ "location": "bar", "unit": "bar", }, Required: []string{"location"}, }, Name: "name", AllowedCallers: []string{"direct"}, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, 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), TopP: anthropic.Float(0.7), 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 TestBetaMessageCountTokensWithOptionalParams(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.Messages.CountTokens(context.TODO(), anthropic.BetaMessageCountTokensParams{ Messages: []anthropic.BetaMessageParam{{ Content: []anthropic.BetaContentBlockParamUnion{{ 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.ModelClaudeOpus4_6, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, ContextManagement: anthropic.BetaContextManagementConfigParam{ 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, }, }, }, }}, }, MCPServers: []anthropic.BetaRequestMCPServerURLDefinitionParam{{ Name: "name", URL: "url", AuthorizationToken: anthropic.String("authorization_token"), ToolConfiguration: anthropic.BetaRequestMCPServerToolConfigurationParam{ AllowedTools: []string{"string"}, 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.", 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, }, }}, }}, }, Thinking: anthropic.BetaThinkingConfigParamUnion{ OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{ Display: anthropic.BetaThinkingConfigAdaptiveDisplaySummarized, }, }, ToolChoice: anthropic.BetaToolChoiceUnionParam{ OfAuto: &anthropic.BetaToolChoiceAutoParam{ DisableParallelToolUse: anthropic.Bool(true), }, }, Tools: []anthropic.BetaMessageCountTokensParamsToolUnion{{ OfTool: &anthropic.BetaToolParam{ InputSchema: anthropic.BetaToolInputSchemaParam{ Properties: map[string]any{ "location": "bar", "unit": "bar", }, Required: []string{"location"}, }, Name: "name", AllowedCallers: []string{"direct"}, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, 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}, }) 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 TestBetaAccumulate(t *testing.T) { for name, testCase := range map[string]struct { expected anthropic.BetaMessage events []string }{ "empty message": { expected: anthropic.BetaMessage{Usage: anthropic.BetaUsage{}}, events: []string{ `{"type": "message_start", "message": {}}`, `{"type: "message_stop"}`, }, }, "text content block": { events: []string{ `{"type": "message_start", "message": {}}`, `{"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": "This "}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "is a "}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta": "text": "text block!"}}`, `{"type": "content_block_stop", "index": 0}`, `{"type": "message_stop"}`, }, expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ {Type: "text", Text: "This is a text block!"}, }}, }, "text content block with citations": { events: []string{ `{"type": "message_start", "message": {}}`, `{"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": "1 + 1"}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": " = 2"}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "citations_delta", "citation": {"type": "char_location", "cited_text": "1 + 1 = 2", "document_index": 0, "document_title": "Math Facts", "start_char_index": 300, "end_char_index": 310 }}}`, `{"type": "content_block_stop", "index": 0}`, `{"type": "message_stop"}`, }, expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ {Type: "text", Text: "1 + 1 = 2", Citations: []anthropic.BetaTextCitationUnion{{ Type: "char_location", CitedText: "1 + 1 = 2", DocumentIndex: 0, DocumentTitle: "Math Facts", StartCharIndex: 300, EndCharIndex: 310, }}}, }}, }, "tool use block": { events: []string{ `{"type": "message_start", "message": {}}`, `{"type": "content_block_start", "index": 0, "content_block": {"type": "tool_use", "id": "toolu_id", "name": "tool_name", "input": {}}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "input_json_delta", "partial_json": "{\"argument\":"}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "input_json_delta", "partial_json": " \"value\"}"}}`, `{"type": "content_block_stop", "index": 0}`, `{"type": "message_stop"}`, }, expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ {Type: "tool_use", ID: "toolu_id", Name: "tool_name", Input: []byte(`{"argument": "value"}`)}, }}, }, "tool use block with no params": { events: []string{ `{"type": "message_start", "message": {}}`, `{"type": "content_block_start": "index": 0, "content_block": {"type": "tool_use", "id": "toolu_id", "name": "tool_name", input: {}}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "input_json_delta", "partial_json": ""}}`, `{"type": "content_block_stop", "index": 0}`, `{"type": "message_stop"}`, }, expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ {Type: "tool_use", ID: "toolu_id", Name: "tool_name"}, }}, }, "server tool use block": { events: []string{ `{"type": "message_start", "message": {}}`, `{"type": "content_block_start": "index": 0, "content_block": {"type": "server_tool_use", "id": "srvtoolu_id", "name": "web_search", input: {}}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "input_json_delta", "partial_json": ""}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "input_json_delta", "partial_json": "{\"query\": \"weat"}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "input_json_delta", "partial_json": "her\"}"}}`, `{"type": "content_block_stop", "index": 0}`, `{"type": "message_stop"}`, }, expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ {Type: "server_tool_use", ID: "srvtoolu_id", Name: "web_search", Input: []byte(`{"query": "weather"}`)}, }}, }, "thinking block": { events: []string{ `{"type": "message_start", "message": {}}`, `{"type": "content_block_start", "index": 0, "content_block": {"type": "thinking", "thinking": "Let me think..."}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": " First, let's try this..."}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "thinking_delta", "thinking": " Therefore, the answer is..."}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "signature_delta", "signature": "ThinkingSignature"}}`, `{"type": "content_block_stop", "index": 0}`, `{"type": "message_stop"}`, }, expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ {Type: "thinking", Thinking: "Let me think...\nFirst, let's try this...\nTherefore, the answer is...", Signature: "ThinkingSignature"}, }}, }, "redacted thinking block": { events: []string{ `{"type": "message_start", "message": {}}`, `{"type": "content_block_start", "index": 0, "content_block": {"type": "redacted_thinking", "data": "Redacted"}}`, `{"type": "content_block_stop", "index": 0}`, `{"type": "message_stop"}`, }, expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ {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": {}}`, `{"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": "Let me look up "}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta", "text": "the weather for "}}`, `{"type": "content_block_delta", "index": 0, "delta": {"type": "text_delta": "text": "you."}}`, `{"type": "content_block_stop", "index": 0}`, `{"type": "content_block_start", "index": 1, "content_block": {"type": "thinking", "thinking": ""}}`, `{"type": "content_block_delta", "index": 1, "delta": {"type": "thinking_delta", "thinking": "I can look this "}}`, `{"type": "content_block_delta", "index": 1, "delta": {"type": "thinking_delta", "thinking": "up using a tool."}}`, `{"type": "content_block_stop", "index": 1}`, `{"type": "content_block_start", "index": 2, "content_block": {"type": "tool_use", "id": "toolu_id", "name": "get_weather", "input": {}}}`, `{"type": "content_block_delta", "index": 2, "delta": {"type": "input_json_delta", "partial_json": "{\"city\": "}}`, `{"type": "content_block_delta", "index": 2, "delta": {"type": "input_json_delta", "partial_json": "\"Los Angeles\"}"}}`, `{"type": "content_block_stop", "index": 2}`, `{"type": "content_block_start", "index": 3, "content_block": {"type": "text", "text": ""}}`, `{"type": "content_block_delta", "index": 3, "delta": {"type": "text_delta", "text": "The weather in Los Angeles"}}`, `{"type": "content_block_delta", "index": 3, "delta": {"type": "text_delta", "text": " is 85 degrees Fahrenheit!"}}`, `{"type": "content_block_stop", "index": 3"}`, `{"type": "message_stop"}`, }, expected: anthropic.BetaMessage{Content: []anthropic.BetaContentBlockUnion{ {Type: "text", Text: "Let me look up the weather for you."}, {Type: "thinking", Thinking: "I can look this up using a tool."}, {Type: "tool_use", ID: "toolu_id", Name: "get_weather", Input: []byte(`{"city": "Los Angeles"}`)}, {Type: "text", Text: "The weather in Los Angeles is 85 degrees Fahrenheit!"}, }}, }, } { t.Run(name, func(t *testing.T) { message := anthropic.BetaMessage{} for _, eventStr := range testCase.events { event := anthropic.BetaRawMessageStreamEventUnion{} err := (&event).UnmarshalJSON([]byte(eventStr)) if err != nil { t.Fatal(err) } (&message).Accumulate(event) } marshaledMessage, err := json.Marshal(message) if err != nil { t.Fatal(err) } marshaledExpectedMessage, err := json.Marshal(testCase.expected) if err != nil { t.Fatal(err) } if string(marshaledMessage) != string(marshaledExpectedMessage) { t.Fatalf("Mismatched message: expected %s but got %s", marshaledExpectedMessage, marshaledMessage) } }) } } ================================================ FILE: betamessagebatch.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic import ( "context" "encoding/json" "errors" "fmt" "net/http" "net/url" "slices" "time" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/internal/apiquery" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/jsonl" "github.com/anthropics/anthropic-sdk-go/packages/pagination" "github.com/anthropics/anthropic-sdk-go/packages/param" "github.com/anthropics/anthropic-sdk-go/packages/respjson" "github.com/anthropics/anthropic-sdk-go/shared/constant" ) // BetaMessageBatchService 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 [NewBetaMessageBatchService] method instead. type BetaMessageBatchService struct { Options []option.RequestOption } // NewBetaMessageBatchService 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 NewBetaMessageBatchService(opts ...option.RequestOption) (r BetaMessageBatchService) { r = BetaMessageBatchService{} r.Options = opts return } // Send a batch of Message creation requests. // // The Message Batches API can be used to process multiple Messages API requests at // once. Once a Message Batch is created, it begins processing immediately. Batches // can take up to 24 hours to complete. // // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) New(ctx context.Context, params BetaMessageBatchNewParams, opts ...option.RequestOption) (res *BetaMessageBatch, err error) { for _, v := range params.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) path := "v1/messages/batches?beta=true" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return res, err } // This endpoint is idempotent and can be used to poll for Message Batch // completion. To access the results of a Message Batch, make a request to the // `results_url` field in the response. // // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) Get(ctx context.Context, messageBatchID string, query BetaMessageBatchGetParams, opts ...option.RequestOption) (res *BetaMessageBatch, err error) { for _, v := range query.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) if messageBatchID == "" { err = errors.New("missing required message_batch_id parameter") return nil, err } path := fmt.Sprintf("v1/messages/batches/%s?beta=true", messageBatchID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) return res, err } // List all Message Batches within a Workspace. Most recently created batches are // returned first. // // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) List(ctx context.Context, params BetaMessageBatchListParams, opts ...option.RequestOption) (res *pagination.Page[BetaMessageBatch], err error) { var raw *http.Response for _, v := range params.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24"), option.WithResponseInto(&raw)}, opts...) path := "v1/messages/batches?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 all Message Batches within a Workspace. Most recently created batches are // returned first. // // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) ListAutoPaging(ctx context.Context, params BetaMessageBatchListParams, opts ...option.RequestOption) *pagination.PageAutoPager[BetaMessageBatch] { return pagination.NewPageAutoPager(r.List(ctx, params, opts...)) } // Delete a Message Batch. // // Message Batches can only be deleted once they've finished processing. If you'd // like to delete an in-progress batch, you must first cancel it. // // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) Delete(ctx context.Context, messageBatchID string, body BetaMessageBatchDeleteParams, opts ...option.RequestOption) (res *BetaDeletedMessageBatch, err error) { for _, v := range body.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) if messageBatchID == "" { err = errors.New("missing required message_batch_id parameter") return nil, err } path := fmt.Sprintf("v1/messages/batches/%s?beta=true", messageBatchID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) return res, err } // Batches may be canceled any time before processing ends. Once cancellation is // initiated, the batch enters a `canceling` state, at which time the system may // complete any in-progress, non-interruptible requests before finalizing // cancellation. // // The number of canceled requests is specified in `request_counts`. To determine // which requests were canceled, check the individual results within the batch. // Note that cancellation may not result in any canceled requests if they were // non-interruptible. // // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) Cancel(ctx context.Context, messageBatchID string, body BetaMessageBatchCancelParams, opts ...option.RequestOption) (res *BetaMessageBatch, err error) { for _, v := range body.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("anthropic-beta", "message-batches-2024-09-24")}, opts...) if messageBatchID == "" { err = errors.New("missing required message_batch_id parameter") return nil, err } path := fmt.Sprintf("v1/messages/batches/%s/cancel?beta=true", messageBatchID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...) return res, err } // Streams the results of a Message Batch as a `.jsonl` file. // // Each line in the file is a JSON object containing the result of a single request // in the Message Batch. Results are not guaranteed to be in the same order as // requests. Use the `custom_id` field to match results to requests. // // Learn more about the Message Batches API in our // [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) func (r *BetaMessageBatchService) 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("%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...) if messageBatchID == "" { err = errors.New("missing required message_batch_id parameter") return jsonl.NewStream[BetaMessageBatchIndividualResponse](nil, err) } path := fmt.Sprintf("v1/messages/batches/%s/results?beta=true", messageBatchID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &raw, opts...) return jsonl.NewStream[BetaMessageBatchIndividualResponse](raw, err) } type BetaDeletedMessageBatch struct { // ID of the Message Batch. ID string `json:"id" api:"required"` // Deleted object type. // // For Message Batches, this is always `"message_batch_deleted"`. Type constant.MessageBatchDeleted `json:"type" api:"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 BetaDeletedMessageBatch) RawJSON() string { return r.JSON.raw } func (r *BetaDeletedMessageBatch) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMessageBatch struct { // Unique object identifier. // // The format and length of IDs may change over time. ID string `json:"id" api:"required"` // RFC 3339 datetime string representing the time at which the Message Batch was // archived and its results became unavailable. ArchivedAt time.Time `json:"archived_at" api:"required" format:"date-time"` // RFC 3339 datetime string representing the time at which cancellation was // initiated for the Message Batch. Specified only if cancellation was initiated. CancelInitiatedAt time.Time `json:"cancel_initiated_at" api:"required" format:"date-time"` // RFC 3339 datetime string representing the time at which the Message Batch was // created. CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // RFC 3339 datetime string representing the time at which processing for the // Message Batch ended. Specified only once processing ends. // // Processing ends when every request in a Message Batch has either succeeded, // errored, canceled, or expired. EndedAt time.Time `json:"ended_at" api:"required" format:"date-time"` // RFC 3339 datetime string representing the time at which the Message Batch will // expire and end processing, which is 24 hours after creation. ExpiresAt time.Time `json:"expires_at" api:"required" format:"date-time"` // Processing status of the Message Batch. // // Any of "in_progress", "canceling", "ended". ProcessingStatus BetaMessageBatchProcessingStatus `json:"processing_status" api:"required"` // Tallies requests within the Message Batch, categorized by their status. // // Requests start as `processing` and move to one of the other statuses only once // processing of the entire batch ends. The sum of all values always matches the // total number of requests in the batch. RequestCounts BetaMessageBatchRequestCounts `json:"request_counts" api:"required"` // URL to a `.jsonl` file containing the results of the Message Batch requests. // Specified only once processing ends. // // Results in the file are not guaranteed to be in the same order as requests. Use // the `custom_id` field to match results to requests. ResultsURL string `json:"results_url" api:"required"` // Object type. // // For Message Batches, this is always `"message_batch"`. Type constant.MessageBatch `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field ArchivedAt respjson.Field CancelInitiatedAt respjson.Field CreatedAt respjson.Field EndedAt respjson.Field ExpiresAt respjson.Field ProcessingStatus respjson.Field RequestCounts respjson.Field ResultsURL respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaMessageBatch) RawJSON() string { return r.JSON.raw } func (r *BetaMessageBatch) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Processing status of the Message Batch. type BetaMessageBatchProcessingStatus string const ( BetaMessageBatchProcessingStatusInProgress BetaMessageBatchProcessingStatus = "in_progress" BetaMessageBatchProcessingStatusCanceling BetaMessageBatchProcessingStatus = "canceling" BetaMessageBatchProcessingStatusEnded BetaMessageBatchProcessingStatus = "ended" ) type BetaMessageBatchCanceledResult struct { Type constant.Canceled `json:"type" api:"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 BetaMessageBatchCanceledResult) RawJSON() string { return r.JSON.raw } func (r *BetaMessageBatchCanceledResult) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMessageBatchErroredResult struct { Error BetaErrorResponse `json:"error" api:"required"` Type constant.Errored `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Error respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaMessageBatchErroredResult) RawJSON() string { return r.JSON.raw } func (r *BetaMessageBatchErroredResult) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMessageBatchExpiredResult struct { Type constant.Expired `json:"type" api:"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 BetaMessageBatchExpiredResult) RawJSON() string { return r.JSON.raw } func (r *BetaMessageBatchExpiredResult) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // This is a single line in the response `.jsonl` file and does not represent the // response as a whole. type BetaMessageBatchIndividualResponse struct { // Developer-provided ID created for each request in a Message Batch. Useful for // matching results to requests, as results may be given out of request order. // // Must be unique for each request within the Message Batch. CustomID string `json:"custom_id" api:"required"` // Processing result for this request. // // Contains a Message output if processing was successful, an error response if // processing failed, or the reason why processing was not attempted, such as // cancellation or expiration. Result BetaMessageBatchResultUnion `json:"result" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { CustomID respjson.Field Result respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaMessageBatchIndividualResponse) RawJSON() string { return r.JSON.raw } func (r *BetaMessageBatchIndividualResponse) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMessageBatchRequestCounts struct { // Number of requests in the Message Batch that have been canceled. // // This is zero until processing of the entire Message Batch has ended. Canceled int64 `json:"canceled" api:"required"` // Number of requests in the Message Batch that encountered an error. // // This is zero until processing of the entire Message Batch has ended. Errored int64 `json:"errored" api:"required"` // Number of requests in the Message Batch that have expired. // // This is zero until processing of the entire Message Batch has ended. Expired int64 `json:"expired" api:"required"` // Number of requests in the Message Batch that are processing. Processing int64 `json:"processing" api:"required"` // Number of requests in the Message Batch that have completed successfully. // // This is zero until processing of the entire Message Batch has ended. Succeeded int64 `json:"succeeded" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Canceled respjson.Field Errored respjson.Field Expired respjson.Field Processing respjson.Field Succeeded respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaMessageBatchRequestCounts) RawJSON() string { return r.JSON.raw } func (r *BetaMessageBatchRequestCounts) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // BetaMessageBatchResultUnion contains all possible properties and values from // [BetaMessageBatchSucceededResult], [BetaMessageBatchErroredResult], // [BetaMessageBatchCanceledResult], [BetaMessageBatchExpiredResult]. // // Use the [BetaMessageBatchResultUnion.AsAny] method to switch on the variant. // // Use the methods beginning with 'As' to cast the union to one of its variants. type BetaMessageBatchResultUnion struct { // This field is from variant [BetaMessageBatchSucceededResult]. Message BetaMessage `json:"message"` // Any of "succeeded", "errored", "canceled", "expired". Type string `json:"type"` // This field is from variant [BetaMessageBatchErroredResult]. Error BetaErrorResponse `json:"error"` JSON struct { Message respjson.Field Type respjson.Field Error respjson.Field raw string } `json:"-"` } // anyBetaMessageBatchResult is implemented by each variant of // [BetaMessageBatchResultUnion] to add type safety for the return type of // [BetaMessageBatchResultUnion.AsAny] type anyBetaMessageBatchResult interface { implBetaMessageBatchResultUnion() } func (BetaMessageBatchSucceededResult) implBetaMessageBatchResultUnion() {} func (BetaMessageBatchErroredResult) implBetaMessageBatchResultUnion() {} func (BetaMessageBatchCanceledResult) implBetaMessageBatchResultUnion() {} func (BetaMessageBatchExpiredResult) implBetaMessageBatchResultUnion() {} // Use the following switch statement to find the correct variant // // switch variant := BetaMessageBatchResultUnion.AsAny().(type) { // case anthropic.BetaMessageBatchSucceededResult: // case anthropic.BetaMessageBatchErroredResult: // case anthropic.BetaMessageBatchCanceledResult: // case anthropic.BetaMessageBatchExpiredResult: // default: // fmt.Errorf("no variant present") // } func (u BetaMessageBatchResultUnion) AsAny() anyBetaMessageBatchResult { switch u.Type { case "succeeded": return u.AsSucceeded() case "errored": return u.AsErrored() case "canceled": return u.AsCanceled() case "expired": return u.AsExpired() } return nil } func (u BetaMessageBatchResultUnion) AsSucceeded() (v BetaMessageBatchSucceededResult) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMessageBatchResultUnion) AsErrored() (v BetaMessageBatchErroredResult) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMessageBatchResultUnion) AsCanceled() (v BetaMessageBatchCanceledResult) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } func (u BetaMessageBatchResultUnion) AsExpired() (v BetaMessageBatchExpiredResult) { apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) return } // Returns the unmodified JSON received from the API func (u BetaMessageBatchResultUnion) RawJSON() string { return u.JSON.raw } func (r *BetaMessageBatchResultUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMessageBatchSucceededResult struct { Message BetaMessage `json:"message" api:"required"` Type constant.Succeeded `json:"type" api:"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 BetaMessageBatchSucceededResult) RawJSON() string { return r.JSON.raw } func (r *BetaMessageBatchSucceededResult) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaMessageBatchNewParams struct { // List of requests for prompt completion. Each is an individual request to create // a Message. Requests []BetaMessageBatchNewParamsRequest `json:"requests,omitzero" api:"required"` // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } func (r BetaMessageBatchNewParams) MarshalJSON() (data []byte, err error) { type shadow BetaMessageBatchNewParams return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaMessageBatchNewParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // The properties CustomID, Params are required. type BetaMessageBatchNewParamsRequest struct { // Developer-provided ID created for each request in a Message Batch. Useful for // matching results to requests, as results may be given out of request order. // // Must be unique for each request within the Message Batch. CustomID string `json:"custom_id" api:"required"` // Messages API creation parameters for the individual request. // // See the [Messages API reference](https://docs.claude.com/en/api/messages) for // full documentation on available parameters. Params BetaMessageBatchNewParamsRequestParams `json:"params,omitzero" api:"required"` paramObj } func (r BetaMessageBatchNewParamsRequest) MarshalJSON() (data []byte, err error) { type shadow BetaMessageBatchNewParamsRequest return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaMessageBatchNewParamsRequest) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Messages API creation parameters for the individual request. // // 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 { // The maximum number of tokens to generate before stopping. // // Note that our models may stop _before_ reaching this maximum. This parameter // only specifies the absolute maximum number of tokens to generate. // // Different models have different maximum values for this parameter. See // [models](https://docs.claude.com/en/docs/models-overview) for details. MaxTokens int64 `json:"max_tokens" api:"required"` // Input messages. // // Our models are trained to operate on alternating `user` and `assistant` // conversational turns. When creating a new `Message`, you specify the prior // conversational turns with the `messages` parameter, and the model then generates // the next `Message` in the conversation. Consecutive `user` or `assistant` turns // in your request will be combined into a single turn. // // Each input message must be an object with a `role` and `content`. You can // specify a single `user`-role message, or you can include multiple `user` and // `assistant` messages. // // If the final message uses the `assistant` role, the response content will // continue immediately from the content in that message. This can be used to // constrain part of the model's response. // // Example with a single `user` message: // // ```json // [{ "role": "user", "content": "Hello, Claude" }] // ``` // // Example with multiple conversational turns: // // ```json // [ // // { "role": "user", "content": "Hello there." }, // { "role": "assistant", "content": "Hi, I'm Claude. How can I help you?" }, // { "role": "user", "content": "Can you explain LLMs in plain English?" } // // ] // ``` // // Example with a partially-filled response from Claude: // // ```json // [ // // { // "role": "user", // "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun" // }, // { "role": "assistant", "content": "The best answer is (" } // // ] // ``` // // Each input message `content` may be either a single `string` or an array of // content blocks, where each block has a specific `type`. Using a `string` for // `content` is shorthand for an array of one content block of type `"text"`. The // following input messages are equivalent: // // ```json // { "role": "user", "content": "Hello, Claude" } // ``` // // ```json // { "role": "user", "content": [{ "type": "text", "text": "Hello, Claude" }] } // ``` // // See [input examples](https://docs.claude.com/en/api/messages-examples). // // Note that if you want to include a // [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" api:"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,omitzero" api:"required"` // 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.claude.com/en/api/messages-streaming) for details. Stream param.Opt[bool] `json:"stream,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` // for analytical / multiple choice, and closer to `1.0` for creative and // generative tasks. // // Note that even with `temperature` of `0.0`, the results will not be fully // deterministic. Temperature param.Opt[float64] `json:"temperature,omitzero"` // Only sample from the top K options for each subsequent token. // // Used to remove "long tail" low probability responses. // [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). // // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopK param.Opt[int64] `json:"top_k,omitzero"` // Use nucleus sampling. // // In nucleus sampling, we compute the cumulative distribution over all the options // for each subsequent token in decreasing probability order and cut it off once it // reaches a particular probability specified by `top_p`. You should either alter // `temperature` or `top_p`, but not both. // // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopP param.Opt[float64] `json:"top_p,omitzero"` // 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.claude.com/en/api/service-tiers) for details. // // Any of "auto", "standard_only". ServiceTier string `json:"service_tier,omitzero"` // Custom text sequences that will cause the model to stop generating. // // Our models will normally stop when they have naturally completed their turn, // which will result in a response `stop_reason` of `"end_turn"`. // // If you want the model to stop generating when it encounters custom strings of // text, you can use the `stop_sequences` parameter. If the model encounters one of // the custom sequences, the response `stop_reason` value will be `"stop_sequence"` // and the response `stop_sequence` value will contain the matched stop sequence. StopSequences []string `json:"stop_sequences,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.claude.com/en/docs/system-prompts). System []BetaTextBlockParam `json:"system,omitzero"` // Configuration for enabling Claude's extended thinking. // // When enabled, responses include `thinking` content blocks showing Claude's // thinking process before the final answer. Requires a minimum budget of 1,024 // tokens and counts towards your `max_tokens` limit. // // See // [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, // any available tool, decide by itself, or not use tools at all. ToolChoice BetaToolChoiceUnionParam `json:"tool_choice,omitzero"` // Definitions of tools that the model may use. // // If you include `tools` in your API request, the model may return `tool_use` // content blocks that represent the model's use of those tools. You can then run // those tools using the tool input generated by the model and then optionally // return results back to the model using `tool_result` content blocks. // // There are two types of tools: **client tools** and **server tools**. The // behavior described below applies to client tools. For // [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.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool)). // // Each tool definition includes: // // - `name`: Name of the tool. // - `description`: Optional, but strongly-recommended description of the tool. // - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the // tool `input` shape that the model will produce in `tool_use` output content // blocks. // // For example, if you defined `tools` as: // // ```json // [ // // { // "name": "get_stock_price", // "description": "Get the current stock price for a given ticker symbol.", // "input_schema": { // "type": "object", // "properties": { // "ticker": { // "type": "string", // "description": "The stock ticker symbol, e.g. AAPL for Apple Inc." // } // }, // "required": ["ticker"] // } // } // // ] // ``` // // And then asked the model "What's the S&P 500 at today?", the model might produce // `tool_use` content blocks in the response like this: // // ```json // [ // // { // "type": "tool_use", // "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", // "name": "get_stock_price", // "input": { "ticker": "^GSPC" } // } // // ] // ``` // // You might then run your `get_stock_price` tool with `{"ticker": "^GSPC"}` as an // input, and return the following back to the model in a subsequent `user` // message: // // ```json // [ // // { // "type": "tool_result", // "tool_use_id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV", // "content": "259.75 USD" // } // // ] // ``` // // Tools can be used for workflows that include running client-side tools and // functions, or more generally whenever you want the model to produce a particular // JSON structure of output. // // See our [guide](https://docs.claude.com/en/docs/tool-use) for more details. Tools []BetaToolUnionParam `json:"tools,omitzero"` paramObj } func (r BetaMessageBatchNewParamsRequestParams) MarshalJSON() (data []byte, err error) { type shadow BetaMessageBatchNewParamsRequestParams return param.MarshalObject(r, (*shadow)(&r)) } func (r *BetaMessageBatchNewParamsRequestParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } 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 { // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } type BetaMessageBatchListParams struct { // ID of the object to use as a cursor for pagination. When provided, returns the // page of results immediately after this object. AfterID param.Opt[string] `query:"after_id,omitzero" json:"-"` // ID of the object to use as a cursor for pagination. When provided, returns the // page of results immediately before this object. BeforeID param.Opt[string] `query:"before_id,omitzero" json:"-"` // Number of items to return per page. // // Defaults to `20`. Ranges from `1` to `1000`. 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 [BetaMessageBatchListParams]'s query parameters as // `url.Values`. func (r BetaMessageBatchListParams) URLQuery() (v url.Values, err error) { return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ ArrayFormat: apiquery.ArrayQueryFormatComma, NestedFormat: apiquery.NestedQueryFormatBrackets, }) } type BetaMessageBatchDeleteParams struct { // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } type BetaMessageBatchCancelParams struct { // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } type BetaMessageBatchResultsParams struct { // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } ================================================ FILE: betamessagebatch_test.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic_test import ( "context" "errors" "os" "testing" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/internal/testutil" "github.com/anthropics/anthropic-sdk-go/option" ) func TestBetaMessageBatchNewWithOptionalParams(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.Messages.Batches.New(context.TODO(), anthropic.BetaMessageBatchNewParams{ Requests: []anthropic.BetaMessageBatchNewParamsRequest{{ CustomID: "my-custom-id-1", Params: anthropic.BetaMessageBatchNewParamsRequestParams{ MaxTokens: 1024, Messages: []anthropic.BetaMessageParam{{ Content: []anthropic.BetaContentBlockParamUnion{{ 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.ModelClaudeOpus4_6, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, Container: anthropic.BetaMessageBatchNewParamsRequestParamsContainerUnion{ OfContainers: &anthropic.BetaContainerParams{ ID: anthropic.String("id"), Skills: []anthropic.BetaSkillParams{{ SkillID: "pdf", Type: anthropic.BetaSkillParamsTypeAnthropic, Version: anthropic.String("latest"), }}, }, }, ContextManagement: anthropic.BetaContextManagementConfigParam{ 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", AuthorizationToken: anthropic.String("authorization_token"), ToolConfiguration: anthropic.BetaRequestMCPServerToolConfigurationParam{ AllowedTools: []string{"string"}, Enabled: anthropic.Bool(true), }, }}, 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: "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{ OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{ Display: anthropic.BetaThinkingConfigAdaptiveDisplaySummarized, }, }, ToolChoice: anthropic.BetaToolChoiceUnionParam{ OfAuto: &anthropic.BetaToolChoiceAutoParam{ DisableParallelToolUse: anthropic.Bool(true), }, }, Tools: []anthropic.BetaToolUnionParam{{ OfTool: &anthropic.BetaToolParam{ InputSchema: anthropic.BetaToolInputSchemaParam{ Properties: map[string]any{ "location": "bar", "unit": "bar", }, Required: []string{"location"}, }, Name: "name", AllowedCallers: []string{"direct"}, CacheControl: anthropic.BetaCacheControlEphemeralParam{ TTL: anthropic.BetaCacheControlEphemeralTTLTTL5m, }, 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), TopP: anthropic.Float(0.7), }, }}, 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 TestBetaMessageBatchGetWithOptionalParams(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.Messages.Batches.Get( context.TODO(), "message_batch_id", anthropic.BetaMessageBatchGetParams{ 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 TestBetaMessageBatchListWithOptionalParams(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.Messages.Batches.List(context.TODO(), anthropic.BetaMessageBatchListParams{ AfterID: anthropic.String("after_id"), BeforeID: anthropic.String("before_id"), Limit: anthropic.Int(1), 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 TestBetaMessageBatchDeleteWithOptionalParams(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.Messages.Batches.Delete( context.TODO(), "message_batch_id", anthropic.BetaMessageBatchDeleteParams{ 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 TestBetaMessageBatchCancelWithOptionalParams(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.Messages.Batches.Cancel( context.TODO(), "message_batch_id", anthropic.BetaMessageBatchCancelParams{ 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()) } } ================================================ FILE: betamessageutil.go ================================================ package anthropic import ( "encoding/json" "fmt" "github.com/anthropics/anthropic-sdk-go/internal/paramutil" "github.com/anthropics/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 } ================================================ FILE: betamodel.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic import ( "context" "errors" "fmt" "net/http" "net/url" "slices" "time" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/internal/apiquery" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/pagination" "github.com/anthropics/anthropic-sdk-go/packages/param" "github.com/anthropics/anthropic-sdk-go/packages/respjson" "github.com/anthropics/anthropic-sdk-go/shared/constant" ) // BetaModelService 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 [NewBetaModelService] method instead. type BetaModelService struct { Options []option.RequestOption } // NewBetaModelService 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 NewBetaModelService(opts ...option.RequestOption) (r BetaModelService) { r = BetaModelService{} r.Options = opts return } // Get a specific model. // // The Models API response can be used to determine information about a specific // model or resolve a model alias to a model ID. func (r *BetaModelService) Get(ctx context.Context, modelID string, query BetaModelGetParams, opts ...option.RequestOption) (res *BetaModelInfo, err error) { for _, v := range query.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) if modelID == "" { err = errors.New("missing required model_id parameter") return nil, err } path := fmt.Sprintf("v1/models/%s?beta=true", modelID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) return res, err } // List available models. // // The Models API response can be used to determine which models are available for // use in the API. More recently released models are listed first. func (r *BetaModelService) List(ctx context.Context, params BetaModelListParams, opts ...option.RequestOption) (res *pagination.Page[BetaModelInfo], err error) { var raw *http.Response for _, v := range params.Betas { opts = append(opts, option.WithHeaderAdd("anthropic-beta", fmt.Sprintf("%v", v))) } opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...) path := "v1/models?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 available models. // // The Models API response can be used to determine which models are available for // use in the API. More recently released models are listed first. func (r *BetaModelService) ListAutoPaging(ctx context.Context, params BetaModelListParams, opts ...option.RequestOption) *pagination.PageAutoPager[BetaModelInfo] { return pagination.NewPageAutoPager(r.List(ctx, params, opts...)) } // Indicates whether a capability is supported. type BetaCapabilitySupport struct { // Whether this capability is supported by the model. Supported bool `json:"supported" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Supported respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaCapabilitySupport) RawJSON() string { return r.JSON.raw } func (r *BetaCapabilitySupport) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Context management capability details. type BetaContextManagementCapability struct { // Indicates whether a capability is supported. ClearThinking20251015 BetaCapabilitySupport `json:"clear_thinking_20251015" api:"required"` // Indicates whether a capability is supported. ClearToolUses20250919 BetaCapabilitySupport `json:"clear_tool_uses_20250919" api:"required"` // Indicates whether a capability is supported. Compact20260112 BetaCapabilitySupport `json:"compact_20260112" api:"required"` // Whether this capability is supported by the model. Supported bool `json:"supported" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ClearThinking20251015 respjson.Field ClearToolUses20250919 respjson.Field Compact20260112 respjson.Field Supported respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaContextManagementCapability) RawJSON() string { return r.JSON.raw } func (r *BetaContextManagementCapability) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Effort (reasoning_effort) capability details. type BetaEffortCapability struct { // Whether the model supports high effort level. High BetaCapabilitySupport `json:"high" api:"required"` // Whether the model supports low effort level. Low BetaCapabilitySupport `json:"low" api:"required"` // Whether the model supports max effort level. Max BetaCapabilitySupport `json:"max" api:"required"` // Whether the model supports medium effort level. Medium BetaCapabilitySupport `json:"medium" api:"required"` // Whether this capability is supported by the model. Supported bool `json:"supported" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { High respjson.Field Low respjson.Field Max respjson.Field Medium respjson.Field Supported respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaEffortCapability) RawJSON() string { return r.JSON.raw } func (r *BetaEffortCapability) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Model capability information. type BetaModelCapabilities struct { // Whether the model supports the Batch API. Batch BetaCapabilitySupport `json:"batch" api:"required"` // Whether the model supports citation generation. Citations BetaCapabilitySupport `json:"citations" api:"required"` // Whether the model supports code execution tools. CodeExecution BetaCapabilitySupport `json:"code_execution" api:"required"` // Context management support and available strategies. ContextManagement BetaContextManagementCapability `json:"context_management" api:"required"` // Effort (reasoning_effort) support and available levels. Effort BetaEffortCapability `json:"effort" api:"required"` // Whether the model accepts image content blocks. ImageInput BetaCapabilitySupport `json:"image_input" api:"required"` // Whether the model accepts PDF content blocks. PDFInput BetaCapabilitySupport `json:"pdf_input" api:"required"` // Whether the model supports structured output / JSON mode / strict tool schemas. StructuredOutputs BetaCapabilitySupport `json:"structured_outputs" api:"required"` // Thinking capability and supported type configurations. Thinking BetaThinkingCapability `json:"thinking" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Batch respjson.Field Citations respjson.Field CodeExecution respjson.Field ContextManagement respjson.Field Effort respjson.Field ImageInput respjson.Field PDFInput respjson.Field StructuredOutputs respjson.Field Thinking respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaModelCapabilities) RawJSON() string { return r.JSON.raw } func (r *BetaModelCapabilities) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaModelInfo struct { // Unique model identifier. ID string `json:"id" api:"required"` // Model capability information. Capabilities BetaModelCapabilities `json:"capabilities" api:"required"` // RFC 3339 datetime string representing the time at which the model was released. // May be set to an epoch value if the release date is unknown. CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // A human-readable name for the model. DisplayName string `json:"display_name" api:"required"` // Maximum input context window size in tokens for this model. MaxInputTokens int64 `json:"max_input_tokens" api:"required"` // Maximum value for the `max_tokens` parameter when using this model. MaxTokens int64 `json:"max_tokens" api:"required"` // Object type. // // For Models, this is always `"model"`. Type constant.Model `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field Capabilities respjson.Field CreatedAt respjson.Field DisplayName respjson.Field MaxInputTokens respjson.Field MaxTokens respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaModelInfo) RawJSON() string { return r.JSON.raw } func (r *BetaModelInfo) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Thinking capability details. type BetaThinkingCapability struct { // Whether this capability is supported by the model. Supported bool `json:"supported" api:"required"` // Supported thinking type configurations. Types BetaThinkingTypes `json:"types" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Supported respjson.Field Types respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaThinkingCapability) RawJSON() string { return r.JSON.raw } func (r *BetaThinkingCapability) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } // Supported thinking type configurations. type BetaThinkingTypes struct { // Whether the model supports thinking with type 'adaptive' (auto). Adaptive BetaCapabilitySupport `json:"adaptive" api:"required"` // Whether the model supports thinking with type 'enabled'. Enabled BetaCapabilitySupport `json:"enabled" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Adaptive respjson.Field Enabled respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r BetaThinkingTypes) RawJSON() string { return r.JSON.raw } func (r *BetaThinkingTypes) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type BetaModelGetParams struct { // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } type BetaModelListParams struct { // ID of the object to use as a cursor for pagination. When provided, returns the // page of results immediately after this object. AfterID param.Opt[string] `query:"after_id,omitzero" json:"-"` // ID of the object to use as a cursor for pagination. When provided, returns the // page of results immediately before this object. BeforeID param.Opt[string] `query:"before_id,omitzero" json:"-"` // Number of items to return per page. // // Defaults to `20`. Ranges from `1` to `1000`. 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 [BetaModelListParams]'s query parameters as `url.Values`. func (r BetaModelListParams) URLQuery() (v url.Values, err error) { return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ ArrayFormat: apiquery.ArrayQueryFormatComma, NestedFormat: apiquery.NestedQueryFormatBrackets, }) } ================================================ FILE: betamodel_test.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic_test import ( "context" "errors" "os" "testing" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/internal/testutil" "github.com/anthropics/anthropic-sdk-go/option" ) func TestBetaModelGetWithOptionalParams(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.Models.Get( context.TODO(), "model_id", anthropic.BetaModelGetParams{ 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 TestBetaModelListWithOptionalParams(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.Models.List(context.TODO(), anthropic.BetaModelListParams{ AfterID: anthropic.String("after_id"), BeforeID: anthropic.String("before_id"), Limit: anthropic.Int(1), 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()) } } ================================================ FILE: betaskill.go ================================================ // 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/anthropics/anthropic-sdk-go/internal/apiform" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/internal/apiquery" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/pagination" "github.com/anthropics/anthropic-sdk-go/packages/param" "github.com/anthropics/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 res, err } // 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 nil, err } path := fmt.Sprintf("v1/skills/%s?beta=true", skillID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) return res, err } // 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 nil, err } path := fmt.Sprintf("v1/skills/%s?beta=true", skillID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) return res, err } type BetaSkillNewResponse struct { // Unique identifier for the skill. // // The format and length of IDs may change over time. ID string `json:"id" api:"required"` // ISO 8601 timestamp of when the skill was created. CreatedAt string `json:"created_at" api:"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" api:"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" api:"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" api:"required"` // Object type. // // For Skills, this is always `"skill"`. Type string `json:"type" api:"required"` // ISO 8601 timestamp of when the skill was last updated. UpdatedAt string `json:"updated_at" api:"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" api:"required"` // ISO 8601 timestamp of when the skill was created. CreatedAt string `json:"created_at" api:"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" api:"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" api:"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" api:"required"` // Object type. // // For Skills, this is always `"skill"`. Type string `json:"type" api:"required"` // ISO 8601 timestamp of when the skill was last updated. UpdatedAt string `json:"updated_at" api:"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" api:"required"` // ISO 8601 timestamp of when the skill was created. CreatedAt string `json:"created_at" api:"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" api:"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" api:"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" api:"required"` // Object type. // // For Skills, this is always `"skill"`. Type string `json:"type" api:"required"` // ISO 8601 timestamp of when the skill was last updated. UpdatedAt string `json:"updated_at" api:"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" api:"required"` // Deleted object type. // // For Skills, this is always `"skill_deleted"`. Type string `json:"type" api:"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 } ================================================ FILE: betaskill_test.go ================================================ // 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/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/internal/testutil" "github.com/anthropics/anthropic-sdk-go/option" ) func TestBetaSkillNewWithOptionalParams(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.New(context.TODO(), anthropic.BetaSkillNewParams{ DisplayTitle: anthropic.String("display_title"), Files: []io.Reader{io.Reader(bytes.NewBuffer([]byte("Example data")))}, 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()) } } ================================================ FILE: betaskillversion.go ================================================ // 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/anthropics/anthropic-sdk-go/internal/apiform" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/internal/apiquery" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/pagination" "github.com/anthropics/anthropic-sdk-go/packages/param" "github.com/anthropics/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 nil, err } path := fmt.Sprintf("v1/skills/%s/versions?beta=true", skillID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return res, err } // 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 nil, err } if version == "" { err = errors.New("missing required version parameter") return nil, err } path := fmt.Sprintf("v1/skills/%s/versions/%s?beta=true", params.SkillID, version) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) return res, err } // 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 nil, err } 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 nil, err } if version == "" { err = errors.New("missing required version parameter") return nil, err } path := fmt.Sprintf("v1/skills/%s/versions/%s?beta=true", params.SkillID, version) err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) return res, err } type BetaSkillVersionNewResponse struct { // Unique identifier for the skill version. // // The format and length of IDs may change over time. ID string `json:"id" api:"required"` // ISO 8601 timestamp of when the skill version was created. CreatedAt string `json:"created_at" api:"required"` // Description of the skill version. // // This is extracted from the SKILL.md file in the skill upload. Description string `json:"description" api:"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" api:"required"` // Human-readable name of the skill version. // // This is extracted from the SKILL.md file in the skill upload. Name string `json:"name" api:"required"` // Identifier for the skill that this version belongs to. SkillID string `json:"skill_id" api:"required"` // Object type. // // For Skill Versions, this is always `"skill_version"`. Type string `json:"type" api:"required"` // Version identifier for the skill. // // Each version is identified by a Unix epoch timestamp (e.g., "1759178010641129"). Version string `json:"version" api:"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" api:"required"` // ISO 8601 timestamp of when the skill version was created. CreatedAt string `json:"created_at" api:"required"` // Description of the skill version. // // This is extracted from the SKILL.md file in the skill upload. Description string `json:"description" api:"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" api:"required"` // Human-readable name of the skill version. // // This is extracted from the SKILL.md file in the skill upload. Name string `json:"name" api:"required"` // Identifier for the skill that this version belongs to. SkillID string `json:"skill_id" api:"required"` // Object type. // // For Skill Versions, this is always `"skill_version"`. Type string `json:"type" api:"required"` // Version identifier for the skill. // // Each version is identified by a Unix epoch timestamp (e.g., "1759178010641129"). Version string `json:"version" api:"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" api:"required"` // ISO 8601 timestamp of when the skill version was created. CreatedAt string `json:"created_at" api:"required"` // Description of the skill version. // // This is extracted from the SKILL.md file in the skill upload. Description string `json:"description" api:"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" api:"required"` // Human-readable name of the skill version. // // This is extracted from the SKILL.md file in the skill upload. Name string `json:"name" api:"required"` // Identifier for the skill that this version belongs to. SkillID string `json:"skill_id" api:"required"` // Object type. // // For Skill Versions, this is always `"skill_version"`. Type string `json:"type" api:"required"` // Version identifier for the skill. // // Each version is identified by a Unix epoch timestamp (e.g., "1759178010641129"). Version string `json:"version" api:"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" api:"required"` // Deleted object type. // // For Skill Versions, this is always `"skill_version_deleted"`. Type string `json:"type" api:"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" api:"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" api:"required" json:"-"` // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } ================================================ FILE: betaskillversion_test.go ================================================ // 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/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/internal/testutil" "github.com/anthropics/anthropic-sdk-go/option" ) func TestBetaSkillVersionNewWithOptionalParams(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.New( context.TODO(), "skill_id", anthropic.BetaSkillVersionNewParams{ Files: []io.Reader{io.Reader(bytes.NewBuffer([]byte("Example data")))}, 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()) } } ================================================ FILE: betatoolrunner.go ================================================ package anthropic import ( "context" "encoding/json" "fmt" "iter" "github.com/anthropics/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 } } } } ================================================ FILE: client.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic import ( "context" "fmt" "net/http" "os" "slices" "time" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/shared/constant" ) // Client creates a struct with services and top level methods that help with // interacting with the anthropic API. You should not instantiate this client // directly, and instead use the [NewClient] method instead. type Client struct { Options []option.RequestOption Completions CompletionService Messages MessageService Models ModelService Beta BetaService } // DefaultClientOptions read from the environment (ANTHROPIC_API_KEY, // ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL). This should be used to initialize new // clients. func DefaultClientOptions() []option.RequestOption { defaults := []option.RequestOption{option.WithEnvironmentProduction()} if o, ok := os.LookupEnv("ANTHROPIC_BASE_URL"); ok { defaults = append(defaults, option.WithBaseURL(o)) } if o, ok := os.LookupEnv("ANTHROPIC_API_KEY"); ok { defaults = append(defaults, option.WithAPIKey(o)) } if o, ok := os.LookupEnv("ANTHROPIC_AUTH_TOKEN"); ok { defaults = append(defaults, option.WithAuthToken(o)) } return defaults } // NewClient generates a new client with the default option read from the // environment (ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL). The // option passed in as arguments are applied after these default arguments, and all // option will be passed down to the services and requests that this client makes. func NewClient(opts ...option.RequestOption) (r Client) { opts = append(DefaultClientOptions(), opts...) r = Client{Options: opts} r.Completions = NewCompletionService(opts...) r.Messages = NewMessageService(opts...) r.Models = NewModelService(opts...) r.Beta = NewBetaService(opts...) return } // Execute makes a request with the given context, method, URL, request params, // response, and request options. This is useful for hitting undocumented endpoints // while retaining the base URL, auth, retries, and other options from the client. // // If a byte slice or an [io.Reader] is supplied to params, it will be used as-is // for the request body. // // The params is by default serialized into the body using [encoding/json]. If your // type implements a MarshalJSON function, it will be used instead to serialize the // request. If a URLQuery method is implemented, the returned [url.Values] will be // used as query strings to the url. // // If your params struct uses [param.Field], you must provide either [MarshalJSON], // [URLQuery], and/or [MarshalForm] functions. It is undefined behavior to use a // struct uses [param.Field] without specifying how it is serialized. // // Any "…Params" object defined in this library can be used as the request // argument. Note that 'path' arguments will not be forwarded into the url. // // The response body will be deserialized into the res variable, depending on its // type: // // - A pointer to a [*http.Response] is populated by the raw response. // - A pointer to a byte array will be populated with the contents of the request // body. // - A pointer to any other type uses this library's default JSON decoding, which // respects UnmarshalJSON if it is defined on the type. // - A nil value will not read the response body. // // For even greater flexibility, see [option.WithResponseInto] and // [option.WithResponseBodyInto]. func (r *Client) Execute(ctx context.Context, method string, path string, params any, res any, opts ...option.RequestOption) error { opts = slices.Concat(r.Options, opts) return requestconfig.ExecuteNewRequest(ctx, method, path, params, res, opts...) } // Get makes a GET request with the given URL, params, and optionally deserializes // to a response. See [Execute] documentation on the params and response. func (r *Client) Get(ctx context.Context, path string, params any, res any, opts ...option.RequestOption) error { return r.Execute(ctx, http.MethodGet, path, params, res, opts...) } // Post makes a POST request with the given URL, params, and optionally // deserializes to a response. See [Execute] documentation on the params and // response. func (r *Client) Post(ctx context.Context, path string, params any, res any, opts ...option.RequestOption) error { return r.Execute(ctx, http.MethodPost, path, params, res, opts...) } // Put makes a PUT request with the given URL, params, and optionally deserializes // to a response. See [Execute] documentation on the params and response. func (r *Client) Put(ctx context.Context, path string, params any, res any, opts ...option.RequestOption) error { return r.Execute(ctx, http.MethodPut, path, params, res, opts...) } // Patch makes a PATCH request with the given URL, params, and optionally // deserializes to a response. See [Execute] documentation on the params and // response. func (r *Client) Patch(ctx context.Context, path string, params any, res any, opts ...option.RequestOption) error { return r.Execute(ctx, http.MethodPatch, path, params, res, opts...) } // Delete makes a DELETE request with the given URL, params, and optionally // deserializes to a response. See [Execute] documentation on the params and // response. 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 } ================================================ FILE: client_test.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic_test import ( "context" "fmt" "io" "net/http" "reflect" "testing" "time" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/internal" "github.com/anthropics/anthropic-sdk-go/option" ) type closureTransport struct { fn func(req *http.Request) (*http.Response, error) } func (t *closureTransport) RoundTrip(req *http.Request) (*http.Response, error) { return t.fn(req) } func TestUserAgentHeader(t *testing.T) { var userAgent string client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { userAgent = req.Header.Get("User-Agent") return &http.Response{ StatusCode: http.StatusOK, }, nil }, }, }), ) _, _ = client.Messages.New(context.Background(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, 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) } } func TestRetryAfter(t *testing.T) { retryCountHeaders := make([]string, 0) client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { retryCountHeaders = append(retryCountHeaders, req.Header.Get("X-Stainless-Retry-Count")) return &http.Response{ StatusCode: http.StatusTooManyRequests, Header: http.Header{ http.CanonicalHeaderKey("Retry-After"): []string{"0.1"}, }, }, nil }, }, }), ) _, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") } attempts := len(retryCountHeaders) if attempts != 3 { t.Errorf("Expected %d attempts, got %d", 3, attempts) } expectedRetryCountHeaders := []string{"0", "1", "2"} if !reflect.DeepEqual(retryCountHeaders, expectedRetryCountHeaders) { t.Errorf("Expected %v retry count headers, got %v", expectedRetryCountHeaders, retryCountHeaders) } } func TestDeleteRetryCountHeader(t *testing.T) { retryCountHeaders := make([]string, 0) client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { retryCountHeaders = append(retryCountHeaders, req.Header.Get("X-Stainless-Retry-Count")) return &http.Response{ StatusCode: http.StatusTooManyRequests, Header: http.Header{ http.CanonicalHeaderKey("Retry-After"): []string{"0.1"}, }, }, nil }, }, }), option.WithHeaderDel("X-Stainless-Retry-Count"), ) _, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") } expectedRetryCountHeaders := []string{"", "", ""} if !reflect.DeepEqual(retryCountHeaders, expectedRetryCountHeaders) { t.Errorf("Expected %v retry count headers, got %v", expectedRetryCountHeaders, retryCountHeaders) } } func TestOverwriteRetryCountHeader(t *testing.T) { retryCountHeaders := make([]string, 0) client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { retryCountHeaders = append(retryCountHeaders, req.Header.Get("X-Stainless-Retry-Count")) return &http.Response{ StatusCode: http.StatusTooManyRequests, Header: http.Header{ http.CanonicalHeaderKey("Retry-After"): []string{"0.1"}, }, }, nil }, }, }), option.WithHeader("X-Stainless-Retry-Count", "42"), ) _, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") } expectedRetryCountHeaders := []string{"42", "42", "42"} if !reflect.DeepEqual(retryCountHeaders, expectedRetryCountHeaders) { t.Errorf("Expected %v retry count headers, got %v", expectedRetryCountHeaders, retryCountHeaders) } } func TestRetryAfterMs(t *testing.T) { attempts := 0 client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { attempts++ return &http.Response{ StatusCode: http.StatusTooManyRequests, Header: http.Header{ http.CanonicalHeaderKey("Retry-After-Ms"): []string{"100"}, }, }, nil }, }, }), ) _, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") } if want := 3; attempts != want { t.Errorf("Expected %d attempts, got %d", want, attempts) } } func TestContextCancel(t *testing.T) { client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { <-req.Context().Done() return nil, req.Context().Err() }, }, }), ) cancelCtx, cancel := context.WithCancel(context.Background()) cancel() _, err := client.Messages.New(cancelCtx, anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("Expected there to be a cancel error") } } func TestContextCancelDelay(t *testing.T) { client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { <-req.Context().Done() return nil, req.Context().Err() }, }, }), ) cancelCtx, cancel := context.WithTimeout(context.Background(), 2*time.Millisecond) defer cancel() _, err := client.Messages.New(cancelCtx, anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("expected there to be a cancel error") } } func TestContextDeadline(t *testing.T) { testTimeout := time.After(3 * time.Second) testDone := make(chan struct{}) deadline := time.Now().Add(100 * time.Millisecond) deadlineCtx, cancel := context.WithDeadline(context.Background(), deadline) defer cancel() go func() { client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { <-req.Context().Done() return nil, req.Context().Err() }, }, }), ) _, err := client.Messages.New(deadlineCtx, anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeSonnet4_5_20250929, }) if err == nil { t.Error("expected there to be a deadline error") } close(testDone) }() select { case <-testTimeout: t.Fatal("client didn't finish in time") case <-testDone: if diff := time.Since(deadline); diff < -30*time.Millisecond || 30*time.Millisecond < diff { t.Fatalf("client did not return within 30ms of context deadline, got %s", diff) } } } func TestContextDeadlineStreaming(t *testing.T) { testTimeout := time.After(3 * time.Second) testDone := make(chan struct{}) deadline := time.Now().Add(100 * time.Millisecond) deadlineCtx, cancel := context.WithDeadline(context.Background(), deadline) defer cancel() go func() { client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: 200, Status: "200 OK", Body: io.NopCloser( io.Reader(readerFunc(func([]byte) (int, error) { <-req.Context().Done() return 0, req.Context().Err() })), ), }, nil }, }, }), ) stream := client.Messages.NewStreaming(deadlineCtx, anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeOpus4_6, }) for stream.Next() { _ = stream.Current() } if stream.Err() == nil { t.Error("expected there to be a deadline error") } close(testDone) }() select { case <-testTimeout: t.Fatal("client didn't finish in time") case <-testDone: if diff := time.Since(deadline); diff < -30*time.Millisecond || 30*time.Millisecond < diff { t.Fatalf("client did not return within 30ms of context deadline, got %s", diff) } } } func TestContextDeadlineStreamingWithRequestTimeout(t *testing.T) { testTimeout := time.After(3 * time.Second) testDone := make(chan struct{}) deadline := time.Now().Add(100 * time.Millisecond) go func() { client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), option.WithHTTPClient(&http.Client{ Transport: &closureTransport{ fn: func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: 200, Status: "200 OK", Body: io.NopCloser( io.Reader(readerFunc(func([]byte) (int, error) { <-req.Context().Done() return 0, req.Context().Err() })), ), }, nil }, }, }), ) stream := client.Messages.NewStreaming( context.Background(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{{ Content: []anthropic.ContentBlockParamUnion{{ OfText: &anthropic.TextBlockParam{ Text: "x", }, }}, Role: anthropic.MessageParamRoleUser, }}, Model: anthropic.ModelClaudeOpus4_6, }, option.WithRequestTimeout((100 * time.Millisecond)), ) for stream.Next() { _ = stream.Current() } if stream.Err() == nil { t.Error("expected there to be a deadline error") } close(testDone) }() select { case <-testTimeout: t.Fatal("client didn't finish in time") case <-testDone: if diff := time.Since(deadline); diff < -30*time.Millisecond || 30*time.Millisecond < diff { t.Fatalf("client did not return within 30ms of context deadline, got %s", diff) } } } type readerFunc func([]byte) (int, error) func (f readerFunc) Read(p []byte) (int, error) { return f(p) } func (f readerFunc) Close() error { return nil } ================================================ FILE: completion.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic import ( "context" "fmt" "net/http" "slices" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/internal/requestconfig" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/param" "github.com/anthropics/anthropic-sdk-go/packages/respjson" "github.com/anthropics/anthropic-sdk-go/packages/ssestream" "github.com/anthropics/anthropic-sdk-go/shared/constant" ) // CompletionService 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 [NewCompletionService] method instead. type CompletionService struct { Options []option.RequestOption } // NewCompletionService 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 NewCompletionService(opts ...option.RequestOption) (r CompletionService) { r = CompletionService{} r.Options = opts return } // [Legacy] Create a Text Completion. // // The Text Completions API is a legacy API. We recommend using the // [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.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("%v", v))) } opts = slices.Concat(r.Options, opts) path := "v1/complete" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, params, &res, opts...) return res, err } // [Legacy] Create a Text Completion. // // The Text Completions API is a legacy API. We recommend using the // [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.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) NewStreaming(ctx context.Context, params CompletionNewParams, opts ...option.RequestOption) (stream *ssestream.Stream[Completion]) { var ( raw *http.Response 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(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) } type Completion struct { // Unique object identifier. // // The format and length of IDs may change over time. ID string `json:"id" api:"required"` // The resulting completion up to and excluding the stop sequences. Completion string `json:"completion" api:"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" api:"required"` // The reason that we stopped. // // This may be one the following values: // // - `"stop_sequence"`: we reached a stop sequence — either provided by you via the // `stop_sequences` parameter, or a stop sequence built into the model // - `"max_tokens"`: we exceeded `max_tokens_to_sample` or the model's maximum StopReason string `json:"stop_reason" api:"required"` // Object type. // // For Text Completions, this is always `"completion"`. Type constant.Completion `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ID respjson.Field Completion respjson.Field Model respjson.Field StopReason respjson.Field Type respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } // Returns the unmodified JSON received from the API func (r Completion) RawJSON() string { return r.JSON.raw } func (r *Completion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } type CompletionNewParams struct { // The maximum number of tokens to generate before stopping. // // Note that our models may stop _before_ reaching this maximum. This parameter // only specifies the absolute maximum number of tokens to generate. MaxTokensToSample int64 `json:"max_tokens_to_sample" api:"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,omitzero" api:"required"` // The prompt that you want Claude to complete. // // For proper response generation you will need to format your prompt using // alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: // // ``` // "\n\nHuman: {userQuestion}\n\nAssistant:" // ``` // // 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" api:"required"` // Amount of randomness injected into the response. // // Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` // for analytical / multiple choice, and closer to `1.0` for creative and // generative tasks. // // Note that even with `temperature` of `0.0`, the results will not be fully // deterministic. Temperature param.Opt[float64] `json:"temperature,omitzero"` // Only sample from the top K options for each subsequent token. // // Used to remove "long tail" low probability responses. // [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). // // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopK param.Opt[int64] `json:"top_k,omitzero"` // Use nucleus sampling. // // In nucleus sampling, we compute the cumulative distribution over all the options // for each subsequent token in decreasing probability order and cut it off once it // reaches a particular probability specified by `top_p`. You should either alter // `temperature` or `top_p`, but not both. // // Recommended for advanced use cases only. You usually only need to use // `temperature`. TopP param.Opt[float64] `json:"top_p,omitzero"` // An object describing metadata about the request. Metadata MetadataParam `json:"metadata,omitzero"` // Sequences that will cause the model to stop generating. // // Our models stop on `"\n\nHuman:"`, and may include additional built-in stop // sequences in the future. By providing the stop_sequences parameter, you may // include additional strings that will cause the model to stop generating. StopSequences []string `json:"stop_sequences,omitzero"` // Optional header to specify the beta version(s) you want to use. Betas []AnthropicBeta `header:"anthropic-beta,omitzero" json:"-"` paramObj } func (r CompletionNewParams) MarshalJSON() (data []byte, err error) { type shadow CompletionNewParams return param.MarshalObject(r, (*shadow)(&r)) } func (r *CompletionNewParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } ================================================ FILE: completion_test.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package anthropic_test import ( "context" "errors" "os" "testing" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/internal/testutil" "github.com/anthropics/anthropic-sdk-go/option" ) func TestCompletionNewWithOptionalParams(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.Completions.New(context.TODO(), anthropic.CompletionNewParams{ MaxTokensToSample: 256, Model: anthropic.ModelClaudeOpus4_6, Prompt: "\n\nHuman: Hello, world!\n\nAssistant:", Metadata: anthropic.MetadataParam{ UserID: anthropic.String("13803d75-b4b5-4c3e-b2a2-6f21399b021b"), }, StopSequences: []string{"string"}, Temperature: anthropic.Float(1), TopK: anthropic.Int(5), TopP: anthropic.Float(0.7), 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()) } } ================================================ FILE: examples/.keep ================================================ File generated from our OpenAPI spec by Stainless. This directory can be used to store example files demonstrating usage of this SDK. It is ignored by Stainless code generation and its content (other than this keep file) won't be touched. ================================================ FILE: examples/bedrock/main.go ================================================ package main import ( "context" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/bedrock" ) func main() { client := anthropic.NewClient( bedrock.WithLoadDefaultConfig(context.Background()), ) 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-5-20250929-v1:0", StopSequences: []string{"```\n"}, }) if err != nil { panic(err) } println("[assistant]: " + message.Content[0].Text + message.StopSequence) } ================================================ FILE: examples/bedrock-bearer-token/main.go ================================================ package main import ( "context" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/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) } ================================================ FILE: examples/bedrock-streaming/main.go ================================================ package main import ( "context" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/bedrock" ) func main() { client := anthropic.NewClient( bedrock.WithLoadDefaultConfig(context.Background()), ) content := "Write me a function to call the Anthropic message API in Node.js using the Anthropic Typescript SDK." println("[user]: " + content) stream := client.Messages.NewStreaming(context.TODO(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock(content)), }, Model: "us.anthropic.claude-sonnet-4-5-20250929-v1:0", StopSequences: []string{"```\n"}, }) print("[assistant]: ") for stream.Next() { event := stream.Current() switch eventVariant := event.AsAny().(type) { case anthropic.MessageDeltaEvent: print(eventVariant.Delta.StopSequence) case anthropic.ContentBlockDeltaEvent: switch deltaVariant := eventVariant.Delta.AsAny().(type) { case anthropic.TextDelta: print(deltaVariant.Text) } } } println() if stream.Err() != nil { panic(stream.Err()) } } ================================================ FILE: examples/file-upload/file.txt ================================================ My top 5 favorite types of birds are, in no particular order: - Flycatchers (especially the Eastern Phoebe) - Hummingbirds - Swallows - Wrens - Sandpipers ================================================ FILE: examples/file-upload/main.go ================================================ package main import ( "context" "fmt" "os" "github.com/anthropics/anthropic-sdk-go" ) func main() { ctx := context.Background() client := anthropic.NewClient() myFile, err := os.Open("examples/file-upload/file.txt") if err != nil { fmt.Printf("Error opening file: %v\n", err) return } fileUploadResult, err := client.Beta.Files.Upload(ctx, anthropic.BetaFileUploadParams{ File: anthropic.File(myFile, "file.txt", "text/plain"), Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaFilesAPI2025_04_14}, }) if err != nil { fmt.Printf("Error uploading file: %v\n", err) return } content := "Write me a summary of my file.txt file in the style of a Shakespearean sonnet.\n\n" println("[user]: " + content) message, err := client.Beta.Messages.New(ctx, anthropic.BetaMessageNewParams{ MaxTokens: 1024, Messages: []anthropic.BetaMessageParam{ anthropic.NewBetaUserMessage( anthropic.NewBetaTextBlock(content), anthropic.NewBetaDocumentBlock(anthropic.BetaFileDocumentSourceParam{ FileID: fileUploadResult.ID, }), ), }, Model: anthropic.ModelClaudeSonnet4_5_20250929, Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaFilesAPI2025_04_14}, }) if err != nil { fmt.Printf("Error creating message: %v\n", err) return } println("[assistant]: " + message.Content[0].Text + message.StopSequence) } ================================================ FILE: examples/go.mod ================================================ module github.com/anthropic/anthropic-sdk-go/examples replace github.com/anthropics/anthropic-sdk-go => ../ go 1.23.0 toolchain go1.24.3 require ( github.com/anthropics/anthropic-sdk-go v0.0.0-00010101000000-000000000000 github.com/invopop/jsonschema v0.13.0 ) require ( cloud.google.com/go/auth v0.7.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect cloud.google.com/go/compute/metadata v0.5.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 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/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // 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 go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect 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/oauth2 v0.30.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/api v0.189.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.v3 v3.0.1 // indirect ) require ( // for the bedrock package github.com/aws/aws-sdk-go-v2 v1.30.3 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect github.com/aws/aws-sdk-go-v2/config v1.27.27 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect 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 ) ================================================ FILE: examples/go.sum ================================================ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go/auth v0.7.2 h1:uiha352VrCDMXg+yoBtaD0tUF4Kv9vrtrWPYXwutnDE= cloud.google.com/go/auth v0.7.2/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM= github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= 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/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= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= 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/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= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 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= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI= google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade h1:oCRSWfwGXQsqlVdErcyTt4A93Y8fo0/9D4b1gnI++qo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 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.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= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= ================================================ FILE: examples/message/main.go ================================================ package main import ( "context" "github.com/anthropics/anthropic-sdk-go" ) func main() { client := anthropic.NewClient() 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: anthropic.ModelClaudeSonnet4_5_20250929, StopSequences: []string{"```\n"}, }) if err != nil { panic(err) } println("[assistant]: " + message.Content[0].Text + message.StopSequence) } ================================================ FILE: examples/message-mcp-streaming/main.go ================================================ package main import ( "context" "fmt" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/option" "github.com/anthropics/anthropic-sdk-go/packages/param" ) func main() { client := anthropic.NewClient(option.WithHeader("anthropic-beta", anthropic.AnthropicBetaMCPClient2025_04_04)) mcpServers := []anthropic.BetaRequestMCPServerURLDefinitionParam{ { URL: "http://example-server.modelcontextprotocol.io/sse", Name: "example", AuthorizationToken: param.NewOpt("YOUR_TOKEN"), ToolConfiguration: anthropic.BetaRequestMCPServerToolConfigurationParam{ Enabled: anthropic.Bool(true), AllowedTools: []string{"echo", "add"}, }, }, } stream := client.Beta.Messages.NewStreaming(context.TODO(), anthropic.BetaMessageNewParams{ MaxTokens: 1024, Messages: []anthropic.BetaMessageParam{ anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("what is 1+1?")), }, MCPServers: mcpServers, Model: anthropic.ModelClaudeSonnet4_5_20250929, StopSequences: []string{"```\n"}, }) message := anthropic.BetaMessage{} for stream.Next() { event := stream.Current() err := message.Accumulate(event) if err != nil { fmt.Printf("error accumulating event: %v\n", err) continue } switch eventVariant := event.AsAny().(type) { case anthropic.BetaRawMessageDeltaEvent: print(eventVariant.Delta.StopSequence) case anthropic.BetaRawContentBlockDeltaEvent: switch deltaVariant := eventVariant.Delta.AsAny().(type) { case anthropic.BetaTextDelta: print(deltaVariant.Text) } default: fmt.Printf("%+v\n", eventVariant) } } println() if stream.Err() != nil { panic(stream.Err()) } } ================================================ FILE: examples/message-streaming/main.go ================================================ package main import ( "context" "github.com/anthropics/anthropic-sdk-go" ) func main() { client := anthropic.NewClient() content := "Write me a function to call the Anthropic message API in Node.js using the Anthropic Typescript SDK." println("[user]: " + content) stream := client.Messages.NewStreaming(context.TODO(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock(content)), }, Model: anthropic.ModelClaudeSonnet4_5_20250929, StopSequences: []string{"```\n"}, }) print("[assistant]: ") for stream.Next() { event := stream.Current() switch eventVariant := event.AsAny().(type) { case anthropic.MessageDeltaEvent: print(eventVariant.Delta.StopSequence) case anthropic.ContentBlockDeltaEvent: switch deltaVariant := eventVariant.Delta.AsAny().(type) { case anthropic.TextDelta: print(deltaVariant.Text) } } } println() if stream.Err() != nil { panic(stream.Err()) } } ================================================ FILE: examples/multimodal/main.go ================================================ package main import ( "context" "encoding/base64" "fmt" "io" "os" "github.com/anthropics/anthropic-sdk-go" ) func main() { client := anthropic.NewClient() content := "How many dogs are in this picture?" println("[user]: " + content) file, err := os.Open("./multimodal/nine_dogs.png") if err != nil { panic(fmt.Errorf("failed to open file: you should run this example from the root of the anthropic-go/examples directory: %w", err)) } fileBytes, err := io.ReadAll(file) if err != nil { panic(err) } fileEncoded := base64.StdEncoding.EncodeToString(fileBytes) message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{ anthropic.NewUserMessage( anthropic.NewTextBlock(content), anthropic.NewImageBlockBase64("image/png", fileEncoded), ), }, Model: anthropic.ModelClaudeSonnet4_5_20250929, StopSequences: []string{"```\n"}, }) if err != nil { panic(err) } println("[assistant]: " + message.Content[0].Text + message.StopSequence) } ================================================ FILE: examples/structured-outputs/main.go ================================================ package main import ( "context" "encoding/json" "fmt" "github.com/anthropics/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)) } ================================================ FILE: examples/tool-runner/main.go ================================================ // Example demonstrating the Tool Runner framework package main import ( "context" "fmt" "strconv" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/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) } ================================================ FILE: examples/tool-runner-streaming/main.go ================================================ // Example demonstrating the Tool Runner framework with streaming package main import ( "context" "fmt" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/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() } } } } ================================================ FILE: examples/tools/main.go ================================================ package main import ( "context" "encoding/json" "fmt" "github.com/anthropics/anthropic-sdk-go" ) func main() { client := anthropic.NewClient() content := "What is the weather in San Francisco, CA?" println(color("[user]: ") + content) messages := []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock(content)), } toolParams := []anthropic.ToolParam{ { 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]any{ "location": map[string]any{ "type": "string", "description": "The location to look up.", }, }, }, }, { Name: "get_temperature_unit", InputSchema: anthropic.ToolInputSchemaParam{ Properties: map[string]any{ "country": map[string]any{ "type": "string", "description": "The country", }, }, }, }, { Name: "get_weather", Description: anthropic.String("Get the weather at a specific location"), InputSchema: anthropic.ToolInputSchemaParam{ Properties: map[string]any{ "lat": map[string]any{ "type": "number", "description": "The lattitude of the location to check weather.", }, "long": map[string]any{ "type": "number", "description": "The longitude of the location to check weather.", }, "unit": map[string]any{ "type": "string", "enum": []string{"celsius", "fahrenheit"}, "description": "Unit for the output", }, }, }, }, } tools := make([]anthropic.ToolUnionParam, len(toolParams)) for i, toolParam := range toolParams { tools[i] = anthropic.ToolUnionParam{OfTool: &toolParam} } for { message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{ Model: anthropic.ModelClaudeSonnet4_5_20250929, MaxTokens: 1024, Messages: messages, Tools: tools, }) if err != nil { panic(err) } print(color("[assistant]: ")) for _, block := range message.Content { switch block := block.AsAny().(type) { case anthropic.TextBlock: println(block.Text) println() case anthropic.ToolUseBlock: inputJSON, _ := json.Marshal(block.Input) println(block.Name + ": " + string(inputJSON)) println() } } println() messages = append(messages, message.ToParam()) toolResults := []anthropic.ContentBlockParamUnion{} for _, block := range message.Content { switch variant := block.AsAny().(type) { case anthropic.ToolUseBlock: print(color("[user (" + block.Name + ")]: ")) var response any switch block.Name { case "get_coordinates": var input struct { Location string `json:"location"` } err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetCoordinates(input.Location) case "get_temperature_unit": var input struct { Country string `json:"country"` } err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetTemperatureUnit(input.Country) case "get_weather": var input struct { Lat float64 `json:"lat"` Long float64 `json:"long"` Unit string `json:"unit"` } err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetWeather(input.Lat, input.Long, input.Unit) } b, err := json.Marshal(response) if err != nil { panic(err) } println(string(b)) toolResults = append(toolResults, anthropic.NewToolResultBlock(block.ID, string(b), false)) } } if len(toolResults) == 0 { break } messages = append(messages, anthropic.NewUserMessage(toolResults...)) } } type CoordinateResponse struct { Long float64 `json:"long"` Lat float64 `json:"lat"` } func GetCoordinates(location string) CoordinateResponse { return CoordinateResponse{ Long: -122.4194, Lat: 37.7749, } } func GetTemperatureUnit(country string) string { return "farenheit" } type WeatherResponse struct { Unit string `json:"unit"` Temperature float64 `json:"temperature"` } func GetWeather(lat, long float64, unit string) WeatherResponse { return WeatherResponse{ Unit: "farenheit", Temperature: 122, } } func color(s string) string { return fmt.Sprintf("\033[1;%sm%s\033[0m", "33", s) } ================================================ FILE: examples/tools-streaming/main.go ================================================ package main import ( "context" "encoding/json" "fmt" "github.com/anthropics/anthropic-sdk-go" ) func main() { client := anthropic.NewClient() content := "What is the weather in San Francisco, CA?" println(color("[user]: ") + content) messages := []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock(content)), } toolParams := []anthropic.ToolParam{ { 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]any{ "location": map[string]any{ "type": "string", "description": "The location to look up.", }, }, }, }, { Name: "get_temperature_unit", InputSchema: anthropic.ToolInputSchemaParam{ Properties: map[string]any{ "country": map[string]any{ "type": "string", "description": "The country", }, }, }, }, { Name: "get_weather", Description: anthropic.String("Get the weather at a specific location"), InputSchema: anthropic.ToolInputSchemaParam{ Properties: map[string]any{ "lat": map[string]any{ "type": "number", "description": "The lattitude of the location to check weather.", }, "long": map[string]any{ "type": "number", "description": "The longitude of the location to check weather.", }, "unit": map[string]any{ "type": "string", "enum": []string{"celsius", "fahrenheit"}, "description": "Unit for the output", }, }, }, }, } tools := make([]anthropic.ToolUnionParam, len(toolParams)) for i, toolParam := range toolParams { tools[i] = anthropic.ToolUnionParam{OfTool: &toolParam} } for { stream := client.Messages.NewStreaming(context.TODO(), anthropic.MessageNewParams{ Model: anthropic.ModelClaudeSonnet4_5_20250929, MaxTokens: 1024, Messages: messages, Tools: tools, }) print(color("[assistant]: ")) message := anthropic.Message{} for stream.Next() { event := stream.Current() err := message.Accumulate(event) if err != nil { panic(err) } switch event := event.AsAny().(type) { case anthropic.ContentBlockStartEvent: if event.ContentBlock.Name != "" { print(event.ContentBlock.Name + ": ") } case anthropic.ContentBlockDeltaEvent: print(event.Delta.Text) print(event.Delta.PartialJSON) case anthropic.ContentBlockStopEvent: println() println() case anthropic.MessageStopEvent: println() } } if stream.Err() != nil { panic(stream.Err()) } messages = append(messages, message.ToParam()) toolResults := []anthropic.ContentBlockParamUnion{} for _, block := range message.Content { switch variant := block.AsAny().(type) { case anthropic.ToolUseBlock: print(color("[user (" + block.Name + ")]: ")) var response any switch block.Name { case "get_coordinates": var input struct { Location string `json:"location"` } err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetCoordinates(input.Location) case "get_temperature_unit": var input struct { Country string `json:"country"` } err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetTemperatureUnit(input.Country) case "get_weather": var input struct { Lat float64 `json:"lat"` Long float64 `json:"long"` Unit string `json:"unit"` } err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetWeather(input.Lat, input.Long, input.Unit) } b, err := json.Marshal(response) if err != nil { panic(err) } println(string(b)) toolResults = append(toolResults, anthropic.NewToolResultBlock(block.ID, string(b), false)) } } if len(toolResults) == 0 { break } messages = append(messages, anthropic.NewUserMessage(toolResults...)) } } type CoordinateResponse struct { Long float64 `json:"long"` Lat float64 `json:"lat"` } func GetCoordinates(location string) CoordinateResponse { return CoordinateResponse{ Long: -122.4194, Lat: 37.7749, } } func GetTemperatureUnit(country string) string { return "farenheit" } type WeatherResponse struct { Unit string `json:"unit"` Temperature float64 `json:"temperature"` } func GetWeather(lat, long float64, unit string) WeatherResponse { return WeatherResponse{ Unit: "farenheit", Temperature: 122, } } func color(s string) string { return fmt.Sprintf("\033[1;%sm%s\033[0m", "33", s) } ================================================ FILE: examples/tools-streaming-jsonschema/main.go ================================================ package main import ( "context" "encoding/json" "fmt" "github.com/anthropics/anthropic-sdk-go" "github.com/invopop/jsonschema" ) func main() { client := anthropic.NewClient() content := "What is the weather in San Francisco, CA?" println(color("[user]: ") + content) messages := []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock(content)), } toolParams := []anthropic.ToolParam{ { Name: "get_coordinates", Description: anthropic.String("Accepts a place as an address, then returns the latitude and longitude coordinates."), InputSchema: GetCoordinatesInputSchema, }, { Name: "get_temperature_unit", InputSchema: GetTemperatureUnitInputSchema, }, { Name: "get_weather", Description: anthropic.String("Get the weather at a specific location"), InputSchema: GetWeatherInputSchema, }, } tools := make([]anthropic.ToolUnionParam, len(toolParams)) for i, toolParam := range toolParams { tools[i] = anthropic.ToolUnionParam{OfTool: &toolParam} } for { stream := client.Messages.NewStreaming(context.TODO(), anthropic.MessageNewParams{ Model: anthropic.ModelClaudeSonnet4_5_20250929, MaxTokens: 1024, Messages: messages, Tools: tools, }) print(color("[assistant]: ")) message := anthropic.Message{} for stream.Next() { event := stream.Current() err := message.Accumulate(event) if err != nil { panic(err) } switch event := event.AsAny().(type) { case anthropic.ContentBlockStartEvent: if event.ContentBlock.Name != "" { print(event.ContentBlock.Name + ": ") } case anthropic.ContentBlockDeltaEvent: print(event.Delta.Text) print(event.Delta.PartialJSON) case anthropic.ContentBlockStopEvent: println() println() case anthropic.MessageStopEvent: println() } } if stream.Err() != nil { panic(stream.Err()) } messages = append(messages, message.ToParam()) toolResults := []anthropic.ContentBlockParamUnion{} for _, block := range message.Content { switch variant := block.AsAny().(type) { case anthropic.ToolUseBlock: print(color("[user (" + block.Name + ")]: ")) var response any switch block.Name { case "get_coordinates": input := GetCoordinatesInput{} err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetCoordinates(input.Location) case "get_temperature_unit": input := GetTemperatureUnitInput{} err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetTemperatureUnit(input.Country) case "get_weather": input := GetWeatherInput{} err := json.Unmarshal([]byte(variant.JSON.Input.Raw()), &input) if err != nil { panic(err) } response = GetWeather(input.Lat, input.Long, input.Unit) } b, err := json.Marshal(response) if err != nil { panic(err) } println(string(b)) toolResults = append(toolResults, anthropic.NewToolResultBlock(block.ID, string(b), false)) } } if len(toolResults) == 0 { break } messages = append(messages, anthropic.NewUserMessage(toolResults...)) } } // Get Coordinates type GetCoordinatesInput struct { Location string `json:"location" jsonschema_description:"The location to look up."` } var GetCoordinatesInputSchema = GenerateSchema[GetCoordinatesInput]() type GetCoordinateResponse struct { Long float64 `json:"long"` Lat float64 `json:"lat"` } func GetCoordinates(location string) GetCoordinateResponse { return GetCoordinateResponse{ Long: -122.4194, Lat: 37.7749, } } // Get Temperature Unit type GetTemperatureUnitInput struct { Country string `json:"country" jsonschema_description:"The country"` } var GetTemperatureUnitInputSchema = GenerateSchema[GetTemperatureUnitInput]() func GetTemperatureUnit(country string) string { return "farenheit" } // Get Weather type GetWeatherInput struct { Lat float64 `json:"lat" jsonschema_description:"The latitude of the location to check weather."` Long float64 `json:"long" jsonschema_description:"The longitude of the location to check weather."` Unit string `json:"unit" jsonschema_description:"Unit for the output"` } var GetWeatherInputSchema = GenerateSchema[GetWeatherInput]() type GetWeatherResponse struct { Unit string `json:"unit"` Temperature float64 `json:"temperature"` } func GetWeather(lat, long float64, unit string) GetWeatherResponse { return GetWeatherResponse{ Unit: "farenheit", Temperature: 122, } } func GenerateSchema[T any]() anthropic.ToolInputSchemaParam { reflector := jsonschema.Reflector{ AllowAdditionalProperties: false, DoNotReference: true, } var v T schema := reflector.Reflect(v) return anthropic.ToolInputSchemaParam{ Properties: schema.Properties, } } func color(s string) string { return fmt.Sprintf("\033[1;%sm%s\033[0m", "33", s) } ================================================ FILE: examples/vertex/main.go ================================================ package main import ( "context" "github.com/anthropics/anthropic-sdk-go/vertex" "github.com/anthropics/anthropic-sdk-go" ) func main() { client := anthropic.NewClient( vertex.WithGoogleAuth(context.Background(), "us-central1", "id-xxx"), ) 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: "claude-sonnet-4-v1@20250514", StopSequences: []string{"```\n"}, }) if err != nil { panic(err) } println("[assistant]: " + message.Content[0].Text + message.StopSequence) } ================================================ FILE: examples/vertex-streaming/main.go ================================================ package main import ( "context" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/vertex" ) func main() { client := anthropic.NewClient( vertex.WithGoogleAuth(context.Background(), "us-central1", "id-xxx"), ) content := "Write me a function to call the Anthropic message API in Node.js using the Anthropic Typescript SDK." println("[user]: " + content) stream := client.Messages.NewStreaming(context.TODO(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock(content)), }, Model: "claude-sonnet-4-v1@20250514", StopSequences: []string{"```\n"}, }) print("[assistant]: ") for stream.Next() { event := stream.Current() switch variant := event.AsAny().(type) { case anthropic.ContentBlockDeltaEvent: if variant.Delta.Text != "" { print(variant.Delta.Text) } case anthropic.MessageDeltaEvent: if variant.Delta.StopSequence != "" { print(variant.Delta.StopSequence) } } } println() if stream.Err() != nil { panic(stream.Err()) } } ================================================ FILE: field.go ================================================ package anthropic import ( "github.com/anthropics/anthropic-sdk-go/packages/param" "io" "time" ) func String(s string) param.Opt[string] { return param.NewOpt(s) } func Int(i int64) param.Opt[int64] { return param.NewOpt(i) } func Bool(b bool) param.Opt[bool] { return param.NewOpt(b) } func Float(f float64) param.Opt[float64] { return param.NewOpt(f) } func Time(t time.Time) param.Opt[time.Time] { return param.NewOpt(t) } func Opt[T comparable](v T) param.Opt[T] { return param.NewOpt(v) } func Ptr[T any](v T) *T { return &v } func IntPtr(v int64) *int64 { return &v } func BoolPtr(v bool) *bool { return &v } func FloatPtr(v float64) *float64 { return &v } func StringPtr(v string) *string { return &v } func TimePtr(v time.Time) *time.Time { return &v } func File(rdr io.Reader, filename string, contentType string) file { return file{rdr, filename, contentType} } type file struct { io.Reader name string contentType string } func (f file) Filename() string { if f.name != "" { return f.name } else if named, ok := f.Reader.(interface{ Name() string }); ok { return named.Name() } return "" } func (f file) ContentType() string { return f.contentType } ================================================ FILE: go.mod ================================================ module github.com/anthropics/anthropic-sdk-go go 1.23.0 toolchain go1.24.3 require ( github.com/aws/aws-sdk-go-v2 v1.30.3 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 ) require ( cloud.google.com/go/auth v0.7.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect cloud.google.com/go/compute/metadata v0.5.0 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect 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/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 github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 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 go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect 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/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 ) ================================================ FILE: go.sum ================================================ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go/auth v0.7.2 h1:uiha352VrCDMXg+yoBtaD0tUF4Kv9vrtrWPYXwutnDE= cloud.google.com/go/auth v0.7.2/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM= github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= 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= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= 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= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 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= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI= google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade h1:oCRSWfwGXQsqlVdErcyTt4A93Y8fo0/9D4b1gnI++qo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 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= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= ================================================ FILE: internal/apierror/apierror.go ================================================ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. package apierror import ( "fmt" "net/http" "net/http/httputil" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/packages/respjson" ) // Error represents an error that originates from the API, i.e. when a request is // made and the API returns a response with a HTTP status code. Other errors are // not wrapped by this SDK. type Error struct { // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { ExtraFields map[string]respjson.Field raw string } `json:"-"` StatusCode int Request *http.Request Response *http.Response RequestID string } // Returns the unmodified JSON received from the API func (r Error) RawJSON() string { return r.JSON.raw } func (r *Error) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } func (r *Error) Error() string { // Attempt to re-populate the response body statusInfo := fmt.Sprintf("%s %q: %d %s", r.Request.Method, r.Request.URL, r.Response.StatusCode, http.StatusText(r.Response.StatusCode)) if r.RequestID != "" { statusInfo += fmt.Sprintf(" (Request-ID: %s)", r.RequestID) } return fmt.Sprintf("%s %s", statusInfo, r.JSON.raw) } func (r *Error) DumpRequest(body bool) []byte { if r.Request.GetBody != nil { r.Request.Body, _ = r.Request.GetBody() } out, _ := httputil.DumpRequestOut(r.Request, body) return out } func (r *Error) DumpResponse(body bool) []byte { out, _ := httputil.DumpResponse(r.Response, body) return out } ================================================ FILE: internal/apiform/encoder.go ================================================ package apiform import ( "fmt" "io" "mime/multipart" "net/textproto" "path" "reflect" "sort" "strconv" "strings" "sync" "time" "github.com/anthropics/anthropic-sdk-go/packages/param" ) var encoders sync.Map // map[encoderEntry]encoderFunc func Marshal(value any, writer *multipart.Writer) error { e := &encoder{ dateFormat: time.RFC3339, arrayFmt: "comma", } return e.marshal(value, writer) } func MarshalRoot(value any, writer *multipart.Writer) error { e := &encoder{ root: true, dateFormat: time.RFC3339, arrayFmt: "comma", } return e.marshal(value, writer) } func MarshalWithSettings(value any, writer *multipart.Writer, arrayFormat string) error { e := &encoder{ arrayFmt: arrayFormat, dateFormat: time.RFC3339, } return e.marshal(value, writer) } type encoder struct { arrayFmt string dateFormat string root bool } type encoderFunc func(key string, value reflect.Value, writer *multipart.Writer) error type encoderField struct { tag parsedStructTag fn encoderFunc idx []int } type encoderEntry struct { reflect.Type dateFormat string arrayFmt string root bool } func (e *encoder) marshal(value any, writer *multipart.Writer) error { val := reflect.ValueOf(value) if !val.IsValid() { return nil } typ := val.Type() enc := e.typeEncoder(typ) return enc("", val, writer) } func (e *encoder) typeEncoder(t reflect.Type) encoderFunc { entry := encoderEntry{ Type: t, dateFormat: e.dateFormat, arrayFmt: e.arrayFmt, root: e.root, } if fi, ok := encoders.Load(entry); ok { return fi.(encoderFunc) } // To deal with recursive types, populate the map with an // indirect func before we build it. This type waits on the // real func (f) to be ready and then calls it. This indirect // func is only used for recursive types. var ( wg sync.WaitGroup f encoderFunc ) wg.Add(1) fi, loaded := encoders.LoadOrStore(entry, encoderFunc(func(key string, v reflect.Value, writer *multipart.Writer) error { wg.Wait() return f(key, v, writer) })) if loaded { return fi.(encoderFunc) } // Compute the real encoder and replace the indirect func with it. f = e.newTypeEncoder(t) wg.Done() encoders.Store(entry, f) return f } func (e *encoder) newTypeEncoder(t reflect.Type) encoderFunc { if t.ConvertibleTo(reflect.TypeOf(time.Time{})) { return e.newTimeTypeEncoder() } if t.Implements(reflect.TypeOf((*io.Reader)(nil)).Elem()) { return e.newReaderTypeEncoder() } e.root = false switch t.Kind() { case reflect.Pointer: inner := t.Elem() innerEncoder := e.typeEncoder(inner) return func(key string, v reflect.Value, writer *multipart.Writer) error { if !v.IsValid() || v.IsNil() { return nil } return innerEncoder(key, v.Elem(), writer) } case reflect.Struct: return e.newStructTypeEncoder(t) case reflect.Slice, reflect.Array: return e.newArrayTypeEncoder(t) case reflect.Map: return e.newMapEncoder(t) case reflect.Interface: return e.newInterfaceEncoder() default: return e.newPrimitiveTypeEncoder(t) } } func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc { switch t.Kind() { // Note that we could use `gjson` to encode these types but it would complicate our // code more and this current code shouldn't cause any issues case reflect.String: return func(key string, v reflect.Value, writer *multipart.Writer) error { return writer.WriteField(key, v.String()) } case reflect.Bool: return func(key string, v reflect.Value, writer *multipart.Writer) error { if v.Bool() { return writer.WriteField(key, "true") } return writer.WriteField(key, "false") } case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: return func(key string, v reflect.Value, writer *multipart.Writer) error { return writer.WriteField(key, strconv.FormatInt(v.Int(), 10)) } case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: return func(key string, v reflect.Value, writer *multipart.Writer) error { return writer.WriteField(key, strconv.FormatUint(v.Uint(), 10)) } case reflect.Float32: return func(key string, v reflect.Value, writer *multipart.Writer) error { return writer.WriteField(key, strconv.FormatFloat(v.Float(), 'f', -1, 32)) } case reflect.Float64: return func(key string, v reflect.Value, writer *multipart.Writer) error { return writer.WriteField(key, strconv.FormatFloat(v.Float(), 'f', -1, 64)) } default: return func(key string, v reflect.Value, writer *multipart.Writer) error { return fmt.Errorf("unknown type received at primitive encoder: %s", t.String()) } } } func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc { itemEncoder := e.typeEncoder(t.Elem()) keyFn := e.arrayKeyEncoder() return func(key string, v reflect.Value, writer *multipart.Writer) error { if keyFn == nil { return fmt.Errorf("apiform: unsupported array format") } for i := 0; i < v.Len(); i++ { err := itemEncoder(keyFn(key, i), v.Index(i), writer) if err != nil { return err } } return nil } } func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc { if t.Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) { return e.newRichFieldTypeEncoder(t) } for i := 0; i < t.NumField(); i++ { if t.Field(i).Type == paramUnionType && t.Field(i).Anonymous { return e.newStructUnionTypeEncoder(t) } } encoderFields := []encoderField{} extraEncoder := (*encoderField)(nil) // This helper allows us to recursively collect field encoders into a flat // array. The parameter `index` keeps track of the access patterns necessary // to get to some field. var collectEncoderFields func(r reflect.Type, index []int) collectEncoderFields = func(r reflect.Type, index []int) { for i := 0; i < r.NumField(); i++ { idx := append(index, i) field := t.FieldByIndex(idx) if !field.IsExported() { continue } // If this is an embedded struct, traverse one level deeper to extract // the field and get their encoders as well. if field.Anonymous { collectEncoderFields(field.Type, idx) continue } // If json tag is not present, then we skip, which is intentionally // different behavior from the stdlib. ptag, ok := parseFormStructTag(field) if !ok { continue } // We only want to support unexported field if they're tagged with // `extras` because that field shouldn't be part of the public API. We // also want to only keep the top level extras if ptag.extras && len(index) == 0 { extraEncoder = &encoderField{ptag, e.typeEncoder(field.Type.Elem()), idx} continue } if ptag.name == "-" || ptag.name == "" { continue } dateFormat, ok := parseFormatStructTag(field) oldFormat := e.dateFormat if ok { switch dateFormat { case "date-time": e.dateFormat = time.RFC3339 case "date": e.dateFormat = "2006-01-02" } } var encoderFn encoderFunc if ptag.omitzero { typeEncoderFn := e.typeEncoder(field.Type) encoderFn = func(key string, value reflect.Value, writer *multipart.Writer) error { if value.IsZero() { return nil } return typeEncoderFn(key, value, writer) } } else { encoderFn = e.typeEncoder(field.Type) } encoderFields = append(encoderFields, encoderField{ptag, encoderFn, idx}) e.dateFormat = oldFormat } } collectEncoderFields(t, []int{}) // Ensure deterministic output by sorting by lexicographic order sort.Slice(encoderFields, func(i, j int) bool { return encoderFields[i].tag.name < encoderFields[j].tag.name }) return func(key string, value reflect.Value, writer *multipart.Writer) error { keyFn := e.objKeyEncoder(key) for _, ef := range encoderFields { field := value.FieldByIndex(ef.idx) err := ef.fn(keyFn(ef.tag.name), field, writer) if err != nil { return err } } if extraEncoder != nil { err := e.encodeMapEntries(key, value.FieldByIndex(extraEncoder.idx), writer) if err != nil { return err } } return nil } } var paramUnionType = reflect.TypeOf((*param.APIUnion)(nil)).Elem() func (e *encoder) newStructUnionTypeEncoder(t reflect.Type) encoderFunc { var fieldEncoders []encoderFunc for i := 0; i < t.NumField(); i++ { field := t.Field(i) if field.Type == paramUnionType && field.Anonymous { fieldEncoders = append(fieldEncoders, nil) continue } fieldEncoders = append(fieldEncoders, e.typeEncoder(field.Type)) } return func(key string, value reflect.Value, writer *multipart.Writer) error { for i := 0; i < t.NumField(); i++ { if value.Field(i).Type() == paramUnionType { continue } if !value.Field(i).IsZero() { return fieldEncoders[i](key, value.Field(i), writer) } } return fmt.Errorf("apiform: union %s has no field set", t.String()) } } func (e *encoder) newTimeTypeEncoder() encoderFunc { format := e.dateFormat return func(key string, value reflect.Value, writer *multipart.Writer) error { return writer.WriteField(key, value.Convert(reflect.TypeOf(time.Time{})).Interface().(time.Time).Format(format)) } } func (e encoder) newInterfaceEncoder() encoderFunc { return func(key string, value reflect.Value, writer *multipart.Writer) error { value = value.Elem() if !value.IsValid() { return nil } return e.typeEncoder(value.Type())(key, value, writer) } } var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"") func escapeQuotes(s string) string { return quoteEscaper.Replace(s) } func (e *encoder) newReaderTypeEncoder() encoderFunc { return func(key string, value reflect.Value, writer *multipart.Writer) error { reader, ok := value.Convert(reflect.TypeOf((*io.Reader)(nil)).Elem()).Interface().(io.Reader) if !ok { return nil } filename := "anonymous_file" contentType := "application/octet-stream" if named, ok := reader.(interface{ Filename() string }); ok { filename = named.Filename() } else if named, ok := reader.(interface{ Name() string }); ok { filename = path.Base(named.Name()) } if typed, ok := reader.(interface{ ContentType() string }); ok { contentType = typed.ContentType() } // Below is taken almost 1-for-1 from [multipart.CreateFormFile] h := make(textproto.MIMEHeader) h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, escapeQuotes(key), escapeQuotes(filename))) h.Set("Content-Type", contentType) filewriter, err := writer.CreatePart(h) if err != nil { return err } _, err = io.Copy(filewriter, reader) return err } } 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 { type mapPair struct { key string value reflect.Value } pairs := []mapPair{} iter := v.MapRange() for iter.Next() { if iter.Key().Type().Kind() == reflect.String { pairs = append(pairs, mapPair{key: iter.Key().String(), value: iter.Value()}) } else { return fmt.Errorf("cannot encode a map with a non string key") } } // Ensure deterministic output sort.Slice(pairs, func(i, j int) bool { return pairs[i].key < pairs[j].key }) elementEncoder := e.typeEncoder(v.Type().Elem()) keyFn := e.objKeyEncoder(key) for _, p := range pairs { err := elementEncoder(keyFn(p.key), p.value, writer) if err != nil { return err } } return nil } func (e *encoder) newMapEncoder(_ reflect.Type) encoderFunc { return func(key string, value reflect.Value, writer *multipart.Writer) error { return e.encodeMapEntries(key, value, writer) } } func WriteExtras(writer *multipart.Writer, extras map[string]any) (err error) { for k, v := range extras { str, ok := v.(string) if !ok { break } err = writer.WriteField(k, str) if err != nil { break } } return err } ================================================ FILE: internal/apiform/form.go ================================================ package apiform type Marshaler interface { MarshalMultipart() ([]byte, string, error) } ================================================ FILE: internal/apiform/form_test.go ================================================ package apiform import ( "bytes" "github.com/anthropics/anthropic-sdk-go/packages/param" "io" "mime/multipart" "strings" "testing" "time" ) func P[T any](v T) *T { return &v } type Primitives struct { A bool `form:"a"` B int `form:"b"` C uint `form:"c"` D float64 `form:"d"` E float32 `form:"e"` F []int `form:"f"` } // These aliases are necessary to bypass the cache. // This only relevant during testing. type int_ int type PrimitivesBrackets struct { F []int_ `form:"f"` } type PrimitivePointers struct { A *bool `form:"a"` B *int `form:"b"` C *uint `form:"c"` D *float64 `form:"d"` E *float32 `form:"e"` F *[]int `form:"f"` } type Slices struct { Slice []Primitives `form:"slices"` } type DateTime struct { Date time.Time `form:"date" format:"date"` DateTime time.Time `form:"date-time" format:"date-time"` } type AdditionalProperties struct { A bool `form:"a"` Extras map[string]any `form:"-" api:"extrafields"` } type TypedAdditionalProperties struct { A bool `form:"a"` Extras map[string]int `form:"-" api:"extrafields"` } type EmbeddedStructs struct { AdditionalProperties A *int `form:"number2"` Extras map[string]any `form:"-" api:"extrafields"` } type Recursive struct { Name string `form:"name"` Child *Recursive `form:"child"` } type UnknownStruct struct { Unknown any `form:"unknown"` } type UnionStruct struct { Union Union `form:"union" format:"date"` } type Union interface { union() } type UnionInteger int64 func (UnionInteger) union() {} type UnionStructA struct { Type string `form:"type"` A string `form:"a"` B string `form:"b"` } func (UnionStructA) union() {} type UnionStructB struct { Type string `form:"type"` A string `form:"a"` } func (UnionStructB) union() {} type UnionTime time.Time func (UnionTime) union() {} type ReaderStruct struct { File io.Reader `form:"file"` } type NamedEnum string const NamedEnumFoo NamedEnum = "foo" type StructUnionWrapper struct { Union StructUnion `form:"union"` } type StructUnion struct { OfInt param.Opt[int64] `form:",omitzero,inline"` OfString param.Opt[string] `form:",omitzero,inline"` OfEnum param.Opt[NamedEnum] `form:",omitzero,inline"` OfA UnionStructA `form:",omitzero,inline"` OfB UnionStructB `form:",omitzero,inline"` 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 }{ "file": { buf: `--xxx Content-Disposition: form-data; name="file"; filename="anonymous_file" Content-Type: application/octet-stream some file contents... --xxx-- `, val: ReaderStruct{ File: io.Reader(bytes.NewBuffer([]byte("some file contents..."))), }, }, "map_string": { `--xxx Content-Disposition: form-data; name="foo" bar --xxx-- `, map[string]string{"foo": "bar"}, }, "map_interface": { `--xxx Content-Disposition: form-data; name="a" 1 --xxx Content-Disposition: form-data; name="b" str --xxx Content-Disposition: form-data; name="c" false --xxx-- `, map[string]any{"a": float64(1), "b": "str", "c": false}, }, "primitive_struct": { `--xxx Content-Disposition: form-data; name="a" false --xxx Content-Disposition: form-data; name="b" 237628372683 --xxx Content-Disposition: form-data; name="c" 654 --xxx Content-Disposition: form-data; name="d" 9999.43 --xxx Content-Disposition: form-data; name="e" 43.76 --xxx Content-Disposition: form-data; name="f.0" 1 --xxx Content-Disposition: form-data; name="f.1" 2 --xxx Content-Disposition: form-data; name="f.2" 3 --xxx Content-Disposition: form-data; name="f.3" 4 --xxx-- `, Primitives{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}, }, "primitive_struct,brackets": { `--xxx Content-Disposition: form-data; name="f[]" 1 --xxx Content-Disposition: form-data; name="f[]" 2 --xxx Content-Disposition: form-data; name="f[]" 3 --xxx Content-Disposition: form-data; name="f[]" 4 --xxx-- `, PrimitivesBrackets{F: []int_{1, 2, 3, 4}}, }, "slices": { `--xxx Content-Disposition: form-data; name="slices.0.a" false --xxx Content-Disposition: form-data; name="slices.0.b" 237628372683 --xxx Content-Disposition: form-data; name="slices.0.c" 654 --xxx Content-Disposition: form-data; name="slices.0.d" 9999.43 --xxx Content-Disposition: form-data; name="slices.0.e" 43.76 --xxx Content-Disposition: form-data; name="slices.0.f.0" 1 --xxx Content-Disposition: form-data; name="slices.0.f.1" 2 --xxx Content-Disposition: form-data; name="slices.0.f.2" 3 --xxx Content-Disposition: form-data; name="slices.0.f.3" 4 --xxx-- `, Slices{ Slice: []Primitives{{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}}, }, }, "primitive_pointer_struct": { `--xxx Content-Disposition: form-data; name="a" false --xxx Content-Disposition: form-data; name="b" 237628372683 --xxx Content-Disposition: form-data; name="c" 654 --xxx Content-Disposition: form-data; name="d" 9999.43 --xxx Content-Disposition: form-data; name="e" 43.76 --xxx Content-Disposition: form-data; name="f.0" 1 --xxx Content-Disposition: form-data; name="f.1" 2 --xxx Content-Disposition: form-data; name="f.2" 3 --xxx Content-Disposition: form-data; name="f.3" 4 --xxx Content-Disposition: form-data; name="f.4" 5 --xxx-- `, PrimitivePointers{ A: P(false), B: P(237628372683), C: P(uint(654)), D: P(9999.43), E: P(float32(43.76)), F: &[]int{1, 2, 3, 4, 5}, }, }, "datetime_struct": { `--xxx Content-Disposition: form-data; name="date" 2006-01-02 --xxx Content-Disposition: form-data; name="date-time" 2006-01-02T15:04:05Z --xxx-- `, DateTime{ Date: time.Date(2006, time.January, 2, 0, 0, 0, 0, time.UTC), DateTime: time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC), }, }, "additional_properties": { `--xxx Content-Disposition: form-data; name="a" true --xxx Content-Disposition: form-data; name="bar" value --xxx Content-Disposition: form-data; name="foo" true --xxx-- `, AdditionalProperties{ A: true, Extras: map[string]any{ "bar": "value", "foo": 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 Content-Disposition: form-data; name="child.name" Alex --xxx Content-Disposition: form-data; name="name" Robert --xxx-- `, Recursive{Name: "Robert", Child: &Recursive{Name: "Alex"}}, }, "unknown_struct_number": { `--xxx Content-Disposition: form-data; name="unknown" 12 --xxx-- `, UnknownStruct{ Unknown: 12., }, }, "unknown_struct_map": { `--xxx Content-Disposition: form-data; name="unknown.foo" bar --xxx-- `, UnknownStruct{ Unknown: map[string]any{ "foo": "bar", }, }, }, "struct_union_integer": { `--xxx Content-Disposition: form-data; name="union" 12 --xxx-- `, StructUnionWrapper{ Union: StructUnion{OfInt: param.NewOpt[int64](12)}, }, }, "union_integer": { `--xxx Content-Disposition: form-data; name="union" 12 --xxx-- `, UnionStruct{ Union: UnionInteger(12), }, }, "struct_union_struct_discriminated_a": { `--xxx Content-Disposition: form-data; name="union.a" foo --xxx Content-Disposition: form-data; name="union.b" bar --xxx Content-Disposition: form-data; name="union.type" typeA --xxx-- `, StructUnionWrapper{ Union: StructUnion{OfA: UnionStructA{ Type: "typeA", A: "foo", B: "bar", }}, }, }, "union_struct_discriminated_a": { `--xxx Content-Disposition: form-data; name="union.a" foo --xxx Content-Disposition: form-data; name="union.b" bar --xxx Content-Disposition: form-data; name="union.type" typeA --xxx-- `, UnionStruct{ Union: UnionStructA{ Type: "typeA", A: "foo", B: "bar", }, }, }, "struct_union_struct_discriminated_b": { `--xxx Content-Disposition: form-data; name="union.a" foo --xxx Content-Disposition: form-data; name="union.type" typeB --xxx-- `, StructUnionWrapper{ Union: StructUnion{OfB: UnionStructB{ Type: "typeB", A: "foo", }}, }, }, "union_struct_discriminated_b": { `--xxx Content-Disposition: form-data; name="union.a" foo --xxx Content-Disposition: form-data; name="union.type" typeB --xxx-- `, UnionStruct{ Union: UnionStructB{ Type: "typeB", A: "foo", }, }, }, "union_struct_time": { `--xxx Content-Disposition: form-data; name="union" 2010-05-23 --xxx-- `, UnionStruct{ Union: UnionTime(time.Date(2010, 05, 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) { for name, test := range tests { t.Run(name, func(t *testing.T) { buf := bytes.NewBuffer(nil) writer := multipart.NewWriter(buf) err := writer.SetBoundary("xxx") if err != nil { t.Errorf("setting boundary for %v failed with error %v", test.val, err) } arrayFmt := "indices:dots" if tags := strings.Split(name, ","); len(tags) > 1 { arrayFmt = tags[1] } err = MarshalWithSettings(test.val, writer, arrayFmt) if err != nil { t.Errorf("serialization of %v failed with error %v", test.val, err) } err = writer.Close() if err != nil { t.Errorf("serialization of %v failed with error %v", test.val, err) } raw := buf.Bytes() if string(raw) != strings.ReplaceAll(test.buf, "\n", "\r\n") { t.Errorf("expected %+#v to serialize to '%s' but got '%s' (with format %s)", test.val, test.buf, string(raw), arrayFmt) } }) } } ================================================ FILE: internal/apiform/richparam.go ================================================ package apiform import ( "github.com/anthropics/anthropic-sdk-go/packages/param" "mime/multipart" "reflect" ) func (e *encoder) newRichFieldTypeEncoder(t reflect.Type) encoderFunc { f, _ := t.FieldByName("Value") enc := e.newPrimitiveTypeEncoder(f.Type) return func(key string, value reflect.Value, writer *multipart.Writer) error { if opt, ok := value.Interface().(param.Optional); ok && opt.Valid() { return enc(key, value.FieldByIndex(f.Index), writer) } else if ok && param.IsNull(opt) { return writer.WriteField(key, "null") } return nil } } ================================================ FILE: internal/apiform/tag.go ================================================ package apiform import ( "reflect" "strings" ) const apiStructTag = "api" const jsonStructTag = "json" const formStructTag = "form" const formatStructTag = "format" type parsedStructTag struct { name string required bool extras bool metadata bool omitzero bool } func parseFormStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) { raw, ok := field.Tag.Lookup(formStructTag) if !ok { raw, ok = field.Tag.Lookup(jsonStructTag) } if !ok { return tag, ok } parts := strings.Split(raw, ",") if len(parts) == 0 { return tag, false } tag.name = parts[0] for _, part := range parts[1:] { switch part { case "required": tag.required = true case "extras": tag.extras = true case "metadata": tag.metadata = true case "omitzero": tag.omitzero = true } } parseApiStructTag(field, &tag) return tag, ok } func parseApiStructTag(field reflect.StructField, tag *parsedStructTag) { raw, ok := field.Tag.Lookup(apiStructTag) if !ok { return } parts := strings.Split(raw, ",") for _, part := range parts { switch part { case "extrafields": tag.extras = true case "required": tag.required = true case "metadata": tag.metadata = true } } } func parseFormatStructTag(field reflect.StructField) (format string, ok bool) { format, ok = field.Tag.Lookup(formatStructTag) return format, ok } ================================================ FILE: internal/apijson/decodeparam_test.go ================================================ package apijson_test import ( "encoding/json" "fmt" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/packages/param" "reflect" "testing" ) func TestOptionalDecoders(t *testing.T) { cases := map[string]struct { buf string val any }{ "opt_string_present": { `"hello"`, param.NewOpt("hello"), }, "opt_string_empty_present": { `""`, param.NewOpt(""), }, "opt_string_null": { `null`, param.Null[string](), }, "opt_string_null_with_whitespace": { ` null `, param.Null[string](), }, } for name, test := range cases { t.Run(name, func(t *testing.T) { result := reflect.New(reflect.TypeOf(test.val)) if err := json.Unmarshal([]byte(test.buf), result.Interface()); err != nil { t.Fatalf("deserialization of %v failed with error %v", result, err) } if !reflect.DeepEqual(result.Elem().Interface(), test.val) { t.Fatalf("expected '%s' to deserialize to \n%#v\nbut got\n%#v", test.buf, test.val, result.Elem().Interface()) } }) } } type paramObject = param.APIObject type BasicObject struct { ReqInt int64 `json:"req_int" api:"required"` ReqFloat float64 `json:"req_float" api:"required"` ReqString string `json:"req_string" api:"required"` ReqBool bool `json:"req_bool" api:"required"` OptInt param.Opt[int64] `json:"opt_int"` OptFloat param.Opt[float64] `json:"opt_float"` OptString param.Opt[string] `json:"opt_string"` OptBool param.Opt[bool] `json:"opt_bool"` paramObject } func (o *BasicObject) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, o) } func TestBasicObjectWithNull(t *testing.T) { raw := `{"opt_int":null,"opt_string":null,"opt_bool":null}` var dst BasicObject target := BasicObject{ OptInt: param.Null[int64](), // OptFloat: param.Opt[float64]{}, OptString: param.Null[string](), OptBool: param.Null[bool](), } err := json.Unmarshal([]byte(raw), &dst) if err != nil { t.Fatalf("failed unmarshal") } if !reflect.DeepEqual(dst, target) { t.Fatalf("failed equality check %#v", dst) } } func TestBasicObject(t *testing.T) { raw := `{"req_int":1,"req_float":1.3,"req_string":"test","req_bool":true,"opt_int":2,"opt_float":2.0,"opt_string":"test","opt_bool":false}` var dst BasicObject target := BasicObject{ ReqInt: 1, ReqFloat: 1.3, ReqString: "test", ReqBool: true, OptInt: param.NewOpt[int64](2), OptFloat: param.NewOpt(2.0), OptString: param.NewOpt("test"), OptBool: param.NewOpt(false), } err := json.Unmarshal([]byte(raw), &dst) if err != nil { t.Fatalf("failed unmarshal") } if !reflect.DeepEqual(dst, target) { t.Fatalf("failed equality check %#v", dst) } } type ComplexObject struct { Basic BasicObject `json:"basic" api:"required"` Enum string `json:"enum"` paramObject } func (o *ComplexObject) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, o) } func init() { apijson.RegisterFieldValidator[ComplexObject]("enum", "a", "b", "c") } func TestComplexObject(t *testing.T) { raw := `{"basic":{"req_int":1,"req_float":1.3,"req_string":"test","req_bool":true,"opt_int":2,"opt_float":2.0,"opt_string":"test","opt_bool":false},"enum":"a"}` var dst ComplexObject target := ComplexObject{ Basic: BasicObject{ ReqInt: 1, ReqFloat: 1.3, ReqString: "test", ReqBool: true, OptInt: param.NewOpt[int64](2), OptFloat: param.NewOpt(2.0), OptString: param.NewOpt("test"), OptBool: param.NewOpt(false), }, Enum: "a", } err := json.Unmarshal([]byte(raw), &dst) if err != nil { t.Fatalf("failed unmarshal") } if !reflect.DeepEqual(dst, target) { t.Fatalf("failed equality check %#v", dst) } } type paramUnion = param.APIUnion type MemberA struct { Name string `json:"name" api:"required"` Age int `json:"age" api:"required"` } type MemberB struct { Name string `json:"name" api:"required"` Age string `json:"age" api:"required"` } type MemberC struct { Name string `json:"name" api:"required"` Age int `json:"age" api:"required"` Status string `json:"status"` } type MemberD struct { Cost int `json:"cost" api:"required"` Status string `json:"status" api:"required"` } type MemberE struct { Cost int `json:"cost" api:"required"` Status string `json:"status" api:"required"` } type MemberF struct { D int `json:"d"` E string `json:"e"` F float64 `json:"f"` G param.Opt[int] `json:"g"` } type MemberG struct { D int `json:"d"` E string `json:"e"` F float64 `json:"f"` G param.Opt[bool] `json:"g"` } func init() { apijson.RegisterFieldValidator[MemberD]("status", "good", "ok", "bad") apijson.RegisterFieldValidator[MemberE]("status", "GOOD", "OK", "BAD") } type UnionStruct struct { OfMemberA *MemberA `json:",inline"` OfMemberB *MemberB `json:",inline"` OfMemberC *MemberC `json:",inline"` OfMemberD *MemberD `json:",inline"` OfMemberE *MemberE `json:",inline"` OfMemberF *MemberF `json:",inline"` OfMemberG *MemberG `json:",inline"` OfString param.Opt[string] `json:",inline"` paramUnion } func (union *UnionStruct) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, union) } func TestUnionStruct(t *testing.T) { tests := map[string]struct { raw string target UnionStruct shouldFail bool }{ "fail": { raw: `1200`, target: UnionStruct{}, shouldFail: true, }, "easy": { raw: `{"age":30}`, target: UnionStruct{OfMemberA: &MemberA{Age: 30}}, }, "less-easy": { raw: `{"age":"thirty"}`, target: UnionStruct{OfMemberB: &MemberB{Age: "thirty"}}, }, "even-less-easy": { raw: `{"age":"30"}`, target: UnionStruct{OfMemberB: &MemberB{Age: "30"}}, }, "medium": { raw: `{"name":"jacob","age":30}`, target: UnionStruct{OfMemberA: &MemberA{ Age: 30, Name: "jacob", }}, }, "less-medium": { raw: `{"name":"jacob","age":"thirty"}`, target: UnionStruct{OfMemberB: &MemberB{ Age: "thirty", Name: "jacob", }}, }, "even-less-medium": { raw: `{"name":"jacob","age":"30"}`, target: UnionStruct{OfMemberB: &MemberB{ Name: "jacob", Age: "30", }}, }, "hard": { raw: `{"name":"jacob","age":30,"status":"active"}`, target: UnionStruct{OfMemberC: &MemberC{ Name: "jacob", Age: 30, Status: "active", }}, }, "inline-string": { raw: `"hello there"`, target: UnionStruct{OfString: param.NewOpt("hello there")}, }, "enum-field": { raw: `{"cost":100,"status":"ok"}`, target: UnionStruct{OfMemberD: &MemberD{Cost: 100, Status: "ok"}}, }, "other-enum-field": { raw: `{"cost":100,"status":"GOOD"}`, target: UnionStruct{OfMemberE: &MemberE{Cost: 100, Status: "GOOD"}}, }, "tricky-extra-fields": { raw: `{"d":12,"e":"hello","f":1.00}`, target: UnionStruct{OfMemberF: &MemberF{D: 12, E: "hello", F: 1.00}}, }, "optional-fields": { raw: `{"d":12,"e":"hello","f":1.00,"g":12}`, target: UnionStruct{OfMemberF: &MemberF{D: 12, E: "hello", F: 1.00, G: param.NewOpt(12)}}, }, "optional-fields-2": { raw: `{"d":12,"e":"hello","f":1.00,"g":false}`, target: UnionStruct{OfMemberG: &MemberG{D: 12, E: "hello", F: 1.00, G: param.NewOpt(false)}}, }, } for name, test := range tests { var dst UnionStruct t.Run(name, func(t *testing.T) { err := json.Unmarshal([]byte(test.raw), &dst) if err != nil && !test.shouldFail { t.Fatalf("failed unmarshal with err: %v %#v", err, dst) } if !reflect.DeepEqual(dst, test.target) { if dst.OfMemberA != nil { fmt.Printf("%#v", dst.OfMemberA) } t.Fatalf("failed equality, got %#v but expected %#v", dst, test.target) } }) } } type ConstantA string type ConstantB string type ConstantC string func (c ConstantA) Default() string { return "A" } func (c ConstantB) Default() string { return "B" } func (c ConstantC) Default() string { return "C" } type DiscVariantA struct { Name string `json:"name" api:"required"` Age int `json:"age" api:"required"` Type ConstantA `json:"type" api:"required"` } type DiscVariantB struct { Name string `json:"name" api:"required"` Age int `json:"age" api:"required"` Type ConstantB `json:"type" api:"required"` } type DiscVariantC struct { Name string `json:"name" api:"required"` Age float64 `json:"age" api:"required"` Type ConstantC `json:"type" api:"required"` } type DiscriminatedUnion struct { OfA *DiscVariantA `json:",inline"` OfB *DiscVariantB `json:",inline"` OfC *DiscVariantC `json:",inline"` paramUnion } func init() { apijson.RegisterDiscriminatedUnion[DiscriminatedUnion]("type", map[string]reflect.Type{ "A": reflect.TypeOf(DiscVariantA{}), "B": reflect.TypeOf(DiscVariantB{}), "C": reflect.TypeOf(DiscVariantC{}), }) } type FooVariant struct { Type string `json:"type" api:"required"` Value string `json:"value" api:"required"` } type BarVariant struct { Type string `json:"type" api:"required"` Enable bool `json:"enable" api:"required"` } type MultiDiscriminatorUnion struct { OfFoo *FooVariant `json:",inline"` OfBar *BarVariant `json:",inline"` paramUnion } func init() { apijson.RegisterDiscriminatedUnion[MultiDiscriminatorUnion]("type", map[string]reflect.Type{ "foo": reflect.TypeOf(FooVariant{}), "foo_v2": reflect.TypeOf(FooVariant{}), "bar": reflect.TypeOf(BarVariant{}), "bar_legacy": reflect.TypeOf(BarVariant{}), }) } func (m *MultiDiscriminatorUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, m) } func (d *DiscriminatedUnion) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, d) } func TestDiscriminatedUnion(t *testing.T) { tests := map[string]struct { raw string target DiscriminatedUnion shouldFail bool }{ "variant_a": { raw: `{"name":"Alice","age":25,"type":"A"}`, target: DiscriminatedUnion{OfA: &DiscVariantA{ Name: "Alice", Age: 25, Type: "A", }}, }, "variant_b": { raw: `{"name":"Bob","age":30,"type":"B"}`, target: DiscriminatedUnion{OfB: &DiscVariantB{ Name: "Bob", Age: 30, Type: "B", }}, }, "variant_c": { raw: `{"name":"Charlie","age":35.5,"type":"C"}`, target: DiscriminatedUnion{OfC: &DiscVariantC{ Name: "Charlie", Age: 35.5, Type: "C", }}, }, "invalid_type": { raw: `{"name":"Unknown","age":40,"type":"D"}`, target: DiscriminatedUnion{}, shouldFail: true, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { var dst DiscriminatedUnion err := json.Unmarshal([]byte(test.raw), &dst) if err != nil && !test.shouldFail { t.Fatalf("failed unmarshal with err: %v", err) } if err == nil && test.shouldFail { t.Fatalf("expected unmarshal to fail but it succeeded") } if !reflect.DeepEqual(dst, test.target) { t.Fatalf("failed equality, got %#v but expected %#v", dst, test.target) } }) } } func TestMultiDiscriminatorUnion(t *testing.T) { tests := map[string]struct { raw string target MultiDiscriminatorUnion shouldFail bool }{ "foo_variant": { raw: `{"type":"foo","value":"test"}`, target: MultiDiscriminatorUnion{OfFoo: &FooVariant{ Type: "foo", Value: "test", }}, }, "foo_v2_variant": { raw: `{"type":"foo_v2","value":"test_v2"}`, target: MultiDiscriminatorUnion{OfFoo: &FooVariant{ Type: "foo_v2", Value: "test_v2", }}, }, "bar_variant": { raw: `{"type":"bar","enable":true}`, target: MultiDiscriminatorUnion{OfBar: &BarVariant{ Type: "bar", Enable: true, }}, }, "bar_legacy_variant": { raw: `{"type":"bar_legacy","enable":false}`, target: MultiDiscriminatorUnion{OfBar: &BarVariant{ Type: "bar_legacy", Enable: false, }}, }, "invalid_type": { raw: `{"type":"unknown","value":"test"}`, target: MultiDiscriminatorUnion{}, shouldFail: true, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { var dst MultiDiscriminatorUnion err := json.Unmarshal([]byte(test.raw), &dst) if err != nil && !test.shouldFail { t.Fatalf("failed unmarshal with err: %v", err) } if err == nil && test.shouldFail { t.Fatalf("expected unmarshal to fail but it succeeded") } if !reflect.DeepEqual(dst, test.target) { t.Fatalf("failed equality, got %#v but expected %#v", dst, test.target) } }) } } ================================================ FILE: internal/apijson/decoder.go ================================================ // The deserialization algorithm from apijson may be subject to improvements // between minor versions, particularly with respect to calling [json.Unmarshal] // into param unions. package apijson import ( "encoding/json" "fmt" "github.com/anthropics/anthropic-sdk-go/packages/param" "reflect" "strconv" "sync" "time" "unsafe" "github.com/tidwall/gjson" ) // decoders is a synchronized map with roughly the following type: // map[reflect.Type]decoderFunc var decoders sync.Map // Unmarshal is similar to [encoding/json.Unmarshal] and parses the JSON-encoded // data and stores it in the given pointer. func Unmarshal(raw []byte, to any) error { d := &decoderBuilder{dateFormat: time.RFC3339} return d.unmarshal(raw, to) } // UnmarshalRoot is like Unmarshal, but doesn't try to call MarshalJSON on the // root element. Useful if a struct's UnmarshalJSON is overrode to use the // behavior of this encoder versus the standard library. func UnmarshalRoot(raw []byte, to any) error { d := &decoderBuilder{dateFormat: time.RFC3339, root: true} return d.unmarshal(raw, to) } // decoderBuilder contains the 'compile-time' state of the decoder. type decoderBuilder struct { // Whether or not this is the first element and called by [UnmarshalRoot], see // the documentation there to see why this is necessary. root bool // The dateFormat (a format string for [time.Format]) which is chosen by the // last struct tag that was seen. dateFormat string } // decoderState contains the 'run-time' state of the decoder. type decoderState struct { strict bool exactness exactness validator *validationEntry } // Exactness refers to how close to the type the result was if deserialization // was successful. This is useful in deserializing unions, where you want to try // each entry, first with strict, then with looser validation, without actually // having to do a lot of redundant work by marshalling twice (or maybe even more // times). type exactness int8 const ( // Some values had to fudged a bit, for example by converting a string to an // int, or an enum with extra values. loose exactness = iota // There are some extra arguments, but other wise it matches the union. extras // Exactly right. exact ) type decoderFunc func(node gjson.Result, value reflect.Value, state *decoderState) error type decoderField struct { tag parsedStructTag fn decoderFunc idx []int goname string } type decoderEntry struct { reflect.Type dateFormat string root bool } func (d *decoderBuilder) unmarshal(raw []byte, to any) error { value := reflect.ValueOf(to).Elem() result := gjson.ParseBytes(raw) if !value.IsValid() { return fmt.Errorf("apijson: cannot marshal into invalid value") } return d.typeDecoder(value.Type())(result, value, &decoderState{strict: false, exactness: exact}) } // unmarshalWithExactness is used for internal testing purposes. func (d *decoderBuilder) unmarshalWithExactness(raw []byte, to any) (exactness, error) { value := reflect.ValueOf(to).Elem() result := gjson.ParseBytes(raw) if !value.IsValid() { return 0, fmt.Errorf("apijson: cannot marshal into invalid value") } state := decoderState{strict: false, exactness: exact} err := d.typeDecoder(value.Type())(result, value, &state) return state.exactness, err } func (d *decoderBuilder) typeDecoder(t reflect.Type) decoderFunc { entry := decoderEntry{ Type: t, dateFormat: d.dateFormat, root: d.root, } if fi, ok := decoders.Load(entry); ok { return fi.(decoderFunc) } // To deal with recursive types, populate the map with an // indirect func before we build it. This type waits on the // real func (f) to be ready and then calls it. This indirect // func is only used for recursive types. var ( wg sync.WaitGroup f decoderFunc ) wg.Add(1) fi, loaded := decoders.LoadOrStore(entry, decoderFunc(func(node gjson.Result, v reflect.Value, state *decoderState) error { wg.Wait() return f(node, v, state) })) if loaded { return fi.(decoderFunc) } // Compute the real decoder and replace the indirect func with it. f = d.newTypeDecoder(t) wg.Done() decoders.Store(entry, f) return f } // validatedTypeDecoder wraps the type decoder with a validator. This is helpful // for ensuring that enum fields are correct. func (d *decoderBuilder) validatedTypeDecoder(t reflect.Type, entry *validationEntry) decoderFunc { dec := d.typeDecoder(t) if entry == nil { return dec } // Thread the current validation entry through the decoder, // but clean up in time for the next field. return func(node gjson.Result, v reflect.Value, state *decoderState) error { state.validator = entry err := dec(node, v, state) state.validator = nil return err } } func indirectUnmarshalerDecoder(n gjson.Result, v reflect.Value, state *decoderState) error { return v.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(n.Raw)) } func unmarshalerDecoder(n gjson.Result, v reflect.Value, state *decoderState) error { if v.Kind() == reflect.Pointer && v.CanSet() { v.Set(reflect.New(v.Type().Elem())) } return v.Interface().(json.Unmarshaler).UnmarshalJSON([]byte(n.Raw)) } func (d *decoderBuilder) newTypeDecoder(t reflect.Type) decoderFunc { // Check for custom decoders first if customDecoder, ok := customDecoderRegistry[t]; ok { // Create the default decoder for this type (without the custom decoder) defaultDecoder := d.newDefaultTypeDecoder(t) return func(node gjson.Result, value reflect.Value, state *decoderState) error { // Provide a wrapper that removes the state parameter for the custom decoder defaultWrapper := func(node gjson.Result, value reflect.Value) error { return defaultDecoder(node, value, state) } return customDecoder(node, value, defaultWrapper) } } return d.newDefaultTypeDecoder(t) } func (d *decoderBuilder) newDefaultTypeDecoder(t reflect.Type) decoderFunc { if t.ConvertibleTo(reflect.TypeOf(time.Time{})) { return d.newTimeTypeDecoder(t) } if t.Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) { return d.newOptTypeDecoder(t) } if !d.root && t.Implements(reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()) { return unmarshalerDecoder } if !d.root && reflect.PointerTo(t).Implements(reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()) { if _, ok := unionVariants[t]; !ok { return indirectUnmarshalerDecoder } } d.root = false if _, ok := unionRegistry[t]; ok { if isStructUnion(t) { return d.newStructUnionDecoder(t) } return d.newUnionDecoder(t) } switch t.Kind() { case reflect.Pointer: inner := t.Elem() innerDecoder := d.typeDecoder(inner) return func(n gjson.Result, v reflect.Value, state *decoderState) error { if !v.IsValid() { return fmt.Errorf("apijson: unexpected invalid reflection value %+#v", v) } newValue := reflect.New(inner).Elem() err := innerDecoder(n, newValue, state) if err != nil { return err } v.Set(newValue.Addr()) return nil } case reflect.Struct: if isStructUnion(t) { return d.newStructUnionDecoder(t) } return d.newStructTypeDecoder(t) case reflect.Array: fallthrough case reflect.Slice: return d.newArrayTypeDecoder(t) case reflect.Map: return d.newMapDecoder(t) case reflect.Interface: return func(node gjson.Result, value reflect.Value, state *decoderState) error { if !value.IsValid() { return fmt.Errorf("apijson: unexpected invalid value %+#v", value) } if node.Value() != nil && value.CanSet() { value.Set(reflect.ValueOf(node.Value())) } return nil } default: return d.newPrimitiveTypeDecoder(t) } } func (d *decoderBuilder) newMapDecoder(t reflect.Type) decoderFunc { keyType := t.Key() itemType := t.Elem() itemDecoder := d.typeDecoder(itemType) return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) { mapValue := reflect.MakeMapWithSize(t, len(node.Map())) node.ForEach(func(key, value gjson.Result) bool { // It's fine for us to just use `ValueOf` here because the key types will // always be primitive types so we don't need to decode it using the standard pattern keyValue := reflect.ValueOf(key.Value()) if !keyValue.IsValid() { if err == nil { err = fmt.Errorf("apijson: received invalid key type %v", keyValue.String()) } return false } if keyValue.Type() != keyType { if err == nil { err = fmt.Errorf("apijson: expected key type %v but got %v", keyType, keyValue.Type()) } return false } itemValue := reflect.New(itemType).Elem() itemerr := itemDecoder(value, itemValue, state) if itemerr != nil { if err == nil { err = itemerr } return false } mapValue.SetMapIndex(keyValue, itemValue) return true }) if err != nil { return err } value.Set(mapValue) return nil } } func (d *decoderBuilder) newArrayTypeDecoder(t reflect.Type) decoderFunc { itemDecoder := d.typeDecoder(t.Elem()) return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) { if !node.IsArray() { return fmt.Errorf("apijson: could not deserialize to an array") } arrayNode := node.Array() arrayValue := reflect.MakeSlice(reflect.SliceOf(t.Elem()), len(arrayNode), len(arrayNode)) for i, itemNode := range arrayNode { err = itemDecoder(itemNode, arrayValue.Index(i), state) if err != nil { return err } } value.Set(arrayValue) return nil } } func (d *decoderBuilder) newStructTypeDecoder(t reflect.Type) decoderFunc { // map of json field name to struct field decoders decoderFields := map[string]decoderField{} anonymousDecoders := []decoderField{} extraDecoder := (*decoderField)(nil) var inlineDecoders []decoderField validationEntries := validationRegistry[t] for i := 0; i < t.NumField(); i++ { idx := []int{i} field := t.FieldByIndex(idx) if !field.IsExported() { continue } var validator *validationEntry for _, entry := range validationEntries { if entry.field.Offset == field.Offset { validator = &entry break } } // If this is an embedded struct, traverse one level deeper to extract // the fields and get their encoders as well. if field.Anonymous { anonymousDecoders = append(anonymousDecoders, decoderField{ fn: d.typeDecoder(field.Type), idx: idx[:], }) continue } // If json tag is not present, then we skip, which is intentionally // different behavior from the stdlib. ptag, ok := parseJSONStructTag(field) if !ok { continue } // We only want to support unexported fields if they're tagged with // `extras` because that field shouldn't be part of the public API. if ptag.extras { extraDecoder = &decoderField{ptag, d.typeDecoder(field.Type.Elem()), idx, field.Name} continue } if ptag.inline { df := decoderField{ptag, d.typeDecoder(field.Type), idx, field.Name} inlineDecoders = append(inlineDecoders, df) continue } if ptag.metadata { continue } oldFormat := d.dateFormat dateFormat, ok := parseFormatStructTag(field) if ok { switch dateFormat { case "date-time": d.dateFormat = time.RFC3339 case "date": d.dateFormat = "2006-01-02" } } decoderFields[ptag.name] = decoderField{ ptag, d.validatedTypeDecoder(field.Type, validator), idx, field.Name, } d.dateFormat = oldFormat } return func(node gjson.Result, value reflect.Value, state *decoderState) (err error) { if field := value.FieldByName("JSON"); field.IsValid() { if raw := field.FieldByName("raw"); raw.IsValid() { setUnexportedField(raw, node.Raw) } } for _, decoder := range anonymousDecoders { // ignore errors _ = decoder.fn(node, value.FieldByIndex(decoder.idx), state) } for _, inlineDecoder := range inlineDecoders { var meta Field dest := value.FieldByIndex(inlineDecoder.idx) isValid := false if dest.IsValid() && node.Type != gjson.Null { inlineState := decoderState{exactness: state.exactness, strict: true} err = inlineDecoder.fn(node, dest, &inlineState) if err == nil { isValid = true } } if node.Type == gjson.Null { meta = Field{ raw: node.Raw, status: null, } } else if !isValid { // If an inline decoder fails, unset the field and move on. if dest.IsValid() { dest.SetZero() } continue } else if isValid { meta = Field{ raw: node.Raw, status: valid, } } setMetadataSubField(value, inlineDecoder.idx, inlineDecoder.goname, meta) } typedExtraType := reflect.Type(nil) typedExtraFields := reflect.Value{} if extraDecoder != nil { typedExtraType = value.FieldByIndex(extraDecoder.idx).Type() typedExtraFields = reflect.MakeMap(typedExtraType) } untypedExtraFields := map[string]Field{} for fieldName, itemNode := range node.Map() { df, explicit := decoderFields[fieldName] var ( dest reflect.Value fn decoderFunc meta Field ) if explicit { fn = df.fn dest = value.FieldByIndex(df.idx) } if !explicit && extraDecoder != nil { dest = reflect.New(typedExtraType.Elem()).Elem() fn = extraDecoder.fn } isValid := false if dest.IsValid() && itemNode.Type != gjson.Null { err = fn(itemNode, dest, state) if err == nil { isValid = true } } // Handle null [param.Opt] if itemNode.Type == gjson.Null && dest.IsValid() && dest.Type().Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) { _ = dest.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(itemNode.Raw)) continue } if itemNode.Type == gjson.Null { meta = Field{ raw: itemNode.Raw, status: null, } } else if !isValid { meta = Field{ raw: itemNode.Raw, status: invalid, } } else if isValid { meta = Field{ raw: itemNode.Raw, status: valid, } } if explicit { setMetadataSubField(value, df.idx, df.goname, meta) } if !explicit { untypedExtraFields[fieldName] = meta } if !explicit && extraDecoder != nil { typedExtraFields.SetMapIndex(reflect.ValueOf(fieldName), dest) } } if extraDecoder != nil && typedExtraFields.Len() > 0 { value.FieldByIndex(extraDecoder.idx).Set(typedExtraFields) } // Set exactness to 'extras' if there are untyped, extra fields. if len(untypedExtraFields) > 0 && state.exactness > extras { state.exactness = extras } if len(untypedExtraFields) > 0 { setMetadataExtraFields(value, []int{-1}, "ExtraFields", untypedExtraFields) } return nil } } func (d *decoderBuilder) newPrimitiveTypeDecoder(t reflect.Type) decoderFunc { switch t.Kind() { case reflect.String: return func(n gjson.Result, v reflect.Value, state *decoderState) error { v.SetString(n.String()) if guardStrict(state, n.Type != gjson.String) { return fmt.Errorf("apijson: failed to parse string strictly") } // Everything that is not an object can be loosely stringified. if n.Type == gjson.JSON { return fmt.Errorf("apijson: failed to parse string") } state.validateString(v) if guardUnknown(state, v) { return fmt.Errorf("apijson: failed string enum validation") } return nil } case reflect.Bool: return func(n gjson.Result, v reflect.Value, state *decoderState) error { v.SetBool(n.Bool()) if guardStrict(state, n.Type != gjson.True && n.Type != gjson.False) { return fmt.Errorf("apijson: failed to parse bool strictly") } // Numbers and strings that are either 'true' or 'false' can be loosely // deserialized as bool. if n.Type == gjson.String && (n.Raw != "true" && n.Raw != "false") || n.Type == gjson.JSON { return fmt.Errorf("apijson: failed to parse bool") } state.validateBool(v) if guardUnknown(state, v) { return fmt.Errorf("apijson: failed bool enum validation") } return nil } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return func(n gjson.Result, v reflect.Value, state *decoderState) error { v.SetInt(n.Int()) if guardStrict(state, n.Type != gjson.Number || n.Num != float64(int(n.Num))) { return fmt.Errorf("apijson: failed to parse int strictly") } // Numbers, booleans, and strings that maybe look like numbers can be // loosely deserialized as numbers. if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) { return fmt.Errorf("apijson: failed to parse int") } state.validateInt(v) if guardUnknown(state, v) { return fmt.Errorf("apijson: failed int enum validation") } return nil } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return func(n gjson.Result, v reflect.Value, state *decoderState) error { v.SetUint(n.Uint()) if guardStrict(state, n.Type != gjson.Number || n.Num != float64(int(n.Num)) || n.Num < 0) { return fmt.Errorf("apijson: failed to parse uint strictly") } // Numbers, booleans, and strings that maybe look like numbers can be // loosely deserialized as uint. if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) { return fmt.Errorf("apijson: failed to parse uint") } if guardUnknown(state, v) { return fmt.Errorf("apijson: failed uint enum validation") } return nil } case reflect.Float32, reflect.Float64: return func(n gjson.Result, v reflect.Value, state *decoderState) error { v.SetFloat(n.Float()) if guardStrict(state, n.Type != gjson.Number) { return fmt.Errorf("apijson: failed to parse float strictly") } // Numbers, booleans, and strings that maybe look like numbers can be // loosely deserialized as floats. if n.Type == gjson.JSON || (n.Type == gjson.String && !canParseAsNumber(n.Str)) { return fmt.Errorf("apijson: failed to parse float") } if guardUnknown(state, v) { return fmt.Errorf("apijson: failed float enum validation") } return nil } default: return func(node gjson.Result, v reflect.Value, state *decoderState) error { return fmt.Errorf("unknown type received at primitive decoder: %s", t.String()) } } } func (d *decoderBuilder) newOptTypeDecoder(t reflect.Type) decoderFunc { for t.Kind() == reflect.Pointer { t = t.Elem() } valueField, _ := t.FieldByName("Value") return func(n gjson.Result, v reflect.Value, state *decoderState) error { state.validateOptKind(n, valueField.Type) return v.Addr().Interface().(json.Unmarshaler).UnmarshalJSON([]byte(n.Raw)) } } func (d *decoderBuilder) newTimeTypeDecoder(t reflect.Type) decoderFunc { format := d.dateFormat return func(n gjson.Result, v reflect.Value, state *decoderState) error { parsed, err := time.Parse(format, n.Str) if err == nil { v.Set(reflect.ValueOf(parsed).Convert(t)) return nil } if guardStrict(state, true) { return err } layouts := []string{ "2006-01-02", "2006-01-02T15:04:05Z07:00", "2006-01-02T15:04:05Z0700", "2006-01-02T15:04:05", "2006-01-02 15:04:05Z07:00", "2006-01-02 15:04:05Z0700", "2006-01-02 15:04:05", } for _, layout := range layouts { parsed, err := time.Parse(layout, n.Str) if err == nil { v.Set(reflect.ValueOf(parsed).Convert(t)) return nil } } return fmt.Errorf("unable to leniently parse date-time string: %s", n.Str) } } func setUnexportedField(field reflect.Value, value any) { reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Set(reflect.ValueOf(value)) } func guardStrict(state *decoderState, cond bool) bool { if !cond { return false } if state.strict { return true } state.exactness = loose return false } func canParseAsNumber(str string) bool { _, err := strconv.ParseFloat(str, 64) return err == nil } var stringType = reflect.TypeOf(string("")) func guardUnknown(state *decoderState, v reflect.Value) bool { if have, ok := v.Interface().(interface{ IsKnown() bool }); guardStrict(state, ok && !have.IsKnown()) { return true } constantString, ok := v.Interface().(interface{ Default() string }) named := v.Type() != stringType return guardStrict(state, ok && named && v.Equal(reflect.ValueOf(constantString.Default()))) } ================================================ FILE: internal/apijson/decoderesp_test.go ================================================ package apijson_test import ( "encoding/json" "github.com/anthropics/anthropic-sdk-go/internal/apijson" "github.com/anthropics/anthropic-sdk-go/packages/respjson" "testing" ) type StructWithNullExtraField struct { Results []string `json:"results" api:"required"` JSON struct { Results respjson.Field ExtraFields map[string]respjson.Field raw string } `json:"-"` } func (r *StructWithNullExtraField) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } func TestDecodeWithNullExtraField(t *testing.T) { raw := `{"something_else":null}` var dst *StructWithNullExtraField err := json.Unmarshal([]byte(raw), &dst) if err != nil { t.Fatalf("error: %s", err.Error()) } } ================================================ FILE: internal/apijson/encoder.go ================================================ package apijson import ( "bytes" "encoding/json" "fmt" "reflect" "sort" "strconv" "strings" "sync" "time" "github.com/tidwall/sjson" ) var encoders sync.Map // map[encoderEntry]encoderFunc // If we want to set a literal key value into JSON using sjson, we need to make sure it doesn't have // special characters that sjson interprets as a path. var EscapeSJSONKey = strings.NewReplacer("\\", "\\\\", "|", "\\|", "#", "\\#", "@", "\\@", "*", "\\*", ".", "\\.", ":", "\\:", "?", "\\?").Replace func Marshal(value any) ([]byte, error) { e := &encoder{dateFormat: time.RFC3339} return e.marshal(value) } func MarshalRoot(value any) ([]byte, error) { e := &encoder{root: true, dateFormat: time.RFC3339} return e.marshal(value) } type encoder struct { dateFormat string root bool } type encoderFunc func(value reflect.Value) ([]byte, error) type encoderField struct { tag parsedStructTag fn encoderFunc idx []int } type encoderEntry struct { reflect.Type dateFormat string root bool } func (e *encoder) marshal(value any) ([]byte, error) { val := reflect.ValueOf(value) if !val.IsValid() { return nil, nil } typ := val.Type() enc := e.typeEncoder(typ) return enc(val) } func (e *encoder) typeEncoder(t reflect.Type) encoderFunc { entry := encoderEntry{ Type: t, dateFormat: e.dateFormat, root: e.root, } if fi, ok := encoders.Load(entry); ok { return fi.(encoderFunc) } // To deal with recursive types, populate the map with an // indirect func before we build it. This type waits on the // real func (f) to be ready and then calls it. This indirect // func is only used for recursive types. var ( wg sync.WaitGroup f encoderFunc ) wg.Add(1) fi, loaded := encoders.LoadOrStore(entry, encoderFunc(func(v reflect.Value) ([]byte, error) { wg.Wait() return f(v) })) if loaded { return fi.(encoderFunc) } // Compute the real encoder and replace the indirect func with it. f = e.newTypeEncoder(t) wg.Done() encoders.Store(entry, f) return f } func marshalerEncoder(v reflect.Value) ([]byte, error) { return v.Interface().(json.Marshaler).MarshalJSON() } func indirectMarshalerEncoder(v reflect.Value) ([]byte, error) { return v.Addr().Interface().(json.Marshaler).MarshalJSON() } func (e *encoder) newTypeEncoder(t reflect.Type) encoderFunc { if t.ConvertibleTo(reflect.TypeOf(time.Time{})) { return e.newTimeTypeEncoder() } if !e.root && t.Implements(reflect.TypeOf((*json.Marshaler)(nil)).Elem()) { return marshalerEncoder } if !e.root && reflect.PointerTo(t).Implements(reflect.TypeOf((*json.Marshaler)(nil)).Elem()) { return indirectMarshalerEncoder } e.root = false switch t.Kind() { case reflect.Pointer: inner := t.Elem() innerEncoder := e.typeEncoder(inner) return func(v reflect.Value) ([]byte, error) { if !v.IsValid() || v.IsNil() { return nil, nil } return innerEncoder(v.Elem()) } case reflect.Struct: return e.newStructTypeEncoder(t) case reflect.Array: fallthrough case reflect.Slice: return e.newArrayTypeEncoder(t) case reflect.Map: return e.newMapEncoder(t) case reflect.Interface: return e.newInterfaceEncoder() default: return e.newPrimitiveTypeEncoder(t) } } func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc { switch t.Kind() { // Note that we could use `gjson` to encode these types but it would complicate our // code more and this current code shouldn't cause any issues case reflect.String: return func(v reflect.Value) ([]byte, error) { return json.Marshal(v.Interface()) } case reflect.Bool: return func(v reflect.Value) ([]byte, error) { if v.Bool() { return []byte("true"), nil } return []byte("false"), nil } case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: return func(v reflect.Value) ([]byte, error) { return []byte(strconv.FormatInt(v.Int(), 10)), nil } case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: return func(v reflect.Value) ([]byte, error) { return []byte(strconv.FormatUint(v.Uint(), 10)), nil } case reflect.Float32: return func(v reflect.Value) ([]byte, error) { return []byte(strconv.FormatFloat(v.Float(), 'f', -1, 32)), nil } case reflect.Float64: return func(v reflect.Value) ([]byte, error) { return []byte(strconv.FormatFloat(v.Float(), 'f', -1, 64)), nil } default: return func(v reflect.Value) ([]byte, error) { return nil, fmt.Errorf("unknown type received at primitive encoder: %s", t.String()) } } } func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc { itemEncoder := e.typeEncoder(t.Elem()) return func(value reflect.Value) ([]byte, error) { json := []byte("[]") for i := 0; i < value.Len(); i++ { var value, err = itemEncoder(value.Index(i)) if err != nil { return nil, err } if value == nil { // Assume that empty items should be inserted as `null` so that the output array // will be the same length as the input array value = []byte("null") } json, err = sjson.SetRawBytes(json, "-1", value) if err != nil { return nil, err } } return json, nil } } func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc { encoderFields := []encoderField{} extraEncoder := (*encoderField)(nil) // This helper allows us to recursively collect field encoders into a flat // array. The parameter `index` keeps track of the access patterns necessary // to get to some field. var collectEncoderFields func(r reflect.Type, index []int) collectEncoderFields = func(r reflect.Type, index []int) { for i := 0; i < r.NumField(); i++ { idx := append(index, i) field := t.FieldByIndex(idx) if !field.IsExported() { continue } // If this is an embedded struct, traverse one level deeper to extract // the field and get their encoders as well. if field.Anonymous { collectEncoderFields(field.Type, idx) continue } // If json tag is not present, then we skip, which is intentionally // different behavior from the stdlib. ptag, ok := parseJSONStructTag(field) if !ok { continue } // We only want to support unexported field if they're tagged with // `extras` because that field shouldn't be part of the public API. We // also want to only keep the top level extras if ptag.extras && len(index) == 0 { extraEncoder = &encoderField{ptag, e.typeEncoder(field.Type.Elem()), idx} continue } if ptag.name == "-" { continue } dateFormat, ok := parseFormatStructTag(field) oldFormat := e.dateFormat if ok { switch dateFormat { case "date-time": e.dateFormat = time.RFC3339 case "date": e.dateFormat = "2006-01-02" } } encoderFields = append(encoderFields, encoderField{ptag, e.typeEncoder(field.Type), idx}) e.dateFormat = oldFormat } } collectEncoderFields(t, []int{}) // Ensure deterministic output by sorting by lexicographic order sort.Slice(encoderFields, func(i, j int) bool { return encoderFields[i].tag.name < encoderFields[j].tag.name }) return func(value reflect.Value) (json []byte, err error) { json = []byte("{}") for _, ef := range encoderFields { field := value.FieldByIndex(ef.idx) encoded, err := ef.fn(field) if err != nil { return nil, err } if encoded == nil { continue } json, err = sjson.SetRawBytes(json, EscapeSJSONKey(ef.tag.name), encoded) if err != nil { return nil, err } } if extraEncoder != nil { json, err = e.encodeMapEntries(json, value.FieldByIndex(extraEncoder.idx)) if err != nil { return nil, err } } return json, err } } func (e *encoder) newTimeTypeEncoder() encoderFunc { format := e.dateFormat return func(value reflect.Value) (json []byte, err error) { return []byte(`"` + value.Convert(reflect.TypeOf(time.Time{})).Interface().(time.Time).Format(format) + `"`), nil } } func (e encoder) newInterfaceEncoder() encoderFunc { return func(value reflect.Value) ([]byte, error) { value = value.Elem() if !value.IsValid() { return nil, nil } return e.typeEncoder(value.Type())(value) } } // 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(json []byte, v reflect.Value) ([]byte, error) { type mapPair struct { key []byte value reflect.Value } pairs := []mapPair{} keyEncoder := e.typeEncoder(v.Type().Key()) iter := v.MapRange() for iter.Next() { var encodedKeyString string if iter.Key().Type().Kind() == reflect.String { encodedKeyString = iter.Key().String() } else { var err error encodedKeyBytes, err := keyEncoder(iter.Key()) if err != nil { return nil, err } encodedKeyString = string(encodedKeyBytes) } encodedKey := []byte(encodedKeyString) pairs = append(pairs, mapPair{key: encodedKey, value: iter.Value()}) } // Ensure deterministic output sort.Slice(pairs, func(i, j int) bool { return bytes.Compare(pairs[i].key, pairs[j].key) < 0 }) elementEncoder := e.typeEncoder(v.Type().Elem()) for _, p := range pairs { encodedValue, err := elementEncoder(p.value) if err != nil { return nil, err } if len(encodedValue) == 0 { continue } json, err = sjson.SetRawBytes(json, EscapeSJSONKey(string(p.key)), encodedValue) if err != nil { return nil, err } } return json, nil } func (e *encoder) newMapEncoder(_ reflect.Type) encoderFunc { return func(value reflect.Value) ([]byte, error) { json := []byte("{}") var err error json, err = e.encodeMapEntries(json, value) if err != nil { return nil, err } return json, nil } } ================================================ FILE: internal/apijson/enum.go ================================================ package apijson import ( "fmt" "reflect" "slices" "github.com/tidwall/gjson" ) /********************/ /* Validating Enums */ /********************/ type validationEntry struct { field reflect.StructField legalValues struct { strings []string // 1 represents true, 0 represents false, -1 represents either bools int ints []int64 } } var validationRegistry = map[reflect.Type][]validationEntry{} func RegisterFieldValidator[T any, V string | bool | int | float64](fieldName string, values ...V) { var t T parentType := reflect.TypeOf(t) if _, ok := validationRegistry[parentType]; !ok { validationRegistry[parentType] = []validationEntry{} } // The following checks run at initialization time, // it is impossible for them to panic if any tests pass. if parentType.Kind() != reflect.Struct { panic(fmt.Sprintf("apijson: cannot initialize validator for non-struct %s", parentType.String())) } var field reflect.StructField found := false for i := 0; i < parentType.NumField(); i++ { ptag, ok := parseJSONStructTag(parentType.Field(i)) if ok && ptag.name == fieldName { field = parentType.Field(i) found = true break } } if !found { panic(fmt.Sprintf("apijson: cannot find field %s in struct %s", fieldName, parentType.String())) } newEntry := validationEntry{field: field} newEntry.legalValues.bools = -1 // default to either switch values := any(values).(type) { case []string: newEntry.legalValues.strings = values case []int: newEntry.legalValues.ints = make([]int64, len(values)) for i, value := range values { newEntry.legalValues.ints[i] = int64(value) } case []bool: for i, value := range values { var next int if value { next = 1 } if i > 0 && newEntry.legalValues.bools != next { newEntry.legalValues.bools = -1 // accept either break } newEntry.legalValues.bools = next } } // Store the information necessary to create a validator, so that we can use it // lazily create the validator function when did. validationRegistry[parentType] = append(validationRegistry[parentType], newEntry) } func (state *decoderState) validateString(v reflect.Value) { if state.validator == nil { return } if !slices.Contains(state.validator.legalValues.strings, v.String()) { state.exactness = loose } } func (state *decoderState) validateInt(v reflect.Value) { if state.validator == nil { return } if !slices.Contains(state.validator.legalValues.ints, v.Int()) { state.exactness = loose } } func (state *decoderState) validateBool(v reflect.Value) { if state.validator == nil { return } b := v.Bool() if state.validator.legalValues.bools == 1 && !b { state.exactness = loose } else if state.validator.legalValues.bools == 0 && b { state.exactness = loose } } func (state *decoderState) validateOptKind(node gjson.Result, t reflect.Type) { switch node.Type { case gjson.JSON: state.exactness = loose case gjson.Null: return case gjson.False, gjson.True: if t.Kind() != reflect.Bool { state.exactness = loose } case gjson.Number: switch t.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: return default: state.exactness = loose } case gjson.String: if t.Kind() != reflect.String { state.exactness = loose } } } ================================================ FILE: internal/apijson/enum_test.go ================================================ package apijson import ( "reflect" "testing" ) type EnumStruct struct { NormalString string `json:"normal_string"` StringEnum string `json:"string_enum"` NamedEnum NamedEnumType `json:"named_enum"` IntEnum int `json:"int_enum"` BoolEnum bool `json:"bool_enum"` WeirdBoolEnum bool `json:"weird_bool_enum"` } func (o *EnumStruct) UnmarshalJSON(data []byte) error { return UnmarshalRoot(data, o) } func init() { RegisterFieldValidator[EnumStruct]("string_enum", "one", "two", "three") RegisterFieldValidator[EnumStruct]("int_enum", 200, 404) RegisterFieldValidator[EnumStruct]("bool_enum", false) RegisterFieldValidator[EnumStruct]("weird_bool_enum", true, false) } type NamedEnumType string const ( NamedEnumOne NamedEnumType = "one" NamedEnumTwo NamedEnumType = "two" NamedEnumThree NamedEnumType = "three" ) func (e NamedEnumType) IsKnown() bool { return e == NamedEnumOne || e == NamedEnumTwo || e == NamedEnumThree } func TestEnumStructStringValidator(t *testing.T) { cases := map[string]struct { exactness EnumStruct }{ `{"string_enum":"one"}`: {exact, EnumStruct{StringEnum: "one"}}, `{"string_enum":"two"}`: {exact, EnumStruct{StringEnum: "two"}}, `{"string_enum":"three"}`: {exact, EnumStruct{StringEnum: "three"}}, `{"string_enum":"none"}`: {loose, EnumStruct{StringEnum: "none"}}, `{"int_enum":200}`: {exact, EnumStruct{IntEnum: 200}}, `{"int_enum":404}`: {exact, EnumStruct{IntEnum: 404}}, `{"int_enum":500}`: {loose, EnumStruct{IntEnum: 500}}, `{"bool_enum":false}`: {exact, EnumStruct{BoolEnum: false}}, `{"bool_enum":true}`: {loose, EnumStruct{BoolEnum: true}}, `{"weird_bool_enum":true}`: {exact, EnumStruct{WeirdBoolEnum: true}}, `{"weird_bool_enum":false}`: {exact, EnumStruct{WeirdBoolEnum: false}}, `{"named_enum":"one"}`: {exact, EnumStruct{NamedEnum: NamedEnumOne}}, `{"named_enum":"none"}`: {loose, EnumStruct{NamedEnum: "none"}}, `{"string_enum":"one","named_enum":"one"}`: {exact, EnumStruct{NamedEnum: "one", StringEnum: "one"}}, `{"string_enum":"four","named_enum":"one"}`: { loose, EnumStruct{NamedEnum: "one", StringEnum: "four"}, }, `{"string_enum":"one","named_enum":"four"}`: { loose, EnumStruct{NamedEnum: "four", StringEnum: "one"}, }, `{"wrong_key":"one"}`: {extras, EnumStruct{StringEnum: ""}}, } for raw, expected := range cases { var dst EnumStruct dec := decoderBuilder{root: true} exactness, _ := dec.unmarshalWithExactness([]byte(raw), &dst) if !reflect.DeepEqual(dst, expected.EnumStruct) { t.Fatalf("failed equality check %#v", dst) } if exactness != expected.exactness { t.Fatalf("exactness got %d expected %d %s", exactness, expected.exactness, raw) } } } ================================================ FILE: internal/apijson/field.go ================================================ package apijson type status uint8 const ( missing status = iota null invalid valid ) type Field struct { raw string status status } // Returns true if the field is explicitly `null` _or_ if it is not present at all (ie, missing). // To check if the field's key is present in the JSON with an explicit null value, // you must check `f.IsNull() && !f.IsMissing()`. func (j Field) IsNull() bool { return j.status <= null } func (j Field) IsMissing() bool { return j.status == missing } func (j Field) IsInvalid() bool { return j.status == invalid } func (j Field) Raw() string { return j.raw } ================================================ FILE: internal/apijson/json_test.go ================================================ package apijson import ( "reflect" "strings" "testing" "time" "github.com/tidwall/gjson" ) func P[T any](v T) *T { return &v } type Primitives struct { A bool `json:"a"` B int `json:"b"` C uint `json:"c"` D float64 `json:"d"` E float32 `json:"e"` F []int `json:"f"` } type PrimitivePointers struct { A *bool `json:"a"` B *int `json:"b"` C *uint `json:"c"` D *float64 `json:"d"` E *float32 `json:"e"` F *[]int `json:"f"` } type Slices struct { Slice []Primitives `json:"slices"` } type DateTime struct { Date time.Time `json:"date" format:"date"` DateTime time.Time `json:"date-time" format:"date-time"` } type AdditionalProperties struct { A bool `json:"a"` ExtraFields map[string]any `json:"-" api:"extrafields"` } type TypedAdditionalProperties struct { A bool `json:"a"` ExtraFields map[string]int `json:"-" api:"extrafields"` } type EmbeddedStruct struct { A bool `json:"a"` B string `json:"b"` JSON EmbeddedStructJSON } type EmbeddedStructJSON struct { A Field B Field ExtraFields map[string]Field raw string } type EmbeddedStructs struct { EmbeddedStruct A *int `json:"a"` ExtraFields map[string]any `json:"-" api:"extrafields"` JSON EmbeddedStructsJSON } type EmbeddedStructsJSON struct { A Field ExtraFields map[string]Field raw string } type Recursive struct { Name string `json:"name"` Child *Recursive `json:"child"` } type JSONFieldStruct struct { A bool `json:"a"` B int64 `json:"b"` C string `json:"c"` D string `json:"d"` ExtraFields map[string]int64 `json:"" api:"extrafields"` JSON JSONFieldStructJSON `json:"-" api:"metadata"` } type JSONFieldStructJSON struct { A Field B Field C Field D Field ExtraFields map[string]Field raw string } type UnknownStruct struct { Unknown any `json:"unknown"` } type UnionStruct struct { Union Union `json:"union" format:"date"` } type Union interface { union() } type Inline struct { InlineField Primitives `json:",inline"` JSON InlineJSON `json:"-" api:"metadata"` } type InlineArray struct { InlineField []string `json:",inline"` JSON InlineJSON `json:"-" api:"metadata"` } type InlineJSON struct { InlineField Field raw string } type UnionInteger int64 func (UnionInteger) union() {} type UnionStructA struct { Type string `json:"type"` A string `json:"a"` B string `json:"b"` } func (UnionStructA) union() {} type UnionStructB struct { Type string `json:"type"` A string `json:"a"` } func (UnionStructB) union() {} type UnionTime time.Time func (UnionTime) union() {} func init() { RegisterUnion[Union]("type", UnionVariant{ TypeFilter: gjson.String, Type: reflect.TypeOf(UnionTime{}), }, UnionVariant{ TypeFilter: gjson.Number, Type: reflect.TypeOf(UnionInteger(0)), }, UnionVariant{ TypeFilter: gjson.JSON, DiscriminatorValue: "typeA", Type: reflect.TypeOf(UnionStructA{}), }, UnionVariant{ TypeFilter: gjson.JSON, DiscriminatorValue: "typeB", Type: reflect.TypeOf(UnionStructB{}), }, ) } type ComplexUnionStruct struct { Union ComplexUnion `json:"union"` } type ComplexUnion interface { complexUnion() } type ComplexUnionA struct { Boo string `json:"boo"` Foo bool `json:"foo"` } func (ComplexUnionA) complexUnion() {} type ComplexUnionB struct { Boo bool `json:"boo"` Foo string `json:"foo"` } func (ComplexUnionB) complexUnion() {} type ComplexUnionC struct { Boo int64 `json:"boo"` } func (ComplexUnionC) complexUnion() {} type ComplexUnionTypeA struct { Baz int64 `json:"baz"` Type TypeA `json:"type"` } func (ComplexUnionTypeA) complexUnion() {} type TypeA string func (t TypeA) IsKnown() bool { return t == "a" } type ComplexUnionTypeB struct { Baz int64 `json:"baz"` Type TypeB `json:"type"` } type TypeB string func (t TypeB) IsKnown() bool { return t == "b" } type UnmarshalStruct struct { Foo string `json:"foo"` prop bool `json:"-"` } func (r *UnmarshalStruct) UnmarshalJSON(json []byte) error { r.prop = true return UnmarshalRoot(json, r) } func (ComplexUnionTypeB) complexUnion() {} func init() { RegisterUnion[ComplexUnion]("", UnionVariant{ TypeFilter: gjson.JSON, Type: reflect.TypeOf(ComplexUnionA{}), }, UnionVariant{ TypeFilter: gjson.JSON, Type: reflect.TypeOf(ComplexUnionB{}), }, UnionVariant{ TypeFilter: gjson.JSON, Type: reflect.TypeOf(ComplexUnionC{}), }, UnionVariant{ TypeFilter: gjson.JSON, Type: reflect.TypeOf(ComplexUnionTypeA{}), }, UnionVariant{ TypeFilter: gjson.JSON, Type: reflect.TypeOf(ComplexUnionTypeB{}), }, ) } type MarshallingUnionStruct struct { Union MarshallingUnion } func (r *MarshallingUnionStruct) UnmarshalJSON(data []byte) (err error) { *r = MarshallingUnionStruct{} err = UnmarshalRoot(data, &r.Union) return err } func (r MarshallingUnionStruct) MarshalJSON() (data []byte, err error) { return MarshalRoot(r.Union) } type MarshallingUnion interface { marshallingUnion() } type MarshallingUnionA struct { Boo string `json:"boo"` } func (MarshallingUnionA) marshallingUnion() {} func (r *MarshallingUnionA) UnmarshalJSON(data []byte) (err error) { return UnmarshalRoot(data, r) } type MarshallingUnionB struct { Foo string `json:"foo"` } func (MarshallingUnionB) marshallingUnion() {} func (r *MarshallingUnionB) UnmarshalJSON(data []byte) (err error) { return UnmarshalRoot(data, r) } func init() { RegisterUnion[MarshallingUnion]( "", UnionVariant{ TypeFilter: gjson.JSON, Type: reflect.TypeOf(MarshallingUnionA{}), }, UnionVariant{ TypeFilter: gjson.JSON, Type: reflect.TypeOf(MarshallingUnionB{}), }, ) } var tests = map[string]struct { buf string val any }{ "true": {"true", true}, "false": {"false", false}, "int": {"1", 1}, "int_bigger": {"12324", 12324}, "int_string_coerce": {`"65"`, 65}, "int_boolean_coerce": {"true", 1}, "int64": {"1", int64(1)}, "int64_huge": {"123456789123456789", int64(123456789123456789)}, "uint": {"1", uint(1)}, "uint_bigger": {"12324", uint(12324)}, "uint_coerce": {`"65"`, uint(65)}, "float_1.54": {"1.54", float32(1.54)}, "float_1.89": {"1.89", float64(1.89)}, "string": {`"str"`, "str"}, "string_int_coerce": {`12`, "12"}, "array_string": {`["foo","bar"]`, []string{"foo", "bar"}}, "array_int": {`[1,2]`, []int{1, 2}}, "array_int_coerce": {`["1",2]`, []int{1, 2}}, "ptr_true": {"true", P(true)}, "ptr_false": {"false", P(false)}, "ptr_int": {"1", P(1)}, "ptr_int_bigger": {"12324", P(12324)}, "ptr_int_string_coerce": {`"65"`, P(65)}, "ptr_int_boolean_coerce": {"true", P(1)}, "ptr_int64": {"1", P(int64(1))}, "ptr_int64_huge": {"123456789123456789", P(int64(123456789123456789))}, "ptr_uint": {"1", P(uint(1))}, "ptr_uint_bigger": {"12324", P(uint(12324))}, "ptr_uint_coerce": {`"65"`, P(uint(65))}, "ptr_float_1.54": {"1.54", P(float32(1.54))}, "ptr_float_1.89": {"1.89", P(float64(1.89))}, "date_time": {`"2007-03-01T13:00:00Z"`, time.Date(2007, time.March, 1, 13, 0, 0, 0, time.UTC)}, "date_time_nano_coerce": {`"2007-03-01T13:03:05.123456789Z"`, time.Date(2007, time.March, 1, 13, 3, 5, 123456789, time.UTC)}, "date_time_missing_t_coerce": {`"2007-03-01 13:03:05Z"`, time.Date(2007, time.March, 1, 13, 3, 5, 0, time.UTC)}, "date_time_missing_timezone_coerce": {`"2007-03-01T13:03:05"`, time.Date(2007, time.March, 1, 13, 3, 5, 0, time.UTC)}, // note: using -1200 to minimize probability of conflicting with the local timezone of the test runner // see https://en.wikipedia.org/wiki/UTC%E2%88%9212:00 "date_time_missing_timezone_colon_coerce": {`"2007-03-01T13:03:05-1200"`, time.Date(2007, time.March, 1, 13, 3, 5, 0, time.FixedZone("", -12*60*60))}, "date_time_nano_missing_t_coerce": {`"2007-03-01 13:03:05.123456789Z"`, time.Date(2007, time.March, 1, 13, 3, 5, 123456789, time.UTC)}, "map_string": {`{"foo":"bar"}`, map[string]string{"foo": "bar"}}, "map_string_with_sjson_path_chars": {`{":a.b.c*:d*-1e.f":"bar"}`, map[string]string{":a.b.c*:d*-1e.f": "bar"}}, "map_interface": {`{"a":1,"b":"str","c":false}`, map[string]any{"a": float64(1), "b": "str", "c": false}}, "primitive_struct": { `{"a":false,"b":237628372683,"c":654,"d":9999.43,"e":43.76,"f":[1,2,3,4]}`, Primitives{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}, }, "slices": { `{"slices":[{"a":false,"b":237628372683,"c":654,"d":9999.43,"e":43.76,"f":[1,2,3,4]}]}`, Slices{ Slice: []Primitives{{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}}, }, }, "primitive_pointer_struct": { `{"a":false,"b":237628372683,"c":654,"d":9999.43,"e":43.76,"f":[1,2,3,4,5]}`, PrimitivePointers{ A: P(false), B: P(237628372683), C: P(uint(654)), D: P(9999.43), E: P(float32(43.76)), F: &[]int{1, 2, 3, 4, 5}, }, }, "datetime_struct": { `{"date":"2006-01-02","date-time":"2006-01-02T15:04:05Z"}`, DateTime{ Date: time.Date(2006, time.January, 2, 0, 0, 0, 0, time.UTC), DateTime: time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC), }, }, "additional_properties": { `{"a":true,"bar":"value","foo":true}`, AdditionalProperties{ A: true, ExtraFields: map[string]any{ "bar": "value", "foo": true, }, }, }, "embedded_struct": { `{"a":1,"b":"bar"}`, EmbeddedStructs{ EmbeddedStruct: EmbeddedStruct{ A: true, B: "bar", JSON: EmbeddedStructJSON{ A: Field{raw: `1`, status: valid}, B: Field{raw: `"bar"`, status: valid}, raw: `{"a":1,"b":"bar"}`, }, }, A: P(1), ExtraFields: map[string]any{"b": "bar"}, JSON: EmbeddedStructsJSON{ A: Field{raw: `1`, status: valid}, ExtraFields: map[string]Field{ "b": {raw: `"bar"`, status: valid}, }, raw: `{"a":1,"b":"bar"}`, }, }, }, "recursive_struct": { `{"child":{"name":"Alex"},"name":"Robert"}`, Recursive{Name: "Robert", Child: &Recursive{Name: "Alex"}}, }, "metadata_coerce": { `{"a":"12","b":"12","c":null,"extra_typed":12,"extra_untyped":{"foo":"bar"}}`, JSONFieldStruct{ A: false, B: 12, C: "", JSON: JSONFieldStructJSON{ raw: `{"a":"12","b":"12","c":null,"extra_typed":12,"extra_untyped":{"foo":"bar"}}`, A: Field{raw: `"12"`, status: invalid}, B: Field{raw: `"12"`, status: valid}, C: Field{raw: "null", status: null}, D: Field{raw: "", status: missing}, ExtraFields: map[string]Field{ "extra_typed": { raw: "12", status: valid, }, "extra_untyped": { raw: `{"foo":"bar"}`, status: invalid, }, }, }, ExtraFields: map[string]int64{ "extra_typed": 12, "extra_untyped": 0, }, }, }, "unknown_struct_number": { `{"unknown":12}`, UnknownStruct{ Unknown: 12., }, }, "unknown_struct_map": { `{"unknown":{"foo":"bar"}}`, UnknownStruct{ Unknown: map[string]any{ "foo": "bar", }, }, }, "union_integer": { `{"union":12}`, UnionStruct{ Union: UnionInteger(12), }, }, "union_struct_discriminated_a": { `{"union":{"a":"foo","b":"bar","type":"typeA"}}`, UnionStruct{ Union: UnionStructA{ Type: "typeA", A: "foo", B: "bar", }, }, }, "union_struct_discriminated_b": { `{"union":{"a":"foo","type":"typeB"}}`, UnionStruct{ Union: UnionStructB{ Type: "typeB", A: "foo", }, }, }, "union_struct_time": { `{"union":"2010-05-23"}`, UnionStruct{ Union: UnionTime(time.Date(2010, 05, 23, 0, 0, 0, 0, time.UTC)), }, }, "complex_union_a": { `{"union":{"boo":"12","foo":true}}`, ComplexUnionStruct{Union: ComplexUnionA{Boo: "12", Foo: true}}, }, "complex_union_b": { `{"union":{"boo":true,"foo":"12"}}`, ComplexUnionStruct{Union: ComplexUnionB{Boo: true, Foo: "12"}}, }, "complex_union_c": { `{"union":{"boo":12}}`, ComplexUnionStruct{Union: ComplexUnionC{Boo: 12}}, }, "complex_union_type_a": { `{"union":{"baz":12,"type":"a"}}`, ComplexUnionStruct{Union: ComplexUnionTypeA{Baz: 12, Type: TypeA("a")}}, }, "complex_union_type_b": { `{"union":{"baz":12,"type":"b"}}`, ComplexUnionStruct{Union: ComplexUnionTypeB{Baz: 12, Type: TypeB("b")}}, }, "marshalling_union_a": { `{"boo":"hello"}`, MarshallingUnionStruct{Union: MarshallingUnionA{Boo: "hello"}}, }, "marshalling_union_b": { `{"foo":"hi"}`, MarshallingUnionStruct{Union: MarshallingUnionB{Foo: "hi"}}, }, "unmarshal": { `{"foo":"hello"}`, &UnmarshalStruct{Foo: "hello", prop: true}, }, "array_of_unmarshal": { `[{"foo":"hello"}]`, []UnmarshalStruct{{Foo: "hello", prop: true}}, }, "inline_coerce": { `{"a":false,"b":237628372683,"c":654,"d":9999.43,"e":43.76,"f":[1,2,3,4]}`, Inline{ InlineField: Primitives{A: false, B: 237628372683, C: 0x28e, D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}, JSON: InlineJSON{ InlineField: Field{raw: "{\"a\":false,\"b\":237628372683,\"c\":654,\"d\":9999.43,\"e\":43.76,\"f\":[1,2,3,4]}", status: 3}, raw: "{\"a\":false,\"b\":237628372683,\"c\":654,\"d\":9999.43,\"e\":43.76,\"f\":[1,2,3,4]}", }, }, }, "inline_array_coerce": { `["Hello","foo","bar"]`, InlineArray{ InlineField: []string{"Hello", "foo", "bar"}, JSON: InlineJSON{ InlineField: Field{raw: `["Hello","foo","bar"]`, status: 3}, raw: `["Hello","foo","bar"]`, }, }, }, } func TestDecode(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { result := reflect.New(reflect.TypeOf(test.val)) if err := Unmarshal([]byte(test.buf), result.Interface()); err != nil { t.Fatalf("deserialization of %v failed with error %v", result, err) } if !reflect.DeepEqual(result.Elem().Interface(), test.val) { t.Fatalf("expected '%s' to deserialize to \n%#v\nbut got\n%#v", test.buf, test.val, result.Elem().Interface()) } }) } } func TestEncode(t *testing.T) { for name, test := range tests { if strings.HasSuffix(name, "_coerce") { continue } t.Run(name, func(t *testing.T) { raw, err := Marshal(test.val) if err != nil { t.Fatalf("serialization of %v failed with error %v", test.val, err) } if string(raw) != test.buf { t.Fatalf("expected %+#v to serialize to %s but got %s", test.val, test.buf, string(raw)) } }) } } ================================================ FILE: internal/apijson/port.go ================================================ package apijson import ( "fmt" "reflect" ) // Port copies over values from one struct to another struct. func Port(from any, to any) error { toVal := reflect.ValueOf(to) fromVal := reflect.ValueOf(from) if toVal.Kind() != reflect.Ptr || toVal.IsNil() { return fmt.Errorf("destination must be a non-nil pointer") } for toVal.Kind() == reflect.Ptr { toVal = toVal.Elem() } toType := toVal.Type() for fromVal.Kind() == reflect.Ptr { fromVal = fromVal.Elem() } fromType := fromVal.Type() if toType.Kind() != reflect.Struct { return fmt.Errorf("destination must be a non-nil pointer to a struct (%v %v)", toType, toType.Kind()) } values := map[string]reflect.Value{} fields := map[string]reflect.Value{} fromJSON := fromVal.FieldByName("JSON") toJSON := toVal.FieldByName("JSON") // Iterate through the fields of v and load all the "normal" fields in the struct to the map of // string to reflect.Value, as well as their raw .JSON.Foo counterpart indicated by j. var getFields func(t reflect.Type, v reflect.Value) getFields = func(t reflect.Type, v reflect.Value) { j := v.FieldByName("JSON") // Recurse into anonymous fields first, since the fields on the object should win over the fields in the // embedded object. for i := 0; i < t.NumField(); i++ { field := t.Field(i) if field.Anonymous { getFields(field.Type, v.Field(i)) continue } } for i := 0; i < t.NumField(); i++ { field := t.Field(i) ptag, ok := parseJSONStructTag(field) if !ok || ptag.name == "-" || ptag.name == "" { continue } values[ptag.name] = v.Field(i) if j.IsValid() { fields[ptag.name] = j.FieldByName(field.Name) } } } getFields(fromType, fromVal) // Use the values from the previous step to populate the 'to' struct. for i := 0; i < toType.NumField(); i++ { field := toType.Field(i) ptag, ok := parseJSONStructTag(field) if !ok { continue } if ptag.name == "-" { continue } if value, ok := values[ptag.name]; ok { delete(values, ptag.name) if field.Type.Kind() == reflect.Interface { toVal.Field(i).Set(value) } else { switch value.Kind() { case reflect.String: toVal.Field(i).SetString(value.String()) case reflect.Bool: toVal.Field(i).SetBool(value.Bool()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: toVal.Field(i).SetInt(value.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: toVal.Field(i).SetUint(value.Uint()) case reflect.Float32, reflect.Float64: toVal.Field(i).SetFloat(value.Float()) default: toVal.Field(i).Set(value) } } } if fromJSONField, ok := fields[ptag.name]; ok { if toJSONField := toJSON.FieldByName(field.Name); toJSONField.IsValid() { toJSONField.Set(fromJSONField) } } } // Finally, copy over the .JSON.raw and .JSON.ExtraFields if toJSON.IsValid() { if raw := toJSON.FieldByName("raw"); raw.IsValid() { setUnexportedField(raw, fromJSON.Interface().(interface{ RawJSON() string }).RawJSON()) } if toExtraFields := toJSON.FieldByName("ExtraFields"); toExtraFields.IsValid() { if fromExtraFields := fromJSON.FieldByName("ExtraFields"); fromExtraFields.IsValid() { setUnexportedField(toExtraFields, fromExtraFields.Interface()) } } } return nil } ================================================ FILE: internal/apijson/port_test.go ================================================ package apijson import ( "reflect" "testing" ) type Metadata struct { CreatedAt string `json:"created_at"` } // Card is the "combined" type of CardVisa and CardMastercard type Card struct { Processor CardProcessor `json:"processor"` Data any `json:"data"` IsFoo bool `json:"is_foo"` IsBar bool `json:"is_bar"` Metadata Metadata `json:"metadata"` Value any `json:"value"` JSON cardJSON } type cardJSON struct { Processor Field Data Field IsFoo Field IsBar Field Metadata Field Value Field ExtraFields map[string]Field raw string } func (r cardJSON) RawJSON() string { return r.raw } type CardProcessor string // CardVisa type CardVisa struct { Processor CardVisaProcessor `json:"processor"` Data CardVisaData `json:"data"` IsFoo bool `json:"is_foo"` Metadata Metadata `json:"metadata"` Value string `json:"value"` JSON cardVisaJSON } type cardVisaJSON struct { Processor Field Data Field IsFoo Field Metadata Field Value Field ExtraFields map[string]Field raw string } func (r cardVisaJSON) RawJSON() string { return r.raw } type CardVisaProcessor string type CardVisaData struct { Foo string `json:"foo"` } // CardMastercard type CardMastercard struct { Processor CardMastercardProcessor `json:"processor"` Data CardMastercardData `json:"data"` IsBar bool `json:"is_bar"` Metadata Metadata `json:"metadata"` Value bool `json:"value"` JSON cardMastercardJSON } type cardMastercardJSON struct { Processor Field Data Field IsBar Field Metadata Field Value Field ExtraFields map[string]Field raw string } func (r cardMastercardJSON) RawJSON() string { return r.raw } type CardMastercardProcessor string type CardMastercardData struct { Bar int64 `json:"bar"` } type CommonFields struct { Metadata Metadata `json:"metadata"` Value string `json:"value"` JSON commonFieldsJSON } type commonFieldsJSON struct { Metadata Field Value Field ExtraFields map[string]Field raw string } type CardEmbedded struct { CommonFields Processor CardVisaProcessor `json:"processor"` Data CardVisaData `json:"data"` IsFoo bool `json:"is_foo"` JSON cardEmbeddedJSON } type cardEmbeddedJSON struct { Processor Field Data Field IsFoo Field ExtraFields map[string]Field raw string } func (r cardEmbeddedJSON) RawJSON() string { return r.raw } var portTests = map[string]struct { from any to any }{ "visa to card": { CardVisa{ Processor: "visa", IsFoo: true, Data: CardVisaData{ Foo: "foo", }, Metadata: Metadata{ CreatedAt: "Mar 29 2024", }, Value: "value", JSON: cardVisaJSON{ raw: `{"processor":"visa","is_foo":true,"data":{"foo":"foo"}}`, Processor: Field{raw: `"visa"`, status: valid}, IsFoo: Field{raw: `true`, status: valid}, Data: Field{raw: `{"foo":"foo"}`, status: valid}, Value: Field{raw: `"value"`, status: valid}, ExtraFields: map[string]Field{"extra": {raw: `"yo"`, status: valid}}, }, }, Card{ Processor: "visa", IsFoo: true, IsBar: false, Data: CardVisaData{ Foo: "foo", }, Metadata: Metadata{ CreatedAt: "Mar 29 2024", }, Value: "value", JSON: cardJSON{ raw: `{"processor":"visa","is_foo":true,"data":{"foo":"foo"}}`, Processor: Field{raw: `"visa"`, status: valid}, IsFoo: Field{raw: `true`, status: valid}, Data: Field{raw: `{"foo":"foo"}`, status: valid}, Value: Field{raw: `"value"`, status: valid}, ExtraFields: map[string]Field{"extra": {raw: `"yo"`, status: valid}}, }, }, }, "mastercard to card": { CardMastercard{ Processor: "mastercard", IsBar: true, Data: CardMastercardData{ Bar: 13, }, Value: false, }, Card{ Processor: "mastercard", IsFoo: false, IsBar: true, Data: CardMastercardData{ Bar: 13, }, Value: false, }, }, "embedded to card": { CardEmbedded{ CommonFields: CommonFields{ Metadata: Metadata{ CreatedAt: "Mar 29 2024", }, Value: "embedded_value", JSON: commonFieldsJSON{ Metadata: Field{raw: `{"created_at":"Mar 29 2024"}`, status: valid}, Value: Field{raw: `"embedded_value"`, status: valid}, raw: `should not matter`, }, }, Processor: "visa", IsFoo: true, Data: CardVisaData{ Foo: "embedded_foo", }, JSON: cardEmbeddedJSON{ raw: `{"processor":"visa","is_foo":true,"data":{"foo":"embedded_foo"},"metadata":{"created_at":"Mar 29 2024"},"value":"embedded_value"}`, Processor: Field{raw: `"visa"`, status: valid}, IsFoo: Field{raw: `true`, status: valid}, Data: Field{raw: `{"foo":"embedded_foo"}`, status: valid}, }, }, Card{ Processor: "visa", IsFoo: true, IsBar: false, Data: CardVisaData{ Foo: "embedded_foo", }, Metadata: Metadata{ CreatedAt: "Mar 29 2024", }, Value: "embedded_value", JSON: cardJSON{ raw: `{"processor":"visa","is_foo":true,"data":{"foo":"embedded_foo"},"metadata":{"created_at":"Mar 29 2024"},"value":"embedded_value"}`, Processor: Field{raw: `"visa"`, status: 0x3}, IsFoo: Field{raw: "true", status: 0x3}, Data: Field{raw: `{"foo":"embedded_foo"}`, status: 0x3}, Metadata: Field{raw: `{"created_at":"Mar 29 2024"}`, status: 0x3}, Value: Field{raw: `"embedded_value"`, status: 0x3}, }, }, }, } func TestPort(t *testing.T) { for name, test := range portTests { t.Run(name, func(t *testing.T) { toVal := reflect.New(reflect.TypeOf(test.to)) err := Port(test.from, toVal.Interface()) if err != nil { t.Fatalf("port of %v failed with error %v", test.from, err) } if !reflect.DeepEqual(toVal.Elem().Interface(), test.to) { t.Fatalf("expected:\n%+#v\n\nto port to:\n%+#v\n\nbut got:\n%+#v", test.from, test.to, toVal.Elem().Interface()) } }) } } ================================================ FILE: internal/apijson/registry.go ================================================ package apijson import ( "reflect" "github.com/tidwall/gjson" ) type UnionVariant struct { TypeFilter gjson.Type DiscriminatorValue any Type reflect.Type } var unionRegistry = map[reflect.Type]unionEntry{} var unionVariants = map[reflect.Type]any{} var customDecoderRegistry = map[reflect.Type]CustomDecoderFunc{} type unionEntry struct { discriminatorKey string variants []UnionVariant } func Discriminator[T any](value any) UnionVariant { var zero T return UnionVariant{ TypeFilter: gjson.JSON, DiscriminatorValue: value, Type: reflect.TypeOf(zero), } } func RegisterUnion[T any](discriminator string, variants ...UnionVariant) { typ := reflect.TypeOf((*T)(nil)).Elem() unionRegistry[typ] = unionEntry{ discriminatorKey: discriminator, variants: variants, } for _, variant := range variants { unionVariants[variant.Type] = typ } } // Useful to wrap a union type to force it to use [apijson.UnmarshalJSON] since you cannot define an // UnmarshalJSON function on the interface itself. type UnionUnmarshaler[T any] struct { Value T } func (c *UnionUnmarshaler[T]) UnmarshalJSON(buf []byte) error { return UnmarshalRoot(buf, &c.Value) } type CustomDecoderFunc func(node gjson.Result, value reflect.Value, defaultDecoder func(gjson.Result, reflect.Value) error) error func RegisterCustomDecoder[T any](decoder CustomDecoderFunc) { typ := reflect.TypeOf((*T)(nil)).Elem() customDecoderRegistry[typ] = decoder } ================================================ FILE: internal/apijson/subfield.go ================================================ package apijson import ( "github.com/anthropics/anthropic-sdk-go/packages/respjson" "reflect" ) func getSubField(root reflect.Value, index []int, name string) reflect.Value { strct := root.FieldByIndex(index[:len(index)-1]) if !strct.IsValid() { panic("couldn't find encapsulating struct for field " + name) } meta := strct.FieldByName("JSON") if !meta.IsValid() { return reflect.Value{} } field := meta.FieldByName(name) if !field.IsValid() { return reflect.Value{} } return field } func setMetadataSubField(root reflect.Value, index []int, name string, meta Field) { target := getSubField(root, index, name) if !target.IsValid() { return } if target.Type() == reflect.TypeOf(meta) { target.Set(reflect.ValueOf(meta)) } else if respMeta := meta.toRespField(); target.Type() == reflect.TypeOf(respMeta) { target.Set(reflect.ValueOf(respMeta)) } } func setMetadataExtraFields(root reflect.Value, index []int, name string, metaExtras map[string]Field) { target := getSubField(root, index, name) if !target.IsValid() { return } if target.Type() == reflect.TypeOf(metaExtras) { target.Set(reflect.ValueOf(metaExtras)) return } newMap := make(map[string]respjson.Field, len(metaExtras)) if target.Type() == reflect.TypeOf(newMap) { for k, v := range metaExtras { newMap[k] = v.toRespField() } target.Set(reflect.ValueOf(newMap)) } } func (f Field) toRespField() respjson.Field { if f.IsMissing() { return respjson.Field{} } else if f.IsNull() { return respjson.NewField("null") } else if f.IsInvalid() { return respjson.NewInvalidField(f.raw) } else { return respjson.NewField(f.raw) } } ================================================ FILE: internal/apijson/tag.go ================================================ package apijson import ( "reflect" "strings" ) const apiStructTag = "api" const jsonStructTag = "json" const formatStructTag = "format" type parsedStructTag struct { name string required bool extras bool metadata bool inline bool } func parseJSONStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) { raw, ok := field.Tag.Lookup(jsonStructTag) if !ok { return tag, ok } parts := strings.Split(raw, ",") if len(parts) == 0 { return tag, false } tag.name = parts[0] for _, part := range parts[1:] { switch part { case "required": tag.required = true case "extras": tag.extras = true case "metadata": tag.metadata = true case "inline": tag.inline = true } } // the `api` struct tag is only used alongside `json` for custom behaviour parseApiStructTag(field, &tag) return tag, ok } func parseApiStructTag(field reflect.StructField, tag *parsedStructTag) { raw, ok := field.Tag.Lookup(apiStructTag) if !ok { return } parts := strings.Split(raw, ",") for _, part := range parts { switch part { case "extrafields": tag.extras = true case "required": tag.required = true case "metadata": tag.metadata = true } } } func parseFormatStructTag(field reflect.StructField) (format string, ok bool) { format, ok = field.Tag.Lookup(formatStructTag) return format, ok } ================================================ FILE: internal/apijson/union.go ================================================ package apijson import ( "errors" "github.com/anthropics/anthropic-sdk-go/packages/param" "reflect" "github.com/tidwall/gjson" ) var apiUnionType = reflect.TypeOf(param.APIUnion{}) func isStructUnion(t reflect.Type) bool { if t.Kind() != reflect.Struct { return false } for i := 0; i < t.NumField(); i++ { if t.Field(i).Type == apiUnionType && t.Field(i).Anonymous { return true } } return false } func RegisterDiscriminatedUnion[T any](key string, mappings map[string]reflect.Type) { var t T entry := unionEntry{ discriminatorKey: key, variants: []UnionVariant{}, } for k, typ := range mappings { entry.variants = append(entry.variants, UnionVariant{ DiscriminatorValue: k, Type: typ, }) } unionRegistry[reflect.TypeOf(t)] = entry } func (d *decoderBuilder) newStructUnionDecoder(t reflect.Type) decoderFunc { type variantDecoder struct { decoder decoderFunc field reflect.StructField } decoders := []variantDecoder{} for i := 0; i < t.NumField(); i++ { field := t.Field(i) if field.Anonymous && field.Type == apiUnionType { continue } decoder := d.typeDecoder(field.Type) decoders = append(decoders, variantDecoder{ decoder: decoder, field: field, }) } type discriminatedDecoder struct { variantDecoder discriminator any } discriminatedDecoders := []discriminatedDecoder{} unionEntry, discriminated := unionRegistry[t] for _, variant := range unionEntry.variants { // For each union variant, find a matching decoder and save it for _, decoder := range decoders { if decoder.field.Type.Elem() == variant.Type { discriminatedDecoders = append(discriminatedDecoders, discriminatedDecoder{ decoder, variant.DiscriminatorValue, }) break } } } return func(n gjson.Result, v reflect.Value, state *decoderState) error { if discriminated && n.Type == gjson.JSON && len(unionEntry.discriminatorKey) != 0 { discriminator := n.Get(EscapeSJSONKey(unionEntry.discriminatorKey)).Value() for _, decoder := range discriminatedDecoders { if discriminator == decoder.discriminator { inner := v.FieldByIndex(decoder.field.Index) return decoder.decoder(n, inner, state) } } return errors.New("apijson: was not able to find discriminated union variant") } // Set bestExactness to worse than loose bestExactness := loose - 1 bestVariant := -1 for i, decoder := range decoders { // Pointers are used to discern JSON object variants from value variants if n.Type != gjson.JSON && decoder.field.Type.Kind() == reflect.Ptr { continue } sub := decoderState{strict: state.strict, exactness: exact} inner := v.FieldByIndex(decoder.field.Index) err := decoder.decoder(n, inner, &sub) if err != nil { continue } if sub.exactness == exact { bestExactness = exact bestVariant = i break } if sub.exactness > bestExactness { bestExactness = sub.exactness bestVariant = i } } if bestExactness < loose { return errors.New("apijson: was not able to coerce type as union") } if guardStrict(state, bestExactness != exact) { return errors.New("apijson: was not able to coerce type as union strictly") } for i := 0; i < len(decoders); i++ { if i == bestVariant { continue } v.FieldByIndex(decoders[i].field.Index).SetZero() } return nil } } // newUnionDecoder returns a decoderFunc that deserializes into a union using an // algorithm roughly similar to Pydantic's [smart algorithm]. // // Conceptually this is equivalent to choosing the best schema based on how 'exact' // the deserialization is for each of the schemas. // // If there is a tie in the level of exactness, then the tie is broken // left-to-right. // // [smart algorithm]: https://docs.pydantic.dev/latest/concepts/unions/#smart-mode func (d *decoderBuilder) newUnionDecoder(t reflect.Type) decoderFunc { unionEntry, ok := unionRegistry[t] if !ok { panic("apijson: couldn't find union of type " + t.String() + " in union registry") } decoders := []decoderFunc{} for _, variant := range unionEntry.variants { decoder := d.typeDecoder(variant.Type) decoders = append(decoders, decoder) } return func(n gjson.Result, v reflect.Value, state *decoderState) error { // If there is a discriminator match, circumvent the exactness logic entirely for idx, variant := range unionEntry.variants { decoder := decoders[idx] if variant.TypeFilter != n.Type { continue } if len(unionEntry.discriminatorKey) != 0 { discriminatorValue := n.Get(EscapeSJSONKey(unionEntry.discriminatorKey)).Value() if discriminatorValue == variant.DiscriminatorValue { inner := reflect.New(variant.Type).Elem() err := decoder(n, inner, state) v.Set(inner) return err } } } // Set bestExactness to worse than loose bestExactness := loose - 1 for idx, variant := range unionEntry.variants { decoder := decoders[idx] if variant.TypeFilter != n.Type { continue } sub := decoderState{strict: state.strict, exactness: exact} inner := reflect.New(variant.Type).Elem() err := decoder(n, inner, &sub) if err != nil { continue } if sub.exactness == exact { v.Set(inner) return nil } if sub.exactness > bestExactness { v.Set(inner) bestExactness = sub.exactness } } if bestExactness < loose { return errors.New("apijson: was not able to coerce type as union") } if guardStrict(state, bestExactness != exact) { return errors.New("apijson: was not able to coerce type as union strictly") } return nil } } ================================================ FILE: internal/apiquery/encoder.go ================================================ package apiquery import ( "encoding/json" "fmt" "reflect" "strconv" "strings" "sync" "time" "github.com/anthropics/anthropic-sdk-go/packages/param" ) var encoders sync.Map // map[reflect.Type]encoderFunc type encoder struct { dateFormat string root bool settings QuerySettings } type encoderFunc func(key string, value reflect.Value) ([]Pair, error) type encoderField struct { tag parsedStructTag fn encoderFunc idx []int } type encoderEntry struct { reflect.Type dateFormat string root bool settings QuerySettings } type Pair struct { key string value string } func (e *encoder) typeEncoder(t reflect.Type) encoderFunc { entry := encoderEntry{ Type: t, dateFormat: e.dateFormat, root: e.root, settings: e.settings, } if fi, ok := encoders.Load(entry); ok { return fi.(encoderFunc) } // To deal with recursive types, populate the map with an // indirect func before we build it. This type waits on the // real func (f) to be ready and then calls it. This indirect // func is only used for recursive types. var ( wg sync.WaitGroup f encoderFunc ) wg.Add(1) fi, loaded := encoders.LoadOrStore(entry, encoderFunc(func(key string, v reflect.Value) ([]Pair, error) { wg.Wait() return f(key, v) })) if loaded { return fi.(encoderFunc) } // Compute the real encoder and replace the indirect func with it. f = e.newTypeEncoder(t) wg.Done() encoders.Store(entry, f) return f } func marshalerEncoder(key string, value reflect.Value) ([]Pair, error) { s, err := value.Interface().(json.Marshaler).MarshalJSON() if err != nil { return nil, fmt.Errorf("apiquery: json fallback marshal error %s", err) } return []Pair{{key, string(s)}}, nil } func (e *encoder) newTypeEncoder(t reflect.Type) encoderFunc { if t.ConvertibleTo(reflect.TypeOf(time.Time{})) { return e.newTimeTypeEncoder(t) } if t.Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) { return e.newRichFieldTypeEncoder(t) } if !e.root && t.Implements(reflect.TypeOf((*json.Marshaler)(nil)).Elem()) { return marshalerEncoder } e.root = false switch t.Kind() { case reflect.Pointer: encoder := e.typeEncoder(t.Elem()) return func(key string, value reflect.Value) (pairs []Pair, err error) { if !value.IsValid() || value.IsNil() { return pairs, err } return encoder(key, value.Elem()) } case reflect.Struct: return e.newStructTypeEncoder(t) case reflect.Array: fallthrough case reflect.Slice: return e.newArrayTypeEncoder(t) case reflect.Map: return e.newMapEncoder(t) case reflect.Interface: return e.newInterfaceEncoder() default: return e.newPrimitiveTypeEncoder(t) } } func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc { if t.Implements(reflect.TypeOf((*param.Optional)(nil)).Elem()) { return e.newRichFieldTypeEncoder(t) } for i := 0; i < t.NumField(); i++ { if t.Field(i).Type == paramUnionType && t.Field(i).Anonymous { return e.newStructUnionTypeEncoder(t) } } encoderFields := []encoderField{} // This helper allows us to recursively collect field encoders into a flat // array. The parameter `index` keeps track of the access patterns necessary // to get to some field. var collectEncoderFields func(r reflect.Type, index []int) collectEncoderFields = func(r reflect.Type, index []int) { for i := 0; i < r.NumField(); i++ { idx := append(index, i) field := t.FieldByIndex(idx) if !field.IsExported() { continue } // If this is an embedded struct, traverse one level deeper to extract // the field and get their encoders as well. if field.Anonymous { collectEncoderFields(field.Type, idx) continue } // If query tag is not present, then we skip, which is intentionally // different behavior from the stdlib. ptag, ok := parseQueryStructTag(field) if !ok { continue } if (ptag.name == "-" || ptag.name == "") && !ptag.inline { continue } dateFormat, ok := parseFormatStructTag(field) oldFormat := e.dateFormat if ok { switch dateFormat { case "date-time": e.dateFormat = time.RFC3339 case "date": e.dateFormat = "2006-01-02" } } var encoderFn encoderFunc if ptag.omitzero { typeEncoderFn := e.typeEncoder(field.Type) encoderFn = func(key string, value reflect.Value) ([]Pair, error) { if value.IsZero() { return nil, nil } return typeEncoderFn(key, value) } } else { encoderFn = e.typeEncoder(field.Type) } encoderFields = append(encoderFields, encoderField{ptag, encoderFn, idx}) e.dateFormat = oldFormat } } collectEncoderFields(t, []int{}) return func(key string, value reflect.Value) (pairs []Pair, err error) { for _, ef := range encoderFields { subkey := e.renderKeyPath(key, ef.tag.name) if ef.tag.inline { subkey = key } field := value.FieldByIndex(ef.idx) subpairs, suberr := ef.fn(subkey, field) if suberr != nil { err = suberr } pairs = append(pairs, subpairs...) } return pairs, err } } var paramUnionType = reflect.TypeOf((*param.APIUnion)(nil)).Elem() func (e *encoder) newStructUnionTypeEncoder(t reflect.Type) encoderFunc { var fieldEncoders []encoderFunc for i := 0; i < t.NumField(); i++ { field := t.Field(i) if field.Type == paramUnionType && field.Anonymous { fieldEncoders = append(fieldEncoders, nil) continue } fieldEncoders = append(fieldEncoders, e.typeEncoder(field.Type)) } return func(key string, value reflect.Value) (pairs []Pair, err error) { for i := 0; i < t.NumField(); i++ { if value.Field(i).Type() == paramUnionType { continue } if !value.Field(i).IsZero() { return fieldEncoders[i](key, value.Field(i)) } } return nil, fmt.Errorf("apiquery: union %s has no field set", t.String()) } } func (e *encoder) newMapEncoder(t reflect.Type) encoderFunc { keyEncoder := e.typeEncoder(t.Key()) elementEncoder := e.typeEncoder(t.Elem()) return func(key string, value reflect.Value) (pairs []Pair, err error) { iter := value.MapRange() for iter.Next() { encodedKey, err := keyEncoder("", iter.Key()) if err != nil { return nil, err } if len(encodedKey) != 1 { return nil, fmt.Errorf("apiquery: unexpected number of parts for encoded map key, map may contain non-primitive") } subkey := encodedKey[0].value keyPath := e.renderKeyPath(key, subkey) subpairs, suberr := elementEncoder(keyPath, iter.Value()) if suberr != nil { err = suberr } pairs = append(pairs, subpairs...) } return pairs, err } } func (e *encoder) renderKeyPath(key string, subkey string) string { if len(key) == 0 { return subkey } if e.settings.NestedFormat == NestedQueryFormatDots { return fmt.Sprintf("%s.%s", key, subkey) } return fmt.Sprintf("%s[%s]", key, subkey) } func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc { switch e.settings.ArrayFormat { case ArrayQueryFormatComma: innerEncoder := e.typeEncoder(t.Elem()) return func(key string, v reflect.Value) ([]Pair, error) { elements := []string{} for i := 0; i < v.Len(); i++ { innerPairs, err := innerEncoder("", v.Index(i)) if err != nil { return nil, err } for _, pair := range innerPairs { elements = append(elements, pair.value) } } if len(elements) == 0 { return []Pair{}, nil } return []Pair{{key, strings.Join(elements, ",")}}, nil } case ArrayQueryFormatRepeat: innerEncoder := e.typeEncoder(t.Elem()) return func(key string, value reflect.Value) (pairs []Pair, err error) { for i := 0; i < value.Len(); i++ { subpairs, suberr := innerEncoder(key, value.Index(i)) if suberr != nil { err = suberr } pairs = append(pairs, subpairs...) } return pairs, err } case ArrayQueryFormatIndices: panic("The array indices format is not supported yet") case ArrayQueryFormatBrackets: innerEncoder := e.typeEncoder(t.Elem()) return func(key string, value reflect.Value) (pairs []Pair, err error) { pairs = []Pair{} for i := 0; i < value.Len(); i++ { subpairs, suberr := innerEncoder(key+"[]", value.Index(i)) if suberr != nil { err = suberr } pairs = append(pairs, subpairs...) } return pairs, err } default: panic(fmt.Sprintf("Unknown ArrayFormat value: %d", e.settings.ArrayFormat)) } } func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc { switch t.Kind() { case reflect.Pointer: inner := t.Elem() innerEncoder := e.newPrimitiveTypeEncoder(inner) return func(key string, v reflect.Value) ([]Pair, error) { if !v.IsValid() || v.IsNil() { return nil, nil } return innerEncoder(key, v.Elem()) } case reflect.String: return func(key string, v reflect.Value) ([]Pair, error) { return []Pair{{key, v.String()}}, nil } case reflect.Bool: return func(key string, v reflect.Value) ([]Pair, error) { if v.Bool() { return []Pair{{key, "true"}}, nil } return []Pair{{key, "false"}}, nil } case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: return func(key string, v reflect.Value) ([]Pair, error) { return []Pair{{key, strconv.FormatInt(v.Int(), 10)}}, nil } case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: return func(key string, v reflect.Value) ([]Pair, error) { return []Pair{{key, strconv.FormatUint(v.Uint(), 10)}}, nil } case reflect.Float32, reflect.Float64: return func(key string, v reflect.Value) ([]Pair, error) { return []Pair{{key, strconv.FormatFloat(v.Float(), 'f', -1, 64)}}, nil } case reflect.Complex64, reflect.Complex128: bitSize := 64 if t.Kind() == reflect.Complex128 { bitSize = 128 } return func(key string, v reflect.Value) ([]Pair, error) { return []Pair{{key, strconv.FormatComplex(v.Complex(), 'f', -1, bitSize)}}, nil } default: return func(key string, v reflect.Value) ([]Pair, error) { return nil, nil } } } func (e *encoder) newTimeTypeEncoder(_ reflect.Type) encoderFunc { format := e.dateFormat return func(key string, value reflect.Value) ([]Pair, error) { return []Pair{{ key, value.Convert(reflect.TypeOf(time.Time{})).Interface().(time.Time).Format(format), }}, nil } } func (e encoder) newInterfaceEncoder() encoderFunc { return func(key string, value reflect.Value) ([]Pair, error) { value = value.Elem() if !value.IsValid() { return nil, nil } return e.typeEncoder(value.Type())(key, value) } } ================================================ FILE: internal/apiquery/query.go ================================================ package apiquery import ( "net/url" "reflect" "time" ) func MarshalWithSettings(value any, settings QuerySettings) (url.Values, error) { e := encoder{time.RFC3339, true, settings} kv := url.Values{} val := reflect.ValueOf(value) if !val.IsValid() { return nil, nil } typ := val.Type() pairs, err := e.typeEncoder(typ)("", val) if err != nil { return nil, err } for _, pair := range pairs { kv.Add(pair.key, pair.value) } return kv, nil } func Marshal(value any) (url.Values, error) { return MarshalWithSettings(value, QuerySettings{}) } type Queryer interface { URLQuery() (url.Values, error) } type QuerySettings struct { NestedFormat NestedQueryFormat ArrayFormat ArrayQueryFormat } type NestedQueryFormat int const ( NestedQueryFormatBrackets NestedQueryFormat = iota NestedQueryFormatDots ) type ArrayQueryFormat int const ( ArrayQueryFormatComma ArrayQueryFormat = iota ArrayQueryFormatRepeat ArrayQueryFormatIndices ArrayQueryFormatBrackets ) ================================================ FILE: internal/apiquery/query_test.go ================================================ package apiquery import ( "github.com/anthropics/anthropic-sdk-go/packages/param" "net/url" "testing" "time" ) func P[T any](v T) *T { return &v } type Primitives struct { A bool `query:"a"` B int `query:"b"` C uint `query:"c"` D float64 `query:"d"` E float32 `query:"e"` F []int `query:"f"` } type PrimitivePointers struct { A *bool `query:"a"` B *int `query:"b"` C *uint `query:"c"` D *float64 `query:"d"` E *float32 `query:"e"` F *[]int `query:"f"` } type Slices struct { Slice []Primitives `query:"slices"` Mixed []any `query:"mixed"` } type DateTime struct { Date time.Time `query:"date" format:"date"` DateTime time.Time `query:"date-time" format:"date-time"` } type AdditionalProperties struct { A bool `query:"a"` Extras map[string]any `query:"-,inline"` } type Recursive struct { Name string `query:"name"` Child *Recursive `query:"child"` } type UnknownStruct struct { Unknown any `query:"unknown"` } type UnionStruct struct { Union Union `query:"union" format:"date"` } type Union interface { union() } type UnionInteger int64 func (UnionInteger) union() {} type UnionString string func (UnionString) union() {} type UnionStructA struct { Type string `query:"type"` A string `query:"a"` B string `query:"b"` } func (UnionStructA) union() {} type UnionStructB struct { Type string `query:"type"` A string `query:"a"` } func (UnionStructB) union() {} type UnionTime time.Time func (UnionTime) union() {} type DeeplyNested struct { A DeeplyNested1 `query:"a"` } type DeeplyNested1 struct { B DeeplyNested2 `query:"b"` } type DeeplyNested2 struct { C DeeplyNested3 `query:"c"` } type DeeplyNested3 struct { D *string `query:"d"` } type RichPrimitives struct { A param.Opt[string] `query:"a"` } type QueryOmitTest struct { A param.Opt[string] `query:"a,omitzero"` B string `query:"b,omitzero"` } type NamedEnum string const NamedEnumFoo NamedEnum = "foo" type StructUnionWrapper struct { Union StructUnion `query:"union"` } type StructUnion struct { OfInt param.Opt[int64] `query:",omitzero,inline"` OfString param.Opt[string] `query:",omitzero,inline"` OfEnum param.Opt[NamedEnum] `query:",omitzero,inline"` OfA UnionStructA `query:",omitzero,inline"` OfB UnionStructB `query:",omitzero,inline"` param.APIUnion } var tests = map[string]struct { enc string val any settings QuerySettings }{ "primitives": { "a=false&b=237628372683&c=654&d=9999.43&e=43.7599983215332&f=1,2,3,4", Primitives{A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}, QuerySettings{}, }, "slices_brackets": { `mixed[]=1&mixed[]=2.3&mixed[]=hello&slices[][a]=false&slices[][a]=false&slices[][b]=237628372683&slices[][b]=237628372683&slices[][c]=654&slices[][c]=654&slices[][d]=9999.43&slices[][d]=9999.43&slices[][e]=43.7599983215332&slices[][e]=43.7599983215332&slices[][f][]=1&slices[][f][]=2&slices[][f][]=3&slices[][f][]=4&slices[][f][]=1&slices[][f][]=2&slices[][f][]=3&slices[][f][]=4`, Slices{ Slice: []Primitives{ {A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}, {A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}, }, Mixed: []any{1, 2.3, "hello"}, }, QuerySettings{ArrayFormat: ArrayQueryFormatBrackets}, }, "slices_comma": { `mixed=1,2.3,hello`, Slices{ Mixed: []any{1, 2.3, "hello"}, }, QuerySettings{ArrayFormat: ArrayQueryFormatComma}, }, "slices_repeat": { `mixed=1&mixed=2.3&mixed=hello&slices[a]=false&slices[a]=false&slices[b]=237628372683&slices[b]=237628372683&slices[c]=654&slices[c]=654&slices[d]=9999.43&slices[d]=9999.43&slices[e]=43.7599983215332&slices[e]=43.7599983215332&slices[f]=1&slices[f]=2&slices[f]=3&slices[f]=4&slices[f]=1&slices[f]=2&slices[f]=3&slices[f]=4`, Slices{ Slice: []Primitives{ {A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}, {A: false, B: 237628372683, C: uint(654), D: 9999.43, E: 43.76, F: []int{1, 2, 3, 4}}, }, Mixed: []any{1, 2.3, "hello"}, }, QuerySettings{ArrayFormat: ArrayQueryFormatRepeat}, }, "primitive_pointer_struct": { "a=false&b=237628372683&c=654&d=9999.43&e=43.7599983215332&f=1,2,3,4,5", PrimitivePointers{ A: P(false), B: P(237628372683), C: P(uint(654)), D: P(9999.43), E: P(float32(43.76)), F: &[]int{1, 2, 3, 4, 5}, }, QuerySettings{}, }, "datetime_struct": { `date=2006-01-02&date-time=2006-01-02T15:04:05Z`, DateTime{ Date: time.Date(2006, time.January, 2, 0, 0, 0, 0, time.UTC), DateTime: time.Date(2006, time.January, 2, 15, 4, 5, 0, time.UTC), }, QuerySettings{}, }, "additional_properties": { `a=true&bar=value&foo=true`, AdditionalProperties{ A: true, Extras: map[string]any{ "bar": "value", "foo": true, }, }, QuerySettings{}, }, "recursive_struct_brackets": { `child[name]=Alex&name=Robert`, Recursive{Name: "Robert", Child: &Recursive{Name: "Alex"}}, QuerySettings{NestedFormat: NestedQueryFormatBrackets}, }, "recursive_struct_dots": { `child.name=Alex&name=Robert`, Recursive{Name: "Robert", Child: &Recursive{Name: "Alex"}}, QuerySettings{NestedFormat: NestedQueryFormatDots}, }, "unknown_struct_number": { `unknown=12`, UnknownStruct{ Unknown: 12., }, QuerySettings{}, }, "unknown_struct_map_brackets": { `unknown[foo]=bar`, UnknownStruct{ Unknown: map[string]any{ "foo": "bar", }, }, QuerySettings{NestedFormat: NestedQueryFormatBrackets}, }, "unknown_struct_map_dots": { `unknown.foo=bar`, UnknownStruct{ Unknown: map[string]any{ "foo": "bar", }, }, QuerySettings{NestedFormat: NestedQueryFormatDots}, }, "struct_union_string": { `union=hello`, StructUnionWrapper{ Union: StructUnion{OfString: param.NewOpt("hello")}, }, QuerySettings{}, }, "union_string": { `union=hello`, UnionStruct{ Union: UnionString("hello"), }, QuerySettings{}, }, "struct_union_integer": { `union=12`, StructUnionWrapper{ Union: StructUnion{OfInt: param.NewOpt[int64](12)}, }, QuerySettings{}, }, "union_integer": { `union=12`, UnionStruct{ Union: UnionInteger(12), }, QuerySettings{}, }, "struct_union_enum": { `union=foo`, StructUnionWrapper{ Union: StructUnion{OfEnum: param.NewOpt[NamedEnum](NamedEnumFoo)}, }, QuerySettings{}, }, "struct_union_struct_discriminated_a": { `union[a]=foo&union[b]=bar&union[type]=typeA`, StructUnionWrapper{ Union: StructUnion{OfA: UnionStructA{ Type: "typeA", A: "foo", B: "bar", }}, }, QuerySettings{}, }, "union_struct_discriminated_a": { `union[a]=foo&union[b]=bar&union[type]=typeA`, UnionStruct{ Union: UnionStructA{ Type: "typeA", A: "foo", B: "bar", }, }, QuerySettings{}, }, "struct_union_struct_discriminated_b": { `union[a]=foo&union[type]=typeB`, StructUnionWrapper{ Union: StructUnion{OfB: UnionStructB{ Type: "typeB", A: "foo", }}, }, QuerySettings{}, }, "union_struct_discriminated_b": { `union[a]=foo&union[type]=typeB`, UnionStruct{ Union: UnionStructB{ Type: "typeB", A: "foo", }, }, QuerySettings{}, }, "union_struct_time": { `union=2010-05-23`, UnionStruct{ Union: UnionTime(time.Date(2010, 05, 23, 0, 0, 0, 0, time.UTC)), }, QuerySettings{}, }, "deeply_nested_brackets": { `a[b][c][d]=hello`, DeeplyNested{ A: DeeplyNested1{ B: DeeplyNested2{ C: DeeplyNested3{ D: P("hello"), }, }, }, }, QuerySettings{NestedFormat: NestedQueryFormatBrackets}, }, "deeply_nested_dots": { `a.b.c.d=hello`, DeeplyNested{ A: DeeplyNested1{ B: DeeplyNested2{ C: DeeplyNested3{ D: P("hello"), }, }, }, }, QuerySettings{NestedFormat: NestedQueryFormatDots}, }, "deeply_nested_brackets_empty": { ``, DeeplyNested{ A: DeeplyNested1{ B: DeeplyNested2{ C: DeeplyNested3{ D: nil, }, }, }, }, QuerySettings{NestedFormat: NestedQueryFormatBrackets}, }, "deeply_nested_dots_empty": { ``, DeeplyNested{ A: DeeplyNested1{ B: DeeplyNested2{ C: DeeplyNested3{ D: nil, }, }, }, }, QuerySettings{NestedFormat: NestedQueryFormatDots}, }, "rich_primitives": { `a=hello`, RichPrimitives{ A: param.Opt[string]{Value: "hello"}, }, QuerySettings{}, }, "rich_primitives_omit": { ``, QueryOmitTest{ A: param.Opt[string]{}, }, QuerySettings{}, }, "query_omit": { `a=hello`, QueryOmitTest{ A: param.Opt[string]{Value: "hello"}, }, QuerySettings{}, }, } func TestEncode(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { values, err := MarshalWithSettings(test.val, test.settings) if err != nil { t.Fatalf("failed to marshal url %s", err) } str, _ := url.QueryUnescape(values.Encode()) if str != test.enc { t.Fatalf("expected %+#v to serialize to %s but got %s", test.val, test.enc, str) } }) } } ================================================ FILE: internal/apiquery/richparam.go ================================================ package apiquery import ( "github.com/anthropics/anthropic-sdk-go/packages/param" "reflect" ) func (e *encoder) newRichFieldTypeEncoder(t reflect.Type) encoderFunc { f, _ := t.FieldByName("Value") enc := e.typeEncoder(f.Type) return func(key string, value reflect.Value) ([]Pair, error) { if opt, ok := value.Interface().(param.Optional); ok && opt.Valid() { return enc(key, value.FieldByIndex(f.Index)) } else if ok && param.IsNull(opt) { return []Pair{{key, "null"}}, nil } return nil, nil } } ================================================ FILE: internal/apiquery/tag.go ================================================ package apiquery import ( "reflect" "strings" ) const queryStructTag = "query" const formatStructTag = "format" type parsedStructTag struct { name string omitempty bool omitzero bool inline bool } func parseQueryStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) { raw, ok := field.Tag.Lookup(queryStructTag) if !ok { return tag, ok } parts := strings.Split(raw, ",") if len(parts) == 0 { return tag, false } tag.name = parts[0] for _, part := range parts[1:] { switch part { case "omitzero": tag.omitzero = true case "omitempty": tag.omitempty = true case "inline": tag.inline = true } } return tag, ok } func parseFormatStructTag(field reflect.StructField) (format string, ok bool) { format, ok = field.Tag.Lookup(formatStructTag) return format, ok } ================================================ FILE: internal/encoding/json/decode.go ================================================ // Vendored from Go 1.24.0-pre-release // To find alterations, check package shims, and comments beginning in SHIM(). // // Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Represents JSON data structure using native Go types: booleans, floats, // strings, arrays, and maps. package json import ( "encoding" "encoding/base64" "fmt" "github.com/anthropics/anthropic-sdk-go/internal/encoding/json/shims" "reflect" "strconv" "strings" "unicode" "unicode/utf16" "unicode/utf8" _ "unsafe" // for linkname ) // Unmarshal parses the JSON-encoded data and stores the result // in the value pointed to by v. If v is nil or not a pointer, // Unmarshal returns an [InvalidUnmarshalError]. // // Unmarshal uses the inverse of the encodings that // [Marshal] uses, allocating maps, slices, and pointers as necessary, // with the following additional rules: // // To unmarshal JSON into a pointer, Unmarshal first handles the case of // the JSON being the JSON literal null. In that case, Unmarshal sets // the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into // the value pointed at by the pointer. If the pointer is nil, Unmarshal // allocates a new value for it to point to. // // To unmarshal JSON into a value implementing [Unmarshaler], // Unmarshal calls that value's [Unmarshaler.UnmarshalJSON] method, including // when the input is a JSON null. // Otherwise, if the value implements [encoding.TextUnmarshaler] // and the input is a JSON quoted string, Unmarshal calls // [encoding.TextUnmarshaler.UnmarshalText] with the unquoted form of the string. // // To unmarshal JSON into a struct, Unmarshal matches incoming object // keys to the keys used by [Marshal] (either the struct field name or its tag), // preferring an exact match but also accepting a case-insensitive match. By // default, object keys which don't have a corresponding struct field are // ignored (see [Decoder.DisallowUnknownFields] for an alternative). // // To unmarshal JSON into an interface value, // Unmarshal stores one of these in the interface value: // // - bool, for JSON booleans // - float64, for JSON numbers // - string, for JSON strings // - []any, for JSON arrays // - map[string]any, for JSON objects // - nil for JSON null // // To unmarshal a JSON array into a slice, Unmarshal resets the slice length // to zero and then appends each element to the slice. // As a special case, to unmarshal an empty JSON array into a slice, // Unmarshal replaces the slice with a new empty slice. // // To unmarshal a JSON array into a Go array, Unmarshal decodes // JSON array elements into corresponding Go array elements. // If the Go array is smaller than the JSON array, // the additional JSON array elements are discarded. // If the JSON array is smaller than the Go array, // the additional Go array elements are set to zero values. // // To unmarshal a JSON object into a map, Unmarshal first establishes a map to // use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal // reuses the existing map, keeping existing entries. Unmarshal then stores // key-value pairs from the JSON object into the map. The map's key type must // either be any string type, an integer, or implement [encoding.TextUnmarshaler]. // // If the JSON-encoded data contain a syntax error, Unmarshal returns a [SyntaxError]. // // If a JSON value is not appropriate for a given target type, // or if a JSON number overflows the target type, Unmarshal // skips that field and completes the unmarshaling as best it can. // If no more serious errors are encountered, Unmarshal returns // an [UnmarshalTypeError] describing the earliest such error. In any // case, it's not guaranteed that all the remaining fields following // the problematic one will be unmarshaled into the target object. // // The JSON null value unmarshals into an interface, map, pointer, or slice // by setting that Go value to nil. Because null is often used in JSON to mean // “not present,” unmarshaling a JSON null into any other Go type has no effect // on the value and produces no error. // // When unmarshaling quoted strings, invalid UTF-8 or // invalid UTF-16 surrogate pairs are not treated as an error. // Instead, they are replaced by the Unicode replacement // character U+FFFD. func Unmarshal(data []byte, v any) error { // Check for well-formedness. // Avoids filling out half a data structure // before discovering a JSON syntax error. var d decodeState err := checkValid(data, &d.scan) if err != nil { return err } d.init(data) return d.unmarshal(v) } // Unmarshaler is the interface implemented by types // that can unmarshal a JSON description of themselves. // The input can be assumed to be a valid encoding of // a JSON value. UnmarshalJSON must copy the JSON data // if it wishes to retain the data after returning. // // By convention, to approximate the behavior of [Unmarshal] itself, // Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. type Unmarshaler interface { UnmarshalJSON([]byte) error } // An UnmarshalTypeError describes a JSON value that was // not appropriate for a value of a specific Go type. type UnmarshalTypeError struct { Value string // description of JSON value - "bool", "array", "number -5" Type reflect.Type // type of Go value it could not be assigned to Offset int64 // error occurred after reading Offset bytes Struct string // name of the struct type containing the field Field string // the full path from root node to the field, include embedded struct } func (e *UnmarshalTypeError) Error() string { if e.Struct != "" || e.Field != "" { return "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type.String() } return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() } // An UnmarshalFieldError describes a JSON object key that // led to an unexported (and therefore unwritable) struct field. // // Deprecated: No longer used; kept for compatibility. type UnmarshalFieldError struct { Key string Type reflect.Type Field reflect.StructField } func (e *UnmarshalFieldError) Error() string { return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String() } // An InvalidUnmarshalError describes an invalid argument passed to [Unmarshal]. // (The argument to [Unmarshal] must be a non-nil pointer.) type InvalidUnmarshalError struct { Type reflect.Type } func (e *InvalidUnmarshalError) Error() string { if e.Type == nil { return "json: Unmarshal(nil)" } if e.Type.Kind() != reflect.Pointer { return "json: Unmarshal(non-pointer " + e.Type.String() + ")" } return "json: Unmarshal(nil " + e.Type.String() + ")" } func (d *decodeState) unmarshal(v any) error { rv := reflect.ValueOf(v) if rv.Kind() != reflect.Pointer || rv.IsNil() { return &InvalidUnmarshalError{reflect.TypeOf(v)} } d.scan.reset() d.scanWhile(scanSkipSpace) // We decode rv not rv.Elem because the Unmarshaler interface // test must be applied at the top level of the value. err := d.value(rv) if err != nil { return d.addErrorContext(err) } return d.savedError } // A Number represents a JSON number literal. type Number string // String returns the literal text of the number. func (n Number) String() string { return string(n) } // Float64 returns the number as a float64. func (n Number) Float64() (float64, error) { return strconv.ParseFloat(string(n), 64) } // Int64 returns the number as an int64. func (n Number) Int64() (int64, error) { return strconv.ParseInt(string(n), 10, 64) } // An errorContext provides context for type errors during decoding. type errorContext struct { Struct reflect.Type FieldStack []string } // decodeState represents the state while decoding a JSON value. type decodeState struct { data []byte off int // next read offset in data opcode int // last read result scan scanner errorContext *errorContext savedError error useNumber bool disallowUnknownFields bool } // readIndex returns the position of the last byte read. func (d *decodeState) readIndex() int { return d.off - 1 } // phasePanicMsg is used as a panic message when we end up with something that // shouldn't happen. It can indicate a bug in the JSON decoder, or that // something is editing the data slice while the decoder executes. const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?" func (d *decodeState) init(data []byte) *decodeState { d.data = data d.off = 0 d.savedError = nil if d.errorContext != nil { d.errorContext.Struct = nil // Reuse the allocated space for the FieldStack slice. d.errorContext.FieldStack = d.errorContext.FieldStack[:0] } return d } // saveError saves the first err it is called with, // for reporting at the end of the unmarshal. func (d *decodeState) saveError(err error) { if d.savedError == nil { d.savedError = d.addErrorContext(err) } } // addErrorContext returns a new error enhanced with information from d.errorContext func (d *decodeState) addErrorContext(err error) error { if d.errorContext != nil && (d.errorContext.Struct != nil || len(d.errorContext.FieldStack) > 0) { switch err := err.(type) { case *UnmarshalTypeError: err.Struct = d.errorContext.Struct.Name() fieldStack := d.errorContext.FieldStack if err.Field != "" { fieldStack = append(fieldStack, err.Field) } err.Field = strings.Join(fieldStack, ".") } } return err } // skip scans to the end of what was started. func (d *decodeState) skip() { s, data, i := &d.scan, d.data, d.off depth := len(s.parseState) for { op := s.step(s, data[i]) i++ if len(s.parseState) < depth { d.off = i d.opcode = op return } } } // scanNext processes the byte at d.data[d.off]. func (d *decodeState) scanNext() { if d.off < len(d.data) { d.opcode = d.scan.step(&d.scan, d.data[d.off]) d.off++ } else { d.opcode = d.scan.eof() d.off = len(d.data) + 1 // mark processed EOF with len+1 } } // scanWhile processes bytes in d.data[d.off:] until it // receives a scan code not equal to op. func (d *decodeState) scanWhile(op int) { s, data, i := &d.scan, d.data, d.off for i < len(data) { newOp := s.step(s, data[i]) i++ if newOp != op { d.opcode = newOp d.off = i return } } d.off = len(data) + 1 // mark processed EOF with len+1 d.opcode = d.scan.eof() } // rescanLiteral is similar to scanWhile(scanContinue), but it specialises the // common case where we're decoding a literal. The decoder scans the input // twice, once for syntax errors and to check the length of the value, and the // second to perform the decoding. // // Only in the second step do we use decodeState to tokenize literals, so we // know there aren't any syntax errors. We can take advantage of that knowledge, // and scan a literal's bytes much more quickly. func (d *decodeState) rescanLiteral() { data, i := d.data, d.off Switch: switch data[i-1] { case '"': // string for ; i < len(data); i++ { switch data[i] { case '\\': i++ // escaped char case '"': i++ // tokenize the closing quote too break Switch } } case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': // number for ; i < len(data); i++ { switch data[i] { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E', '+', '-': default: break Switch } } case 't': // true i += len("rue") case 'f': // false i += len("alse") case 'n': // null i += len("ull") } if i < len(data) { d.opcode = stateEndValue(&d.scan, data[i]) } else { d.opcode = scanEnd } d.off = i + 1 } // value consumes a JSON value from d.data[d.off-1:], decoding into v, and // reads the following byte ahead. If v is invalid, the value is discarded. // The first byte of the value has been read already. func (d *decodeState) value(v reflect.Value) error { switch d.opcode { default: panic(phasePanicMsg) case scanBeginArray: if v.IsValid() { if err := d.array(v); err != nil { return err } } else { d.skip() } d.scanNext() case scanBeginObject: if v.IsValid() { if err := d.object(v); err != nil { return err } } else { d.skip() } d.scanNext() case scanBeginLiteral: // All bytes inside literal return scanContinue op code. start := d.readIndex() d.rescanLiteral() if v.IsValid() { if err := d.literalStore(d.data[start:d.readIndex()], v, false); err != nil { return err } } } return nil } type unquotedValue struct{} // valueQuoted is like value but decodes a // quoted string literal or literal null into an interface value. // If it finds anything other than a quoted string literal or null, // valueQuoted returns unquotedValue{}. func (d *decodeState) valueQuoted() any { switch d.opcode { default: panic(phasePanicMsg) case scanBeginArray, scanBeginObject: d.skip() d.scanNext() case scanBeginLiteral: v := d.literalInterface() switch v.(type) { case nil, string: return v } } return unquotedValue{} } // indirect walks down v allocating pointers as needed, // until it gets to a non-pointer. // If it encounters an Unmarshaler, indirect stops and returns that. // If decodingNull is true, indirect stops at the first settable pointer so it // can be set to nil. func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { // Issue #24153 indicates that it is generally not a guaranteed property // that you may round-trip a reflect.Value by calling Value.Addr().Elem() // and expect the value to still be settable for values derived from // unexported embedded struct fields. // // The logic below effectively does this when it first addresses the value // (to satisfy possible pointer methods) and continues to dereference // subsequent pointers as necessary. // // After the first round-trip, we set v back to the original value to // preserve the original RW flags contained in reflect.Value. v0 := v haveAddr := false // If v is a named type and is addressable, // start with its address, so that if the type has pointer methods, // we find them. if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() { haveAddr = true v = v.Addr() } for { // Load value from interface, but only if the result will be // usefully addressable. if v.Kind() == reflect.Interface && !v.IsNil() { e := v.Elem() if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) { haveAddr = false v = e continue } } if v.Kind() != reflect.Pointer { break } if decodingNull && v.CanSet() { break } // Prevent infinite loop if v is an interface pointing to its own address: // var v any // v = &v if v.Elem().Kind() == reflect.Interface && v.Elem().Elem().Equal(v) { v = v.Elem() break } if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } if v.Type().NumMethod() > 0 && v.CanInterface() { if u, ok := v.Interface().(Unmarshaler); ok { return u, nil, reflect.Value{} } if !decodingNull { if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { return nil, u, reflect.Value{} } } } if haveAddr { v = v0 // restore original value after round-trip Value.Addr().Elem() haveAddr = false } else { v = v.Elem() } } return nil, nil, v } // array consumes an array from d.data[d.off-1:], decoding into v. // The first byte of the array ('[') has been read already. func (d *decodeState) array(v reflect.Value) error { // Check for unmarshaler. u, ut, pv := indirect(v, false) if u != nil { start := d.readIndex() d.skip() return u.UnmarshalJSON(d.data[start:d.off]) } if ut != nil { d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)}) d.skip() return nil } v = pv // Check type of target. switch v.Kind() { case reflect.Interface: if v.NumMethod() == 0 { // Decoding into nil interface? Switch to non-reflect code. ai := d.arrayInterface() v.Set(reflect.ValueOf(ai)) return nil } // Otherwise it's invalid. fallthrough default: d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)}) d.skip() return nil case reflect.Array, reflect.Slice: break } i := 0 for { // Look ahead for ] - can only happen on first iteration. d.scanWhile(scanSkipSpace) if d.opcode == scanEndArray { break } // Expand slice length, growing the slice if necessary. if v.Kind() == reflect.Slice { if i >= v.Cap() { v.Grow(1) } if i >= v.Len() { v.SetLen(i + 1) } } if i < v.Len() { // Decode into element. if err := d.value(v.Index(i)); err != nil { return err } } else { // Ran out of fixed array: skip. if err := d.value(reflect.Value{}); err != nil { return err } } i++ // Next token must be , or ]. if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } if d.opcode == scanEndArray { break } if d.opcode != scanArrayValue { panic(phasePanicMsg) } } if i < v.Len() { if v.Kind() == reflect.Array { for ; i < v.Len(); i++ { v.Index(i).SetZero() // zero remainder of array } } else { v.SetLen(i) // truncate the slice } } if i == 0 && v.Kind() == reflect.Slice { v.Set(reflect.MakeSlice(v.Type(), 0, 0)) } return nil } var nullLiteral = []byte("null") // SHIM(reflect): reflect.TypeFor[T]() reflect.T var textUnmarshalerType = shims.TypeFor[encoding.TextUnmarshaler]() // object consumes an object from d.data[d.off-1:], decoding into v. // The first byte ('{') of the object has been read already. func (d *decodeState) object(v reflect.Value) error { // Check for unmarshaler. u, ut, pv := indirect(v, false) if u != nil { start := d.readIndex() d.skip() return u.UnmarshalJSON(d.data[start:d.off]) } if ut != nil { d.saveError(&UnmarshalTypeError{Value: "object", Type: v.Type(), Offset: int64(d.off)}) d.skip() return nil } v = pv t := v.Type() // Decoding into nil interface? Switch to non-reflect code. if v.Kind() == reflect.Interface && v.NumMethod() == 0 { oi := d.objectInterface() v.Set(reflect.ValueOf(oi)) return nil } var fields structFields // Check type of target: // struct or // map[T1]T2 where T1 is string, an integer type, // or an encoding.TextUnmarshaler switch v.Kind() { case reflect.Map: // Map key must either have string kind, have an integer kind, // or be an encoding.TextUnmarshaler. switch t.Key().Kind() { case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: default: if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) { d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)}) d.skip() return nil } } if v.IsNil() { v.Set(reflect.MakeMap(t)) } case reflect.Struct: fields = cachedTypeFields(t) // ok default: d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)}) d.skip() return nil } var mapElem reflect.Value var origErrorContext errorContext if d.errorContext != nil { origErrorContext = *d.errorContext } for { // Read opening " of string key or closing }. d.scanWhile(scanSkipSpace) if d.opcode == scanEndObject { // closing } - can only happen on first iteration. break } if d.opcode != scanBeginLiteral { panic(phasePanicMsg) } // Read key. start := d.readIndex() d.rescanLiteral() item := d.data[start:d.readIndex()] key, ok := unquoteBytes(item) if !ok { panic(phasePanicMsg) } // Figure out field corresponding to key. var subv reflect.Value destring := false // whether the value is wrapped in a string to be decoded first if v.Kind() == reflect.Map { elemType := t.Elem() if !mapElem.IsValid() { mapElem = reflect.New(elemType).Elem() } else { mapElem.SetZero() } subv = mapElem } else { f := fields.byExactName[string(key)] if f == nil { f = fields.byFoldedName[string(foldName(key))] } if f != nil { subv = v destring = f.quoted if d.errorContext == nil { d.errorContext = new(errorContext) } for i, ind := range f.index { if subv.Kind() == reflect.Pointer { if subv.IsNil() { // If a struct embeds a pointer to an unexported type, // it is not possible to set a newly allocated value // since the field is unexported. // // See https://golang.org/issue/21357 if !subv.CanSet() { d.saveError(fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", subv.Type().Elem())) // Invalidate subv to ensure d.value(subv) skips over // the JSON value without assigning it to subv. subv = reflect.Value{} destring = false break } subv.Set(reflect.New(subv.Type().Elem())) } subv = subv.Elem() } if i < len(f.index)-1 { d.errorContext.FieldStack = append( d.errorContext.FieldStack, subv.Type().Field(ind).Name, ) } subv = subv.Field(ind) } d.errorContext.Struct = t d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name) } else if d.disallowUnknownFields { d.saveError(fmt.Errorf("json: unknown field %q", key)) } } // Read : before value. if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } if d.opcode != scanObjectKey { panic(phasePanicMsg) } d.scanWhile(scanSkipSpace) if destring { switch qv := d.valueQuoted().(type) { case nil: if err := d.literalStore(nullLiteral, subv, false); err != nil { return err } case string: if err := d.literalStore([]byte(qv), subv, true); err != nil { return err } default: d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) } } else { if err := d.value(subv); err != nil { return err } } // Write value back to map; // if using struct, subv points into struct already. if v.Kind() == reflect.Map { kt := t.Key() var kv reflect.Value if reflect.PointerTo(kt).Implements(textUnmarshalerType) { kv = reflect.New(kt) if err := d.literalStore(item, kv, true); err != nil { return err } kv = kv.Elem() } else { switch kt.Kind() { case reflect.String: kv = reflect.New(kt).Elem() kv.SetString(string(key)) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: s := string(key) n, err := strconv.ParseInt(s, 10, 64) // SHIM(reflect): reflect.Type.OverflowInt(int64) bool okt := shims.OverflowableType{Type: kt} if err != nil || okt.OverflowInt(n) { d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)}) break } kv = reflect.New(kt).Elem() kv.SetInt(n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: s := string(key) n, err := strconv.ParseUint(s, 10, 64) // SHIM(reflect): reflect.Type.OverflowUint(uint64) bool okt := shims.OverflowableType{Type: kt} if err != nil || okt.OverflowUint(n) { d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)}) break } kv = reflect.New(kt).Elem() kv.SetUint(n) default: panic("json: Unexpected key type") // should never occur } } if kv.IsValid() { v.SetMapIndex(kv, subv) } } // Next token must be , or }. if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } if d.errorContext != nil { // Reset errorContext to its original state. // Keep the same underlying array for FieldStack, to reuse the // space and avoid unnecessary allocs. d.errorContext.FieldStack = d.errorContext.FieldStack[:len(origErrorContext.FieldStack)] d.errorContext.Struct = origErrorContext.Struct } if d.opcode == scanEndObject { break } if d.opcode != scanObjectValue { panic(phasePanicMsg) } } return nil } // convertNumber converts the number literal s to a float64 or a Number // depending on the setting of d.useNumber. func (d *decodeState) convertNumber(s string) (any, error) { if d.useNumber { return Number(s), nil } f, err := strconv.ParseFloat(s, 64) if err != nil { // SHIM(reflect): reflect.TypeFor[T]() reflect.Type return nil, &UnmarshalTypeError{Value: "number " + s, Type: shims.TypeFor[float64](), Offset: int64(d.off)} } return f, nil } // SHIM(reflect): TypeFor[T]() reflect.Type var numberType = shims.TypeFor[Number]() // literalStore decodes a literal stored in item into v. // // fromQuoted indicates whether this literal came from unwrapping a // string from the ",string" struct tag option. this is used only to // produce more helpful error messages. func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) error { // Check for unmarshaler. if len(item) == 0 { // Empty string given. d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) return nil } isNull := item[0] == 'n' // null u, ut, pv := indirect(v, isNull) if u != nil { return u.UnmarshalJSON(item) } if ut != nil { if item[0] != '"' { if fromQuoted { d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) return nil } val := "number" switch item[0] { case 'n': val = "null" case 't', 'f': val = "bool" } d.saveError(&UnmarshalTypeError{Value: val, Type: v.Type(), Offset: int64(d.readIndex())}) return nil } s, ok := unquoteBytes(item) if !ok { if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) } panic(phasePanicMsg) } return ut.UnmarshalText(s) } v = pv switch c := item[0]; c { case 'n': // null // The main parser checks that only true and false can reach here, // but if this was a quoted string input, it could be anything. if fromQuoted && string(item) != "null" { d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) break } switch v.Kind() { case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice: v.SetZero() // otherwise, ignore null for primitives/string } case 't', 'f': // true, false value := item[0] == 't' // The main parser checks that only true and false can reach here, // but if this was a quoted string input, it could be anything. if fromQuoted && string(item) != "true" && string(item) != "false" { d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) break } switch v.Kind() { default: if fromQuoted { d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) } else { d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())}) } case reflect.Bool: v.SetBool(value) case reflect.Interface: if v.NumMethod() == 0 { v.Set(reflect.ValueOf(value)) } else { d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())}) } } case '"': // string s, ok := unquoteBytes(item) if !ok { if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) } panic(phasePanicMsg) } switch v.Kind() { default: d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) case reflect.Slice: if v.Type().Elem().Kind() != reflect.Uint8 { d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) break } b := make([]byte, base64.StdEncoding.DecodedLen(len(s))) n, err := base64.StdEncoding.Decode(b, s) if err != nil { d.saveError(err) break } v.SetBytes(b[:n]) case reflect.String: t := string(s) if v.Type() == numberType && !isValidNumber(t) { return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item) } v.SetString(t) case reflect.Interface: if v.NumMethod() == 0 { v.Set(reflect.ValueOf(string(s))) } else { d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())}) } } default: // number if c != '-' && (c < '0' || c > '9') { if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) } panic(phasePanicMsg) } switch v.Kind() { default: if v.Kind() == reflect.String && v.Type() == numberType { // s must be a valid number, because it's // already been tokenized. v.SetString(string(item)) break } if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) } d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}) case reflect.Interface: n, err := d.convertNumber(string(item)) if err != nil { d.saveError(err) break } if v.NumMethod() != 0 { d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())}) break } v.Set(reflect.ValueOf(n)) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: n, err := strconv.ParseInt(string(item), 10, 64) if err != nil || v.OverflowInt(n) { d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())}) break } v.SetInt(n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: n, err := strconv.ParseUint(string(item), 10, 64) if err != nil || v.OverflowUint(n) { d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())}) break } v.SetUint(n) case reflect.Float32, reflect.Float64: n, err := strconv.ParseFloat(string(item), v.Type().Bits()) if err != nil || v.OverflowFloat(n) { d.saveError(&UnmarshalTypeError{Value: "number " + string(item), Type: v.Type(), Offset: int64(d.readIndex())}) break } v.SetFloat(n) } } return nil } // The xxxInterface routines build up a value to be stored // in an empty interface. They are not strictly necessary, // but they avoid the weight of reflection in this common case. // valueInterface is like value but returns any. func (d *decodeState) valueInterface() (val any) { switch d.opcode { default: panic(phasePanicMsg) case scanBeginArray: val = d.arrayInterface() d.scanNext() case scanBeginObject: val = d.objectInterface() d.scanNext() case scanBeginLiteral: val = d.literalInterface() } return } // arrayInterface is like array but returns []any. func (d *decodeState) arrayInterface() []any { var v = make([]any, 0) for { // Look ahead for ] - can only happen on first iteration. d.scanWhile(scanSkipSpace) if d.opcode == scanEndArray { break } v = append(v, d.valueInterface()) // Next token must be , or ]. if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } if d.opcode == scanEndArray { break } if d.opcode != scanArrayValue { panic(phasePanicMsg) } } return v } // objectInterface is like object but returns map[string]any. func (d *decodeState) objectInterface() map[string]any { m := make(map[string]any) for { // Read opening " of string key or closing }. d.scanWhile(scanSkipSpace) if d.opcode == scanEndObject { // closing } - can only happen on first iteration. break } if d.opcode != scanBeginLiteral { panic(phasePanicMsg) } // Read string key. start := d.readIndex() d.rescanLiteral() item := d.data[start:d.readIndex()] key, ok := unquote(item) if !ok { panic(phasePanicMsg) } // Read : before value. if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } if d.opcode != scanObjectKey { panic(phasePanicMsg) } d.scanWhile(scanSkipSpace) // Read value. m[key] = d.valueInterface() // Next token must be , or }. if d.opcode == scanSkipSpace { d.scanWhile(scanSkipSpace) } if d.opcode == scanEndObject { break } if d.opcode != scanObjectValue { panic(phasePanicMsg) } } return m } // literalInterface consumes and returns a literal from d.data[d.off-1:] and // it reads the following byte ahead. The first byte of the literal has been // read already (that's how the caller knows it's a literal). func (d *decodeState) literalInterface() any { // All bytes inside literal return scanContinue op code. start := d.readIndex() d.rescanLiteral() item := d.data[start:d.readIndex()] switch c := item[0]; c { case 'n': // null return nil case 't', 'f': // true, false return c == 't' case '"': // string s, ok := unquote(item) if !ok { panic(phasePanicMsg) } return s default: // number if c != '-' && (c < '0' || c > '9') { panic(phasePanicMsg) } n, err := d.convertNumber(string(item)) if err != nil { d.saveError(err) } return n } } // getu4 decodes \uXXXX from the beginning of s, returning the hex value, // or it returns -1. func getu4(s []byte) rune { if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { return -1 } var r rune for _, c := range s[2:6] { switch { case '0' <= c && c <= '9': c = c - '0' case 'a' <= c && c <= 'f': c = c - 'a' + 10 case 'A' <= c && c <= 'F': c = c - 'A' + 10 default: return -1 } r = r*16 + rune(c) } return r } // unquote converts a quoted JSON string literal s into an actual string t. // The rules are different than for Go, so cannot use strconv.Unquote. func unquote(s []byte) (t string, ok bool) { s, ok = unquoteBytes(s) t = string(s) return } // unquoteBytes should be an internal detail, // but widely used packages access it using linkname. // Notable members of the hall of shame include: // - github.com/bytedance/sonic // // Do not remove or change the type signature. // See go.dev/issue/67401. // //go:linkname unquoteBytes func unquoteBytes(s []byte) (t []byte, ok bool) { if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { return } s = s[1 : len(s)-1] // Check for unusual characters. If there are none, // then no unquoting is needed, so return a slice of the // original bytes. r := 0 for r < len(s) { c := s[r] if c == '\\' || c == '"' || c < ' ' { break } if c < utf8.RuneSelf { r++ continue } rr, size := utf8.DecodeRune(s[r:]) if rr == utf8.RuneError && size == 1 { break } r += size } if r == len(s) { return s, true } b := make([]byte, len(s)+2*utf8.UTFMax) w := copy(b, s[0:r]) for r < len(s) { // Out of room? Can only happen if s is full of // malformed UTF-8 and we're replacing each // byte with RuneError. if w >= len(b)-2*utf8.UTFMax { nb := make([]byte, (len(b)+utf8.UTFMax)*2) copy(nb, b[0:w]) b = nb } switch c := s[r]; { case c == '\\': r++ if r >= len(s) { return } switch s[r] { default: return case '"', '\\', '/', '\'': b[w] = s[r] r++ w++ case 'b': b[w] = '\b' r++ w++ case 'f': b[w] = '\f' r++ w++ case 'n': b[w] = '\n' r++ w++ case 'r': b[w] = '\r' r++ w++ case 't': b[w] = '\t' r++ w++ case 'u': r-- rr := getu4(s[r:]) if rr < 0 { return } r += 6 if utf16.IsSurrogate(rr) { rr1 := getu4(s[r:]) if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { // A valid pair; consume. r += 6 w += utf8.EncodeRune(b[w:], dec) break } // Invalid surrogate; fall back to replacement rune. rr = unicode.ReplacementChar } w += utf8.EncodeRune(b[w:], rr) } // Quote, control characters are invalid. case c == '"', c < ' ': return // ASCII case c < utf8.RuneSelf: b[w] = c r++ w++ // Coerce to well-formed UTF-8. default: rr, size := utf8.DecodeRune(s[r:]) r += size w += utf8.EncodeRune(b[w:], rr) } } return b[0:w], true } ================================================ FILE: internal/encoding/json/encode.go ================================================ // Vendored from Go 1.24.0-pre-release // To find alterations, check package shims, and comments beginning in SHIM(). // // Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package json implements encoding and decoding of JSON as defined in // RFC 7159. The mapping between JSON and Go values is described // in the documentation for the Marshal and Unmarshal functions. // // See "JSON and Go" for an introduction to this package: // https://golang.org/doc/articles/json_and_go.html package json import ( "bytes" "cmp" "encoding" "encoding/base64" "fmt" "github.com/anthropics/anthropic-sdk-go/internal/encoding/json/sentinel" "github.com/anthropics/anthropic-sdk-go/internal/encoding/json/shims" "math" "reflect" "slices" "strconv" "strings" "sync" "unicode" "unicode/utf8" _ "unsafe" // for linkname ) // Marshal returns the JSON encoding of v. // // Marshal traverses the value v recursively. // If an encountered value implements [Marshaler] // and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON] // to produce JSON. If no [Marshaler.MarshalJSON] method is present but the // value implements [encoding.TextMarshaler] instead, Marshal calls // [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string. // The nil pointer exception is not strictly necessary // but mimics a similar, necessary exception in the behavior of // [Unmarshaler.UnmarshalJSON]. // // Otherwise, Marshal uses the following type-dependent default encodings: // // Boolean values encode as JSON booleans. // // Floating point, integer, and [Number] values encode as JSON numbers. // NaN and +/-Inf values will return an [UnsupportedValueError]. // // String values encode as JSON strings coerced to valid UTF-8, // replacing invalid bytes with the Unicode replacement rune. // So that the JSON will be safe to embed inside HTML