diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml index 0b7a00f..159ebcc 100644 --- a/.github/actions/setup-go/action.yml +++ b/.github/actions/setup-go/action.yml @@ -8,16 +8,16 @@ runs: using: composite steps: - uses: stainless-api/retrieve-github-access-token@1f03f929b746c5b03dcdafa2bebbb18ca5672e1a # v1.0.0 - if: github.repository == 'stainless-sdks/anthropic-cli' + if: github.repository == 'anthropics/anthropic-sdk-cli-private' id: get_token with: - repo: stainless-sdks/anthropic-go + repo: anthropics/anthropic-sdk-go-private stainless-api-key: ${{ inputs.stainless-api-key }} - name: Configure Git for access to the Go SDK's staging repo - if: github.repository == 'stainless-sdks/anthropic-cli' + if: github.repository == 'anthropics/anthropic-sdk-cli-private' shell: bash - run: git config --global url."https://x-access-token:${{ steps.get_token.outputs.github_access_token }}@github.com/stainless-sdks/anthropic-go".insteadOf "https://github.com/stainless-sdks/anthropic-go" + run: git config --global url."https://x-access-token:${{ steps.get_token.outputs.github_access_token }}@github.com/anthropics/anthropic-sdk-go-private".insteadOf "https://github.com/anthropics/anthropic-sdk-go-private" - name: Setup go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 diff --git a/.github/demo.gif b/.github/demo.gif new file mode 100644 index 0000000..13b4254 Binary files /dev/null and b/.github/demo.gif differ diff --git a/.github/demo.tape b/.github/demo.tape new file mode 100644 index 0000000..4475d2f --- /dev/null +++ b/.github/demo.tape @@ -0,0 +1,67 @@ +# VHS tape that records the demo GIF embedded in README.md. +# +# To re-record, run ./scripts/record-demo from the repository root. It builds +# the CLI, starts a local mock API server, places an `ant` wrapper pointed at +# the mock in /tmp/ant-demo, and runs vhs against this tape. + +Output .github/demo.gif + +Set Shell "bash" +Set FontSize 18 +Set Width 1200 +Set Height 680 +Set Padding 24 +Set WindowBar Colorful +Set TypingSpeed 30ms +Set CursorBlink false +Set Theme { "name": "Claude", "background": "#262624", "foreground": "#F0EEE6", "cursor": "#D97757", "selection": "#51504A", "black": "#262624", "red": "#E5484D", "green": "#62A87C", "yellow": "#D9A45B", "blue": "#7BA4C7", "magenta": "#C47ED1", "cyan": "#6FBFC9", "white": "#F0EEE6", "brightBlack": "#83827D", "brightRed": "#FF6369", "brightGreen": "#7DC894", "brightYellow": "#EBC06D", "brightBlue": "#96BDE0", "brightMagenta": "#D9A0E8", "brightCyan": "#8BD4DE", "brightWhite": "#FFFFFF" } + +# Hidden setup: put the authenticated `ant` wrapper first on PATH. +Hide +Type `PATH="/tmp/ant-demo:$PATH"; clear` +Enter +Show + +# Scene 1: send a message to Claude. +Type "ant messages create \" +Enter +Type " --model claude-opus-4-8 \" +Enter +Type " --max-tokens 1024 \" +Enter +Type ` --message '{role: user, content: "Hello, Claude"}'` +Sleep 500ms +Enter +Sleep 4.5s + +# Scene 2: the same request, extracting just the reply text. +Type "ant messages create \" +Enter +Type " --model claude-opus-4-8 \" +Enter +Type " --max-tokens 1024 \" +Enter +Type ` --message '{role: user, content: "Hello, Claude"}' \` +Enter +Type " --transform content.0.text --raw-output" +Sleep 500ms +Enter +Sleep 3.5s + +# Scene 3: browse a resource in the interactive explorer. +Hide +Type "clear" +Enter +Show +Type "ant models retrieve --model-id claude-opus-4-8" +Sleep 500ms +Enter +Sleep 2.5s +Down@300ms 6 +Sleep 1s +Right +Sleep 2s +Down@300ms 3 +Sleep 1.5s +Type "q" +Sleep 1.5s diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7451008..0bdce58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,13 +15,13 @@ on: - 'stl-preview-base/**' env: - GOPRIVATE: github.com/anthropics/anthropic-sdk-go,github.com/stainless-sdks/anthropic-go + GOPRIVATE: github.com/anthropics/anthropic-sdk-go,github.com/anthropics/anthropic-sdk-go-private jobs: lint: timeout-minutes: 10 name: lint - runs-on: ${{ github.repository == 'stainless-sdks/anthropic-cli' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: 'ubuntu-latest' if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) steps: @@ -32,11 +32,11 @@ jobs: stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} - name: Link staging branch - if: github.repository == 'stainless-sdks/anthropic-cli' + if: github.repository == 'anthropics/anthropic-sdk-cli-private' env: REF_NAME: ${{ github.ref_name }} run: | - ./scripts/link 'github.com/stainless-sdks/anthropic-go@${{ github.ref_name }}' || true + ./scripts/link 'github.com/anthropics/anthropic-sdk-go-private@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap @@ -50,7 +50,7 @@ jobs: permissions: contents: read id-token: write - runs-on: ${{ github.repository == 'stainless-sdks/anthropic-cli' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: 'ubuntu-latest' if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -60,11 +60,11 @@ jobs: stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} - name: Link staging branch - if: github.repository == 'stainless-sdks/anthropic-cli' + if: github.repository == 'anthropics/anthropic-sdk-cli-private' env: REF_NAME: ${{ github.ref_name }} run: | - ./scripts/link 'github.com/stainless-sdks/anthropic-go@${{ github.ref_name }}' || true + ./scripts/link 'github.com/anthropics/anthropic-sdk-go-private@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap @@ -79,7 +79,7 @@ jobs: - name: Get GitHub OIDC Token if: |- - github.repository == 'stainless-sdks/anthropic-cli' && + github.repository == 'anthropics/anthropic-sdk-cli-private' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 @@ -88,7 +88,7 @@ jobs: - name: Upload tarball if: |- - github.repository == 'stainless-sdks/anthropic-cli' && + github.repository == 'anthropics/anthropic-sdk-cli-private' && !startsWith(github.ref, 'refs/heads/stl/') env: URL: https://pkg.stainless.com/s @@ -147,7 +147,7 @@ jobs: test: timeout-minutes: 20 name: test - runs-on: ${{ github.repository == 'stainless-sdks/anthropic-cli' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: 'ubuntu-latest' if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -157,11 +157,11 @@ jobs: stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} - name: Link staging branch - if: github.repository == 'stainless-sdks/anthropic-cli' + if: github.repository == 'anthropics/anthropic-sdk-cli-private' env: REF_NAME: ${{ github.ref_name }} run: | - ./scripts/link 'github.com/stainless-sdks/anthropic-go@${{ github.ref_name }}' || true + ./scripts/link 'github.com/anthropics/anthropic-sdk-go-private@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap diff --git a/.release-please-manifest.json b/.release-please-manifest.json index eb4e0db..caf1487 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.10.0" + ".": "1.11.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 932c86c..15bfd9e 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 106 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic/anthropic-71eed687650366ea3e1abe6cfed0d15877e6423a56ecf7193a952fd4ee0cb72b.yml -openapi_spec_hash: 2790eecb0b38738a32441184273601a7 -config_hash: 70d06a7957e45a3ea82fb73a3f269ccc +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic/anthropic-e171bad0ea7923db27b0b640915579588c46e44f26c0d4b2bfd63eb6da486b2a.yml +openapi_spec_hash: 29b3b2ba0d00467b5c6943533fa0c07a +config_hash: 12441a8fae7ee2cb6a2accf3a5fa43ee diff --git a/CHANGELOG.md b/CHANGELOG.md index 23379b0..e01af4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Changelog +## 1.11.0 (2026-06-09) + +Full Changelog: [v1.10.0...v1.11.0](https://github.com/anthropics/anthropic-cli/compare/v1.10.0...v1.11.0) + +### Features + +* **api:** add support for claude-mythos-5 and claude-fable-5, with support for server-side fallbacks on refusal ([8302a45](https://github.com/anthropics/anthropic-cli/commit/8302a45f5d5a6df0289f9061e9cd6318d7530c63)) +* **api:** manual updates ([c5d792d](https://github.com/anthropics/anthropic-cli/commit/c5d792d52248a85aa9adf7d33f8ae7bd88ae949a)) +* **api:** small updates to Managed Agents types ([242c693](https://github.com/anthropics/anthropic-cli/commit/242c69330b3c195defc83ffded8eeb634c136968)) +* **client:** adds client-side fallbacks middleware for API providers that do not support server-side fallbacks ([8302a45](https://github.com/anthropics/anthropic-cli/commit/8302a45f5d5a6df0289f9061e9cd6318d7530c63)) + + +### Chores + +* **internal:** fix artifact url ([20689c3](https://github.com/anthropics/anthropic-cli/commit/20689c394a7eae8edc47a2070d6b65259bd9f1d5)) +* **internal:** fix branch names ([2168a5a](https://github.com/anthropics/anthropic-cli/commit/2168a5a12630129de4cb05e75447ad9d08185d05)) +* **internal:** update private repo name ([c4f0954](https://github.com/anthropics/anthropic-cli/commit/c4f09545a37a0401ee14fee042585ca0e1fefe80)) + + +### Documentation + +* add animated terminal demo ([7573585](https://github.com/anthropics/anthropic-cli/commit/75735853716522fe7363f6df7efe45e89bf76df9)) +* move development docs into CONTRIBUTING.md ([ab8aed7](https://github.com/anthropics/anthropic-cli/commit/ab8aed756a4edeb242f5470f643eb30348e0a12c)) +* point security reports to Anthropic's HackerOne program ([#5](https://github.com/anthropics/anthropic-cli/issues/5)) ([f5c8f0f](https://github.com/anthropics/anthropic-cli/commit/f5c8f0faa5eeee57e5c644cf09465a0d48852aad)) +* release-branch readiness sweep (model-release Step 5) + coverage-audit refinements ([2454db4](https://github.com/anthropics/anthropic-cli/commit/2454db4a3c1a2d77761c48a3285c0850ff547eea)) +* replace README demo GIF with webm and poster frame ([46d7f93](https://github.com/anthropics/anthropic-cli/commit/46d7f93d32750879f84a15be69e6b674891a7f05)) +* restore README demo GIF ([46e0b71](https://github.com/anthropics/anthropic-cli/commit/46e0b71e0cd581cc3764ff1970dd02d32caf6c00)) +* restructure README to match SDK conventions ([e22f218](https://github.com/anthropics/anthropic-cli/commit/e22f218a4c1b5f6edd955a37e31eb59922c1a7eb)) +* update product name to Claude Platform ([fa89021](https://github.com/anthropics/anthropic-cli/commit/fa89021825e94af94ae5df03ce9a1e0fbdc3ad2a)) +* use claude-opus-4-8 in examples and lead with the ant name ([8ecc617](https://github.com/anthropics/anthropic-cli/commit/8ecc617d62bd23f1df0c6705b8dd289d2cb32cf1)) + ## 1.10.0 (2026-05-28) Full Changelog: [v1.9.3...v1.10.0](https://github.com/anthropics/anthropic-cli/compare/v1.9.3...v1.10.0) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e82b777 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,77 @@ +## Contributing to documentation + +The documentation for the CLI lives at [platform.claude.com/docs/en/api/sdks/cli](https://platform.claude.com/docs/en/api/sdks/cli). 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 CLI. + + +## Modifying/Adding code + +Most of the CLI's command code is generated from the API spec. Modifications to generated code will be persisted between generations, but may result in merge conflicts between manual patches and changes from the generator. + +## Running the CLI locally + +Use the `scripts/run` script to build and run the CLI from source: + +```sh +$ ./scripts/run messages create --help +``` + +To produce a standalone binary instead, run `./scripts/build`, which places an `ant` binary in the repository root. + +## Linking different Go SDK versions + +The CLI is built on the [Anthropic Go SDK](https://github.com/anthropics/anthropic-sdk-go). You can link the CLI against a different version of the SDK using the `./scripts/link` script. + +To link to a specific version from a repository (version can be a branch, git tag, or commit hash): + +```sh +$ ./scripts/link github.com/org/repo@version +``` + +To link to a local copy of the SDK: + +```sh +$ ./scripts/link ../path/to/anthropic-go +``` + +If you run the link script without any arguments, it will default to `../anthropic-go`. Run `./scripts/unlink` to undo. + +## Running tests + +Tests run against a mock server set up from the OpenAPI spec. Most of the time the test script manages the mock server for you: + +```sh +$ ./scripts/test +``` + +To run the mock server yourself (for example, to run the CLI against it manually), use: + +```sh +$ ./scripts/mock +``` + +## Formatting + +This repository uses the standard gofmt code formatter: + +```sh +$ ./scripts/format +``` + +## Re-recording the README demo + +The demo GIF at the top of the README is recorded with [VHS](https://github.com/charmbracelet/vhs) from [`.github/demo.tape`](.github/demo.tape). After changing the tape or the examples it shows, re-record it with: + +```sh +$ ./scripts/record-demo +``` diff --git a/README.md b/README.md index cb941d5..4d687be 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,35 @@ -# Claude Platform CLI +# ant — Claude Platform CLI -The official CLI for the [Claude Developer Platform](https://platform.claude.com/docs/en/api). +[![GitHub release](https://img.shields.io/github/v/release/anthropics/anthropic-cli)](https://github.com/anthropics/anthropic-cli/releases) +[![Homebrew](https://img.shields.io/badge/homebrew-anthropics%2Ftap%2Fant-FBB040?logo=homebrew&logoColor=white)](https://github.com/anthropics/homebrew-tap) + +`ant` is the official CLI for the [Claude Platform](https://platform.claude.com/docs/en/api). It puts the Claude API in your terminal — send messages, manage agents and sessions, upload files, and script against every API endpoint. + +![Demo of the ant CLI](.github/demo.gif) + +## Documentation + +Full documentation is available at **[platform.claude.com/docs/en/api/sdks/cli](https://platform.claude.com/docs/en/api/sdks/cli)**. ## Installation -### Installing with Homebrew +### Homebrew ```sh brew install anthropics/tap/ant ``` -### Installing with Go +### Go -To test or install the CLI locally, you need [Go](https://go.dev/doc/install) version 1.22 or later installed. +To install from source, you need [Go](https://go.dev/doc/install) version 1.22 or later. ```sh go install 'github.com/anthropics/anthropic-cli/cmd/ant@latest' ``` -Once you have run `go install`, the binary is placed in your Go bin directory: - -- **Default location**: `$HOME/go/bin` (or `$GOPATH/bin` if GOPATH is set) -- **Check your path**: Run `go env GOPATH` to see the base directory - -If commands aren't found after installation, add the Go bin directory to your PATH: +The binary is placed in `$(go env GOPATH)/bin`. If `ant` isn't found after installation, add that directory to your `PATH`: ```sh # Add to your shell profile (.zshrc, .bashrc, etc.) @@ -34,111 +38,72 @@ export PATH="$PATH:$(go env GOPATH)/bin" -### Running Locally +## Getting started -After cloning the git repository for this project, you can use the -`scripts/run` script to run the tool locally: +Log in with your Claude Console account: ```sh -./scripts/run args... +ant auth login ``` -## Usage - -The CLI follows a resource-based command structure: +Or set the `ANTHROPIC_API_KEY` environment variable to an API key from the [Claude Console](https://platform.claude.com/settings/keys). -```sh -ant [resource] [flags...] -``` +Then send your first message: ```sh ant messages create \ - --api-key my-anthropic-api-key \ + --model claude-opus-4-8 \ --max-tokens 1024 \ - --message '{content: [{text: x, type: text}], role: user}' \ - --model claude-sonnet-4-5-20250929 + --message '{role: user, content: "Hello, Claude"}' ``` -For details about specific commands, use the `--help` flag. - -### Environment variables - -| Environment variable | Required | Default value | -| ------------------------------- | -------- | ------------- | -| `ANTHROPIC_API_KEY` | no | `null` | -| `ANTHROPIC_AUTH_TOKEN` | no | `null` | -| `ANTHROPIC_WEBHOOK_SIGNING_KEY` | no | `null` | - -### Global flags - -- `--api-key` (can also be set with `ANTHROPIC_API_KEY` env var) -- `--auth-token` (can also be set with `ANTHROPIC_AUTH_TOKEN` env var) -- `--webhook-key` (can also be set with `ANTHROPIC_WEBHOOK_SIGNING_KEY` env var) -- `--help` - Show command line usage -- `--debug` - Enable debug logging (includes HTTP request/response details) -- `--version`, `-v` - Show the CLI version -- `--base-url` - Use a custom API backend URL -- `--format` - Change the output format (`auto`, `explore`, `json`, `jsonl`, `pretty`, `raw`, `yaml`) -- `--format-error` - Change the output format for errors (`auto`, `explore`, `json`, `jsonl`, `pretty`, `raw`, `yaml`) -- `--transform` - Transform the data output using [GJSON syntax](https://github.com/tidwall/gjson/blob/master/SYNTAX.md) -- `--transform-error` - Transform the error output using [GJSON syntax](https://github.com/tidwall/gjson/blob/master/SYNTAX.md) +Structured flags accept relaxed JSON or YAML, so unquoted keys are fine. -### Passing files as arguments - -To pass files to your API, you can use the `@myfile.ext` syntax: - -```bash -ant --arg @abe.jpg -``` +## Usage -Files can also be passed inside JSON or YAML blobs: +The CLI follows a resource-based command structure, with nested resources separated by colons: -```bash -ant --arg '{image: "@abe.jpg"}' -# Equivalent: -ant <[:] [flags...] ``` -If you need to pass a string literal that begins with an `@` sign, you can -escape the `@` sign to avoid accidentally passing a file. +```sh +# List available models +ant models list -```bash -ant --username '\@abe' -``` +# Browse a response in the interactive explorer (the default in a terminal) +ant models retrieve --model-id claude-opus-4-8 -#### Explicit encoding +# Extract a single field from a response, jq-style +ant messages create \ + --model claude-opus-4-8 \ + --max-tokens 1024 \ + --message '{role: user, content: "Hello, Claude"}' \ + --transform content.0.text --raw-output -For JSON endpoints, the CLI tool does filetype sniffing to determine whether the -file contents should be sent as a string literal (for plain text files) or as a -base64-encoded string literal (for binary files). If you need to explicitly send -the file as either plain text or base64-encoded data, you can use -`@file://myfile.txt` (for string encoding) or `@data://myfile.dat` (for -base64-encoding). Note that absolute paths will begin with `@file://` or -`@data://`, followed by a third `/` (for example, `@file:///tmp/file.txt`). +# Send a file using the @path syntax +ant messages create \ + --model claude-opus-4-8 \ + --max-tokens 1024 \ + --message '{role: user, content: [ + {type: image, source: {type: base64, media_type: image/jpeg, data: "@photo.jpg"}}, + {type: text, text: "What is in this image?"} + ]}' -```bash -ant --arg @data://file.txt +# Manage beta resources such as agents, sessions, and files +ant beta:agents list ``` -## Linking different Go SDK versions +Run `ant --help` for the full list of resources, or append `--help` to any command to see its flags. -You can link the CLI against a different version of the Anthropic Go SDK -for development purposes using the `./scripts/link` script. +## Requirements -To link to a specific version from a repository (version can be a branch, -git tag, or commit hash): +macOS, Linux, or Windows. -```bash -./scripts/link github.com/org/repo@version -``` +## Contributing -To link to a local copy of the SDK: +See [CONTRIBUTING.md](./CONTRIBUTING.md). -```bash -./scripts/link ../path/to/anthropic-go -``` +## License -If you run the link script without any arguments, it will default to `../anthropic-go`. +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. diff --git a/SECURITY.md b/SECURITY.md index 49f2cc7..95b204a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,27 +1,15 @@ # 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. +Thank you for helping us keep the SDKs and systems they interact with secure. -## Reporting Non-SDK Related Security Issues +## Reporting 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. +This SDK is maintained by [Anthropic](https://www.anthropic.com/). -### Anthropic Terms and Policies +The security of our systems and user data is Anthropic’s top priority. We appreciate the work of security researchers acting in good faith in identifying and reporting potential vulnerabilities. -Please contact support@anthropic.com for any questions or concerns regarding the security of our services. +Our security program is managed on HackerOne and we ask that any validated vulnerability in this functionality be reported through their [submission form](https://hackerone.com/4f1f16ba-10d3-4d09-9ecc-c721aad90f24/embedded_submissions/new). ---- +## Anthropic Bug Bounty -Thank you for helping us keep the SDKs and systems they interact with secure. +Our Bug Bounty Program Guidelines are defined on our [HackerOne program page](https://hackerone.com/anthropic). diff --git a/go.mod b/go.mod index 4dfb8bb..1202194 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/anthropics/anthropic-cli go 1.25 require ( - github.com/anthropics/anthropic-sdk-go v1.46.0 + github.com/anthropics/anthropic-sdk-go v1.49.0 github.com/charmbracelet/bubbles v0.21.0 github.com/charmbracelet/bubbletea v1.3.6 github.com/charmbracelet/lipgloss v1.1.0 @@ -11,7 +11,7 @@ require ( github.com/goccy/go-yaml v1.18.0 github.com/itchyny/json2yaml v0.1.4 github.com/muesli/reflow v0.3.0 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 github.com/tidwall/pretty v1.2.1 github.com/urfave/cli-docs/v3 v3.0.0-alpha6 @@ -30,23 +30,23 @@ require ( github.com/creack/pty v1.1.24 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/invopop/jsonschema v0.13.0 // indirect + github.com/invopop/jsonschema v0.14.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect + github.com/pb33f/ordered-map/v2 v2.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/standard-webhooks/standard-webhooks/libraries v0.0.1 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + go.yaml.in/yaml/v4 v4.0.0-rc.2 // indirect golang.org/x/sync v0.16.0 // indirect golang.org/x/text v0.27.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 126594a..cb0ef3a 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/anthropics/anthropic-sdk-go v1.46.0 h1:yl3n+el5ZfNgiCtQ7zQ7s/NXxB11YbrKXdc3uLPNWlU= -github.com/anthropics/anthropic-sdk-go v1.46.0/go.mod h1:bx5vWuHFuGPkELH8Z4KUiNSohFnUwScdpTyr+50myPo= +github.com/anthropics/anthropic-sdk-go v1.49.0 h1:7maVcwOXaNGBkQC3Mi7CxWlUvrReZzXJPpeN94Rre/o= +github.com/anthropics/anthropic-sdk-go v1.49.0/go.mod h1:3EfIfmFqxH6rbiLcIP4tPFyXL/IHakx2wDG4OU+TIEI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= @@ -36,15 +36,12 @@ github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6 github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= -github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/invopop/jsonschema v0.14.0 h1:MHQqLhvpNUZfw+hM3AZDYK7jxO8FZoQeQM77g8iyZjg= +github.com/invopop/jsonschema v0.14.0/go.mod h1:ygm6C2EaVNMBDPpaPlnOA2pFAxBnxGjFlMZABxm9n2I= github.com/itchyny/json2yaml v0.1.4 h1:/pErVOXGG5iTyXHi/QKR4y3uzhLjGTEmmJIy97YT+k8= github.com/itchyny/json2yaml v0.1.4/go.mod h1:6iudhBZdarpjLFRNj+clWLAkGft+9uCcjAZYXUH9eGI= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -60,6 +57,8 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +github.com/pb33f/ordered-map/v2 v2.3.1 h1:5319HDO0aw4DA4gzi+zv4FXU9UlSs3xGZ40wcP1nBjY= +github.com/pb33f/ordered-map/v2 v2.3.1/go.mod h1:qxFQgd0PkVUtOMCkTapqotNgzRhMPL7VvaHKbd1HnmQ= 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/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -70,8 +69,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/standard-webhooks/standard-webhooks/libraries v0.0.1 h1:uOfcYT+3QungH6tIGSVCR/Y3KJmgJiHcojJbMTPDZAI= github.com/standard-webhooks/standard-webhooks/libraries v0.0.1/go.mod h1:L1MQhA6x4dn9r007T033lsaZMv9EmBAdXyU/+EF40fo= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 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= @@ -86,10 +85,10 @@ github.com/urfave/cli-docs/v3 v3.0.0-alpha6 h1:w/l/N0xw1rO/aHRIGXJ0lDwwYFOzilup1 github.com/urfave/cli-docs/v3 v3.0.0-alpha6/go.mod h1:p7Z4lg8FSTrPB9GTaNyTrK3ygffHZcK3w0cU2VE+mzU= github.com/urfave/cli/v3 v3.3.2 h1:BYFVnhhZ8RqT38DxEYVFPPmGFTEf7tJwySTXsVRrS/o= github.com/urfave/cli/v3 v3.3.2/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo= -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= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= +go.yaml.in/yaml/v4 v4.0.0-rc.2 h1:/FrI8D64VSr4HtGIlUtlFMGsm7H7pWTbj6vOLVZcA6s= +go.yaml.in/yaml/v4 v4.0.0-rc.2/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= diff --git a/pkg/cmd/betaagent.go b/pkg/cmd/betaagent.go index c1616c7..4ff656d 100644 --- a/pkg/cmd/betaagent.go +++ b/pkg/cmd/betaagent.go @@ -27,13 +27,13 @@ var betaAgentsCreate = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[string]{ Name: "name", - Usage: "Human-readable name for the agent. 1-256 characters.", + Usage: "Human-readable name for the agent.", Required: true, BodyPath: "name", }, &requestflag.Flag[*string]{ Name: "description", - Usage: "Description of what the agent does. Up to 2048 characters.", + Usage: "Description of what the agent does.", BodyPath: "description", }, &requestflag.Flag[[]map[string]any]{ @@ -53,12 +53,12 @@ var betaAgentsCreate = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[[]map[string]any]{ Name: "skill", - Usage: "Skills available to the agent. Maximum 20.", + Usage: "Skills available to the agent.", BodyPath: "skills", }, &requestflag.Flag[*string]{ Name: "system", - Usage: "System prompt for the agent. Up to 100,000 characters.", + Usage: "System prompt for the agent.", BodyPath: "system", }, &requestflag.Flag[[]map[string]any]{ @@ -150,7 +150,7 @@ var betaAgentsUpdate = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[*string]{ Name: "description", - Usage: "Description. Up to 2048 characters. Omit to preserve; send empty string or null to clear.", + Usage: "Description. Omit to preserve; send empty string or null to clear.", BodyPath: "description", }, &requestflag.Flag[any]{ @@ -175,17 +175,17 @@ var betaAgentsUpdate = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[string]{ Name: "name", - Usage: "Human-readable name. 1-256 characters. Omit to preserve. Cannot be cleared.", + Usage: "Human-readable name. Must be non-empty. Omit to preserve. Cannot be cleared.", BodyPath: "name", }, &requestflag.Flag[any]{ Name: "skill", - Usage: "Skills. Full replacement. Omit to preserve; send empty array or null to clear. Maximum 20.", + Usage: "Skills. Full replacement. Omit to preserve; send empty array or null to clear.", BodyPath: "skills", }, &requestflag.Flag[*string]{ Name: "system", - Usage: "System prompt. Up to 100,000 characters. Omit to preserve; send empty string or null to clear.", + Usage: "System prompt. Omit to preserve; send empty string or null to clear.", BodyPath: "system", }, &requestflag.Flag[any]{ diff --git a/pkg/cmd/betamessage.go b/pkg/cmd/betamessage.go index 5a08f9e..7b173af 100644 --- a/pkg/cmd/betamessage.go +++ b/pkg/cmd/betamessage.go @@ -55,6 +55,16 @@ var betaMessagesCreate = requestflag.WithInnerFlags(cli.Command{ Usage: "Request-level diagnostics. Currently carries the previous response\nid for prompt-cache divergence reporting.", BodyPath: "diagnostics", }, + &requestflag.Flag[*string]{ + Name: "fallback-credit-token", + Usage: "The `fallback_credit_token` from a prior refusal's `stop_details`.\n\nWhen a preceding request was refused and returned a `fallback_credit_token`,\npass that code here on the retry to have the retry's cache-creation tokens\nfor the prefix that was warm on the refused model billed at the cache-read\nrate. Must be redeemed by the same organization and workspace, with the same\nrequest body (optionally extended by one appended `assistant` message whose\ncontent is the partial text — with any trailing whitespace stripped from\nthe final text block — and paired server-tool blocks streamed before the\nrefusal; the appended-assistant form is not available for requests with\n`output_format` set or forced `tool_choice`), on an eligible fallback\nmodel, on the same platform,\nand within 5 minutes of the refusal; a mismatch is a 400. A token minted\nmid-server-tool-loop whose partial content was continuable may only be\nredeemed with the appended-assistant form — if an exact-body retry is\nrejected with a 400 saying the token must be redeemed by continuing the\npartial response, retry with the appended-assistant form instead.\n\nWhen the appended-assistant form is used on a model that otherwise disallows\nassistant-turn prefill, this token also authorizes that one prefill.", + BodyPath: "fallback_credit_token", + }, + &requestflag.Flag[any]{ + Name: "fallback", + Usage: "Opt-in server-side retry on one or more substitute models when the requested model declines for policy reasons. Tried in order: if the first entry also declines, the second is tried, and so on.", + BodyPath: "fallbacks", + }, &requestflag.Flag[*string]{ Name: "inference-geo", Usage: "Specifies the geographic region for inference processing. If not specified, the workspace's `default_inference_geo` is used.", @@ -119,7 +129,7 @@ var betaMessagesCreate = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[[]map[string]any]{ Name: "tool", - Usage: "Definitions of tools that the model may use.\n\nIf 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.\n\nThere 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)).\n\nEach tool definition includes:\n\n* `name`: Name of the tool.\n* `description`: Optional, but strongly-recommended description of the tool.\n* `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.\n\nFor example, if you defined `tools` as:\n\n```json\n[\n {\n \"name\": \"get_stock_price\",\n \"description\": \"Get the current stock price for a given ticker symbol.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"ticker\": {\n \"type\": \"string\",\n \"description\": \"The stock ticker symbol, e.g. AAPL for Apple Inc.\"\n }\n },\n \"required\": [\"ticker\"]\n }\n }\n]\n```\n\nAnd 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:\n\n```json\n[\n {\n \"type\": \"tool_use\",\n \"id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"name\": \"get_stock_price\",\n \"input\": { \"ticker\": \"^GSPC\" }\n }\n]\n```\n\nYou 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:\n\n```json\n[\n {\n \"type\": \"tool_result\",\n \"tool_use_id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"content\": \"259.75 USD\"\n }\n]\n```\n\nTools 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.\n\nSee our [guide](https://docs.claude.com/en/docs/tool-use) for more details.", + Usage: "Definitions of tools that the model may use.\n\nIf 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.\n\nThere 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)).\n\nEach tool definition includes:\n\n* `name`: Name of the tool.\n* `description`: Optional, but strongly-recommended description of the tool.\n* `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.\n\nFor example, if you defined `tools` as:\n\n```json\n[\n {\n \"name\": \"get_stock_price\",\n \"description\": \"Get the current stock price for a given ticker symbol.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"ticker\": {\n \"type\": \"string\",\n \"description\": \"The stock ticker symbol, e.g. AAPL for Apple Inc.\"\n }\n },\n \"required\": [\"ticker\"]\n }\n }\n]\n```\n\nAnd 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:\n\n```json\n[\n {\n \"type\": \"tool_use\",\n \"id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"name\": \"get_stock_price\",\n \"input\": { \"ticker\": \"^GSPC\" }\n }\n]\n```\n\nYou 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:\n\n```json\n[\n {\n \"type\": \"tool_result\",\n \"tool_use_id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"content\": \"259.75 USD\"\n }\n]\n```\n\nTools 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.\n\nSee our [guide](https://docs.claude.com/en/docs/tool-use) for more details.", BodyPath: "tools", }, &requestflag.Flag[int64]{ @@ -187,6 +197,35 @@ var betaMessagesCreate = requestflag.WithInnerFlags(cli.Command{ InnerField: "previous_message_id", }, }, + "fallback": { + &requestflag.InnerFlag[string]{ + Name: "fallback.model", + Usage: "The model that will complete your prompt.\n\nSee [models](https://docs.anthropic.com/en/docs/models-overview) for additional details and options.", + InnerField: "model", + OuterIsArrayOfObjects: true, + }, + &requestflag.InnerFlag[*int64]{ + Name: "fallback.max-tokens", + InnerField: "max_tokens", + OuterIsArrayOfObjects: true, + }, + &requestflag.InnerFlag[map[string]any]{ + Name: "fallback.output-config", + InnerField: "output_config", + OuterIsArrayOfObjects: true, + }, + &requestflag.InnerFlag[*string]{ + Name: "fallback.speed", + Usage: `Allowed values: "standard", "fast".`, + InnerField: "speed", + OuterIsArrayOfObjects: true, + }, + &requestflag.InnerFlag[map[string]any]{ + Name: "fallback.thinking", + InnerField: "thinking", + OuterIsArrayOfObjects: true, + }, + }, "mcp-server": { &requestflag.InnerFlag[string]{ Name: "mcp-server.name", @@ -307,7 +346,7 @@ var betaMessagesCountTokens = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[[]map[string]any]{ Name: "tool", - Usage: "Definitions of tools that the model may use.\n\nIf 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.\n\nThere 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)).\n\nEach tool definition includes:\n\n* `name`: Name of the tool.\n* `description`: Optional, but strongly-recommended description of the tool.\n* `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.\n\nFor example, if you defined `tools` as:\n\n```json\n[\n {\n \"name\": \"get_stock_price\",\n \"description\": \"Get the current stock price for a given ticker symbol.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"ticker\": {\n \"type\": \"string\",\n \"description\": \"The stock ticker symbol, e.g. AAPL for Apple Inc.\"\n }\n },\n \"required\": [\"ticker\"]\n }\n }\n]\n```\n\nAnd 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:\n\n```json\n[\n {\n \"type\": \"tool_use\",\n \"id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"name\": \"get_stock_price\",\n \"input\": { \"ticker\": \"^GSPC\" }\n }\n]\n```\n\nYou 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:\n\n```json\n[\n {\n \"type\": \"tool_result\",\n \"tool_use_id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"content\": \"259.75 USD\"\n }\n]\n```\n\nTools 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.\n\nSee our [guide](https://docs.claude.com/en/docs/tool-use) for more details.", + Usage: "Definitions of tools that the model may use.\n\nIf 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.\n\nThere 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)).\n\nEach tool definition includes:\n\n* `name`: Name of the tool.\n* `description`: Optional, but strongly-recommended description of the tool.\n* `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.\n\nFor example, if you defined `tools` as:\n\n```json\n[\n {\n \"name\": \"get_stock_price\",\n \"description\": \"Get the current stock price for a given ticker symbol.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"ticker\": {\n \"type\": \"string\",\n \"description\": \"The stock ticker symbol, e.g. AAPL for Apple Inc.\"\n }\n },\n \"required\": [\"ticker\"]\n }\n }\n]\n```\n\nAnd 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:\n\n```json\n[\n {\n \"type\": \"tool_use\",\n \"id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"name\": \"get_stock_price\",\n \"input\": { \"ticker\": \"^GSPC\" }\n }\n]\n```\n\nYou 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:\n\n```json\n[\n {\n \"type\": \"tool_result\",\n \"tool_use_id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"content\": \"259.75 USD\"\n }\n]\n```\n\nTools 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.\n\nSee our [guide](https://docs.claude.com/en/docs/tool-use) for more details.", BodyPath: "tools", }, &requestflag.Flag[[]string]{ diff --git a/pkg/cmd/betamessage_test.go b/pkg/cmd/betamessage_test.go index cc27f1b..6178ffc 100644 --- a/pkg/cmd/betamessage_test.go +++ b/pkg/cmd/betamessage_test.go @@ -23,6 +23,8 @@ func TestBetaMessagesCreate(t *testing.T) { "--container", "{id: id, skills: [{skill_id: pdf, type: anthropic, version: latest}]}", "--context-management", "{edits: [{type: clear_tool_uses_20250919, clear_at_least: {type: input_tokens, value: 0}, clear_tool_inputs: true, exclude_tools: [string], keep: {type: tool_uses, value: 0}, trigger: {type: input_tokens, value: 1}}]}", "--diagnostics", "{previous_message_id: previous_message_id}", + "--fallback-credit-token", "x", + "--fallback", "[{model: claude-fable-5, max_tokens: 0, output_config: {effort: low, format: {schema: {foo: bar}, type: json_schema}, task_budget: {total: 1024, type: tokens, remaining: 0}}, speed: standard, thinking: {budget_tokens: 1024, type: enabled, display: summarized}}]", "--inference-geo", "inference_geo", "--mcp-server", "{name: name, type: url, url: url, authorization_token: authorization_token, tool_configuration: {allowed_tools: [string], enabled: true}}", "--metadata", "{user_id: 13803d75-b4b5-4c3e-b2a2-6f21399b021b}", @@ -63,6 +65,12 @@ func TestBetaMessagesCreate(t *testing.T) { "--container", "{id: id, skills: [{skill_id: pdf, type: anthropic, version: latest}]}", "--context-management.edits", "[{type: clear_tool_uses_20250919, clear_at_least: {type: input_tokens, value: 0}, clear_tool_inputs: true, exclude_tools: [string], keep: {type: tool_uses, value: 0}, trigger: {type: input_tokens, value: 1}}]", "--diagnostics.previous-message-id", "previous_message_id", + "--fallback-credit-token", "x", + "--fallback.model", "claude-fable-5", + "--fallback.max-tokens", "0", + "--fallback.output-config", "{effort: low, format: {schema: {foo: bar}, type: json_schema}, task_budget: {total: 1024, type: tokens, remaining: 0}}", + "--fallback.speed", "standard", + "--fallback.thinking", "{budget_tokens: 1024, type: enabled, display: summarized}", "--inference-geo", "inference_geo", "--mcp-server.name", "name", "--mcp-server.type", "url", @@ -137,6 +145,25 @@ func TestBetaMessagesCreate(t *testing.T) { " value: 1\n" + "diagnostics:\n" + " previous_message_id: previous_message_id\n" + + "fallback_credit_token: x\n" + + "fallbacks:\n" + + " - model: claude-fable-5\n" + + " max_tokens: 0\n" + + " output_config:\n" + + " effort: low\n" + + " format:\n" + + " schema:\n" + + " foo: bar\n" + + " type: json_schema\n" + + " task_budget:\n" + + " total: 1024\n" + + " type: tokens\n" + + " remaining: 0\n" + + " speed: standard\n" + + " thinking:\n" + + " budget_tokens: 1024\n" + + " type: enabled\n" + + " display: summarized\n" + "inference_geo: inference_geo\n" + "mcp_servers:\n" + " - name: name\n" + diff --git a/pkg/cmd/betamessagebatch_test.go b/pkg/cmd/betamessagebatch_test.go index c205c8c..1f16a65 100644 --- a/pkg/cmd/betamessagebatch_test.go +++ b/pkg/cmd/betamessagebatch_test.go @@ -15,7 +15,7 @@ func TestBetaMessagesBatchesCreate(t *testing.T) { t, "--api-key", "string", "beta:messages:batches", "create", - "--request", "{custom_id: my-custom-id-1, params: {max_tokens: 1024, messages: [{content: [{text: x, type: text, cache_control: {type: ephemeral, ttl: 5m}, citations: [{cited_text: cited_text, document_index: 0, document_title: x, end_char_index: 0, start_char_index: 0, type: char_location}]}], role: user}], model: claude-opus-4-6, cache_control: {type: ephemeral, ttl: 5m}, container: {id: id, skills: [{skill_id: pdf, type: anthropic, version: latest}]}, context_management: {edits: [{type: clear_tool_uses_20250919, clear_at_least: {type: input_tokens, value: 0}, clear_tool_inputs: true, exclude_tools: [string], keep: {type: tool_uses, value: 0}, trigger: {type: input_tokens, value: 1}}]}, diagnostics: {previous_message_id: previous_message_id}, inference_geo: inference_geo, mcp_servers: [{name: name, type: url, url: url, authorization_token: authorization_token, tool_configuration: {allowed_tools: [string], enabled: true}}], metadata: {user_id: 13803d75-b4b5-4c3e-b2a2-6f21399b021b}, output_config: {effort: low, format: {schema: {foo: bar}, type: json_schema}, task_budget: {total: 1024, type: tokens, remaining: 0}}, output_format: {schema: {foo: bar}, type: json_schema}, service_tier: auto, speed: standard, stop_sequences: [string], stream: true, system: [{text: Today's date is 2024-06-01., type: text, cache_control: {type: ephemeral, ttl: 5m}, citations: [{cited_text: cited_text, document_index: 0, document_title: x, end_char_index: 0, start_char_index: 0, type: char_location}]}], temperature: 1, thinking: {type: adaptive, display: summarized}, tool_choice: {type: auto, disable_parallel_tool_use: true}, tools: [{input_schema: {type: object, properties: {location: bar, unit: bar}, required: [location]}, name: name, allowed_callers: [direct], cache_control: {type: ephemeral, ttl: 5m}, defer_loading: true, description: Get the current weather in a given location, eager_input_streaming: true, input_examples: [{foo: bar}], strict: true, type: custom}], top_k: 5, top_p: 0.7, user_profile_id: user_profile_id}}", + "--request", "{custom_id: my-custom-id-1, params: {max_tokens: 1024, messages: [{content: [{text: x, type: text, cache_control: {type: ephemeral, ttl: 5m}, citations: [{cited_text: cited_text, document_index: 0, document_title: x, end_char_index: 0, start_char_index: 0, type: char_location}]}], role: user}], model: claude-opus-4-6, cache_control: {type: ephemeral, ttl: 5m}, container: {id: id, skills: [{skill_id: pdf, type: anthropic, version: latest}]}, context_management: {edits: [{type: clear_tool_uses_20250919, clear_at_least: {type: input_tokens, value: 0}, clear_tool_inputs: true, exclude_tools: [string], keep: {type: tool_uses, value: 0}, trigger: {type: input_tokens, value: 1}}]}, diagnostics: {previous_message_id: previous_message_id}, fallback_credit_token: x, fallbacks: [{model: claude-fable-5, max_tokens: 0, output_config: {effort: low, format: {schema: {foo: bar}, type: json_schema}, task_budget: {total: 1024, type: tokens, remaining: 0}}, speed: standard, thinking: {budget_tokens: 1024, type: enabled, display: summarized}}], inference_geo: inference_geo, mcp_servers: [{name: name, type: url, url: url, authorization_token: authorization_token, tool_configuration: {allowed_tools: [string], enabled: true}}], metadata: {user_id: 13803d75-b4b5-4c3e-b2a2-6f21399b021b}, output_config: {effort: low, format: {schema: {foo: bar}, type: json_schema}, task_budget: {total: 1024, type: tokens, remaining: 0}}, output_format: {schema: {foo: bar}, type: json_schema}, service_tier: auto, speed: standard, stop_sequences: [string], stream: true, system: [{text: Today's date is 2024-06-01., type: text, cache_control: {type: ephemeral, ttl: 5m}, citations: [{cited_text: cited_text, document_index: 0, document_title: x, end_char_index: 0, start_char_index: 0, type: char_location}]}], temperature: 1, thinking: {type: adaptive, display: summarized}, tool_choice: {type: auto, disable_parallel_tool_use: true}, tools: [{input_schema: {type: object, properties: {location: bar, unit: bar}, required: [location]}, name: name, allowed_callers: [direct], cache_control: {type: ephemeral, ttl: 5m}, defer_loading: true, description: Get the current weather in a given location, eager_input_streaming: true, input_examples: [{foo: bar}], strict: true, type: custom}], top_k: 5, top_p: 0.7, user_profile_id: user_profile_id}}", "--beta", "message-batches-2024-09-24", ) }) @@ -30,7 +30,7 @@ func TestBetaMessagesBatchesCreate(t *testing.T) { "--api-key", "string", "beta:messages:batches", "create", "--request.custom-id", "my-custom-id-1", - "--request.params", "{max_tokens: 1024, messages: [{content: [{text: x, type: text, cache_control: {type: ephemeral, ttl: 5m}, citations: [{cited_text: cited_text, document_index: 0, document_title: x, end_char_index: 0, start_char_index: 0, type: char_location}]}], role: user}], model: claude-opus-4-6, cache_control: {type: ephemeral, ttl: 5m}, container: {id: id, skills: [{skill_id: pdf, type: anthropic, version: latest}]}, context_management: {edits: [{type: clear_tool_uses_20250919, clear_at_least: {type: input_tokens, value: 0}, clear_tool_inputs: true, exclude_tools: [string], keep: {type: tool_uses, value: 0}, trigger: {type: input_tokens, value: 1}}]}, diagnostics: {previous_message_id: previous_message_id}, inference_geo: inference_geo, mcp_servers: [{name: name, type: url, url: url, authorization_token: authorization_token, tool_configuration: {allowed_tools: [string], enabled: true}}], metadata: {user_id: 13803d75-b4b5-4c3e-b2a2-6f21399b021b}, output_config: {effort: low, format: {schema: {foo: bar}, type: json_schema}, task_budget: {total: 1024, type: tokens, remaining: 0}}, output_format: {schema: {foo: bar}, type: json_schema}, service_tier: auto, speed: standard, stop_sequences: [string], stream: true, system: [{text: Today's date is 2024-06-01., type: text, cache_control: {type: ephemeral, ttl: 5m}, citations: [{cited_text: cited_text, document_index: 0, document_title: x, end_char_index: 0, start_char_index: 0, type: char_location}]}], temperature: 1, thinking: {type: adaptive, display: summarized}, tool_choice: {type: auto, disable_parallel_tool_use: true}, tools: [{input_schema: {type: object, properties: {location: bar, unit: bar}, required: [location]}, name: name, allowed_callers: [direct], cache_control: {type: ephemeral, ttl: 5m}, defer_loading: true, description: Get the current weather in a given location, eager_input_streaming: true, input_examples: [{foo: bar}], strict: true, type: custom}], top_k: 5, top_p: 0.7, user_profile_id: user_profile_id}", + "--request.params", "{max_tokens: 1024, messages: [{content: [{text: x, type: text, cache_control: {type: ephemeral, ttl: 5m}, citations: [{cited_text: cited_text, document_index: 0, document_title: x, end_char_index: 0, start_char_index: 0, type: char_location}]}], role: user}], model: claude-opus-4-6, cache_control: {type: ephemeral, ttl: 5m}, container: {id: id, skills: [{skill_id: pdf, type: anthropic, version: latest}]}, context_management: {edits: [{type: clear_tool_uses_20250919, clear_at_least: {type: input_tokens, value: 0}, clear_tool_inputs: true, exclude_tools: [string], keep: {type: tool_uses, value: 0}, trigger: {type: input_tokens, value: 1}}]}, diagnostics: {previous_message_id: previous_message_id}, fallback_credit_token: x, fallbacks: [{model: claude-fable-5, max_tokens: 0, output_config: {effort: low, format: {schema: {foo: bar}, type: json_schema}, task_budget: {total: 1024, type: tokens, remaining: 0}}, speed: standard, thinking: {budget_tokens: 1024, type: enabled, display: summarized}}], inference_geo: inference_geo, mcp_servers: [{name: name, type: url, url: url, authorization_token: authorization_token, tool_configuration: {allowed_tools: [string], enabled: true}}], metadata: {user_id: 13803d75-b4b5-4c3e-b2a2-6f21399b021b}, output_config: {effort: low, format: {schema: {foo: bar}, type: json_schema}, task_budget: {total: 1024, type: tokens, remaining: 0}}, output_format: {schema: {foo: bar}, type: json_schema}, service_tier: auto, speed: standard, stop_sequences: [string], stream: true, system: [{text: Today's date is 2024-06-01., type: text, cache_control: {type: ephemeral, ttl: 5m}, citations: [{cited_text: cited_text, document_index: 0, document_title: x, end_char_index: 0, start_char_index: 0, type: char_location}]}], temperature: 1, thinking: {type: adaptive, display: summarized}, tool_choice: {type: auto, disable_parallel_tool_use: true}, tools: [{input_schema: {type: object, properties: {location: bar, unit: bar}, required: [location]}, name: name, allowed_callers: [direct], cache_control: {type: ephemeral, ttl: 5m}, defer_loading: true, description: Get the current weather in a given location, eager_input_streaming: true, input_examples: [{foo: bar}], strict: true, type: custom}], top_k: 5, top_p: 0.7, user_profile_id: user_profile_id}", "--beta", "message-batches-2024-09-24", ) }) @@ -84,6 +84,25 @@ func TestBetaMessagesBatchesCreate(t *testing.T) { " value: 1\n" + " diagnostics:\n" + " previous_message_id: previous_message_id\n" + + " fallback_credit_token: x\n" + + " fallbacks:\n" + + " - model: claude-fable-5\n" + + " max_tokens: 0\n" + + " output_config:\n" + + " effort: low\n" + + " format:\n" + + " schema:\n" + + " foo: bar\n" + + " type: json_schema\n" + + " task_budget:\n" + + " total: 1024\n" + + " type: tokens\n" + + " remaining: 0\n" + + " speed: standard\n" + + " thinking:\n" + + " budget_tokens: 1024\n" + + " type: enabled\n" + + " display: summarized\n" + " inference_geo: inference_geo\n" + " mcp_servers:\n" + " - name: name\n" + diff --git a/pkg/cmd/betasession.go b/pkg/cmd/betasession.go index ef96a57..05296ad 100644 --- a/pkg/cmd/betasession.go +++ b/pkg/cmd/betasession.go @@ -192,7 +192,7 @@ var betaSessionsList = cli.Command{ }, &requestflag.Flag[string]{ Name: "page", - Usage: "Opaque pagination cursor from a previous response's next_page.", + Usage: "Opaque pagination cursor from a previous response.", QueryPath: "page", }, &requestflag.Flag[[]string]{ diff --git a/pkg/cmd/completion_test.go b/pkg/cmd/completion_test.go index b952b00..5553c6c 100644 --- a/pkg/cmd/completion_test.go +++ b/pkg/cmd/completion_test.go @@ -17,7 +17,7 @@ func TestCompletionsCreate(t *testing.T) { "completions", "create", "--max-items", "10", "--max-tokens-to-sample", "256", - "--model", "claude-opus-4-8", + "--model", "claude-fable-5", "--prompt", "\n\nHuman: Hello, world!\n\nAssistant:", "--metadata", "{user_id: 13803d75-b4b5-4c3e-b2a2-6f21399b021b}", "--stop-sequence", "string", @@ -40,7 +40,7 @@ func TestCompletionsCreate(t *testing.T) { "completions", "create", "--max-items", "10", "--max-tokens-to-sample", "256", - "--model", "claude-opus-4-8", + "--model", "claude-fable-5", "--prompt", "\n\nHuman: Hello, world!\n\nAssistant:", "--metadata.user-id", "13803d75-b4b5-4c3e-b2a2-6f21399b021b", "--stop-sequence", "string", @@ -56,7 +56,7 @@ func TestCompletionsCreate(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("" + "max_tokens_to_sample: 256\n" + - "model: claude-opus-4-8\n" + + "model: claude-fable-5\n" + "prompt: |-\n" + "\n" + "\n" + diff --git a/pkg/cmd/message.go b/pkg/cmd/message.go index 04d1464..aeadb41 100644 --- a/pkg/cmd/message.go +++ b/pkg/cmd/message.go @@ -96,7 +96,7 @@ var messagesCreate = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[[]map[string]any]{ Name: "tool", - Usage: "Definitions of tools that the model may use.\n\nIf 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.\n\nThere 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)).\n\nEach tool definition includes:\n\n* `name`: Name of the tool.\n* `description`: Optional, but strongly-recommended description of the tool.\n* `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.\n\nFor example, if you defined `tools` as:\n\n```json\n[\n {\n \"name\": \"get_stock_price\",\n \"description\": \"Get the current stock price for a given ticker symbol.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"ticker\": {\n \"type\": \"string\",\n \"description\": \"The stock ticker symbol, e.g. AAPL for Apple Inc.\"\n }\n },\n \"required\": [\"ticker\"]\n }\n }\n]\n```\n\nAnd 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:\n\n```json\n[\n {\n \"type\": \"tool_use\",\n \"id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"name\": \"get_stock_price\",\n \"input\": { \"ticker\": \"^GSPC\" }\n }\n]\n```\n\nYou 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:\n\n```json\n[\n {\n \"type\": \"tool_result\",\n \"tool_use_id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"content\": \"259.75 USD\"\n }\n]\n```\n\nTools 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.\n\nSee our [guide](https://docs.claude.com/en/docs/tool-use) for more details.", + Usage: "Definitions of tools that the model may use.\n\nIf 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.\n\nThere 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)).\n\nEach tool definition includes:\n\n* `name`: Name of the tool.\n* `description`: Optional, but strongly-recommended description of the tool.\n* `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.\n\nFor example, if you defined `tools` as:\n\n```json\n[\n {\n \"name\": \"get_stock_price\",\n \"description\": \"Get the current stock price for a given ticker symbol.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"ticker\": {\n \"type\": \"string\",\n \"description\": \"The stock ticker symbol, e.g. AAPL for Apple Inc.\"\n }\n },\n \"required\": [\"ticker\"]\n }\n }\n]\n```\n\nAnd 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:\n\n```json\n[\n {\n \"type\": \"tool_use\",\n \"id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"name\": \"get_stock_price\",\n \"input\": { \"ticker\": \"^GSPC\" }\n }\n]\n```\n\nYou 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:\n\n```json\n[\n {\n \"type\": \"tool_result\",\n \"tool_use_id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"content\": \"259.75 USD\"\n }\n]\n```\n\nTools 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.\n\nSee our [guide](https://docs.claude.com/en/docs/tool-use) for more details.", BodyPath: "tools", }, &requestflag.Flag[int64]{ @@ -202,7 +202,7 @@ var messagesCountTokens = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[[]map[string]any]{ Name: "tool", - Usage: "Definitions of tools that the model may use.\n\nIf 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.\n\nThere 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)).\n\nEach tool definition includes:\n\n* `name`: Name of the tool.\n* `description`: Optional, but strongly-recommended description of the tool.\n* `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.\n\nFor example, if you defined `tools` as:\n\n```json\n[\n {\n \"name\": \"get_stock_price\",\n \"description\": \"Get the current stock price for a given ticker symbol.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"ticker\": {\n \"type\": \"string\",\n \"description\": \"The stock ticker symbol, e.g. AAPL for Apple Inc.\"\n }\n },\n \"required\": [\"ticker\"]\n }\n }\n]\n```\n\nAnd 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:\n\n```json\n[\n {\n \"type\": \"tool_use\",\n \"id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"name\": \"get_stock_price\",\n \"input\": { \"ticker\": \"^GSPC\" }\n }\n]\n```\n\nYou 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:\n\n```json\n[\n {\n \"type\": \"tool_result\",\n \"tool_use_id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"content\": \"259.75 USD\"\n }\n]\n```\n\nTools 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.\n\nSee our [guide](https://docs.claude.com/en/docs/tool-use) for more details.", + Usage: "Definitions of tools that the model may use.\n\nIf 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.\n\nThere 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)).\n\nEach tool definition includes:\n\n* `name`: Name of the tool.\n* `description`: Optional, but strongly-recommended description of the tool.\n* `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.\n\nFor example, if you defined `tools` as:\n\n```json\n[\n {\n \"name\": \"get_stock_price\",\n \"description\": \"Get the current stock price for a given ticker symbol.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"ticker\": {\n \"type\": \"string\",\n \"description\": \"The stock ticker symbol, e.g. AAPL for Apple Inc.\"\n }\n },\n \"required\": [\"ticker\"]\n }\n }\n]\n```\n\nAnd 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:\n\n```json\n[\n {\n \"type\": \"tool_use\",\n \"id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"name\": \"get_stock_price\",\n \"input\": { \"ticker\": \"^GSPC\" }\n }\n]\n```\n\nYou 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:\n\n```json\n[\n {\n \"type\": \"tool_result\",\n \"tool_use_id\": \"toolu_01D7FLrfh4GYq7yT1ULFeyMV\",\n \"content\": \"259.75 USD\"\n }\n]\n```\n\nTools 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.\n\nSee our [guide](https://docs.claude.com/en/docs/tool-use) for more details.", BodyPath: "tools", }, }, diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index becade7..b5f5fd1 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -2,4 +2,4 @@ package cmd -const Version = "1.10.0" // x-release-please-version +const Version = "1.11.0" // x-release-please-version diff --git a/scripts/build b/scripts/build index 2d7092a..7ab9d60 100755 --- a/scripts/build +++ b/scripts/build @@ -5,7 +5,7 @@ set -euo pipefail cd "$(dirname "$0")/.." # Mark the necessary Go modules as private to avoid Go's proxy -export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/stainless-sdks/anthropic-go" +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/anthropics/anthropic-sdk-go-private" echo "==> Building ant" go build ./cmd/ant diff --git a/scripts/link b/scripts/link index 75e33ef..991e7b6 100755 --- a/scripts/link +++ b/scripts/link @@ -5,7 +5,7 @@ set -euo pipefail cd "$(dirname "$0")/.." # Mark the necessary Go modules as private to avoid Go's proxy -export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/stainless-sdks/anthropic-go" +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/anthropics/anthropic-sdk-go-private" REPLACEMENT="${1:-"../anthropic-go"}" echo "==> Replacing Go SDK with $REPLACEMENT" diff --git a/scripts/lint b/scripts/lint index 953eebd..ec7cc24 100755 --- a/scripts/lint +++ b/scripts/lint @@ -5,7 +5,7 @@ set -euo pipefail cd "$(dirname "$0")/.." # Mark the necessary Go modules as private to avoid Go's proxy -export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/stainless-sdks/anthropic-go" +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/anthropics/anthropic-sdk-go-private" echo "==> Running Go build" go build ./... diff --git a/scripts/record-demo b/scripts/record-demo new file mode 100755 index 0000000..206771f --- /dev/null +++ b/scripts/record-demo @@ -0,0 +1,135 @@ +#!/usr/bin/env bash + +# Re-records the README demo GIF (.github/demo.gif) from .github/demo.tape. +# +# Requires vhs, ttyd, and ffmpeg (https://github.com/charmbracelet/vhs#installation), +# plus python3 to serve canned API responses. No API credentials are needed: +# the recording runs against a local mock so the demo output is deterministic. + +set -euo pipefail + +cd "$(dirname "$0")/.." + +for tool in vhs ttyd ffmpeg python3; do + if ! command -v "$tool" >/dev/null 2>&1; then + echo "error: $tool is required to record the demo" >&2 + exit 1 + fi +done + +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/anthropics/anthropic-sdk-go-private" + +echo "==> Building ant" +go build ./cmd/ant + +DEMO_DIR=/tmp/ant-demo +MOCK_PORT=4011 +mkdir -p "$DEMO_DIR" + +# Mock API server with realistic, deterministic responses for the +# endpoints used in the tape. +cat > "$DEMO_DIR/mock_server.py" <<'PYEOF' +import json +from http.server import HTTPServer, BaseHTTPRequestHandler + +MESSAGE = { + "id": "msg_01XFUDUfYJgACzvnptvVoYEL", + "type": "message", + "role": "assistant", + "model": "claude-opus-4-8", + "content": [ + { + "type": "text", + "text": "Hello! It's nice to meet you. How can I help you today?", + } + ], + "stop_reason": "end_turn", + "stop_sequence": None, + "usage": {"input_tokens": 10, "output_tokens": 17}, +} + +MODEL = { + "type": "model", + "id": "claude-opus-4-8", + "display_name": "Claude Opus 4.8", + "created_at": "2026-02-04T00:00:00Z", + "max_input_tokens": 200000, + "max_tokens": 128000, + "capabilities": { + "batch": {"supported": True}, + "citations": {"supported": True}, + "code_execution": {"supported": True}, + "context_management": { + "supported": True, + "clear_thinking_20251015": {"supported": True}, + "clear_tool_uses_20250919": {"supported": True}, + "compact_20260112": {"supported": True}, + }, + "effort": { + "supported": True, + "low": {"supported": True}, + "medium": {"supported": True}, + "high": {"supported": True}, + "max": {"supported": True}, + "xhigh": {"supported": False}, + }, + "image_input": {"supported": True}, + "pdf_input": {"supported": True}, + "structured_outputs": {"supported": True}, + "thinking": { + "supported": True, + "types": { + "adaptive": {"supported": True}, + "enabled": {"supported": True}, + }, + }, + }, +} + + +class Handler(BaseHTTPRequestHandler): + def _send(self, obj): + body = json.dumps(obj).encode() + self.send_response(200) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + + def do_POST(self): + self._send(MESSAGE) + + def do_GET(self): + self._send(MODEL) + + def log_message(self, *args): + pass + + +if __name__ == "__main__": + import sys + + HTTPServer(("127.0.0.1", int(sys.argv[1])), Handler).serve_forever() +PYEOF + +# Wrapper so the tape can run plain `ant ...` commands against the mock. +# ANTHROPIC_CONFIG_DIR points at an empty directory so auth profiles on the +# recording machine can't leak warnings into the demo. +mkdir -p "$DEMO_DIR/config" +cat > "$DEMO_DIR/ant" < Starting mock server on port $MOCK_PORT" +python3 "$DEMO_DIR/mock_server.py" "$MOCK_PORT" & +MOCK_PID=$! +trap 'kill $MOCK_PID 2>/dev/null' EXIT + +echo "==> Recording .github/demo.gif" +vhs .github/demo.tape + +echo "==> Done" diff --git a/scripts/run b/scripts/run index 1148fed..ff64da8 100755 --- a/scripts/run +++ b/scripts/run @@ -5,6 +5,6 @@ set -euo pipefail cd "$(dirname "$0")/.." # Mark the necessary Go modules as private to avoid Go's proxy -export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/stainless-sdks/anthropic-go" +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/anthropics/anthropic-sdk-go-private" go run ./cmd/ant "$@" diff --git a/scripts/test b/scripts/test index 8161892..6c50885 100755 --- a/scripts/test +++ b/scripts/test @@ -5,7 +5,7 @@ set -euo pipefail cd "$(dirname "$0")/.." # Mark the necessary Go modules as private to avoid Go's proxy -export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/stainless-sdks/anthropic-go" +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/anthropics/anthropic-sdk-go,github.com/anthropics/anthropic-sdk-go-private" RED='\033[0;31m' GREEN='\033[0;32m'