diff --git a/.github/logo.svg b/.github/logo.svg new file mode 100644 index 00000000..26d103d0 --- /dev/null +++ b/.github/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 00000000..a4c8f6a8 --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,57 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize] + # Optional: Only run on specific file changes + # paths: + # - "src/**/*.ts" + # - "src/**/*.tsx" + # - "src/**/*.js" + # - "src/**/*.jsx" + +jobs: + claude-review: + # Optional: Filter by PR author + # if: | + # github.event.pull_request.user.login == 'external-contributor' || + # github.event.pull_request.user.login == 'new-developer' || + # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + prompt: | + REPO: ${{ github.repository }} + PR NUMBER: ${{ github.event.pull_request.number }} + + Please review this pull request and provide feedback on: + - Code quality and best practices + - Potential bugs or issues + - Performance considerations + - Security concerns + - Test coverage + + Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback. + + Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR. + + # 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 issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"' + diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 00000000..79fe0564 --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,50 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. + # prompt: 'Update the pull request description to include a summary of changes.' + + # Optional: Add claude_args to customize behavior and configuration + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + # claude_args: '--allowed-tools Bash(gh pr:*)' + diff --git a/.github/workflows/create-releases.yml b/.github/workflows/create-releases.yml index 28303487..ac31db22 100644 --- a/.github/workflows/create-releases.yml +++ b/.github/workflows/create-releases.yml @@ -39,6 +39,7 @@ jobs: - name: Publish to NPM if: ${{ steps.release.outputs.releases_created }} run: | - bash ./bin/publish-npm + yarn tsn scripts/publish-packages.ts env: + DATA: ${{ toJSON(steps.release.outputs) }} NPM_TOKEN: ${{ secrets.ANTHROPIC_NPM_TOKEN || secrets.NPM_TOKEN }} diff --git a/.github/workflows/detect-breaking-changes.yml b/.github/workflows/detect-breaking-changes.yml new file mode 100644 index 00000000..34fc1c9c --- /dev/null +++ b/.github/workflows/detect-breaking-changes.yml @@ -0,0 +1,36 @@ +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-typescript' + steps: + - name: Calculate fetch-depth + run: | + echo "FETCH_DEPTH=$(expr ${{ github.event.pull_request.commits }} + 1)" >> $GITHUB_ENV + + - uses: actions/checkout@v4 + with: + # Ensure we can check out the pull request base in the script below. + fetch-depth: ${{ env.FETCH_DEPTH }} + + - name: Set up Node + uses: actions/setup-node@v3 + with: + node-version: '20' + - name: Install dependencies + run: | + yarn install + + - 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 }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 514d4536..ecaaf83f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,6 +1,6 @@ { - ".": "0.71.2", - "packages/vertex-sdk": "0.14.1", - "packages/bedrock-sdk": "0.26.1", - "packages/foundry-sdk": "0.2.1" + ".": "0.72.0", + "packages/vertex-sdk": "0.14.2", + "packages/bedrock-sdk": "0.26.2", + "packages/foundry-sdk": "0.2.2" } diff --git a/.stats.yml b/.stats.yml index a2b0ec56..5c393e00 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 34 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-a49e89deec4e00d1da490808099d66e2001531b12d8666a7f5d0b496f760440d.yml openapi_spec_hash: c93ef3808c58e233b01966ff154f31ce -config_hash: a5d8cd02f9a686d4e0baa7ba652e3e55 +config_hash: 269cb3d4ee1981862834b04f1511263d diff --git a/CHANGELOG.md b/CHANGELOG.md index e270dfe6..a2b465ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## 0.72.0 (2026-01-09) + +Full Changelog: [sdk-v0.71.2...sdk-v0.72.0](https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.71.2...sdk-v0.72.0) + +### Features + +* **ci:** add breaking change detection workflow ([7d51dac](https://github.com/anthropics/anthropic-sdk-typescript/commit/7d51dacef07727ceaae192e6a0fefb2e0a60a987)) + + +### Bug Fixes + +* **mcp:** correct code tool API endpoint ([ba21721](https://github.com/anthropics/anthropic-sdk-typescript/commit/ba21721557b96dd0fd89e2b3459aed7e95dd733a)) +* **mcp:** return correct lines on typescript errors ([0b98943](https://github.com/anthropics/anthropic-sdk-typescript/commit/0b98943430f7d6c5c85047d9d676efbf2b6b8052)) + + +### Chores + +* break long lines in snippets into multiline ([80e8e4c](https://github.com/anthropics/anthropic-sdk-typescript/commit/80e8e4c8027db6f5238eb2e0c62d89f5ddbd0bd0)) +* **ci:** Add Claude Code GitHub Workflow ([#612](https://github.com/anthropics/anthropic-sdk-typescript/issues/612)) ([0a6c372](https://github.com/anthropics/anthropic-sdk-typescript/commit/0a6c372e5c9524aef125c854a0f39680d82be642)) +* **ci:** fix multi package publishing ([a7e605c](https://github.com/anthropics/anthropic-sdk-typescript/commit/a7e605c3bee736409b10ef92f95da1ad9bf8ac8b)) +* **internal:** codegen related update ([a7fbcd8](https://github.com/anthropics/anthropic-sdk-typescript/commit/a7fbcd8733d554a7682d612ab0cf4873a4d05265)) +* **internal:** codegen related update ([2a6e2cd](https://github.com/anthropics/anthropic-sdk-typescript/commit/2a6e2cd068a6c5846054e4d0d0103be9750b1f57)) +* **internal:** version bump ([f3e89e8](https://github.com/anthropics/anthropic-sdk-typescript/commit/f3e89e84a2c807d7ded1738a9a9090710cb6605e)) +* **tests:** remove extraneous header test ([fd388c6](https://github.com/anthropics/anthropic-sdk-typescript/commit/fd388c6a113d655409659aff82dd3336b946f8b4)) + + +### Documentation + +* update README with Claude branding ([#611](https://github.com/anthropics/anthropic-sdk-typescript/issues/611)) ([203223a](https://github.com/anthropics/anthropic-sdk-typescript/commit/203223ac1720b1387b37dc83d6e36a89c2af9179)) + ## 0.71.2 (2025-12-05) Full Changelog: [sdk-v0.71.1...sdk-v0.71.2](https://github.com/anthropics/anthropic-sdk-typescript/compare/sdk-v0.71.1...sdk-v0.71.2) diff --git a/README.md b/README.md index 520e7f8a..55cb66db 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Anthropic TypeScript API Library +# Claude SDK for TypeScript [![NPM version]()](https://npmjs.org/package/@anthropic-ai/sdk) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/@anthropic-ai/sdk) -This library provides convenient access to the Anthropic REST API from server-side TypeScript or JavaScript. +This library provides convenient access to the Claude API from TypeScript or JavaScript. -The REST API documentation can be found on [docs.anthropic.com](https://docs.anthropic.com/claude/reference/). The full API of this library can be found in [api.md](api.md). +The full API documentation can be found at [platform.claude.com/docs](https://platform.claude.com/docs/en/api/typescript/messages/create) or in [api.md](api.md). ## Installation @@ -14,8 +14,6 @@ npm install @anthropic-ai/sdk ## Usage -The full API of this library can be found in [api.md](api.md). - ```js import Anthropic from '@anthropic-ai/sdk'; @@ -124,42 +122,9 @@ Streaming with `client.messages.stream(...)` exposes [various helpers for your c Alternatively, you can use `client.messages.create({ ..., stream: true })` which only returns an async iterable of the events in the stream and thus uses less memory (it does not build up a final message object for you). -## Tool Helpers - -This SDK provides helpers for making it easy to create and run tools in the Messages API. You can use Zod schemas or JSON Schemas to describe the input to a tool. You can then run those tools using the `client.messages.toolRunner()` method. This method will handle passing the inputs generated by the chosen model into the right tool and passing the result back to the model. - -```ts -import Anthropic from '@anthropic-ai/sdk'; - -import { betaZodTool } from '@anthropic-ai/sdk/helpers/beta/zod'; -import { z } from 'zod'; - -const anthropic = new Anthropic(); - -const weatherTool = betaZodTool({ - name: 'get_weather', - inputSchema: z.object({ - location: z.string(), - }), - description: 'Get the current weather in a given location', - run: (input) => { - return `The weather in ${input.location} is foggy and 60°F`; - }, -}); - -const finalMessage = await anthropic.beta.messages.toolRunner({ - model: 'claude-3-5-sonnet-20241022', - max_tokens: 1000, - messages: [{ role: 'user', content: 'What is the weather in San Francisco?' }], - tools: [weatherTool], -}); -``` - -You can find more details on how to use these tool helpers [here](helpers.md#tool-helpers). - ## Message Batches -This SDK provides support for the [Message Batches API](https://docs.anthropic.com/en/docs/build-with-claude/message-batches) under the `client.messages.batches` namespace. +This SDK provides support for the [Message Batches API](https://platform.claude.com/docs/en/api/typescript/messages/batches/create) under the `client.messages.batches` namespace. ### Creating a batch @@ -203,7 +168,35 @@ for await (const entry of results) { ## Tool use -This SDK provides support for tool use, aka function calling. More details can be found in [the documentation](https://docs.anthropic.com/claude/docs/tool-use). +This SDK provides support for tool use, aka function calling. More details can be found in [the documentation](https://platform.claude.com/docs/en/api/tool-use). +The SDK provides helpers for making it easy to create and run tools. You can use Zod schemas or JSON Schemas to describe the input to a tool. You can then run those tools using the `client.messages.toolRunner()` method. This method will handle passing the inputs generated by the chosen model into the right tool and passing the result back to the model. + +```ts +import Anthropic from '@anthropic-ai/sdk'; + +import { betaZodTool } from '@anthropic-ai/sdk/helpers/beta/zod'; +import { z } from 'zod'; + +const anthropic = new Anthropic(); + +const weatherTool = betaZodTool({ + name: 'get_weather', + inputSchema: z.object({ + location: z.string(), + }), + description: 'Get the current weather in a given location', + run: (input) => { + return `The weather in ${input.location} is foggy and 60°F`; + }, +}); + +const finalMessage = await anthropic.beta.messages.toolRunner({ + model: 'claude-3-5-sonnet-20241022', + max_tokens: 1000, + messages: [{ role: 'user', content: 'What is the weather in San Francisco?' }], + tools: [weatherTool], +}); +``` ## AWS Bedrock @@ -294,7 +287,7 @@ Error codes are as follows: ## Request IDs -> For more information on debugging requests, see [these docs](https://docs.anthropic.com/en/api/errors#request-id) +> For more information on debugging requests, see [these docs](https://platform.claude.com/docs/en/api/errors#request-id) All object responses in the SDK provide a `_request_id` property which is added from the `request-id` response header so that you can quickly log failing requests and report them back to Anthropic. @@ -323,7 +316,11 @@ const client = new Anthropic({ }); // Or, configure per-request: -await client.messages.create({ max_tokens: 1024, messages: [{ role: 'user', content: 'Hello, Claude' }], model: 'claude-sonnet-4-5-20250929' }, { +await client.messages.create({ + max_tokens: 1024, + messages: [{ role: 'user', content: 'Hello, Claude' }], + model: 'claude-sonnet-4-5-20250929', +}, { maxRetries: 5, }); ``` @@ -351,7 +348,11 @@ const client = new Anthropic({ }); // Override per-request: -await client.messages.create({ max_tokens: 1024, messages: [{ role: 'user', content: 'Hello, Claude' }], model: 'claude-sonnet-4-5-20250929' }, { +await client.messages.create({ + max_tokens: 1024, + messages: [{ role: 'user', content: 'Hello, Claude' }], + model: 'claude-sonnet-4-5-20250929', +}, { timeout: 5 * 1000, }); ``` @@ -381,7 +382,7 @@ This can be [overriden](#configuring-an-https-agent-eg-for-proxies) by configuri ## Auto-pagination -List methods in the Anthropic API are paginated. +List methods in the Claude API are paginated. You can use the `for await … of` syntax to iterate through items across all pages: ```ts @@ -645,9 +646,9 @@ const client = new Anthropic({ ### Beta Features -We introduce beta features before they are generally available to get early feedback and test new functionality. You can check the availability of all of Claude's capabilities and tools [here](https://docs.anthropic.com/en/docs/build-with-claude/overview). +We introduce beta features before they are generally available to get early feedback and test new functionality. You can check the availability of all of Claude's capabilities and tools [here](https://platform.claude.com/docs/en/api/overview). -You can access most beta API features through the beta property of the client. To enable a particular beta feature, you need to add the appropriate [beta header](https://docs.anthropic.com/en/api/beta-headers) to the `betas` field when creating a message. +You can access most beta API features through the beta property of the client. To enable a particular beta feature, you need to add the appropriate [beta header](https://platform.claude.com/docs/en/api/beta-headers) to the `betas` field when creating a message. For example, to use code execution: diff --git a/package.json b/package.json index 6634b809..79a461b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@anthropic-ai/sdk", - "version": "0.71.2", + "version": "0.72.0", "description": "The official TypeScript library for the Anthropic API", "author": "Anthropic ", "types": "dist/index.d.ts", diff --git a/packages/bedrock-sdk/CHANGELOG.md b/packages/bedrock-sdk/CHANGELOG.md index ef146b3b..e15bf5fc 100644 --- a/packages/bedrock-sdk/CHANGELOG.md +++ b/packages/bedrock-sdk/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.26.2 (2026-01-09) + +Full Changelog: [bedrock-sdk-v0.26.1...bedrock-sdk-v0.26.2](https://github.com/anthropics/anthropic-sdk-typescript/compare/bedrock-sdk-v0.26.1...bedrock-sdk-v0.26.2) + +### Chores + +* **internal:** version bump ([f3e89e8](https://github.com/anthropics/anthropic-sdk-typescript/commit/f3e89e84a2c807d7ded1738a9a9090710cb6605e)) + + +### Documentation + +* update README with Claude branding ([#611](https://github.com/anthropics/anthropic-sdk-typescript/issues/611)) ([203223a](https://github.com/anthropics/anthropic-sdk-typescript/commit/203223ac1720b1387b37dc83d6e36a89c2af9179)) + ## 0.26.1 (2025-11-24) Full Changelog: [bedrock-sdk-v0.26.0...bedrock-sdk-v0.26.1](https://github.com/anthropics/anthropic-sdk-typescript/compare/bedrock-sdk-v0.26.0...bedrock-sdk-v0.26.1) diff --git a/packages/bedrock-sdk/README.md b/packages/bedrock-sdk/README.md index c5dcd9db..99e67526 100644 --- a/packages/bedrock-sdk/README.md +++ b/packages/bedrock-sdk/README.md @@ -1,10 +1,10 @@ -# Anthropic Bedrock TypeScript API Library +# Claude SDK for AWS Bedrock -[![NPM version](https://img.shields.io/npm/v/@anthropic-ai/bedrock-sdk.svg)](https://npmjs.org/package/@anthropic-ai/bedrock-sdk) +[![NPM version](https://img.shields.io/npm/v/@anthropic-ai/bedrock-sdk.svg?color=blue)](https://npmjs.org/package/@anthropic-ai/bedrock-sdk) -This library provides convenient access to the Anthropic Bedrock API. +This library provides convenient access to the Claude API via AWS Bedrock. See the [documentation](https://platform.claude.com/docs/en/build-with-claude/claude-on-amazon-bedrock) for more details. -For the non-Bedrock Anthropic API at api.anthropic.com, see [`@anthropic-ai/sdk`](https://github.com/anthropics/anthropic-sdk-typescript). +For the direct Claude API at api.anthropic.com, see [`@anthropic-ai/sdk`](https://github.com/anthropics/anthropic-sdk-typescript). ## Installation @@ -66,7 +66,7 @@ const client = new AnthropicBedrock({ }); ``` -For more details on how to use the SDK, see the [README.md for the main Anthropic SDK](https://github.com/anthropics/anthropic-sdk-typescript/tree/main#anthropic-typescript-api-library) which this library extends. +For more details on how to use the SDK, see the [README.md for the main Claude SDK](https://github.com/anthropics/anthropic-sdk-typescript/tree/main#readme) which this library extends. ## Requirements diff --git a/packages/bedrock-sdk/build b/packages/bedrock-sdk/build index 7d397804..9107e1f8 100755 --- a/packages/bedrock-sdk/build +++ b/packages/bedrock-sdk/build @@ -6,6 +6,10 @@ rm -rf dist; mkdir dist # Copy src to dist/src and build from dist/src into dist, so that # the source map for index.js.map will refer to ./src/index.ts etc cp -rp src README.md dist +if [ -d "../../.github" ]; then + mkdir -p dist/.github + cp -p ../../.github/logo.svg dist/.github/ 2>/dev/null || true +fi for file in LICENSE; do if [ -e "../../${file}" ]; then cp "../../${file}" dist; fi diff --git a/packages/bedrock-sdk/package.json b/packages/bedrock-sdk/package.json index 98859cf0..8bb64d15 100644 --- a/packages/bedrock-sdk/package.json +++ b/packages/bedrock-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@anthropic-ai/bedrock-sdk", - "version": "0.26.1", + "version": "0.26.2", "description": "The official TypeScript library for the Anthropic Bedrock API", "author": "Anthropic ", "types": "dist/index.d.ts", diff --git a/packages/foundry-sdk/CHANGELOG.md b/packages/foundry-sdk/CHANGELOG.md index ac951643..4b942cab 100644 --- a/packages/foundry-sdk/CHANGELOG.md +++ b/packages/foundry-sdk/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.2.2 (2026-01-09) + +Full Changelog: [foundry-sdk-v0.2.1...foundry-sdk-v0.2.2](https://github.com/anthropics/anthropic-sdk-typescript/compare/foundry-sdk-v0.2.1...foundry-sdk-v0.2.2) + +### Chores + +* **internal:** version bump ([f3e89e8](https://github.com/anthropics/anthropic-sdk-typescript/commit/f3e89e84a2c807d7ded1738a9a9090710cb6605e)) + + +### Documentation + +* update README with Claude branding ([#611](https://github.com/anthropics/anthropic-sdk-typescript/issues/611)) ([203223a](https://github.com/anthropics/anthropic-sdk-typescript/commit/203223ac1720b1387b37dc83d6e36a89c2af9179)) + ## 0.2.1 (2025-11-20) Full Changelog: [foundry-sdk-v0.2.0...foundry-sdk-v0.2.1](https://github.com/anthropics/anthropic-sdk-typescript/compare/foundry-sdk-v0.2.0...foundry-sdk-v0.2.1) diff --git a/packages/foundry-sdk/README.md b/packages/foundry-sdk/README.md index 0dbec48a..d46a3b49 100644 --- a/packages/foundry-sdk/README.md +++ b/packages/foundry-sdk/README.md @@ -1,7 +1,10 @@ -# Anthropic Foundry +# Claude SDK for Microsoft Foundry -To use this library with Foundry, use the `AnthropicFoundry` -class instead of the `Anthropic` class. +[![NPM version](https://img.shields.io/npm/v/@anthropic-ai/foundry-sdk.svg?color=blue)](https://npmjs.org/package/@anthropic-ai/foundry-sdk) + +This library provides convenient access to the Claude API via Microsoft Azure AI Foundry. See the [documentation](https://platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry) for more details. + +For the direct Claude API at api.anthropic.com, see [`@anthropic-ai/sdk`](https://github.com/anthropics/anthropic-sdk-typescript). ## Installation diff --git a/packages/foundry-sdk/build b/packages/foundry-sdk/build index 35f01b7a..d382622c 100755 --- a/packages/foundry-sdk/build +++ b/packages/foundry-sdk/build @@ -6,6 +6,10 @@ rm -rf dist; mkdir dist # Copy src to dist/src and build from dist/src into dist, so that # the source map for index.js.map will refer to ./src/index.ts etc cp -rp src README.md dist +if [ -d "../../.github" ]; then + mkdir -p dist/.github + cp -p ../../.github/logo.svg dist/.github/ 2>/dev/null || true +fi for file in LICENSE; do if [ -e "../../${file}" ]; then cp "../../${file}" dist; fi diff --git a/packages/foundry-sdk/package.json b/packages/foundry-sdk/package.json index d71528ae..56fbb130 100644 --- a/packages/foundry-sdk/package.json +++ b/packages/foundry-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@anthropic-ai/foundry-sdk", - "version": "0.2.1", + "version": "0.2.2", "description": "The official TypeScript library for the Anthropic Foundry API", "author": "Anthropic ", "types": "dist/index.d.ts", diff --git a/packages/vertex-sdk/CHANGELOG.md b/packages/vertex-sdk/CHANGELOG.md index 628a565f..3cc74240 100644 --- a/packages/vertex-sdk/CHANGELOG.md +++ b/packages/vertex-sdk/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.14.2 (2026-01-09) + +Full Changelog: [vertex-sdk-v0.14.1...vertex-sdk-v0.14.2](https://github.com/anthropics/anthropic-sdk-typescript/compare/vertex-sdk-v0.14.1...vertex-sdk-v0.14.2) + +### Chores + +* **internal:** version bump ([f3e89e8](https://github.com/anthropics/anthropic-sdk-typescript/commit/f3e89e84a2c807d7ded1738a9a9090710cb6605e)) + + +### Documentation + +* update README with Claude branding ([#611](https://github.com/anthropics/anthropic-sdk-typescript/issues/611)) ([203223a](https://github.com/anthropics/anthropic-sdk-typescript/commit/203223ac1720b1387b37dc83d6e36a89c2af9179)) + ## 0.14.1 (2025-11-24) Full Changelog: [vertex-sdk-v0.14.0...vertex-sdk-v0.14.1](https://github.com/anthropics/anthropic-sdk-typescript/compare/vertex-sdk-v0.14.0...vertex-sdk-v0.14.1) diff --git a/packages/vertex-sdk/README.md b/packages/vertex-sdk/README.md index 539db0d5..5d33e678 100644 --- a/packages/vertex-sdk/README.md +++ b/packages/vertex-sdk/README.md @@ -1,10 +1,10 @@ -# Anthropic Vertex TypeScript API Library +# Claude SDK for Google Vertex -[![NPM version](https://img.shields.io/npm/v/@anthropic-ai/vertex-sdk.svg)](https://npmjs.org/package/@anthropic-ai/vertex-sdk) +[![NPM version](https://img.shields.io/npm/v/@anthropic-ai/vertex-sdk.svg?color=blue)](https://npmjs.org/package/@anthropic-ai/vertex-sdk) -This library provides convenient access to the Anthropic Vertex API. +This library provides convenient access to the Claude API via Google Vertex AI. See the [documentation](https://platform.claude.com/docs/en/build-with-claude/claude-on-vertex-ai) for more details. -For the non-Vertex Anthropic API at api.anthropic.com, see [`@anthropic-ai/sdk`](https://github.com/anthropics/anthropic-sdk-typescript). +For the direct Claude API at api.anthropic.com, see [`@anthropic-ai/sdk`](https://github.com/anthropics/anthropic-sdk-typescript). ## Installation @@ -39,7 +39,7 @@ async function main() { main(); ``` -For more details on how to use the SDK, see the [README.md for the main Anthropic SDK](https://github.com/anthropics/anthropic-sdk-typescript/tree/main#anthropic-typescript-api-library) which this library extends. +For more details on how to use the SDK, see the [README.md for the main Claude SDK](https://github.com/anthropics/anthropic-sdk-typescript/tree/main#readme) which this library extends. ## Authentication diff --git a/packages/vertex-sdk/build b/packages/vertex-sdk/build index 3dcbe428..1b8adde1 100755 --- a/packages/vertex-sdk/build +++ b/packages/vertex-sdk/build @@ -6,6 +6,10 @@ rm -rf dist; mkdir dist # Copy src to dist/src and build from dist/src into dist, so that # the source map for index.js.map will refer to ./src/index.ts etc cp -rp src README.md dist +if [ -d "../../.github" ]; then + mkdir -p dist/.github + cp -p ../../.github/logo.svg dist/.github/ 2>/dev/null || true +fi for file in LICENSE; do if [ -e "../../${file}" ]; then cp "../../${file}" dist; fi diff --git a/packages/vertex-sdk/package.json b/packages/vertex-sdk/package.json index 49260d41..9b587c59 100644 --- a/packages/vertex-sdk/package.json +++ b/packages/vertex-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@anthropic-ai/vertex-sdk", - "version": "0.14.1", + "version": "0.14.2", "description": "The official TypeScript library for the Anthropic Vertex API", "author": "Anthropic ", "types": "dist/index.d.ts", diff --git a/packages/vertex-sdk/yarn.lock b/packages/vertex-sdk/yarn.lock index a31911ac..ca195558 100644 --- a/packages/vertex-sdk/yarn.lock +++ b/packages/vertex-sdk/yarn.lock @@ -17,7 +17,7 @@ "@anthropic-ai/sdk@file:../../dist": # x-release-please-start-version - version "0.71.2" + version "0.72.0" # x-release-please-end-version dependencies: json-schema-to-ts "^3.1.1" diff --git a/scripts/build b/scripts/build index 42e848a6..52008ddb 100755 --- a/scripts/build +++ b/scripts/build @@ -15,6 +15,10 @@ rm -rf dist; mkdir dist # Copy src to dist/src and build from dist/src into dist, so that # the source map for index.js.map will refer to ./src/index.ts etc cp -rp src README.md dist +if [ -d ".github" ]; then + mkdir -p dist/.github + cp -p .github/logo.svg dist/.github/ 2>/dev/null || true +fi for file in LICENSE CHANGELOG.md; do if [ -e "${file}" ]; then cp "${file}" dist; fi done diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts index b2969fda..59f62b0b 100644 --- a/src/internal/to-file.ts +++ b/src/internal/to-file.ts @@ -90,7 +90,7 @@ export async function toFile( // If it's a promise, resolve it. value = await value; - name ||= getName(value); + name ||= getName(value, true); // If we've been given a `File` we don't need to do anything if the name / options // have not been customised. diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index 93d52a7c..99b24a36 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -49,20 +49,17 @@ export function makeFile( return new File(fileBits as any, fileName ?? 'unknown_file', options); } -export function getName(value: any): string | undefined { - return ( - ( - (typeof value === 'object' && - value !== null && - (('name' in value && value.name && String(value.name)) || - ('url' in value && value.url && String(value.url)) || - ('filename' in value && value.filename && String(value.filename)) || - ('path' in value && value.path && String(value.path)))) || - '' - ) - .split(/[\\/]/) - .pop() || undefined - ); +export function getName(value: any, stripPath: boolean): string | undefined { + const val = + (typeof value === 'object' && + value !== null && + (('name' in value && value.name && String(value.name)) || + ('url' in value && value.url && String(value.url)) || + ('filename' in value && value.filename && String(value.filename)) || + ('path' in value && value.path && String(value.path)))) || + ''; + + return stripPath ? val.split(/[\\/]/).pop() || undefined : val; } export const isAsyncIterable = (value: any): value is AsyncIterable => @@ -86,8 +83,9 @@ type MultipartFormRequestOptions = Omit & { body: unknow export const multipartFormRequestOptions = async ( opts: MultipartFormRequestOptions, fetch: BaseAnthropic | Fetch, + stripFilenames: boolean = true, ): Promise => { - return { ...opts, body: await createForm(opts.body, fetch) }; + return { ...opts, body: await createForm(opts.body, fetch, stripFilenames) }; }; const supportsFormDataMap = /* @__PURE__ */ new WeakMap>(); @@ -125,6 +123,7 @@ function supportsFormData(fetchObject: BaseAnthropic | Fetch): Promise export const createForm = async >( body: T | undefined, fetch: BaseAnthropic | Fetch, + stripFilenames: boolean = true, ): Promise => { if (!(await supportsFormData(fetch))) { throw new TypeError( @@ -132,7 +131,9 @@ export const createForm = async >( ); } const form = new FormData(); - await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value))); + await Promise.all( + Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value, stripFilenames)), + ); return form; }; @@ -156,7 +157,12 @@ const hasUploadableValue = (value: unknown): boolean => { return false; }; -const addFormValue = async (form: FormData, key: string, value: unknown): Promise => { +const addFormValue = async ( + form: FormData, + key: string, + value: unknown, + stripFilenames: boolean, +): Promise => { if (value === undefined) return; if (value == null) { throw new TypeError( @@ -174,16 +180,21 @@ const addFormValue = async (form: FormData, key: string, value: unknown): Promis options = { type: contentType }; } - form.append(key, makeFile([await value.blob()], getName(value), options)); + form.append(key, makeFile([await value.blob()], getName(value, stripFilenames), options)); } else if (isAsyncIterable(value)) { - form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value))); + form.append( + key, + makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value, stripFilenames)), + ); } else if (isNamedBlob(value)) { - form.append(key, makeFile([value], getName(value), { type: value.type })); + form.append(key, makeFile([value], getName(value, stripFilenames), { type: value.type })); } else if (Array.isArray(value)) { - await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry))); + await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry, stripFilenames))); } else if (typeof value === 'object') { await Promise.all( - Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)), + Object.entries(value).map(([name, prop]) => + addFormValue(form, `${key}[${name}]`, prop, stripFilenames), + ), ); } else { throw new TypeError( diff --git a/src/resources/beta/skills/skills.ts b/src/resources/beta/skills/skills.ts index c5b33668..13737de2 100644 --- a/src/resources/beta/skills/skills.ts +++ b/src/resources/beta/skills/skills.ts @@ -51,6 +51,7 @@ export class Skills extends APIResource { ]), }, this._client, + false, ), ); } diff --git a/src/version.ts b/src/version.ts index 731e1e91..73387f81 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.71.2'; // x-release-please-version +export const VERSION = '0.72.0'; // x-release-please-version diff --git a/tests/api-resources/beta/files.test.ts b/tests/api-resources/beta/files.test.ts index c451bc02..4389b225 100644 --- a/tests/api-resources/beta/files.test.ts +++ b/tests/api-resources/beta/files.test.ts @@ -23,7 +23,12 @@ describe('resource files', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.beta.files.list( - { after_id: 'after_id', before_id: 'before_id', limit: 1, betas: ['string'] }, + { + after_id: 'after_id', + before_id: 'before_id', + limit: 1, + betas: ['string'], + }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Anthropic.NotFoundError); diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index 01875a64..7f044001 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -41,7 +41,16 @@ describe('resource batches', () => { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], model: 'claude-sonnet-4-5-20250929', - container: { id: 'id', skills: [{ skill_id: 'x', type: 'anthropic', version: 'x' }] }, + container: { + id: 'id', + skills: [ + { + skill_id: 'x', + type: 'anthropic', + version: 'x', + }, + ], + }, context_management: { edits: [ { @@ -65,7 +74,10 @@ describe('resource batches', () => { ], metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, output_config: { effort: 'low' }, - output_format: { schema: { foo: 'bar' }, type: 'json_schema' }, + output_format: { + schema: { foo: 'bar' }, + type: 'json_schema', + }, service_tier: 'auto', stop_sequences: ['string'], stream: false, @@ -152,7 +164,12 @@ describe('resource batches', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.beta.messages.batches.list( - { after_id: 'after_id', before_id: 'before_id', limit: 1, betas: ['string'] }, + { + after_id: 'after_id', + before_id: 'before_id', + limit: 1, + betas: ['string'], + }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Anthropic.NotFoundError); diff --git a/tests/api-resources/beta/messages/messages.test.ts b/tests/api-resources/beta/messages/messages.test.ts index ca36c6e2..bac90c77 100644 --- a/tests/api-resources/beta/messages/messages.test.ts +++ b/tests/api-resources/beta/messages/messages.test.ts @@ -30,7 +30,16 @@ describe('resource messages', () => { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], model: 'claude-sonnet-4-5-20250929', - container: { id: 'id', skills: [{ skill_id: 'x', type: 'anthropic', version: 'x' }] }, + container: { + id: 'id', + skills: [ + { + skill_id: 'x', + type: 'anthropic', + version: 'x', + }, + ], + }, context_management: { edits: [ { @@ -54,7 +63,10 @@ describe('resource messages', () => { ], metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, output_config: { effort: 'low' }, - output_format: { schema: { foo: 'bar' }, type: 'json_schema' }, + output_format: { + schema: { foo: 'bar' }, + type: 'json_schema', + }, service_tier: 'auto', stop_sequences: ['string'], stream: false, @@ -143,7 +155,10 @@ describe('resource messages', () => { }, ], output_config: { effort: 'low' }, - output_format: { schema: { foo: 'bar' }, type: 'json_schema' }, + output_format: { + schema: { foo: 'bar' }, + type: 'json_schema', + }, system: [ { text: "Today's date is 2024-06-01.", diff --git a/tests/api-resources/beta/models.test.ts b/tests/api-resources/beta/models.test.ts index 678078c8..4d3d0627 100644 --- a/tests/api-resources/beta/models.test.ts +++ b/tests/api-resources/beta/models.test.ts @@ -48,7 +48,12 @@ describe('resource models', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.beta.models.list( - { after_id: 'after_id', before_id: 'before_id', limit: 1, betas: ['string'] }, + { + after_id: 'after_id', + before_id: 'before_id', + limit: 1, + betas: ['string'], + }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Anthropic.NotFoundError); diff --git a/tests/api-resources/beta/skills/skills.test.ts b/tests/api-resources/beta/skills/skills.test.ts index 01fef704..0b87e2a3 100644 --- a/tests/api-resources/beta/skills/skills.test.ts +++ b/tests/api-resources/beta/skills/skills.test.ts @@ -68,7 +68,12 @@ describe('resource skills', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.beta.skills.list( - { limit: 0, page: 'page', source: 'source', betas: ['string'] }, + { + limit: 0, + page: 'page', + source: 'source', + betas: ['string'], + }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Anthropic.NotFoundError); diff --git a/tests/api-resources/beta/skills/versions.test.ts b/tests/api-resources/beta/skills/versions.test.ts index ad7e1b12..e700244f 100644 --- a/tests/api-resources/beta/skills/versions.test.ts +++ b/tests/api-resources/beta/skills/versions.test.ts @@ -66,7 +66,11 @@ describe('resource versions', () => { await expect( client.beta.skills.versions.list( 'skill_id', - { limit: 0, page: 'page', betas: ['string'] }, + { + limit: 0, + page: 'page', + betas: ['string'], + }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Anthropic.NotFoundError); diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index 1079bd4f..e4abe0e8 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -109,7 +109,11 @@ describe('resource batches', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.messages.batches.list( - { after_id: 'after_id', before_id: 'before_id', limit: 1 }, + { + after_id: 'after_id', + before_id: 'before_id', + limit: 1, + }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Anthropic.NotFoundError); diff --git a/tests/api-resources/models.test.ts b/tests/api-resources/models.test.ts index 40e63144..7cd2df82 100644 --- a/tests/api-resources/models.test.ts +++ b/tests/api-resources/models.test.ts @@ -48,7 +48,12 @@ describe('resource models', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.models.list( - { after_id: 'after_id', before_id: 'before_id', limit: 1, betas: ['string'] }, + { + after_id: 'after_id', + before_id: 'before_id', + limit: 1, + betas: ['string'], + }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Anthropic.NotFoundError); diff --git a/tests/index.test.ts b/tests/index.test.ts index 467653ee..7d2cbdfa 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -87,7 +87,11 @@ describe('instantiate client', () => { error: jest.fn(), }; - const client = new Anthropic({ logger: logger, logLevel: 'debug', apiKey: 'my-anthropic-api-key' }); + const client = new Anthropic({ + logger: logger, + logLevel: 'debug', + apiKey: 'my-anthropic-api-key', + }); await forceAPIResponseForClient(client); expect(debugMock).toHaveBeenCalled(); @@ -107,7 +111,11 @@ describe('instantiate client', () => { error: jest.fn(), }; - const client = new Anthropic({ logger: logger, logLevel: 'info', apiKey: 'my-anthropic-api-key' }); + const client = new Anthropic({ + logger: logger, + logLevel: 'info', + apiKey: 'my-anthropic-api-key', + }); await forceAPIResponseForClient(client); expect(debugMock).not.toHaveBeenCalled(); @@ -157,7 +165,11 @@ describe('instantiate client', () => { }; process.env['ANTHROPIC_LOG'] = 'debug'; - const client = new Anthropic({ logger: logger, logLevel: 'off', apiKey: 'my-anthropic-api-key' }); + const client = new Anthropic({ + logger: logger, + logLevel: 'off', + apiKey: 'my-anthropic-api-key', + }); await forceAPIResponseForClient(client); expect(debugMock).not.toHaveBeenCalled(); @@ -173,7 +185,11 @@ describe('instantiate client', () => { }; process.env['ANTHROPIC_LOG'] = 'not a log level'; - const client = new Anthropic({ logger: logger, logLevel: 'debug', apiKey: 'my-anthropic-api-key' }); + const client = new Anthropic({ + logger: logger, + logLevel: 'debug', + apiKey: 'my-anthropic-api-key', + }); expect(client.logLevel).toBe('debug'); expect(warnMock).not.toHaveBeenCalled(); }); @@ -552,7 +568,11 @@ describe('retries', () => { return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; - const client = new Anthropic({ apiKey: 'my-anthropic-api-key', timeout: 10, fetch: testFetch }); + const client = new Anthropic({ + apiKey: 'my-anthropic-api-key', + timeout: 10, + fetch: testFetch, + }); expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 }); expect(count).toEqual(2); @@ -582,7 +602,11 @@ describe('retries', () => { return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; - const client = new Anthropic({ apiKey: 'my-anthropic-api-key', fetch: testFetch, maxRetries: 4 }); + const client = new Anthropic({ + apiKey: 'my-anthropic-api-key', + fetch: testFetch, + maxRetries: 4, + }); expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 }); @@ -606,7 +630,11 @@ describe('retries', () => { capturedRequest = init; return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; - const client = new Anthropic({ apiKey: 'my-anthropic-api-key', fetch: testFetch, maxRetries: 4 }); + const client = new Anthropic({ + apiKey: 'my-anthropic-api-key', + fetch: testFetch, + maxRetries: 4, + }); expect( await client.request({ @@ -668,7 +696,11 @@ describe('retries', () => { capturedRequest = init; return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; - const client = new Anthropic({ apiKey: 'my-anthropic-api-key', fetch: testFetch, maxRetries: 4 }); + const client = new Anthropic({ + apiKey: 'my-anthropic-api-key', + fetch: testFetch, + maxRetries: 4, + }); expect( await client.request({