From b05424562987c48d623bd94acf5023a8ee4bb480 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:54:19 -0500 Subject: [PATCH 001/105] chore(internal): update examples chore: unknown commit message --- tests/api-resources/beta/messages/batches.test.ts | 2 +- tests/api-resources/beta/messages/messages.test.ts | 4 ++-- tests/api-resources/messages/batches.test.ts | 2 +- tests/api-resources/messages/messages.test.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index 77380750..23f6c37c 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -59,7 +59,7 @@ describe('resource batches', () => { }, }, }, - name: 'x', + name: 'name', cache_control: { type: 'ephemeral' }, description: 'Get the current weather in a given location', type: 'custom', diff --git a/tests/api-resources/beta/messages/messages.test.ts b/tests/api-resources/beta/messages/messages.test.ts index 8b77c33d..67a23cd0 100644 --- a/tests/api-resources/beta/messages/messages.test.ts +++ b/tests/api-resources/beta/messages/messages.test.ts @@ -43,7 +43,7 @@ describe('resource messages', () => { unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, }, }, - name: 'x', + name: 'name', cache_control: { type: 'ephemeral' }, description: 'Get the current weather in a given location', type: 'custom', @@ -84,7 +84,7 @@ describe('resource messages', () => { unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, }, }, - name: 'x', + name: 'name', cache_control: { type: 'ephemeral' }, description: 'Get the current weather in a given location', type: 'custom', diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index 0016d399..95a4deb6 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -58,7 +58,7 @@ describe('resource batches', () => { }, }, }, - name: 'x', + name: 'name', cache_control: { type: 'ephemeral' }, description: 'Get the current weather in a given location', }, diff --git a/tests/api-resources/messages/messages.test.ts b/tests/api-resources/messages/messages.test.ts index 1fd80bc8..1add2073 100644 --- a/tests/api-resources/messages/messages.test.ts +++ b/tests/api-resources/messages/messages.test.ts @@ -43,7 +43,7 @@ describe('resource messages', () => { unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, }, }, - name: 'x', + name: 'name', cache_control: { type: 'ephemeral' }, description: 'Get the current weather in a given location', }, @@ -82,7 +82,7 @@ describe('resource messages', () => { unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, }, }, - name: 'x', + name: 'name', cache_control: { type: 'ephemeral' }, description: 'Get the current weather in a given location', }, From 4775c060951a66c822e026aeb73075cd4b4ed28b Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:03:38 -0500 Subject: [PATCH 002/105] docs(readme): fix misplaced . chore: unknown commit message --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a36f15f7..9964608c 100644 --- a/README.md +++ b/README.md @@ -490,7 +490,7 @@ await client.messages.create( This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions: 1. Changes that only affect static types, without breaking runtime behavior. -2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_. +2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_ 3. Changes that we do not expect to impact the vast majority of users in practice. We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. From d6e83f7e7faa9aa10e9a3109e30dd1c9fb5f2b54 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:08:22 -0500 Subject: [PATCH 003/105] chore: use more explicit type re-exports chore: unknown commit message --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index b1ded2ef..8416e13e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,12 +5,12 @@ export { Anthropic as default } from './client'; export { multipartFormRequestOptions, maybeMultipartFormRequestOptions, - Uploadable, + type Uploadable, createForm, toFile, } from './uploads'; export { APIPromise } from './api-promise'; -export { BaseAnthropic, Anthropic, ClientOptions, HUMAN_PROMPT, AI_PROMPT } from './client'; +export { BaseAnthropic, Anthropic, type ClientOptions, HUMAN_PROMPT, AI_PROMPT } from './client'; export { PagePromise } from './pagination'; export { AnthropicError, From ce581622fabcf916bc852a8542fc4c04e48ee3c9 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:49:45 -0500 Subject: [PATCH 004/105] feat(client): improve debug logs chore: unknown commit message --- README.md | 2 +- src/api-promise.ts | 14 +++++-- src/client.ts | 60 +++++++++++++++++++++++++--- src/internal/parse.ts | 16 +++++--- src/internal/utils/log.ts | 48 ++++++++++++++++++++-- src/pagination.ts | 20 ++++++---- tests/index.test.ts | 83 +++++++++++++++++++++++++++++++++++++++ tests/responses.test.ts | 5 +++ 8 files changed, 222 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 9964608c..1c0e5417 100644 --- a/README.md +++ b/README.md @@ -451,7 +451,7 @@ const client = new Anthropic({ }); ``` -Note that if given a `DEBUG=true` environment variable, this library will log all requests and responses automatically. +Note that if given a `ANTHROPIC_LOG=debug` environment variable, this library will log all requests and responses automatically. This is intended for debugging purposes only and may change in the future without notice. ### Configuring an HTTP(S) Agent (e.g., for proxies) diff --git a/src/api-promise.ts b/src/api-promise.ts index 66ecbd35..33c0a240 100644 --- a/src/api-promise.ts +++ b/src/api-promise.ts @@ -1,5 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +import { type BaseAnthropic } from './client'; + import { type PromiseOrValue } from './internal/types'; import { type APIResponseProps, @@ -14,10 +16,13 @@ import { */ export class APIPromise extends Promise> { private parsedPromise: Promise> | undefined; + #client: BaseAnthropic; constructor( + client: BaseAnthropic, private responsePromise: Promise, private parseResponse: ( + client: BaseAnthropic, props: APIResponseProps, ) => PromiseOrValue> = defaultParseResponse, ) { @@ -27,11 +32,12 @@ export class APIPromise extends Promise> { // to parse the response resolve(null as any); }); + this.#client = client; } _thenUnwrap(transform: (data: T, props: APIResponseProps) => U): APIPromise { - return new APIPromise(this.responsePromise, async (props) => - addRequestID(transform(await this.parseResponse(props), props), props.response), + return new APIPromise(this.#client, this.responsePromise, async (client, props) => + addRequestID(transform(await this.parseResponse(client, props), props), props.response), ); } @@ -69,7 +75,9 @@ export class APIPromise extends Promise> { private parse(): Promise> { if (!this.parsedPromise) { - this.parsedPromise = this.responsePromise.then(this.parseResponse) as any as Promise>; + this.parsedPromise = this.responsePromise.then( + (data) => this.parseResponse(this.#client, data) as any as Promise>, + ); } return this.parsedPromise; } diff --git a/src/client.ts b/src/client.ts index b409e685..8e638b2f 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2,7 +2,6 @@ import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types'; import type { HTTPMethod, PromiseOrValue } from './internal/types'; -import { debug } from './internal/utils/log'; import { uuid4 } from './internal/utils/uuid'; import { validatePositiveInteger, isAbsoluteURL } from './internal/utils/values'; import { sleep } from './internal/utils/sleep'; @@ -33,6 +32,7 @@ import { } from './resources/completions'; import { ModelInfo, ModelInfosPage, ModelListParams, Models } from './resources/models'; import { readEnv } from './internal/utils/env'; +import { logger } from './internal/utils/log'; import { isEmptyObj } from './internal/utils/values'; import { AnthropicBeta, @@ -105,6 +105,25 @@ const safeJSON = (text: string) => { } }; +type LogFn = (message: string, ...rest: unknown[]) => void; +export type Logger = { + error: LogFn; + warn: LogFn; + info: LogFn; + debug: LogFn; +}; +export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug'; +const isLogLevel = (key: string | undefined): key is LogLevel => { + const levels: Record = { + off: true, + error: true, + warn: true, + info: true, + debug: true, + }; + return key! in levels; +}; + export interface ClientOptions { /** * Defaults to process.env['ANTHROPIC_API_KEY']. @@ -176,6 +195,20 @@ export interface ClientOptions { * Only set this option to `true` if you understand the risks and have appropriate mitigations in place. */ dangerouslyAllowBrowser?: boolean; + + /** + * Set the log level. + * + * Defaults to process.env['ANTHROPIC_LOG']. + */ + logLevel?: LogLevel | undefined | null; + + /** + * Set the logger. + * + * Defaults to globalThis.console. + */ + logger?: Logger | undefined | null; } type FinalizedRequestInit = RequestInit & { headers: Headers }; @@ -187,6 +220,8 @@ export class BaseAnthropic { baseURL: string; maxRetries: number; timeout: number; + logger: Logger | undefined; + logLevel: LogLevel | undefined; httpAgent: Shims.Agent | undefined; private fetch: Fetch; @@ -229,6 +264,15 @@ export class BaseAnthropic { this.baseURL = options.baseURL!; this.timeout = options.timeout ?? Anthropic.DEFAULT_TIMEOUT /* 10 minutes */; + this.logger = options.logger ?? console; + if (options.logLevel != null) { + this.logLevel = options.logLevel; + } else { + const envLevel = readEnv('ANTHROPIC_LOG'); + if (isLogLevel(envLevel)) { + this.logLevel = envLevel; + } + } this.httpAgent = options.httpAgent; this.maxRetries = options.maxRetries ?? 2; this.fetch = options.fetch ?? Shims.getDefaultFetch(); @@ -423,7 +467,7 @@ export class BaseAnthropic { options: PromiseOrValue, remainingRetries: number | null = null, ): APIPromise { - return new APIPromise(this.makeRequest(options, remainingRetries)); + return new APIPromise(this, this.makeRequest(options, remainingRetries)); } private async makeRequest( @@ -442,7 +486,7 @@ export class BaseAnthropic { await this.prepareRequest(req, { url, options }); - debug('request', url, options, req.headers); + logger(this).debug('request', url, options, req.headers); if (options.signal?.aborted) { throw new Errors.APIUserAbortError(); @@ -467,7 +511,7 @@ export class BaseAnthropic { if (!response.ok) { if (retriesRemaining && this.shouldRetry(response)) { const retryMessage = `retrying, ${retriesRemaining} attempts remaining`; - debug(`response (error; ${retryMessage})`, response.status, url, response.headers); + logger(this).debug(`response (error; ${retryMessage})`, response.status, url, response.headers); return this.retryRequest(options, retriesRemaining, response.headers); } @@ -476,7 +520,13 @@ export class BaseAnthropic { const errMessage = errJSON ? undefined : errText; const retryMessage = retriesRemaining ? `(error; no more retries left)` : `(error; not retryable)`; - debug(`response (error; ${retryMessage})`, response.status, url, response.headers, errMessage); + logger(this).debug( + `response (error; ${retryMessage})`, + response.status, + url, + response.headers, + errMessage, + ); const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers); throw err; diff --git a/src/internal/parse.ts b/src/internal/parse.ts index 7a4e8611..7755e27e 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -1,8 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { debug } from './utils/log'; -import { FinalRequestOptions } from './request-options'; +import type { FinalRequestOptions } from './request-options'; import { Stream } from '../streaming'; +import { type BaseAnthropic } from '../client'; +import { logger } from './utils/log'; import { type AbstractPage } from '../pagination'; export type APIResponseProps = { @@ -16,10 +17,13 @@ export type WithRequestID = : T extends Record ? T & { _request_id?: string | null } : T; -export async function defaultParseResponse(props: APIResponseProps): Promise> { +export async function defaultParseResponse( + client: BaseAnthropic, + props: APIResponseProps, +): Promise> { const { response } = props; if (props.options.stream) { - debug('response', response.status, response.url, response.headers, response.body); + logger(client).debug('response', response.status, response.url, response.headers, response.body); // Note: there is an invariant here that isn't represented in the type system // that if you set `stream: true` the response type must also be `Stream` @@ -46,13 +50,13 @@ export async function defaultParseResponse(props: APIResponseProps): Promise< if (isJSON) { const json = await response.json(); - debug('response', response.status, response.url, response.headers, json); + logger(client).debug('response', response.status, response.url, response.headers, json); return addRequestID(json as T, response); } const text = await response.text(); - debug('response', response.status, response.url, response.headers, text); + logger(client).debug('response', response.status, response.url, response.headers, text); // TODO handle blob, arraybuffer, other content types, etc. return text as unknown as WithRequestID; diff --git a/src/internal/utils/log.ts b/src/internal/utils/log.ts index 7fe7ccba..157a584c 100644 --- a/src/internal/utils/log.ts +++ b/src/internal/utils/log.ts @@ -1,9 +1,49 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { readEnv } from './env'; +import type { LogLevel, Logger } from '../../client'; +import { type BaseAnthropic } from '../../client'; -export function debug(action: string, ...args: any[]) { - if (readEnv('DEBUG') === 'true') { - console.log(`Anthropic:DEBUG:${action}`, ...args); +const levelNumbers = { + off: 0, + error: 200, + warn: 300, + info: 400, + debug: 500, +}; + +function noop() {} + +function logFn(logger: Logger | undefined, clientLevel: LogLevel | undefined, level: keyof Logger) { + if (!logger || levelNumbers[level] > levelNumbers[clientLevel!]!) { + return noop; + } else { + // Don't wrap logger functions, we want the stacktrace intact! + return logger[level].bind(logger); + } +} + +let lastLogger: { deref(): Logger } | undefined; +let lastLevel: LogLevel | undefined; +let lastLevelLogger: Logger; + +export function logger(client: BaseAnthropic): Logger { + let { logger, logLevel: clientLevel } = client; + if (lastLevel === clientLevel && (logger === lastLogger || logger === lastLogger?.deref())) { + return lastLevelLogger; } + const levelLogger = { + error: logFn(logger, clientLevel, 'error'), + warn: logFn(logger, clientLevel, 'warn'), + info: logFn(logger, clientLevel, 'info'), + debug: logFn(logger, clientLevel, 'debug'), + }; + const { WeakRef } = globalThis as any; + lastLogger = + logger ? + WeakRef ? new WeakRef(logger) + : { deref: () => logger } + : undefined; + lastLevel = clientLevel; + lastLevelLogger = levelLogger; + return levelLogger; } diff --git a/src/pagination.ts b/src/pagination.ts index ccd364f6..107a8fc7 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -1,23 +1,23 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import type { Anthropic } from './client'; import { AnthropicError } from './error'; import { FinalRequestOptions } from './internal/request-options'; import { defaultParseResponse, type WithRequestID } from './internal/parse'; import { APIPromise } from './api-promise'; +import { type BaseAnthropic } from './client'; import { type APIResponseProps } from './internal/parse'; import { maybeObj } from './internal/utils/values'; export type PageRequestOptions = Pick; export abstract class AbstractPage implements AsyncIterable { - #client: Anthropic; + #client: BaseAnthropic; protected options: FinalRequestOptions; protected response: Response; protected body: unknown; - constructor(client: Anthropic, response: Response, body: unknown, options: FinalRequestOptions) { + constructor(client: BaseAnthropic, response: Response, body: unknown, options: FinalRequestOptions) { this.#client = client; this.options = options; this.response = response; @@ -81,17 +81,18 @@ export class PagePromise< implements AsyncIterable { constructor( - client: Anthropic, + client: BaseAnthropic, request: Promise, Page: new (...args: ConstructorParameters) => PageClass, ) { super( + client, request, - async (props) => + async (client, props) => new Page( client, props.response, - await defaultParseResponse(props), + await defaultParseResponse(client, props), props.options, ) as WithRequestID, ); @@ -142,7 +143,12 @@ export class Page extends AbstractPage implements PageResponse last_id: string | null; - constructor(client: Anthropic, response: Response, body: PageResponse, options: FinalRequestOptions) { + constructor( + client: BaseAnthropic, + response: Response, + body: PageResponse, + options: FinalRequestOptions, + ) { super(client, response, body, options); this.data = body.data || []; diff --git a/tests/index.test.ts b/tests/index.test.ts index a0ed1b54..ff0339e7 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,5 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +import { APIPromise } from '@anthropic-ai/sdk/api-promise'; + import util from 'node:util'; import Anthropic from '@anthropic-ai/sdk'; import { APIUserAbortError } from '@anthropic-ai/sdk'; @@ -49,6 +51,87 @@ describe('instantiate client', () => { expect(req.headers.has('x-my-default-header')).toBe(false); }); }); + describe('logging', () => { + afterEach(() => { + process.env['ANTHROPIC_LOG'] = undefined; + }); + + const forceAPIResponseForClient = async (client: Anthropic) => { + await new APIPromise( + client, + Promise.resolve({ + response: new Response(), + controller: new AbortController(), + options: { + method: 'get', + path: '/', + }, + }), + ); + }; + + test('debug logs when log level is debug', async () => { + const debugMock = jest.fn(); + const logger = { + debug: debugMock, + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }; + + const client = new Anthropic({ logger: logger, logLevel: 'debug', apiKey: 'my-anthropic-api-key' }); + + await forceAPIResponseForClient(client); + expect(debugMock).toHaveBeenCalled(); + }); + + test('debug logs are skipped when log level is info', async () => { + const debugMock = jest.fn(); + const logger = { + debug: debugMock, + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }; + + const client = new Anthropic({ logger: logger, logLevel: 'info', apiKey: 'my-anthropic-api-key' }); + + await forceAPIResponseForClient(client); + expect(debugMock).not.toHaveBeenCalled(); + }); + + test('debug logs happen with debug env var', async () => { + const debugMock = jest.fn(); + const logger = { + debug: debugMock, + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }; + + process.env['ANTHROPIC_LOG'] = 'debug'; + const client = new Anthropic({ logger: logger, apiKey: 'my-anthropic-api-key' }); + + await forceAPIResponseForClient(client); + expect(debugMock).toHaveBeenCalled(); + }); + + test('client log level overrides env var', async () => { + const debugMock = jest.fn(); + const logger = { + debug: debugMock, + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + }; + + process.env['ANTHROPIC_LOG'] = 'debug'; + const client = new Anthropic({ logger: logger, logLevel: 'off', apiKey: 'my-anthropic-api-key' }); + + await forceAPIResponseForClient(client); + expect(debugMock).not.toHaveBeenCalled(); + }); + }); describe('defaultQuery', () => { test('with null query params given', () => { diff --git a/tests/responses.test.ts b/tests/responses.test.ts index 587e5508..5000e68b 100644 --- a/tests/responses.test.ts +++ b/tests/responses.test.ts @@ -2,6 +2,8 @@ import { APIPromise } from '@anthropic-ai/sdk/api-promise'; import Anthropic from '@anthropic-ai/sdk/index'; import { compareType } from './utils/typing'; +const client = new Anthropic({ apiKey: 'dummy' }); + describe('request id', () => { test('types', () => { compareType>, string>(true); @@ -60,6 +62,7 @@ describe('request id', () => { test('envelope response', async () => { const promise = new APIPromise<{ data: { foo: string } }>( + client, (async () => { return { response: new Response(JSON.stringify({ data: { foo: 'bar' } }), { @@ -92,6 +95,7 @@ describe('request id', () => { test('array response', async () => { const promise = new APIPromise>( + client, (async () => { return { response: new Response(JSON.stringify([{ foo: 'bar' }]), { @@ -111,6 +115,7 @@ describe('request id', () => { test('string response', async () => { const promise = new APIPromise( + client, (async () => { return { response: new Response('hello world', { From ecf84dda346d4758908564ff45de4da8b9bd10fb Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Mon, 24 Feb 2025 14:39:53 +0000 Subject: [PATCH 005/105] chore(internal): fix eslint rules --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 67bf4a71..f1f2cdc3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -19,7 +19,7 @@ module.exports = { }, overrides: [ { - files: ['tests/**', 'examples/**'], + files: ['tests/**', 'examples/**', 'packages/**'], rules: { 'no-restricted-imports': 'off', }, From 6aa53d1d67e6583a57079f88cd37b5f3e094c51e Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:53:05 -0500 Subject: [PATCH 006/105] fix: send correct Accept header for certain endpoints chore: unknown commit message --- src/resources/beta/messages/batches.ts | 1 + src/resources/messages/batches.ts | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index 6862c1f9..e3192814 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -139,6 +139,7 @@ export class Batches extends APIResource { ...options, headers: { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), + Accept: 'application/binary', ...options?.headers, }, __binaryResponse: true, diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index 23fe87d1..b9bccc15 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -84,7 +84,11 @@ export class Batches extends APIResource { } return this._client - .get(batch.results_url, { ...options, __binaryResponse: true }) + .get(batch.results_url, { + ...options, + headers: { Accept: 'application/binary', ...options?.headers }, + __binaryResponse: true, + }) ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)); } } From ab38e8a91d5426278901c0e0b83bba2227829e56 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 14 Jan 2025 18:05:43 -0500 Subject: [PATCH 007/105] chore(client): clean up file helpers chore: unknown commit message --- src/client.ts | 11 +- src/index.ts | 8 +- src/internal/uploads.ts | 262 ++++++++++++++++++++++++++++++++++++++++ src/uploads.ts | 259 +-------------------------------------- tests/form.test.ts | 3 +- tests/uploads.test.ts | 5 +- 6 files changed, 271 insertions(+), 277 deletions(-) create mode 100644 src/internal/uploads.ts diff --git a/src/client.ts b/src/client.ts index 8e638b2f..874229db 100644 --- a/src/client.ts +++ b/src/client.ts @@ -11,7 +11,6 @@ import { getPlatformHeaders } from './internal/detect-platform'; import * as Shims from './internal/shims'; import * as Opts from './internal/request-options'; import { VERSION } from './version'; -import { isBlobLike } from './uploads'; import { buildHeaders } from './internal/headers'; import * as Errors from './error'; import * as Pagination from './pagination'; @@ -451,14 +450,8 @@ export class BaseAnthropic { opts?: PromiseOrValue, ): APIPromise { return this.request( - Promise.resolve(opts).then(async (opts) => { - const body = - opts && isBlobLike(opts?.body) ? new DataView(await opts.body.arrayBuffer()) - : opts?.body instanceof DataView ? opts.body - : opts?.body instanceof ArrayBuffer ? new DataView(opts.body) - : opts && ArrayBuffer.isView(opts?.body) ? new DataView(opts.body.buffer) - : opts?.body; - return { method, path, ...opts, body }; + Promise.resolve(opts).then((opts) => { + return { method, path, ...opts }; }), ); } diff --git a/src/index.ts b/src/index.ts index 8416e13e..53a4df4b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,13 +2,7 @@ export { Anthropic as default } from './client'; -export { - multipartFormRequestOptions, - maybeMultipartFormRequestOptions, - type Uploadable, - createForm, - toFile, -} from './uploads'; +export { type Uploadable, toFile } from './uploads'; export { APIPromise } from './api-promise'; export { BaseAnthropic, Anthropic, type ClientOptions, HUMAN_PROMPT, AI_PROMPT } from './client'; export { PagePromise } from './pagination'; diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts new file mode 100644 index 00000000..60861827 --- /dev/null +++ b/src/internal/uploads.ts @@ -0,0 +1,262 @@ +import { type RequestOptions } from './request-options'; +import { type FilePropertyBag } from './builtin-types'; +import { isFsReadStreamLike, type FsReadStreamLike } from './shims'; +import './polyfill/file.node.js'; + +type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView; +type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; + +/** + * Typically, this is a native "File" class. + * + * We provide the {@link toFile} utility to convert a variety of objects + * into the File class. + * + * For convenience, you can also pass a fetch Response, or in Node, + * the result of fs.createReadStream(). + */ +export type Uploadable = FileLike | ResponseLike | FsReadStreamLike; + +/** + * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc. + * Don't add arrayBuffer here, node-fetch doesn't have it + */ +interface BlobLike { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */ + readonly size: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */ + readonly type: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */ + text(): Promise; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */ + slice(start?: number, end?: number): BlobLike; +} + +/** + * This check adds the arrayBuffer() method type because it is available and used at runtime + */ +const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise } => + value != null && + typeof value === 'object' && + typeof value.size === 'number' && + typeof value.type === 'string' && + typeof value.text === 'function' && + typeof value.slice === 'function' && + typeof value.arrayBuffer === 'function'; + +/** + * Intended to match DOM File, node:buffer File, undici File, etc. + */ +interface FileLike extends BlobLike { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */ + readonly lastModified: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */ + readonly name: string; +} +declare var FileClass: { + prototype: FileLike; + new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike; +}; + +/** + * This check adds the arrayBuffer() method type because it is available and used at runtime + */ +const isFileLike = (value: any): value is FileLike & { arrayBuffer(): Promise } => + value != null && + typeof value === 'object' && + typeof value.name === 'string' && + typeof value.lastModified === 'number' && + isBlobLike(value); + +/** + * Intended to match DOM Response, node-fetch Response, undici Response, etc. + */ +export interface ResponseLike { + url: string; + blob(): Promise; +} + +const isResponseLike = (value: any): value is ResponseLike => + value != null && + typeof value === 'object' && + typeof value.url === 'string' && + typeof value.blob === 'function'; + +const isUploadable = (value: any): value is Uploadable => { + return isFileLike(value) || isResponseLike(value) || isFsReadStreamLike(value); +}; + +type ToFileInput = Uploadable | Exclude | AsyncIterable; + +/** + * Construct a `File` instance. This is used to ensure a helpful error is thrown + * for environments that don't define a global `File` yet and so that we don't + * accidentally rely on a global `File` type in our annotations. + */ +function makeFile(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike { + const File = (globalThis as any).File as typeof FileClass | undefined; + if (typeof File === 'undefined') { + throw new Error('`File` is not defined as a global which is required for file uploads'); + } + + return new File(fileBits, fileName, options); +} + +/** + * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats + * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s + * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible + * @param {Object=} options additional properties + * @param {string=} options.type the MIME type of the content + * @param {number=} options.lastModified the last modified timestamp + * @returns a {@link File} with the given properties + */ +export async function toFile( + value: ToFileInput | PromiseLike, + name?: string | null | undefined, + options?: FilePropertyBag | undefined, +): Promise { + // If it's a promise, resolve it. + value = await value; + + // If we've been given a `File` we don't need to do anything + if (isFileLike(value)) { + const File = (globalThis as any).File as typeof FileClass | undefined; + if (File && value instanceof File) { + return value; + } + return makeFile([await value.arrayBuffer()], value.name); + } + + if (isResponseLike(value)) { + const blob = await value.blob(); + name ||= new URL(value.url).pathname.split(/[\\/]/).pop() ?? 'unknown_file'; + + return makeFile(await getBytes(blob), name, options); + } + + const parts = await getBytes(value); + + name ||= getName(value) ?? 'unknown_file'; + + if (!options?.type) { + const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type); + if (typeof type === 'string') { + options = { ...options, type }; + } + } + + return makeFile(parts, name, options); +} + +export async function getBytes( + value: Uploadable | BlobLikePart | AsyncIterable, +): Promise> { + let parts: Array = []; + if ( + typeof value === 'string' || + ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc. + value instanceof ArrayBuffer + ) { + parts.push(value); + } else if (isBlobLike(value)) { + parts.push(value instanceof Blob ? value : await value.arrayBuffer()); + } else if ( + isAsyncIterableIterator(value) // includes Readable, ReadableStream, etc. + ) { + for await (const chunk of value) { + parts.push(...(await getBytes(chunk as BlobLikePart))); // TODO, consider validating? + } + } else { + const constructor = value?.constructor?.name; + throw new Error( + `Unexpected data type: ${typeof value}${ + constructor ? `; constructor: ${constructor}` : '' + }${propsForError(value)}`, + ); + } + + return parts; +} + +function propsForError(value: unknown): string { + if (typeof value !== 'object' || value === null) return ''; + const props = Object.getOwnPropertyNames(value); + return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`; +} + +function getName(value: unknown): string | undefined { + return ( + (typeof value === 'object' && + value !== null && + (('name' in value && String(value.name)) || + ('filename' in value && String(value.filename)) || + ('path' in value && String(value.path).split(/[\\/]/).pop()))) || + undefined + ); +} + +const isAsyncIterableIterator = (value: any): value is AsyncIterableIterator => + value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function'; + +/** + * Returns a multipart/form-data request if any part of the given request body contains a File / Blob value. + * Otherwise returns the request as is. + */ +export const maybeMultipartFormRequestOptions = async (opts: RequestOptions): Promise => { + if (!hasUploadableValue(opts.body)) return opts; + + return { ...opts, body: await createForm(opts.body) }; +}; + +type MultipartFormRequestOptions = Omit & { body: unknown }; + +export const multipartFormRequestOptions = async ( + opts: MultipartFormRequestOptions, +): Promise => { + return { ...opts, body: await createForm(opts.body) }; +}; + +export const createForm = async >(body: T | undefined): Promise => { + const form = new FormData(); + await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value))); + return form; +}; + +const hasUploadableValue = (value: unknown): boolean => { + if (isUploadable(value)) return true; + if (Array.isArray(value)) return value.some(hasUploadableValue); + if (value && typeof value === 'object') { + for (const k in value) { + if (hasUploadableValue((value as any)[k])) return true; + } + } + return false; +}; + +const addFormValue = async (form: FormData, key: string, value: unknown): Promise => { + if (value === undefined) return; + if (value == null) { + throw new TypeError( + `Received null for "${key}"; to pass null in FormData, you must use the string 'null'`, + ); + } + + // TODO: make nested formats configurable + if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { + form.append(key, String(value)); + } else if (isUploadable(value)) { + const file = await toFile(value); + form.append(key, file as any); + } else if (Array.isArray(value)) { + await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry))); + } else if (typeof value === 'object') { + await Promise.all( + Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)), + ); + } else { + throw new TypeError( + `Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`, + ); + } +}; diff --git a/src/uploads.ts b/src/uploads.ts index 58f3782b..e4c4b2db 100644 --- a/src/uploads.ts +++ b/src/uploads.ts @@ -1,258 +1 @@ -import { type RequestOptions } from './internal/request-options'; -import { type FilePropertyBag } from './internal/builtin-types'; -import { isFsReadStreamLike, type FsReadStreamLike } from './internal/shims'; -import './internal/polyfill/file.node.js'; - -type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | Uint8Array | DataView; -export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | Uint8Array | DataView; - -/** - * Typically, this is a native "File" class. - * - * We provide the {@link toFile} utility to convert a variety of objects - * into the File class. - * - * For convenience, you can also pass a fetch Response, or in Node, - * the result of fs.createReadStream(). - */ -export type Uploadable = FileLike | ResponseLike | FsReadStreamLike; - -/** - * Intended to match web.Blob, node.Blob, undici.Blob, etc. - */ -export interface BlobLike { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */ - readonly size: number; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */ - readonly type: string; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */ - text(): Promise; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */ - slice(start?: number, end?: number): BlobLike; -} - -/** - * This check adds the arrayBuffer() method type because it is available and used at runtime - */ -export const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise } => - value != null && - typeof value === 'object' && - typeof value.size === 'number' && - typeof value.type === 'string' && - typeof value.text === 'function' && - typeof value.slice === 'function' && - typeof value.arrayBuffer === 'function'; - -/** - * Intended to match web.File, node.File, undici.File, etc. - */ -export interface FileLike extends BlobLike { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */ - readonly lastModified: number; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */ - readonly name: string; -} -declare var FileClass: { - prototype: FileLike; - new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike; -}; - -export const isFileLike = (value: any): value is FileLike => - value != null && - typeof value === 'object' && - typeof value.name === 'string' && - typeof value.lastModified === 'number' && - isBlobLike(value); - -/** - * Intended to match web.Response, node.Response, undici.Response, etc. - */ -export interface ResponseLike { - url: string; - blob(): Promise; -} - -export const isResponseLike = (value: any): value is ResponseLike => - value != null && - typeof value === 'object' && - typeof value.url === 'string' && - typeof value.blob === 'function'; - -export const isUploadable = (value: any): value is Uploadable => { - return isFileLike(value) || isResponseLike(value) || isFsReadStreamLike(value); -}; - -export type ToFileInput = Uploadable | Exclude | AsyncIterable; - -/** - * Construct a `File` instance. This is used to ensure a helpful error is thrown - * for environments that don't define a global `File` yet and so that we don't - * accidentally rely on a global `File` type in our annotations. - */ -function makeFile(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike { - const File = (globalThis as any).File as typeof FileClass | undefined; - if (typeof File === 'undefined') { - throw new Error('`File` is not defined as a global which is required for file uploads'); - } - - return new File(fileBits, fileName, options); -} - -/** - * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats - * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s - * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible - * @param {Object=} options additional properties - * @param {string=} options.type the MIME type of the content - * @param {number=} options.lastModified the last modified timestamp - * @returns a {@link File} with the given properties - */ -export async function toFile( - value: ToFileInput | PromiseLike, - name?: string | null | undefined, - options?: FilePropertyBag | undefined, -): Promise { - // If it's a promise, resolve it. - value = await value; - - // If we've been given a `File` we don't need to do anything - if (isFileLike(value)) { - return value; - } - - if (isResponseLike(value)) { - const blob = await value.blob(); - name ||= new URL(value.url).pathname.split(/[\\/]/).pop() ?? 'unknown_file'; - - // we need to convert the `Blob` into an array buffer because the `Blob` class - // that `node-fetch` defines is incompatible with the web standard which results - // in `new File` interpreting it as a string instead of binary data. - const data = isBlobLike(blob) ? [(await blob.arrayBuffer()) as any] : [blob]; - - return makeFile(data, name, options); - } - - const bits = await getBytes(value); - - name ||= getName(value) ?? 'unknown_file'; - - if (!options?.type) { - const type = (bits[0] as any)?.type; - if (typeof type === 'string') { - options = { ...options, type }; - } - } - - return makeFile(bits, name, options); -} - -async function getBytes(value: ToFileInput): Promise> { - let parts: Array = []; - if ( - typeof value === 'string' || - ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc. - value instanceof ArrayBuffer - ) { - parts.push(value); - } else if (isBlobLike(value)) { - parts.push(await value.arrayBuffer()); - } else if ( - isAsyncIterableIterator(value) // includes Readable, ReadableStream, etc. - ) { - for await (const chunk of value) { - parts.push(chunk as BlobPart); // TODO, consider validating? - } - } else { - throw new Error( - `Unexpected data type: ${typeof value}; constructor: ${value?.constructor - ?.name}; props: ${propsForError(value)}`, - ); - } - - return parts; -} - -function propsForError(value: any): string { - const props = Object.getOwnPropertyNames(value); - return `[${props.map((p) => `"${p}"`).join(', ')}]`; -} - -function getName(value: any): string | undefined { - return ( - getStringFromMaybeBuffer(value.name) || - getStringFromMaybeBuffer(value.filename) || - // For fs.ReadStream - getStringFromMaybeBuffer(value.path)?.split(/[\\/]/).pop() - ); -} - -const getStringFromMaybeBuffer = (x: string | Buffer | unknown): string | undefined => { - if (typeof x === 'string') return x; - if (typeof Buffer !== 'undefined' && x instanceof Buffer) return String(x); - return undefined; -}; - -const isAsyncIterableIterator = (value: any): value is AsyncIterableIterator => - value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function'; - -/** - * Returns a multipart/form-data request if any part of the given request body contains a File / Blob value. - * Otherwise returns the request as is. - */ -export const maybeMultipartFormRequestOptions = async (opts: RequestOptions): Promise => { - if (!hasUploadableValue(opts.body)) return opts; - - return { ...opts, body: await createForm(opts.body) }; -}; - -type MultipartFormRequestOptions = Omit & { body: unknown }; - -export const multipartFormRequestOptions = async ( - opts: MultipartFormRequestOptions, -): Promise => { - return { ...opts, body: await createForm(opts.body) }; -}; - -export const createForm = async >(body: T | undefined): Promise => { - const form = new FormData(); - await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value))); - return form; -}; - -const hasUploadableValue = (value: unknown): boolean => { - if (isUploadable(value)) return true; - if (Array.isArray(value)) return value.some(hasUploadableValue); - if (value && typeof value === 'object') { - for (const k in value) { - if (hasUploadableValue((value as any)[k])) return true; - } - } - return false; -}; - -const addFormValue = async (form: FormData, key: string, value: unknown): Promise => { - if (value === undefined) return; - if (value == null) { - throw new TypeError( - `Received null for "${key}"; to pass null in FormData, you must use the string 'null'`, - ); - } - - // TODO: make nested formats configurable - if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { - form.append(key, String(value)); - } else if (isUploadable(value)) { - const file = await toFile(value); - form.append(key, file as any); - } else if (Array.isArray(value)) { - await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry))); - } else if (typeof value === 'object') { - await Promise.all( - Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)), - ); - } else { - throw new TypeError( - `Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`, - ); - } -}; +export { Uploadable, toFile } from './internal/uploads'; diff --git a/tests/form.test.ts b/tests/form.test.ts index ac5c2101..02acf7a3 100644 --- a/tests/form.test.ts +++ b/tests/form.test.ts @@ -1,4 +1,5 @@ -import { multipartFormRequestOptions, createForm, toFile } from '@anthropic-ai/sdk'; +import { multipartFormRequestOptions, createForm } from '@anthropic-ai/sdk/internal/uploads'; +import { toFile } from '@anthropic-ai/sdk/uploads'; describe('form data validation', () => { test('valid values do not error', async () => { diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index ab55f1b9..3defd6fa 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,5 +1,6 @@ import fs from 'fs'; -import { toFile, type ResponseLike } from '@anthropic-ai/sdk/uploads'; +import type { ResponseLike } from '@anthropic-ai/sdk/internal/uploads'; +import { toFile } from '@anthropic-ai/sdk/uploads'; class MyClass { name: string = 'foo'; @@ -8,7 +9,7 @@ class MyClass { function mockResponse({ url, content }: { url: string; content?: Blob }): ResponseLike { return { url, - blob: async () => content as any, + blob: async () => content || new Blob([]), }; } From 6485bc73062fea1f1953985b620027e567219197 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 15 Jan 2025 08:54:53 -0500 Subject: [PATCH 008/105] chore(types): add `| undefined` to client options properties chore: unknown commit message --- src/client.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client.ts b/src/client.ts index 874229db..a14607e3 100644 --- a/src/client.ts +++ b/src/client.ts @@ -148,7 +148,7 @@ export interface ClientOptions { * Note that request timeouts are retried by default, so in a worst-case scenario you may wait * much longer than this timeout before the promise succeeds or fails. */ - timeout?: number; + timeout?: number | undefined; /** * An HTTP agent used to manage HTTP(S) connections. @@ -156,7 +156,7 @@ export interface ClientOptions { * If not provided, an agent will be constructed by default in the Node.js environment, * otherwise no agent is used. */ - httpAgent?: Shims.Agent; + httpAgent?: Shims.Agent | undefined; /** * Specify a custom `fetch` function implementation. @@ -171,7 +171,7 @@ export interface ClientOptions { * * @default 2 */ - maxRetries?: number; + maxRetries?: number | undefined; /** * Default headers to include with every request to the API. @@ -179,7 +179,7 @@ export interface ClientOptions { * These can be removed in individual requests by explicitly setting the * header to `null` in request options. */ - defaultHeaders?: HeadersLike; + defaultHeaders?: HeadersLike | undefined; /** * Default query parameters to include with every request to the API. @@ -187,13 +187,13 @@ export interface ClientOptions { * These can be removed in individual requests by explicitly setting the * param to `undefined` in request options. */ - defaultQuery?: Record; + defaultQuery?: Record | undefined; /** * By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers. * Only set this option to `true` if you understand the risks and have appropriate mitigations in place. */ - dangerouslyAllowBrowser?: boolean; + dangerouslyAllowBrowser?: boolean | undefined; /** * Set the log level. From b55025fdd1f7e19ec1d38b276706131ac20b9638 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Mon, 20 Jan 2025 12:26:26 -0500 Subject: [PATCH 009/105] chore(client): improve node-fetch file upload errors chore: unknown commit message --- src/internal/uploads.ts | 55 ++++++++++++++++++++++++--- tests/form.test.ts | 83 ++++++++++++++++++++++++++--------------- 2 files changed, 102 insertions(+), 36 deletions(-) diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index 60861827..02e1be49 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -1,6 +1,7 @@ import { type RequestOptions } from './request-options'; -import { type FilePropertyBag } from './builtin-types'; +import type { FilePropertyBag, Fetch } from './builtin-types'; import { isFsReadStreamLike, type FsReadStreamLike } from './shims'; +import type { BaseAnthropic } from '../client'; import './polyfill/file.node.js'; type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView; @@ -203,21 +204,65 @@ const isAsyncIterableIterator = (value: any): value is AsyncIterableIterator => { +export const maybeMultipartFormRequestOptions = async ( + opts: RequestOptions, + fetch: BaseAnthropic | Fetch, +): Promise => { if (!hasUploadableValue(opts.body)) return opts; - return { ...opts, body: await createForm(opts.body) }; + return { ...opts, body: await createForm(opts.body, fetch) }; }; type MultipartFormRequestOptions = Omit & { body: unknown }; export const multipartFormRequestOptions = async ( opts: MultipartFormRequestOptions, + fetch: BaseAnthropic | Fetch, ): Promise => { - return { ...opts, body: await createForm(opts.body) }; + return { ...opts, body: await createForm(opts.body, fetch) }; }; -export const createForm = async >(body: T | undefined): Promise => { +const supportsFormDataMap = new WeakMap>(); + +/** + * node-fetch doesn't support the global FormData object in recent node versions. Instead of sending + * properly-encoded form data, it just stringifies the object, resulting in a request body of "[object FormData]". + * This function detects if the fetch function provided supports the global FormData object to avoid + * confusing error messages later on. + */ +function supportsFormData(fetchObject: BaseAnthropic | Fetch): Promise { + const fetch: Fetch = typeof fetchObject === 'function' ? fetchObject : (fetchObject as any).fetch; + const cached = supportsFormDataMap.get(fetch); + if (cached) return cached; + const promise = (async () => { + try { + const FetchResponse = ( + 'Response' in fetch ? + fetch.Response + : (await fetch('data:,')).constructor) as typeof Response; + const data = new FormData(); + if (data.toString() === (await new FetchResponse(data).text())) { + return false; + } + return true; + } catch { + // avoid false negatives + return true; + } + })(); + supportsFormDataMap.set(fetch, promise); + return promise; +} + +export const createForm = async >( + body: T | undefined, + fetch: BaseAnthropic | Fetch, +): Promise => { + if (!(await supportsFormData(fetch))) { + throw new TypeError( + 'The provided fetch function does not support file uploads with the current global FormData class.', + ); + } const form = new FormData(); await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value))); return form; diff --git a/tests/form.test.ts b/tests/form.test.ts index 02acf7a3..2dc667ff 100644 --- a/tests/form.test.ts +++ b/tests/form.test.ts @@ -3,62 +3,83 @@ import { toFile } from '@anthropic-ai/sdk/uploads'; describe('form data validation', () => { test('valid values do not error', async () => { - await multipartFormRequestOptions({ - body: { - foo: 'foo', - string: 1, - bool: true, - file: await toFile(Buffer.from('some-content')), - blob: new Blob(['Some content'], { type: 'text/plain' }), + await multipartFormRequestOptions( + { + body: { + foo: 'foo', + string: 1, + bool: true, + file: await toFile(Buffer.from('some-content')), + blob: new Blob(['Some content'], { type: 'text/plain' }), + }, }, - }); + fetch, + ); }); test('null', async () => { await expect(() => - multipartFormRequestOptions({ - body: { - null: null, + multipartFormRequestOptions( + { + body: { + null: null, + }, }, - }), + fetch, + ), ).rejects.toThrow(TypeError); }); test('undefined is stripped', async () => { - const form = await createForm({ - foo: undefined, - bar: 'baz', - }); + const form = await createForm( + { + foo: undefined, + bar: 'baz', + }, + fetch, + ); expect(form.has('foo')).toBe(false); expect(form.get('bar')).toBe('baz'); }); test('nested undefined property is stripped', async () => { - const form = await createForm({ - bar: { - baz: undefined, + const form = await createForm( + { + bar: { + baz: undefined, + }, }, - }); + fetch, + ); expect(Array.from(form.entries())).toEqual([]); - const form2 = await createForm({ - bar: { - foo: 'string', - baz: undefined, + const form2 = await createForm( + { + bar: { + foo: 'string', + baz: undefined, + }, }, - }); + fetch, + ); expect(Array.from(form2.entries())).toEqual([['bar[foo]', 'string']]); }); test('nested undefined array item is stripped', async () => { - const form = await createForm({ - bar: [undefined, undefined], - }); + const form = await createForm( + { + bar: [undefined, undefined], + }, + fetch, + ); expect(Array.from(form.entries())).toEqual([]); - const form2 = await createForm({ - bar: [undefined, 'foo'], - }); + const form2 = await createForm( + { + bar: [undefined, 'foo'], + }, + fetch, + ); expect(Array.from(form2.entries())).toEqual([['bar[]', 'foo']]); }); }); From ab17fbc3c6c8ca52449e4835c9ea7737eb67fab5 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Mon, 20 Jan 2025 12:55:34 -0500 Subject: [PATCH 010/105] chore(client)!: document proxy use + clean up old code chore: unknown commit message --- README.md | 63 ++++++++++++++++------ scripts/utils/attw-report.cjs | 5 +- src/client.ts | 33 ++++-------- src/internal/builtin-types.ts | 2 +- src/internal/request-options.ts | 7 ++- src/internal/shims.ts | 12 ----- src/internal/types.ts | 92 +++++++++++++++++++++++++++++++++ tests/index.test.ts | 9 ++++ 8 files changed, 164 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 1c0e5417..cbd043a2 100644 --- a/README.md +++ b/README.md @@ -454,33 +454,62 @@ const client = new Anthropic({ Note that if given a `ANTHROPIC_LOG=debug` environment variable, this library will log all requests and responses automatically. This is intended for debugging purposes only and may change in the future without notice. -### Configuring an HTTP(S) Agent (e.g., for proxies) +### Fetch options -By default, this library uses a stable agent for all http/https requests to reuse TCP connections, eliminating many TCP & TLS handshakes and shaving around 100ms off most requests. +If you want to set custom `fetch` options without overriding the `fetch` function, you can provide a `fetchOptions` object when instantiating the client or making a request. (Request-specific options override client options.) -If you would like to disable or customize this behavior, for example to use the API behind a proxy, you can pass an `httpAgent` which is used for all requests (be they http or https), for example: +```ts +import Anthropic from '@anthropic-ai/sdk'; + +const client = new Anthropic({ + fetchOptions: { + // `RequestInit` options + }, +}); +``` + +#### Configuring proxies + +To modify proxy behavior, you can provide custom `fetchOptions` that add runtime-specific proxy +options to requests: + + **Node** [[docs](https://github.com/nodejs/undici/blob/main/docs/docs/api/ProxyAgent.md#example---proxyagent-with-fetch)] - ```ts -import http from 'http'; -import { HttpsProxyAgent } from 'https-proxy-agent'; +import Anthropic from '@anthropic-ai/sdk'; +import * as undici from 'undici'; -// Configure the default for all requests: +const proxyAgent = new undici.ProxyAgent('http://localhost:8888'); const client = new Anthropic({ - httpAgent: new HttpsProxyAgent(process.env.PROXY_URL), + fetchOptions: { + dispatcher: proxyAgent, + }, }); +``` -// Override per-request: -await client.messages.create( - { - max_tokens: 1024, - messages: [{ role: 'user', content: 'Hello, Claude' }], - model: 'claude-3-5-sonnet-latest', + **Bun** [[docs](https://bun.sh/guides/http/proxy)] + +```ts +import Anthropic from '@anthropic-ai/sdk'; + +const client = new Anthropic({ + fetchOptions: { + proxy: 'http://localhost:8888', }, - { - httpAgent: new http.Agent({ keepAlive: false }), +}); +``` + + **Deno** [[docs](https://docs.deno.com/api/deno/~/Deno.createHttpClient)] + +```ts +import Anthropic from 'npm:@anthropic-ai/sdk'; + +const httpClient = Deno.createHttpClient({ proxy: { url: 'http://localhost:8888' } }); +const client = new Anthropic({ + fetchOptions: { + client: httpClient, }, -); +}); ``` ## Frequently Asked Questions diff --git a/scripts/utils/attw-report.cjs b/scripts/utils/attw-report.cjs index e45e7952..b3477c0e 100644 --- a/scripts/utils/attw-report.cjs +++ b/scripts/utils/attw-report.cjs @@ -8,7 +8,10 @@ const problems = Object.values(JSON.parse(fs.readFileSync('.attw.json', 'utf-8') ( (problem.kind === 'CJSResolvesToESM' && problem.entrypoint.endsWith('.mjs')) || // This is intentional for backwards compat reasons. - (problem.kind === 'MissingExportEquals' && problem.implementationFileName.endsWith('/index.js')) + (problem.kind === 'MissingExportEquals' && problem.implementationFileName.endsWith('/index.js')) || + // this is intentional, we deliberately attempt to import types that may not exist from parent node_modules + // folders to better support various runtimes without triggering automatic type acquisition. + (problem.kind === 'InternalResolutionError' && problem.moduleSpecifier.includes('node_modules')) ) ), ); diff --git a/src/client.ts b/src/client.ts index a14607e3..7aaecd90 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types'; -import type { HTTPMethod, PromiseOrValue } from './internal/types'; +import type { HTTPMethod, PromiseOrValue, MergedRequestInit } from './internal/types'; import { uuid4 } from './internal/utils/uuid'; import { validatePositiveInteger, isAbsoluteURL } from './internal/utils/values'; import { sleep } from './internal/utils/sleep'; @@ -149,14 +149,11 @@ export interface ClientOptions { * much longer than this timeout before the promise succeeds or fails. */ timeout?: number | undefined; - /** - * An HTTP agent used to manage HTTP(S) connections. - * - * If not provided, an agent will be constructed by default in the Node.js environment, - * otherwise no agent is used. + * Additional `RequestInit` options to be passed to `fetch` calls. + * Properties will be overridden by per-request `fetchOptions`. */ - httpAgent?: Shims.Agent | undefined; + fetchOptions?: MergedRequestInit | undefined; /** * Specify a custom `fetch` function implementation. @@ -221,7 +218,7 @@ export class BaseAnthropic { timeout: number; logger: Logger | undefined; logLevel: LogLevel | undefined; - httpAgent: Shims.Agent | undefined; + fetchOptions: MergedRequestInit | undefined; private fetch: Fetch; #encoder: Opts.RequestEncoder; @@ -235,7 +232,7 @@ export class BaseAnthropic { * @param {string | null | undefined} [opts.authToken=process.env['ANTHROPIC_AUTH_TOKEN'] ?? null] * @param {string} [opts.baseURL=process.env['ANTHROPIC_BASE_URL'] ?? https://api.anthropic.com] - Override the default base URL for the API. * @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out. - * @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections. + * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls. * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation. * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request. * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API. @@ -272,7 +269,7 @@ export class BaseAnthropic { this.logLevel = envLevel; } } - this.httpAgent = options.httpAgent; + this.fetchOptions = options.fetchOptions; this.maxRetries = options.maxRetries ?? 2; this.fetch = options.fetch ?? Shims.getDefaultFetch(); this.#encoder = Opts.FallbackEncoder; @@ -665,30 +662,18 @@ export class BaseAnthropic { const url = this.buildURL(path!, query as Record); if ('timeout' in options) validatePositiveInteger('timeout', options.timeout); const timeout = options.timeout ?? this.timeout; - const httpAgent = options.httpAgent ?? this.httpAgent; - const minAgentTimeout = timeout + 1000; - if ( - typeof (httpAgent as any)?.options?.timeout === 'number' && - minAgentTimeout > ((httpAgent as any).options.timeout ?? 0) - ) { - // Allow any given request to bump our agent active socket timeout. - // This may seem strange, but leaking active sockets should be rare and not particularly problematic, - // and without mutating agent we would need to create more of them. - // This tradeoff optimizes for performance. - (httpAgent as any).options.timeout = minAgentTimeout; - } - const { bodyHeaders, body } = this.buildBody({ options }); const reqHeaders = this.buildHeaders({ options, method, bodyHeaders, retryCount }); const req: FinalizedRequestInit = { method, headers: reqHeaders, - ...(httpAgent && { agent: httpAgent }), ...(options.signal && { signal: options.signal }), ...((globalThis as any).ReadableStream && body instanceof (globalThis as any).ReadableStream && { duplex: 'half' }), ...(body && { body }), + ...((this.fetchOptions as any) ?? {}), + ...((options.fetchOptions as any) ?? {}), }; return { req, url, timeout }; diff --git a/src/internal/builtin-types.ts b/src/internal/builtin-types.ts index ca1be792..b2e598a8 100644 --- a/src/internal/builtin-types.ts +++ b/src/internal/builtin-types.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -export type Fetch = typeof fetch; +export type Fetch = (input: string | URL | Request, init?: RequestInit) => Promise; /** * An alias to the builtin `RequestInit` type so we can diff --git a/src/internal/request-options.ts b/src/internal/request-options.ts index d4a5c66d..8a862700 100644 --- a/src/internal/request-options.ts +++ b/src/internal/request-options.ts @@ -2,11 +2,10 @@ import { NullableHeaders } from './headers'; -import type { Agent } from './shims'; import type { BodyInit } from './builtin-types'; import { isEmptyObj, hasOwn } from './utils/values'; import { Stream } from '../streaming'; -import type { HTTPMethod, KeysEnum } from './types'; +import type { HTTPMethod, KeysEnum, MergedRequestInit } from './types'; import { type HeadersLike } from './headers'; export type FinalRequestOptions = RequestOptions & { method: HTTPMethod; path: string }; @@ -20,7 +19,7 @@ export type RequestOptions = { maxRetries?: number; stream?: boolean | undefined; timeout?: number; - httpAgent?: Agent; + fetchOptions?: MergedRequestInit; signal?: AbortSignal | undefined | null; idempotencyKey?: string; @@ -41,7 +40,7 @@ const requestOptionsKeys: KeysEnum = { maxRetries: true, stream: true, timeout: true, - httpAgent: true, + fetchOptions: true, signal: true, idempotencyKey: true, diff --git a/src/internal/shims.ts b/src/internal/shims.ts index bb5a2037..8adb8280 100644 --- a/src/internal/shims.ts +++ b/src/internal/shims.ts @@ -10,18 +10,6 @@ import { type Fetch } from './builtin-types'; import { type ReadableStream } from './shim-types'; -/** - * A minimal copy of the `Agent` type from `undici-types` so we can - * use it in the `ClientOptions` type. - * - * https://nodejs.org/api/http.html#class-httpagent - */ -export interface Agent { - dispatch(options: any, handler: any): boolean; - closed: boolean; - destroyed: boolean; -} - export function getDefaultFetch(): Fetch { if (typeof fetch !== 'undefined') { return fetch; diff --git a/src/internal/types.ts b/src/internal/types.ts index 99740c34..50c16e9d 100644 --- a/src/internal/types.ts +++ b/src/internal/types.ts @@ -4,3 +4,95 @@ export type PromiseOrValue = T | Promise; export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'; export type KeysEnum = { [P in keyof Required]: true }; + +type NotAny = [unknown] extends [T] ? never : T; +type Literal = PropertyKey extends T ? never : T; +type MappedLiteralKeys = T extends any ? Literal : never; +type MappedIndex = + T extends any ? + K extends keyof T ? + T[K] + : never + : never; + +/** + * Some environments overload the global fetch function, and Parameters only gets the last signature. + */ +type OverloadedParameters = + T extends ( + { + (...args: infer A): unknown; + (...args: infer B): unknown; + (...args: infer C): unknown; + (...args: infer D): unknown; + } + ) ? + A | B | C | D + : T extends ( + { + (...args: infer A): unknown; + (...args: infer B): unknown; + (...args: infer C): unknown; + } + ) ? + A | B | C + : T extends ( + { + (...args: infer A): unknown; + (...args: infer B): unknown; + } + ) ? + A | B + : T extends (...args: infer A) => unknown ? A + : never; + +/* eslint-disable */ +/** + * These imports attempt to get types from a parent package's dependencies. + * Unresolved bare specifiers can trigger [automatic type acquisition][1] in some projects, which + * would cause typescript to show types not present at runtime. To avoid this, we import + * directly from parent node_modules folders. + * + * We need to check multiple levels because we don't know what directory structure we'll be in. + * For example, pnpm generates directories like this: + * ``` + * node_modules + * ├── .pnpm + * │ └── pkg@1.0.0 + * │ └── node_modules + * │ └── pkg + * │ └── internal + * │ └── types.d.ts + * ├── pkg -> .pnpm/pkg@1.0.0/node_modules/pkg + * └── undici + * ``` + * + * [1]: https://www.typescriptlang.org/tsconfig/#typeAcquisition + */ +/** @ts-ignore For users with \@types/node */ +type UndiciTypesRequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; +/** @ts-ignore For users with undici */ +type UndiciRequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; +/** @ts-ignore For users with \@types/bun */ +type BunRequestInit = globalThis.FetchRequestInit; +/** @ts-ignore For users with node-fetch */ +type NodeFetchRequestInit = NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny | NotAny; +/** @ts-ignore For users who use Deno */ +type FetchRequestInit = NonNullable[1]>; +/* eslint-enable */ + +type RequestInits = + | NotAny + | NotAny + | NotAny + | NotAny + | NotAny + | NotAny; + +/** + * This type contains `RequestInit` options that may be available on the current runtime, + * including per-platform extensions like `dispatcher`, `agent`, `client`, etc. + */ +export type MergedRequestInit = { + [K in MappedLiteralKeys]?: MappedIndex | undefined; +}; diff --git a/tests/index.test.ts b/tests/index.test.ts index ff0339e7..e90b140f 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -179,6 +179,15 @@ describe('instantiate client', () => { expect(response).toEqual({ url: 'http://localhost:5000/foo', custom: true }); }); + test('explicit global fetch', async () => { + // make sure the global fetch type is assignable to our Fetch type + const client = new Anthropic({ + baseURL: 'http://localhost:5000/', + apiKey: 'my-anthropic-api-key', + fetch: defaultFetch, + }); + }); + test('custom signal', async () => { const client = new Anthropic({ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', From 2063781c71e575aa932b651502c8bfbae65c57a8 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 21 Jan 2025 11:02:49 -0500 Subject: [PATCH 011/105] fix: correctly send default header values chore: unknown commit message --- src/client.ts | 3 +- src/resources/beta/messages/batches.ts | 53 +++++++++++++------------ src/resources/beta/messages/messages.ts | 17 ++++---- src/resources/messages/batches.ts | 4 +- 4 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/client.ts b/src/client.ts index 7aaecd90..2a81487c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -11,7 +11,6 @@ import { getPlatformHeaders } from './internal/detect-platform'; import * as Shims from './internal/shims'; import * as Opts from './internal/request-options'; import { VERSION } from './version'; -import { buildHeaders } from './internal/headers'; import * as Errors from './error'; import * as Pagination from './pagination'; import { AbstractPage, type PageParams, PageResponse } from './pagination'; @@ -20,7 +19,7 @@ import * as API from './resources/index'; import { APIPromise } from './api-promise'; import { type Fetch } from './internal/builtin-types'; import { isRunningInBrowser } from './internal/detect-platform'; -import { HeadersLike, NullableHeaders, isEmptyHeaders } from './internal/headers'; +import { HeadersLike, NullableHeaders, buildHeaders, isEmptyHeaders } from './internal/headers'; import { FinalRequestOptions, RequestOptions } from './internal/request-options'; import { Completion, diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index e3192814..bcf7a630 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -5,6 +5,7 @@ import * as BetaAPI from '../beta'; import * as BetaMessagesAPI from './messages'; import { APIPromise } from '../../../api-promise'; import { Page, type PageParams, PagePromise } from '../../../pagination'; +import { buildHeaders } from '../../../internal/headers'; import { RequestOptions } from '../../../internal/request-options'; import { JSONLDecoder } from '../../../internal/decoders/jsonl'; import { AnthropicError } from '../../../error'; @@ -22,10 +23,10 @@ export class Batches extends APIResource { return this._client.post('/v1/messages/batches?beta=true', { body, ...options, - headers: { - 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), - ...options?.headers, - }, + headers: buildHeaders([ + { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString() }, + options?.headers, + ]), }); } @@ -42,10 +43,10 @@ export class Batches extends APIResource { const { betas } = params ?? {}; return this._client.get(`/v1/messages/batches/${messageBatchID}?beta=true`, { ...options, - headers: { - 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), - ...options?.headers, - }, + headers: buildHeaders([ + { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString() }, + options?.headers, + ]), }); } @@ -61,10 +62,10 @@ export class Batches extends APIResource { return this._client.getAPIList('/v1/messages/batches?beta=true', Page, { query, ...options, - headers: { - 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), - ...options?.headers, - }, + headers: buildHeaders([ + { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString() }, + options?.headers, + ]), }); } @@ -81,10 +82,10 @@ export class Batches extends APIResource { const { betas } = params ?? {}; return this._client.delete(`/v1/messages/batches/${messageBatchID}?beta=true`, { ...options, - headers: { - 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), - ...options?.headers, - }, + headers: buildHeaders([ + { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString() }, + options?.headers, + ]), }); } @@ -107,10 +108,10 @@ export class Batches extends APIResource { const { betas } = params ?? {}; return this._client.post(`/v1/messages/batches/${messageBatchID}/cancel?beta=true`, { ...options, - headers: { - 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), - ...options?.headers, - }, + headers: buildHeaders([ + { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString() }, + options?.headers, + ]), }); } @@ -137,11 +138,13 @@ export class Batches extends APIResource { return this._client .get(batch.results_url, { ...options, - headers: { - 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), - Accept: 'application/binary', - ...options?.headers, - }, + headers: buildHeaders([ + { + 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), + Accept: 'application/binary', + }, + options?.headers, + ]), __binaryResponse: true, }) ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)); diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index f56295bb..a24dd92e 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -26,6 +26,7 @@ import { } from './batches'; import { APIPromise } from '../../../api-promise'; import { Stream } from '../../../streaming'; +import { buildHeaders } from '../../../internal/headers'; import { RequestOptions } from '../../../internal/request-options'; export class Messages extends APIResource { @@ -56,10 +57,10 @@ export class Messages extends APIResource { body, timeout: (this._client as any)._options.timeout ?? 600000, ...options, - headers: { - ...(betas?.toString() != null ? { 'anthropic-beta': betas?.toString() } : undefined), - ...options?.headers, - }, + headers: buildHeaders([ + { ...(betas?.toString() != null ? { 'anthropic-beta': betas?.toString() } : undefined) }, + options?.headers, + ]), stream: params.stream ?? false, }) as APIPromise | APIPromise>; } @@ -78,10 +79,10 @@ export class Messages extends APIResource { return this._client.post('/v1/messages/count_tokens?beta=true', { body, ...options, - headers: { - 'anthropic-beta': [...(betas ?? []), 'token-counting-2024-11-01'].toString(), - ...options?.headers, - }, + headers: buildHeaders([ + { 'anthropic-beta': [...(betas ?? []), 'token-counting-2024-11-01'].toString() }, + options?.headers, + ]), }); } } diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index b9bccc15..bce8b12f 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -5,6 +5,7 @@ import * as Shared from '../shared'; import * as MessagesAPI from './messages'; import { APIPromise } from '../../api-promise'; import { Page, type PageParams, PagePromise } from '../../pagination'; +import { buildHeaders } from '../../internal/headers'; import { RequestOptions } from '../../internal/request-options'; import { JSONLDecoder } from '../../internal/decoders/jsonl'; import { AnthropicError } from '../../error'; @@ -86,7 +87,8 @@ export class Batches extends APIResource { return this._client .get(batch.results_url, { ...options, - headers: { Accept: 'application/binary', ...options?.headers }, + headers: buildHeaders([{ Accept: 'application/binary' }, options?.headers]), + __binaryResponse: true, }) ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)); From 4a4f9a137f836cd2675414df6eb6b502086baef6 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 21 Jan 2025 15:57:40 -0500 Subject: [PATCH 012/105] chore(internal): minor restructuring chore: unknown commit message --- src/internal/shims.ts | 33 +++++++++++++++++++++++++++++++++ src/streaming.ts | 38 +++----------------------------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/internal/shims.ts b/src/internal/shims.ts index 8adb8280..46951605 100644 --- a/src/internal/shims.ts +++ b/src/internal/shims.ts @@ -110,3 +110,36 @@ export function ReadableStreamFrom(iterable: Iterable | AsyncIterable): }, }); } + +/** + * Most browsers don't yet have async iterable support for ReadableStream, + * and Node has a very different way of reading bytes from its "ReadableStream". + * + * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490 + */ +export function ReadableStreamToAsyncIterable(stream: any): AsyncIterableIterator { + if (stream[Symbol.asyncIterator]) return stream; + + const reader = stream.getReader(); + return { + async next() { + try { + const result = await reader.read(); + if (result?.done) reader.releaseLock(); // release lock when stream becomes closed + return result; + } catch (e) { + reader.releaseLock(); // release lock when stream becomes errored + throw e; + } + }, + async return() { + const cancelPromise = reader.cancel(); + reader.releaseLock(); + await cancelPromise; + return { done: true, value: undefined }; + }, + [Symbol.asyncIterator]() { + return this; + }, + }; +} diff --git a/src/streaming.ts b/src/streaming.ts index 8dd0fcd3..ff54311e 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -2,6 +2,7 @@ import { AnthropicError } from './error'; import { type ReadableStream } from './internal/shim-types'; import { makeReadableStream } from './internal/shims'; import { LineDecoder } from './internal/decoders/line'; +import { ReadableStreamToAsyncIterable } from './internal/shims'; import { APIError } from './error'; @@ -93,7 +94,7 @@ export class Stream implements AsyncIterable { async function* iterLines(): AsyncGenerator { const lineDecoder = new LineDecoder(); - const iter = readableStreamAsyncIterable(readableStream); + const iter = ReadableStreamToAsyncIterable(readableStream); for await (const chunk of iter) { for (const line of lineDecoder.decode(chunk)) { yield line; @@ -207,7 +208,7 @@ export async function* _iterSSEMessages( const sseDecoder = new SSEDecoder(); const lineDecoder = new LineDecoder(); - const iter = readableStreamAsyncIterable(response.body); + const iter = ReadableStreamToAsyncIterable(response.body); for await (const sseChunk of iterSSEChunks(iter)) { for (const line of lineDecoder.decode(sseChunk)) { const sse = sseDecoder.decode(line); @@ -360,36 +361,3 @@ function partition(str: string, delimiter: string): [string, string, string] { return [str, '', '']; } - -/** - * Most browsers don't yet have async iterable support for ReadableStream, - * and Node has a very different way of reading bytes from its "ReadableStream". - * - * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490 - */ -export function readableStreamAsyncIterable(stream: any): AsyncIterableIterator { - if (stream[Symbol.asyncIterator]) return stream; - - const reader = stream.getReader(); - return { - async next() { - try { - const result = await reader.read(); - if (result?.done) reader.releaseLock(); // release lock when stream becomes closed - return result; - } catch (e) { - reader.releaseLock(); // release lock when stream becomes errored - throw e; - } - }, - async return() { - const cancelPromise = reader.cancel(); - reader.releaseLock(); - await cancelPromise; - return { done: true, value: undefined }; - }, - [Symbol.asyncIterator]() { - return this; - }, - }; -} From caedce767e4c536f11bd2f57c2e90249ba8bb41c Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:32:08 -0500 Subject: [PATCH 013/105] feat(client): support results endpoint chore: unknown commit message --- .stats.yml | 2 +- api.md | 4 ++-- src/internal/decoders/jsonl.ts | 4 ++-- src/resources/beta/messages/batches.ts | 2 +- src/resources/messages/batches.ts | 2 +- tests/api-resources/beta/messages/batches.test.ts | 15 ++++++++++++++- tests/api-resources/messages/batches.test.ts | 12 ++++++++++++ 7 files changed, 33 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 239e17b7..c809f63b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-fd67aea6883f1ee9e46f31a42d3940f0acb1749e787055bd9b9f278b20fa53ec.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-75f0573c3d6d79650bcbd8b1b4fcf93ce146d567afeb1061cd4afccf8d1d6799.yml diff --git a/api.md b/api.md index 390a0b3f..c342afc5 100644 --- a/api.md +++ b/api.md @@ -87,7 +87,7 @@ Methods: - client.messages.batches.list({ ...params }) -> MessageBatchesPage - client.messages.batches.delete(messageBatchID) -> DeletedMessageBatch - client.messages.batches.cancel(messageBatchID) -> MessageBatch -- client.messages.batches.results(messageBatchID) -> Response +- client.messages.batches.results(messageBatchID) -> JSONLDecoder<MessageBatchIndividualResponse> # Models @@ -194,4 +194,4 @@ Methods: - client.beta.messages.batches.list({ ...params }) -> BetaMessageBatchesPage - client.beta.messages.batches.delete(messageBatchID, { ...params }) -> BetaDeletedMessageBatch - client.beta.messages.batches.cancel(messageBatchID, { ...params }) -> BetaMessageBatch -- client.beta.messages.batches.results(messageBatchID, { ...params }) -> Response +- client.beta.messages.batches.results(messageBatchID, { ...params }) -> JSONLDecoder<BetaMessageBatchIndividualResponse> diff --git a/src/internal/decoders/jsonl.ts b/src/internal/decoders/jsonl.ts index 8886529f..54a49bf2 100644 --- a/src/internal/decoders/jsonl.ts +++ b/src/internal/decoders/jsonl.ts @@ -1,5 +1,5 @@ import { AnthropicError } from '../../error'; -import { readableStreamAsyncIterable } from '../../streaming'; +import { ReadableStreamToAsyncIterable } from '../shims'; import { LineDecoder, type Bytes } from './line'; export class JSONLDecoder { @@ -35,6 +35,6 @@ export class JSONLDecoder { throw new AnthropicError(`Attempted to iterate over a response with no body`); } - return new JSONLDecoder(readableStreamAsyncIterable(response.body), controller); + return new JSONLDecoder(ReadableStreamToAsyncIterable(response.body), controller); } } diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index bcf7a630..1efb5660 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -141,7 +141,7 @@ export class Batches extends APIResource { headers: buildHeaders([ { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString(), - Accept: 'application/binary', + Accept: 'application/x-jsonl', }, options?.headers, ]), diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index bce8b12f..0a3346a4 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -87,7 +87,7 @@ export class Batches extends APIResource { return this._client .get(batch.results_url, { ...options, - headers: buildHeaders([{ Accept: 'application/binary' }, options?.headers]), + headers: buildHeaders([{ Accept: 'application/x-jsonl' }, options?.headers]), __binaryResponse: true, }) diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index 23f6c37c..e5f571e3 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -161,7 +161,20 @@ describe('resource batches', () => { ).rejects.toThrow(Anthropic.NotFoundError); }); - test('results: request options and params are passed correctly', async () => { + // Prism doesn't support JSONL responses yet + test.skip('results', async () => { + const responsePromise = client.beta.messages.batches.results('message_batch_id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism doesn't support JSONL responses yet + test.skip('results: request options and params are passed correctly', async () => { // 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.results( diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index 95a4deb6..eee68216 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -124,4 +124,16 @@ describe('resource batches', () => { expect(dataAndResponse.data).toBe(response); expect(dataAndResponse.response).toBe(rawResponse); }); + + // Prism doesn't support JSONL responses yet + test.skip('results', async () => { + const responsePromise = client.messages.batches.results('message_batch_id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); }); From 718442e5152b189b66e3cddc0c038075a4245127 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 23 Jan 2025 11:45:05 -0500 Subject: [PATCH 014/105] feat(api): add citations chore: unknown commit message --- .stats.yml | 2 +- api.md | 26 +++ src/client.ts | 26 +++ src/resources/beta/beta.ts | 26 +++ src/resources/beta/index.ts | 13 ++ src/resources/beta/messages/batches.ts | 7 +- src/resources/beta/messages/index.ts | 13 ++ src/resources/beta/messages/messages.ts | 154 +++++++++++++++++- src/resources/index.ts | 13 ++ src/resources/messages/batches.ts | 7 +- src/resources/messages/index.ts | 13 ++ src/resources/messages/messages.ts | 151 ++++++++++++++++- .../beta/messages/batches.test.ts | 16 +- .../beta/messages/messages.test.ts | 36 +++- tests/api-resources/messages/batches.test.ts | 16 +- tests/api-resources/messages/messages.test.ts | 36 +++- 16 files changed, 538 insertions(+), 17 deletions(-) diff --git a/.stats.yml b/.stats.yml index c809f63b..e7d06698 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-75f0573c3d6d79650bcbd8b1b4fcf93ce146d567afeb1061cd4afccf8d1d6799.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-7270ee0a79d885681ee507414608229f61c27f47c40f355dcd210b38aa7cddf1.yml diff --git a/api.md b/api.md index c342afc5..c4454a79 100644 --- a/api.md +++ b/api.md @@ -22,9 +22,19 @@ Types: - Base64PDFSource - CacheControlEphemeral +- CitationCharLocation +- CitationCharLocationParam +- CitationContentBlockLocation +- CitationContentBlockLocationParam +- CitationPageLocation +- CitationPageLocationParam +- CitationsConfigParam +- CitationsDelta - ContentBlock - ContentBlockDeltaEvent - ContentBlockParam +- ContentBlockSource +- ContentBlockSourceContent - ContentBlockStartEvent - ContentBlockStopEvent - DocumentBlockParam @@ -40,6 +50,7 @@ Types: - MessageTokensCount - Metadata - Model +- PlainTextSource - RawContentBlockDeltaEvent - RawContentBlockStartEvent - RawContentBlockStopEvent @@ -49,6 +60,8 @@ Types: - RawMessageStreamEvent - TextBlock - TextBlockParam +- TextCitation +- TextCitationParam - TextDelta - Tool - ToolChoice @@ -135,8 +148,18 @@ Types: - BetaBase64PDFBlock - BetaBase64PDFSource - BetaCacheControlEphemeral +- BetaCitationCharLocation +- BetaCitationCharLocationParam +- BetaCitationContentBlockLocation +- BetaCitationContentBlockLocationParam +- BetaCitationPageLocation +- BetaCitationPageLocationParam +- BetaCitationsConfigParam +- BetaCitationsDelta - BetaContentBlock - BetaContentBlockParam +- BetaContentBlockSource +- BetaContentBlockSourceContent - BetaImageBlockParam - BetaInputJSONDelta - BetaMessage @@ -144,6 +167,7 @@ Types: - BetaMessageParam - BetaMessageTokensCount - BetaMetadata +- BetaPlainTextSource - BetaRawContentBlockDeltaEvent - BetaRawContentBlockStartEvent - BetaRawContentBlockStopEvent @@ -153,6 +177,8 @@ Types: - BetaRawMessageStreamEvent - BetaTextBlock - BetaTextBlockParam +- BetaTextCitation +- BetaTextCitationParam - BetaTextDelta - BetaTool - BetaToolBash20241022 diff --git a/src/client.ts b/src/client.ts index 2a81487c..587ec529 100644 --- a/src/client.ts +++ b/src/client.ts @@ -50,11 +50,21 @@ import { import { Base64PDFSource, CacheControlEphemeral, + CitationCharLocation, + CitationCharLocationParam, + CitationContentBlockLocation, + CitationContentBlockLocationParam, + CitationPageLocation, + CitationPageLocationParam, + CitationsConfigParam, + CitationsDelta, ContentBlock, ContentBlockDeltaEvent, ContentBlockParam, ContentBlockStartEvent, ContentBlockStopEvent, + ContentBlockSource, + ContentBlockSourceContent, DocumentBlockParam, ImageBlockParam, InputJSONDelta, @@ -74,6 +84,7 @@ import { Messages, Metadata, Model, + PlainTextSource, RawContentBlockDeltaEvent, RawContentBlockStartEvent, RawContentBlockStopEvent, @@ -83,6 +94,8 @@ import { RawMessageStreamEvent, TextBlock, TextBlockParam, + TextCitation, + TextCitationParam, TextDelta, Tool, ToolChoice, @@ -808,11 +821,21 @@ export declare namespace Anthropic { Messages as Messages, type Base64PDFSource as Base64PDFSource, type CacheControlEphemeral as CacheControlEphemeral, + type CitationCharLocation as CitationCharLocation, + type CitationCharLocationParam as CitationCharLocationParam, + type CitationContentBlockLocation as CitationContentBlockLocation, + type CitationContentBlockLocationParam as CitationContentBlockLocationParam, + type CitationPageLocation as CitationPageLocation, + type CitationPageLocationParam as CitationPageLocationParam, + type CitationsConfigParam as CitationsConfigParam, + type CitationsDelta as CitationsDelta, type ContentBlock as ContentBlock, type ContentBlockDeltaEvent as ContentBlockDeltaEvent, type ContentBlockParam as ContentBlockParam, type ContentBlockStartEvent as ContentBlockStartEvent, type ContentBlockStopEvent as ContentBlockStopEvent, + type ContentBlockSource as ContentBlockSource, + type ContentBlockSourceContent as ContentBlockSourceContent, type DocumentBlockParam as DocumentBlockParam, type ImageBlockParam as ImageBlockParam, type InputJSONDelta as InputJSONDelta, @@ -826,6 +849,7 @@ export declare namespace Anthropic { type MessageTokensCount as MessageTokensCount, type Metadata as Metadata, type Model as Model, + type PlainTextSource as PlainTextSource, type RawContentBlockDeltaEvent as RawContentBlockDeltaEvent, type RawContentBlockStartEvent as RawContentBlockStartEvent, type RawContentBlockStopEvent as RawContentBlockStopEvent, @@ -835,6 +859,8 @@ export declare namespace Anthropic { type RawMessageStreamEvent as RawMessageStreamEvent, type TextBlock as TextBlock, type TextBlockParam as TextBlockParam, + type TextCitation as TextCitation, + type TextCitationParam as TextCitationParam, type TextDelta as TextDelta, type Tool as Tool, type ToolChoice as ToolChoice, diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index 29ddfbc4..3193d108 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -8,8 +8,18 @@ import { BetaBase64PDFBlock, BetaBase64PDFSource, BetaCacheControlEphemeral, + BetaCitationCharLocation, + BetaCitationCharLocationParam, + BetaCitationContentBlockLocation, + BetaCitationContentBlockLocationParam, + BetaCitationPageLocation, + BetaCitationPageLocationParam, + BetaCitationsConfigParam, + BetaCitationsDelta, BetaContentBlock, BetaContentBlockParam, + BetaContentBlockSource, + BetaContentBlockSourceContent, BetaImageBlockParam, BetaInputJSONDelta, BetaMessage, @@ -17,6 +27,7 @@ import { BetaMessageParam, BetaMessageTokensCount, BetaMetadata, + BetaPlainTextSource, BetaRawContentBlockDeltaEvent, BetaRawContentBlockStartEvent, BetaRawContentBlockStopEvent, @@ -26,6 +37,8 @@ import { BetaRawMessageStreamEvent, BetaTextBlock, BetaTextBlockParam, + BetaTextCitation, + BetaTextCitationParam, BetaTextDelta, BetaTool, BetaToolBash20241022, @@ -162,8 +175,18 @@ export declare namespace Beta { type BetaBase64PDFBlock as BetaBase64PDFBlock, type BetaBase64PDFSource as BetaBase64PDFSource, type BetaCacheControlEphemeral as BetaCacheControlEphemeral, + type BetaCitationCharLocation as BetaCitationCharLocation, + type BetaCitationCharLocationParam as BetaCitationCharLocationParam, + type BetaCitationContentBlockLocation as BetaCitationContentBlockLocation, + type BetaCitationContentBlockLocationParam as BetaCitationContentBlockLocationParam, + type BetaCitationPageLocation as BetaCitationPageLocation, + type BetaCitationPageLocationParam as BetaCitationPageLocationParam, + type BetaCitationsConfigParam as BetaCitationsConfigParam, + type BetaCitationsDelta as BetaCitationsDelta, type BetaContentBlock as BetaContentBlock, type BetaContentBlockParam as BetaContentBlockParam, + type BetaContentBlockSource as BetaContentBlockSource, + type BetaContentBlockSourceContent as BetaContentBlockSourceContent, type BetaImageBlockParam as BetaImageBlockParam, type BetaInputJSONDelta as BetaInputJSONDelta, type BetaMessage as BetaMessage, @@ -171,6 +194,7 @@ export declare namespace Beta { type BetaMessageParam as BetaMessageParam, type BetaMessageTokensCount as BetaMessageTokensCount, type BetaMetadata as BetaMetadata, + type BetaPlainTextSource as BetaPlainTextSource, type BetaRawContentBlockDeltaEvent as BetaRawContentBlockDeltaEvent, type BetaRawContentBlockStartEvent as BetaRawContentBlockStartEvent, type BetaRawContentBlockStopEvent as BetaRawContentBlockStopEvent, @@ -180,6 +204,8 @@ export declare namespace Beta { type BetaRawMessageStreamEvent as BetaRawMessageStreamEvent, type BetaTextBlock as BetaTextBlock, type BetaTextBlockParam as BetaTextBlockParam, + type BetaTextCitation as BetaTextCitation, + type BetaTextCitationParam as BetaTextCitationParam, type BetaTextDelta as BetaTextDelta, type BetaTool as BetaTool, type BetaToolBash20241022 as BetaToolBash20241022, diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts index 5db36de4..e7ae649a 100644 --- a/src/resources/beta/index.ts +++ b/src/resources/beta/index.ts @@ -20,8 +20,18 @@ export { type BetaBase64PDFBlock, type BetaBase64PDFSource, type BetaCacheControlEphemeral, + type BetaCitationCharLocation, + type BetaCitationCharLocationParam, + type BetaCitationContentBlockLocation, + type BetaCitationContentBlockLocationParam, + type BetaCitationPageLocation, + type BetaCitationPageLocationParam, + type BetaCitationsConfigParam, + type BetaCitationsDelta, type BetaContentBlock, type BetaContentBlockParam, + type BetaContentBlockSource, + type BetaContentBlockSourceContent, type BetaImageBlockParam, type BetaInputJSONDelta, type BetaMessage, @@ -29,6 +39,7 @@ export { type BetaMessageParam, type BetaMessageTokensCount, type BetaMetadata, + type BetaPlainTextSource, type BetaRawContentBlockDeltaEvent, type BetaRawContentBlockStartEvent, type BetaRawContentBlockStopEvent, @@ -38,6 +49,8 @@ export { type BetaRawMessageStreamEvent, type BetaTextBlock, type BetaTextBlockParam, + type BetaTextCitation, + type BetaTextCitationParam, type BetaTextDelta, type BetaTool, type BetaToolBash20241022, diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index 1efb5660..d4c0b7aa 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -70,9 +70,10 @@ export class Batches extends APIResource { } /** - * This endpoint is idempotent and can be used to poll for Message Batch - * completion. To access the results of a Message Batch, make a request to the - * `results_url` field in the response. + * Delete a Message Batch. + * + * Message Batches can only be deleted once they've finished processing. If you'd + * like to delete an in-progress batch, you must first cancel it. */ delete( messageBatchID: string, diff --git a/src/resources/beta/messages/index.ts b/src/resources/beta/messages/index.ts index faf65c59..31c4e519 100644 --- a/src/resources/beta/messages/index.ts +++ b/src/resources/beta/messages/index.ts @@ -24,8 +24,18 @@ export { type BetaBase64PDFBlock, type BetaBase64PDFSource, type BetaCacheControlEphemeral, + type BetaCitationCharLocation, + type BetaCitationCharLocationParam, + type BetaCitationContentBlockLocation, + type BetaCitationContentBlockLocationParam, + type BetaCitationPageLocation, + type BetaCitationPageLocationParam, + type BetaCitationsConfigParam, + type BetaCitationsDelta, type BetaContentBlock, type BetaContentBlockParam, + type BetaContentBlockSource, + type BetaContentBlockSourceContent, type BetaImageBlockParam, type BetaInputJSONDelta, type BetaMessage, @@ -33,6 +43,7 @@ export { type BetaMessageParam, type BetaMessageTokensCount, type BetaMetadata, + type BetaPlainTextSource, type BetaRawContentBlockDeltaEvent, type BetaRawContentBlockStartEvent, type BetaRawContentBlockStopEvent, @@ -42,6 +53,8 @@ export { type BetaRawMessageStreamEvent, type BetaTextBlock, type BetaTextBlockParam, + type BetaTextCitation, + type BetaTextCitationParam, type BetaTextDelta, type BetaTool, type BetaToolBash20241022, diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index a24dd92e..4e6f4dde 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -88,11 +88,17 @@ export class Messages extends APIResource { } export interface BetaBase64PDFBlock { - source: BetaBase64PDFSource; + source: BetaBase64PDFSource | BetaPlainTextSource | BetaContentBlockSource; type: 'document'; cache_control?: BetaCacheControlEphemeral | null; + + citations?: BetaCitationsConfigParam; + + context?: string | null; + + title?: string | null; } export interface BetaBase64PDFSource { @@ -107,6 +113,100 @@ export interface BetaCacheControlEphemeral { type: 'ephemeral'; } +export interface BetaCitationCharLocation { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_char_index: number; + + start_char_index: number; + + type: 'char_location'; +} + +export interface BetaCitationCharLocationParam { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_char_index: number; + + start_char_index: number; + + type: 'char_location'; +} + +export interface BetaCitationContentBlockLocation { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_block_index: number; + + start_block_index: number; + + type: 'content_block_location'; +} + +export interface BetaCitationContentBlockLocationParam { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_block_index: number; + + start_block_index: number; + + type: 'content_block_location'; +} + +export interface BetaCitationPageLocation { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_page_number: number; + + start_page_number: number; + + type: 'page_location'; +} + +export interface BetaCitationPageLocationParam { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_page_number: number; + + start_page_number: number; + + type: 'page_location'; +} + +export interface BetaCitationsConfigParam { + enabled?: boolean; +} + +export interface BetaCitationsDelta { + citation: BetaCitationCharLocation | BetaCitationPageLocation | BetaCitationContentBlockLocation; + + type: 'citations_delta'; +} + export type BetaContentBlock = BetaTextBlock | BetaToolUseBlock; export type BetaContentBlockParam = @@ -116,6 +216,14 @@ export type BetaContentBlockParam = | BetaToolResultBlockParam | BetaBase64PDFBlock; +export interface BetaContentBlockSource { + content: string | Array; + + type: 'content'; +} + +export type BetaContentBlockSourceContent = BetaTextBlockParam | BetaImageBlockParam; + export interface BetaImageBlockParam { source: BetaImageBlockParam.Source; @@ -277,8 +385,16 @@ export interface BetaMetadata { user_id?: string | null; } +export interface BetaPlainTextSource { + data: string; + + media_type: 'text/plain'; + + type: 'text'; +} + export interface BetaRawContentBlockDeltaEvent { - delta: BetaTextDelta | BetaInputJSONDelta; + delta: BetaTextDelta | BetaInputJSONDelta | BetaCitationsDelta; index: number; @@ -348,6 +464,15 @@ export type BetaRawMessageStreamEvent = | BetaRawContentBlockStopEvent; export interface BetaTextBlock { + /** + * Citations supporting the text block. + * + * The type of citation returned will depend on the type of document being cited. + * Citing a PDF results in `page_location`, plain text results in `char_location`, + * and content document results in `content_block_location`. + */ + citations: Array | null; + text: string; type: 'text'; @@ -359,8 +484,20 @@ export interface BetaTextBlockParam { type: 'text'; cache_control?: BetaCacheControlEphemeral | null; + + citations?: Array | null; } +export type BetaTextCitation = + | BetaCitationCharLocation + | BetaCitationPageLocation + | BetaCitationContentBlockLocation; + +export type BetaTextCitationParam = + | BetaCitationCharLocationParam + | BetaCitationPageLocationParam + | BetaCitationContentBlockLocationParam; + export interface BetaTextDelta { text: string; @@ -1077,8 +1214,18 @@ export declare namespace Messages { type BetaBase64PDFBlock as BetaBase64PDFBlock, type BetaBase64PDFSource as BetaBase64PDFSource, type BetaCacheControlEphemeral as BetaCacheControlEphemeral, + type BetaCitationCharLocation as BetaCitationCharLocation, + type BetaCitationCharLocationParam as BetaCitationCharLocationParam, + type BetaCitationContentBlockLocation as BetaCitationContentBlockLocation, + type BetaCitationContentBlockLocationParam as BetaCitationContentBlockLocationParam, + type BetaCitationPageLocation as BetaCitationPageLocation, + type BetaCitationPageLocationParam as BetaCitationPageLocationParam, + type BetaCitationsConfigParam as BetaCitationsConfigParam, + type BetaCitationsDelta as BetaCitationsDelta, type BetaContentBlock as BetaContentBlock, type BetaContentBlockParam as BetaContentBlockParam, + type BetaContentBlockSource as BetaContentBlockSource, + type BetaContentBlockSourceContent as BetaContentBlockSourceContent, type BetaImageBlockParam as BetaImageBlockParam, type BetaInputJSONDelta as BetaInputJSONDelta, type BetaMessage as BetaMessage, @@ -1086,6 +1233,7 @@ export declare namespace Messages { type BetaMessageParam as BetaMessageParam, type BetaMessageTokensCount as BetaMessageTokensCount, type BetaMetadata as BetaMetadata, + type BetaPlainTextSource as BetaPlainTextSource, type BetaRawContentBlockDeltaEvent as BetaRawContentBlockDeltaEvent, type BetaRawContentBlockStartEvent as BetaRawContentBlockStartEvent, type BetaRawContentBlockStopEvent as BetaRawContentBlockStopEvent, @@ -1095,6 +1243,8 @@ export declare namespace Messages { type BetaRawMessageStreamEvent as BetaRawMessageStreamEvent, type BetaTextBlock as BetaTextBlock, type BetaTextBlockParam as BetaTextBlockParam, + type BetaTextCitation as BetaTextCitation, + type BetaTextCitationParam as BetaTextCitationParam, type BetaTextDelta as BetaTextDelta, type BetaTool as BetaTool, type BetaToolBash20241022 as BetaToolBash20241022, diff --git a/src/resources/index.ts b/src/resources/index.ts index 5dd6b70f..0bd0fa05 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -27,11 +27,21 @@ export { Messages, type Base64PDFSource, type CacheControlEphemeral, + type CitationCharLocation, + type CitationCharLocationParam, + type CitationContentBlockLocation, + type CitationContentBlockLocationParam, + type CitationPageLocation, + type CitationPageLocationParam, + type CitationsConfigParam, + type CitationsDelta, type ContentBlock, type ContentBlockDeltaEvent, type ContentBlockParam, type ContentBlockStartEvent, type ContentBlockStopEvent, + type ContentBlockSource, + type ContentBlockSourceContent, type DocumentBlockParam, type ImageBlockParam, type InputJsonDelta, @@ -47,6 +57,7 @@ export { type MessageTokensCount, type Metadata, type Model, + type PlainTextSource, type RawContentBlockDeltaEvent, type RawContentBlockStartEvent, type RawContentBlockStopEvent, @@ -56,6 +67,8 @@ export { type RawMessageStreamEvent, type TextBlock, type TextBlockParam, + type TextCitation, + type TextCitationParam, type TextDelta, type Tool, type ToolChoice, diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index 0a3346a4..6c0ccb23 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -43,9 +43,10 @@ export class Batches extends APIResource { } /** - * This endpoint is idempotent and can be used to poll for Message Batch - * completion. To access the results of a Message Batch, make a request to the - * `results_url` field in the response. + * Delete a Message Batch. + * + * Message Batches can only be deleted once they've finished processing. If you'd + * like to delete an in-progress batch, you must first cancel it. */ delete(messageBatchID: string, options?: RequestOptions): APIPromise { return this._client.delete(`/v1/messages/batches/${messageBatchID}`, options); diff --git a/src/resources/messages/index.ts b/src/resources/messages/index.ts index facb9e03..9468a983 100644 --- a/src/resources/messages/index.ts +++ b/src/resources/messages/index.ts @@ -19,11 +19,21 @@ export { Messages, type Base64PDFSource, type CacheControlEphemeral, + type CitationCharLocation, + type CitationCharLocationParam, + type CitationContentBlockLocation, + type CitationContentBlockLocationParam, + type CitationPageLocation, + type CitationPageLocationParam, + type CitationsConfigParam, + type CitationsDelta, type ContentBlock, type ContentBlockDeltaEvent, type ContentBlockParam, type ContentBlockStartEvent, type ContentBlockStopEvent, + type ContentBlockSource, + type ContentBlockSourceContent, type DocumentBlockParam, type ImageBlockParam, type InputJSONDelta, @@ -37,6 +47,7 @@ export { type MessageTokensCount, type Metadata, type Model, + type PlainTextSource, type RawContentBlockDeltaEvent, type RawContentBlockStartEvent, type RawContentBlockStopEvent, @@ -46,6 +57,8 @@ export { type RawMessageStreamEvent, type TextBlock, type TextBlockParam, + type TextCitation, + type TextCitationParam, type TextDelta, type Tool, type ToolChoice, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index 0ce089bf..b10f9725 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -93,6 +93,100 @@ export interface CacheControlEphemeral { type: 'ephemeral'; } +export interface CitationCharLocation { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_char_index: number; + + start_char_index: number; + + type: 'char_location'; +} + +export interface CitationCharLocationParam { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_char_index: number; + + start_char_index: number; + + type: 'char_location'; +} + +export interface CitationContentBlockLocation { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_block_index: number; + + start_block_index: number; + + type: 'content_block_location'; +} + +export interface CitationContentBlockLocationParam { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_block_index: number; + + start_block_index: number; + + type: 'content_block_location'; +} + +export interface CitationPageLocation { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_page_number: number; + + start_page_number: number; + + type: 'page_location'; +} + +export interface CitationPageLocationParam { + cited_text: string; + + document_index: number; + + document_title: string | null; + + end_page_number: number; + + start_page_number: number; + + type: 'page_location'; +} + +export interface CitationsConfigParam { + enabled?: boolean; +} + +export interface CitationsDelta { + citation: CitationCharLocation | CitationPageLocation | CitationContentBlockLocation; + + type: 'citations_delta'; +} + export type ContentBlock = TextBlock | ToolUseBlock; export type ContentBlockDeltaEvent = RawContentBlockDeltaEvent; @@ -108,12 +202,26 @@ export type ContentBlockStartEvent = RawContentBlockStartEvent; export type ContentBlockStopEvent = RawContentBlockStopEvent; +export interface ContentBlockSource { + content: string | Array; + + type: 'content'; +} + +export type ContentBlockSourceContent = TextBlockParam | ImageBlockParam; + export interface DocumentBlockParam { - source: Base64PDFSource; + source: Base64PDFSource | PlainTextSource | ContentBlockSource; type: 'document'; cache_control?: CacheControlEphemeral | null; + + citations?: CitationsConfigParam; + + context?: string | null; + + title?: string | null; } export interface ImageBlockParam { @@ -318,8 +426,16 @@ const DEPRECATED_MODELS: DeprecatedModelsType = { 'claude-instant-1.2': 'November 6th, 2024', }; +export interface PlainTextSource { + data: string; + + media_type: 'text/plain'; + + type: 'text'; +} + export interface RawContentBlockDeltaEvent { - delta: TextDelta | InputJSONDelta; + delta: TextDelta | InputJSONDelta | CitationsDelta; index: number; @@ -389,6 +505,15 @@ export type RawMessageStreamEvent = | RawContentBlockStopEvent; export interface TextBlock { + /** + * Citations supporting the text block. + * + * The type of citation returned will depend on the type of document being cited. + * Citing a PDF results in `page_location`, plain text results in `char_location`, + * and content document results in `content_block_location`. + */ + citations: Array | null; + text: string; type: 'text'; @@ -400,8 +525,17 @@ export interface TextBlockParam { type: 'text'; cache_control?: CacheControlEphemeral | null; + + citations?: Array | null; } +export type TextCitation = CitationCharLocation | CitationPageLocation | CitationContentBlockLocation; + +export type TextCitationParam = + | CitationCharLocationParam + | CitationPageLocationParam + | CitationContentBlockLocationParam; + export interface TextDelta { text: string; @@ -1064,11 +1198,21 @@ export declare namespace Messages { export { type Base64PDFSource as Base64PDFSource, type CacheControlEphemeral as CacheControlEphemeral, + type CitationCharLocation as CitationCharLocation, + type CitationCharLocationParam as CitationCharLocationParam, + type CitationContentBlockLocation as CitationContentBlockLocation, + type CitationContentBlockLocationParam as CitationContentBlockLocationParam, + type CitationPageLocation as CitationPageLocation, + type CitationPageLocationParam as CitationPageLocationParam, + type CitationsConfigParam as CitationsConfigParam, + type CitationsDelta as CitationsDelta, type ContentBlock as ContentBlock, type ContentBlockDeltaEvent as ContentBlockDeltaEvent, type ContentBlockParam as ContentBlockParam, type ContentBlockStartEvent as ContentBlockStartEvent, type ContentBlockStopEvent as ContentBlockStopEvent, + type ContentBlockSource as ContentBlockSource, + type ContentBlockSourceContent as ContentBlockSourceContent, type DocumentBlockParam as DocumentBlockParam, type ImageBlockParam as ImageBlockParam, type InputJsonDelta as InputJsonDelta, @@ -1083,6 +1227,7 @@ export declare namespace Messages { type MessageTokensCount as MessageTokensCount, type Metadata as Metadata, type Model as Model, + type PlainTextSource as PlainTextSource, type RawContentBlockDeltaEvent as RawContentBlockDeltaEvent, type RawContentBlockStartEvent as RawContentBlockStartEvent, type RawContentBlockStopEvent as RawContentBlockStopEvent, @@ -1092,6 +1237,8 @@ export declare namespace Messages { type RawMessageStreamEvent as RawMessageStreamEvent, type TextBlock as TextBlock, type TextBlockParam as TextBlockParam, + type TextCitation as TextCitation, + type TextCitationParam as TextCitationParam, type TextDelta as TextDelta, type Tool as Tool, type ToolChoice as ToolChoice, diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index e5f571e3..769773e8 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -43,7 +43,21 @@ describe('resource batches', () => { stop_sequences: ['string'], stream: false, system: [ - { text: "Today's date is 2024-06-01.", type: 'text', cache_control: { type: 'ephemeral' } }, + { + text: "Today's date is 2024-06-01.", + type: 'text', + cache_control: { type: 'ephemeral' }, + citations: [ + { + cited_text: 'cited_text', + document_index: 0, + document_title: 'x', + end_char_index: 0, + start_char_index: 0, + type: 'char_location', + }, + ], + }, ], temperature: 1, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, diff --git a/tests/api-resources/beta/messages/messages.test.ts b/tests/api-resources/beta/messages/messages.test.ts index 67a23cd0..d03de98c 100644 --- a/tests/api-resources/beta/messages/messages.test.ts +++ b/tests/api-resources/beta/messages/messages.test.ts @@ -31,7 +31,23 @@ describe('resource messages', () => { metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, - system: [{ text: "Today's date is 2024-06-01.", type: 'text', cache_control: { type: 'ephemeral' } }], + system: [ + { + text: "Today's date is 2024-06-01.", + type: 'text', + cache_control: { type: 'ephemeral' }, + citations: [ + { + cited_text: 'cited_text', + document_index: 0, + document_title: 'x', + end_char_index: 0, + start_char_index: 0, + type: 'char_location', + }, + ], + }, + ], temperature: 1, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ @@ -73,7 +89,23 @@ describe('resource messages', () => { const response = await client.beta.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], model: 'string', - system: [{ text: "Today's date is 2024-06-01.", type: 'text', cache_control: { type: 'ephemeral' } }], + system: [ + { + text: "Today's date is 2024-06-01.", + type: 'text', + cache_control: { type: 'ephemeral' }, + citations: [ + { + cited_text: 'cited_text', + document_index: 0, + document_title: 'x', + end_char_index: 0, + start_char_index: 0, + type: 'char_location', + }, + ], + }, + ], tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index eee68216..1388ef36 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -42,7 +42,21 @@ describe('resource batches', () => { metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], system: [ - { text: "Today's date is 2024-06-01.", type: 'text', cache_control: { type: 'ephemeral' } }, + { + text: "Today's date is 2024-06-01.", + type: 'text', + cache_control: { type: 'ephemeral' }, + citations: [ + { + cited_text: 'cited_text', + document_index: 0, + document_title: 'x', + end_char_index: 0, + start_char_index: 0, + type: 'char_location', + }, + ], + }, ], temperature: 1, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, diff --git a/tests/api-resources/messages/messages.test.ts b/tests/api-resources/messages/messages.test.ts index 1add2073..08829c3f 100644 --- a/tests/api-resources/messages/messages.test.ts +++ b/tests/api-resources/messages/messages.test.ts @@ -31,7 +31,23 @@ describe('resource messages', () => { metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, - system: [{ text: "Today's date is 2024-06-01.", type: 'text', cache_control: { type: 'ephemeral' } }], + system: [ + { + text: "Today's date is 2024-06-01.", + type: 'text', + cache_control: { type: 'ephemeral' }, + citations: [ + { + cited_text: 'cited_text', + document_index: 0, + document_title: 'x', + end_char_index: 0, + start_char_index: 0, + type: 'char_location', + }, + ], + }, + ], temperature: 1, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ @@ -71,7 +87,23 @@ describe('resource messages', () => { const response = await client.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], model: 'string', - system: [{ text: "Today's date is 2024-06-01.", type: 'text', cache_control: { type: 'ephemeral' } }], + system: [ + { + text: "Today's date is 2024-06-01.", + type: 'text', + cache_control: { type: 'ephemeral' }, + citations: [ + { + cited_text: 'cited_text', + document_index: 0, + document_title: 'x', + end_char_index: 0, + start_char_index: 0, + type: 'char_location', + }, + ], + }, + ], tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { From b077319197daaf4af4c14a9f342594de52ad0929 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Fri, 24 Jan 2025 07:21:53 -0500 Subject: [PATCH 015/105] chore(docs): updates chore: unknown commit message --- .stats.yml | 2 +- src/resources/beta/messages/batches.ts | 4 ++++ src/resources/messages/batches.ts | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index e7d06698..64f8716d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-7270ee0a79d885681ee507414608229f61c27f47c40f355dcd210b38aa7cddf1.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-f5276eeef7512112e802c85530c51e0a971ee521eebe3a0db309621587b4973d.yml diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index d4c0b7aa..f6794544 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -254,6 +254,10 @@ export interface BetaMessageBatchExpiredResult { type: 'expired'; } +/** + * This is a single line in the response `.jsonl` file and does not represent the + * response as a whole. + */ export interface BetaMessageBatchIndividualResponse { /** * Developer-provided ID created for each request in a Message Batch. Useful for diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index 6c0ccb23..a9f9fb29 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -198,6 +198,10 @@ export interface MessageBatchExpiredResult { type: 'expired'; } +/** + * This is a single line in the response `.jsonl` file and does not represent the + * response as a whole. + */ export interface MessageBatchIndividualResponse { /** * Developer-provided ID created for each request in a Message Batch. Useful for From 9c5e45732528254806bb7c4cabc9a564e3a841c3 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Mon, 27 Jan 2025 09:49:05 -0500 Subject: [PATCH 016/105] chore(types): remove type-level dependency on some platform specifics chore: unknown commit message --- src/client.ts | 8 ++++---- src/internal/decoders/line.ts | 20 ++++++++++++-------- src/internal/detect-platform.ts | 14 +++++++++----- src/internal/shims.ts | 4 ++-- src/internal/utils/base64.ts | 13 +++++-------- src/internal/utils/env.ts | 10 ++++------ src/internal/utils/sleep.ts | 2 +- src/streaming.ts | 8 +++++--- tsconfig.dist-src.json | 4 ++-- 9 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/client.ts b/src/client.ts index 587ec529..c87a0680 100644 --- a/src/client.ts +++ b/src/client.ts @@ -401,12 +401,12 @@ export class BaseAnthropic { private calculateContentLength(body: unknown): string | null { if (typeof body === 'string') { - if (typeof Buffer !== 'undefined') { - return Buffer.byteLength(body, 'utf8').toString(); + if (typeof (globalThis as any).Buffer !== 'undefined') { + return (globalThis as any).Buffer.byteLength(body, 'utf8').toString(); } - if (typeof TextEncoder !== 'undefined') { - const encoder = new TextEncoder(); + if (typeof (globalThis as any).TextEncoder !== 'undefined') { + const encoder = new (globalThis as any).TextEncoder(); const encoded = encoder.encode(body); return encoded.length.toString(); } diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts index a71f9ea0..c786db78 100644 --- a/src/internal/decoders/line.ts +++ b/src/internal/decoders/line.ts @@ -1,6 +1,6 @@ import { AnthropicError } from '../../error'; -export type Bytes = string | ArrayBuffer | Uint8Array | Buffer | null | undefined; +export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; /** * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally @@ -15,7 +15,11 @@ export class LineDecoder { buffer: string[]; trailingCR: boolean; - textDecoder: any; // TextDecoder found in browsers; not typed to avoid pulling in either "dom" or "node" types. + textDecoder: + | undefined + | { + decode(buffer: Uint8Array | ArrayBuffer): string; + }; constructor() { this.buffer = []; @@ -69,12 +73,12 @@ export class LineDecoder { if (typeof bytes === 'string') return bytes; // Node: - if (typeof Buffer !== 'undefined') { - if (bytes instanceof Buffer) { + if (typeof (globalThis as any).Buffer !== 'undefined') { + if (bytes instanceof (globalThis as any).Buffer) { return bytes.toString(); } if (bytes instanceof Uint8Array) { - return Buffer.from(bytes).toString(); + return (globalThis as any).Buffer.from(bytes).toString(); } throw new AnthropicError( @@ -83,10 +87,10 @@ export class LineDecoder { } // Browser - if (typeof TextDecoder !== 'undefined') { + if (typeof (globalThis as any).TextDecoder !== 'undefined') { if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) { - this.textDecoder ??= new TextDecoder('utf8'); - return this.textDecoder.decode(bytes); + this.textDecoder ??= new (globalThis as any).TextDecoder('utf8'); + return this.textDecoder!.decode(bytes); } throw new AnthropicError( diff --git a/src/internal/detect-platform.ts b/src/internal/detect-platform.ts index 24eec519..c5e273b9 100644 --- a/src/internal/detect-platform.ts +++ b/src/internal/detect-platform.ts @@ -25,7 +25,11 @@ function getDetectedPlatform(): DetectedPlatform { if (typeof EdgeRuntime !== 'undefined') { return 'edge'; } - if (Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]') { + if ( + Object.prototype.toString.call( + typeof (globalThis as any).process !== 'undefined' ? (globalThis as any).process : 0, + ) === '[object process]' + ) { return 'node'; } return 'unknown'; @@ -73,7 +77,7 @@ const getPlatformProperties = (): PlatformProperties => { 'X-Stainless-OS': 'Unknown', 'X-Stainless-Arch': `other:${EdgeRuntime}`, 'X-Stainless-Runtime': 'edge', - 'X-Stainless-Runtime-Version': process.version, + 'X-Stainless-Runtime-Version': (globalThis as any).process.version, }; } // Check if Node.js @@ -81,10 +85,10 @@ const getPlatformProperties = (): PlatformProperties => { return { 'X-Stainless-Lang': 'js', 'X-Stainless-Package-Version': VERSION, - 'X-Stainless-OS': normalizePlatform(process.platform), - 'X-Stainless-Arch': normalizeArch(process.arch), + 'X-Stainless-OS': normalizePlatform((globalThis as any).process.platform), + 'X-Stainless-Arch': normalizeArch((globalThis as any).process.arch), 'X-Stainless-Runtime': 'node', - 'X-Stainless-Runtime-Version': process.version, + 'X-Stainless-Runtime-Version': (globalThis as any).process.version, }; } diff --git a/src/internal/shims.ts b/src/internal/shims.ts index 46951605..ada548ce 100644 --- a/src/internal/shims.ts +++ b/src/internal/shims.ts @@ -12,7 +12,7 @@ import { type ReadableStream } from './shim-types'; export function getDefaultFetch(): Fetch { if (typeof fetch !== 'undefined') { - return fetch; + return fetch as any; } throw new Error( @@ -97,7 +97,7 @@ export function ReadableStreamFrom(iterable: Iterable | AsyncIterable): return makeReadableStream({ start() {}, - async pull(controller) { + async pull(controller: any) { const { done, value } = await iter.next(); if (done) { controller.close(); diff --git a/src/internal/utils/base64.ts b/src/internal/utils/base64.ts index 12d70740..ee4a2817 100644 --- a/src/internal/utils/base64.ts +++ b/src/internal/utils/base64.ts @@ -2,18 +2,15 @@ import { AnthropicError } from '../../error'; -// @ts-ignore -declare const Buffer: typeof import('node:buffer').Buffer; - export const toBase64 = (data: string | Uint8Array | null | undefined): string => { if (!data) return ''; if (typeof data === 'string') { - data = new TextEncoder().encode(data); + data = new (globalThis as any).TextEncoder().encode(data); } - if (typeof Buffer !== 'undefined') { - return Buffer.from(data).toString('base64'); + if (typeof (globalThis as any).Buffer !== 'undefined') { + return (globalThis as any).Buffer.from(data).toString('base64'); } if (typeof btoa !== 'undefined') { @@ -24,8 +21,8 @@ export const toBase64 = (data: string | Uint8Array | null | undefined): string = }; export const fromBase64 = (str: string): Uint8Array => { - if (typeof Buffer !== 'undefined') { - return new Uint8Array(Buffer.from(str, 'base64')); + if (typeof (globalThis as any).Buffer !== 'undefined') { + return new Uint8Array((globalThis as any).Buffer.from(str, 'base64')); } if (typeof atob !== 'undefined') { diff --git a/src/internal/utils/env.ts b/src/internal/utils/env.ts index d9b1dc4a..2d848007 100644 --- a/src/internal/utils/env.ts +++ b/src/internal/utils/env.ts @@ -1,7 +1,5 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -declare const Deno: any; - /** * Read an environment variable. * @@ -10,11 +8,11 @@ declare const Deno: any; * Will return undefined if the environment variable doesn't exist or cannot be accessed. */ export const readEnv = (env: string): string | undefined => { - if (typeof process !== 'undefined') { - return process.env?.[env]?.trim() ?? undefined; + if (typeof (globalThis as any).process !== 'undefined') { + return (globalThis as any).process.env?.[env]?.trim() ?? undefined; } - if (typeof Deno !== 'undefined') { - return Deno.env?.get?.(env)?.trim(); + if (typeof (globalThis as any).Deno !== 'undefined') { + return (globalThis as any).Deno.env?.get?.(env)?.trim(); } return undefined; }; diff --git a/src/internal/utils/sleep.ts b/src/internal/utils/sleep.ts index fcf4e083..65e52962 100644 --- a/src/internal/utils/sleep.ts +++ b/src/internal/utils/sleep.ts @@ -1,3 +1,3 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); +export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/src/streaming.ts b/src/streaming.ts index ff54311e..e2894d05 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -6,7 +6,7 @@ import { ReadableStreamToAsyncIterable } from './internal/shims'; import { APIError } from './error'; -type Bytes = string | ArrayBuffer | Uint8Array | Buffer | null | undefined; +type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; export type ServerSentEvent = { event: string | null; @@ -171,7 +171,9 @@ export class Stream implements AsyncIterable { toReadableStream(): ReadableStream { const self = this; let iter: AsyncIterator; - const encoder = new TextEncoder(); + const encoder: { + encode(str: string): Uint8Array; + } = new (globalThis as any).TextEncoder(); return makeReadableStream({ async start() { @@ -236,7 +238,7 @@ async function* iterSSEChunks(iterator: AsyncIterableIterator): AsyncGene const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) - : typeof chunk === 'string' ? new TextEncoder().encode(chunk) + : typeof chunk === 'string' ? new (globalThis as any).TextEncoder().encode(chunk) : chunk; let newData = new Uint8Array(data.length + binaryChunk.length); diff --git a/tsconfig.dist-src.json b/tsconfig.dist-src.json index 0f6aba91..c550e299 100644 --- a/tsconfig.dist-src.json +++ b/tsconfig.dist-src.json @@ -4,8 +4,8 @@ // via declaration maps "include": ["index.ts"], "compilerOptions": { - "target": "es2015", - "lib": ["DOM", "DOM.Iterable"], + "target": "ES2015", + "lib": ["DOM", "DOM.Iterable", "ES2018"], "moduleResolution": "node" } } From 995346674b028817ac1c6dec035b024dfd33ec25 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:40:49 -0500 Subject: [PATCH 017/105] chore(internal): reorder model constants chore: unknown commit message --- .stats.yml | 2 +- src/resources/messages/messages.ts | 4 ++-- tests/api-resources/beta/messages/batches.test.ts | 4 ++-- tests/api-resources/beta/messages/messages.test.ts | 8 ++++---- tests/api-resources/completions.test.ts | 4 ++-- tests/api-resources/messages/batches.test.ts | 4 ++-- tests/api-resources/messages/messages.test.ts | 8 ++++---- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.stats.yml b/.stats.yml index 64f8716d..3ea9b07f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-f5276eeef7512112e802c85530c51e0a971ee521eebe3a0db309621587b4973d.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-946022163d75ddc00f49883756b189412098aa07b600ee0890655eebcb3c440c.yml diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index b10f9725..0af67c54 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -401,7 +401,6 @@ export interface Metadata { * details and options. */ export type Model = - | (string & {}) | 'claude-3-5-haiku-latest' | 'claude-3-5-haiku-20241022' | 'claude-3-5-sonnet-latest' @@ -412,7 +411,8 @@ export type Model = | 'claude-3-sonnet-20240229' | 'claude-3-haiku-20240307' | 'claude-2.1' - | 'claude-2.0'; + | 'claude-2.0' + | (string & {}); type DeprecatedModelsType = { [K in Model]?: string; diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index 769773e8..61c0bb7d 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -16,7 +16,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-sonnet-20241022', + model: 'claude-3-5-haiku-latest', }, }, ], @@ -38,7 +38,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-sonnet-20241022', + model: 'claude-3-5-haiku-latest', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, diff --git a/tests/api-resources/beta/messages/messages.test.ts b/tests/api-resources/beta/messages/messages.test.ts index d03de98c..d9e55ef2 100644 --- a/tests/api-resources/beta/messages/messages.test.ts +++ b/tests/api-resources/beta/messages/messages.test.ts @@ -12,7 +12,7 @@ describe('resource messages', () => { const responsePromise = client.beta.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-sonnet-20241022', + model: 'claude-3-5-haiku-latest', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -27,7 +27,7 @@ describe('resource messages', () => { const response = await client.beta.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-sonnet-20241022', + model: 'claude-3-5-haiku-latest', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, @@ -74,7 +74,7 @@ describe('resource messages', () => { test('countTokens: only required params', async () => { const responsePromise = client.beta.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], - model: 'string', + model: 'claude-3-5-haiku-latest', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -88,7 +88,7 @@ describe('resource messages', () => { test('countTokens: required and optional params', async () => { const response = await client.beta.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], - model: 'string', + model: 'claude-3-5-haiku-latest', system: [ { text: "Today's date is 2024-06-01.", diff --git a/tests/api-resources/completions.test.ts b/tests/api-resources/completions.test.ts index bef08dd6..272bd8c7 100644 --- a/tests/api-resources/completions.test.ts +++ b/tests/api-resources/completions.test.ts @@ -11,7 +11,7 @@ describe('resource completions', () => { test('create: only required params', async () => { const responsePromise = client.completions.create({ max_tokens_to_sample: 256, - model: 'string', + model: 'claude-3-5-haiku-latest', prompt: '\n\nHuman: Hello, world!\n\nAssistant:', }); const rawResponse = await responsePromise.asResponse(); @@ -26,7 +26,7 @@ describe('resource completions', () => { test('create: required and optional params', async () => { const response = await client.completions.create({ max_tokens_to_sample: 256, - model: 'string', + model: 'claude-3-5-haiku-latest', prompt: '\n\nHuman: Hello, world!\n\nAssistant:', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index 1388ef36..d77e510a 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -16,7 +16,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-sonnet-20241022', + model: 'claude-3-5-haiku-latest', }, }, ], @@ -38,7 +38,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-sonnet-20241022', + model: 'claude-3-5-haiku-latest', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], system: [ diff --git a/tests/api-resources/messages/messages.test.ts b/tests/api-resources/messages/messages.test.ts index 08829c3f..e7d2a4c2 100644 --- a/tests/api-resources/messages/messages.test.ts +++ b/tests/api-resources/messages/messages.test.ts @@ -12,7 +12,7 @@ describe('resource messages', () => { const responsePromise = client.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-sonnet-20241022', + model: 'claude-3-5-haiku-latest', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -27,7 +27,7 @@ describe('resource messages', () => { const response = await client.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-sonnet-20241022', + model: 'claude-3-5-haiku-latest', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, @@ -72,7 +72,7 @@ describe('resource messages', () => { test('countTokens: only required params', async () => { const responsePromise = client.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], - model: 'string', + model: 'claude-3-5-haiku-latest', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -86,7 +86,7 @@ describe('resource messages', () => { test('countTokens: required and optional params', async () => { const response = await client.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], - model: 'string', + model: 'claude-3-5-haiku-latest', system: [ { text: "Today's date is 2024-06-01.", From b8251fdac7e8e5df619abf0d17125de7601a364e Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 29 Jan 2025 05:51:41 -0500 Subject: [PATCH 018/105] chore(internal): add explicit export `type` modifier chore: unknown commit message --- src/uploads.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uploads.ts b/src/uploads.ts index e4c4b2db..77b65766 100644 --- a/src/uploads.ts +++ b/src/uploads.ts @@ -1 +1 @@ -export { Uploadable, toFile } from './internal/uploads'; +export { type Uploadable, toFile } from './internal/uploads'; From 25a7fdb2b5c8562fe996fe0ee7706db440b2f627 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 30 Jan 2025 10:54:29 -0500 Subject: [PATCH 019/105] chore(client): handle expo fetch abort errors chore: unknown commit message --- src/client.ts | 4 ++-- src/internal/decoders/jsonl.ts | 8 ++++++++ src/internal/errors.ts | 8 ++++++-- src/streaming.ts | 13 +++++++++++-- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/client.ts b/src/client.ts index c87a0680..288f7b9a 100644 --- a/src/client.ts +++ b/src/client.ts @@ -5,7 +5,7 @@ import type { HTTPMethod, PromiseOrValue, MergedRequestInit } from './internal/t import { uuid4 } from './internal/utils/uuid'; import { validatePositiveInteger, isAbsoluteURL } from './internal/utils/values'; import { sleep } from './internal/utils/sleep'; -import { castToError } from './internal/errors'; +import { castToError, isAbortError } from './internal/errors'; import type { APIResponseProps } from './internal/parse'; import { getPlatformHeaders } from './internal/detect-platform'; import * as Shims from './internal/shims'; @@ -504,7 +504,7 @@ export class BaseAnthropic { if (retriesRemaining) { return this.retryRequest(options, retriesRemaining); } - if (response.name === 'AbortError') { + if (isAbortError(response)) { throw new Errors.APIConnectionTimeoutError(); } throw new Errors.APIConnectionError({ cause: response }); diff --git a/src/internal/decoders/jsonl.ts b/src/internal/decoders/jsonl.ts index 54a49bf2..fb4e4699 100644 --- a/src/internal/decoders/jsonl.ts +++ b/src/internal/decoders/jsonl.ts @@ -32,6 +32,14 @@ export class JSONLDecoder { static fromResponse(response: Response, controller: AbortController): JSONLDecoder { if (!response.body) { controller.abort(); + if ( + typeof (globalThis as any).navigator !== 'undefined' && + (globalThis as any).navigator.product === 'ReactNative' + ) { + throw new AnthropicError( + `The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`, + ); + } throw new AnthropicError(`Attempted to iterate over a response with no body`); } diff --git a/src/internal/errors.ts b/src/internal/errors.ts index 08321f31..2e625bda 100644 --- a/src/internal/errors.ts +++ b/src/internal/errors.ts @@ -2,8 +2,12 @@ export function isAbortError(err: unknown) { return ( - (err instanceof Error && err.name === 'AbortError') || - (typeof err === 'object' && err && 'name' in err && (err as any).name === 'AbortError') + typeof err === 'object' && + err !== null && + // Spec-compliant fetch implementations + (('name' in err && (err as any).name === 'AbortError') || + // Expo fetch + ('message' in err && String((err as any).message).includes('FetchRequestCanceledException'))) ); } diff --git a/src/streaming.ts b/src/streaming.ts index e2894d05..92a5eff2 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -3,6 +3,7 @@ import { type ReadableStream } from './internal/shim-types'; import { makeReadableStream } from './internal/shims'; import { LineDecoder } from './internal/decoders/line'; import { ReadableStreamToAsyncIterable } from './internal/shims'; +import { isAbortError } from './internal/errors'; import { APIError } from './error'; @@ -73,7 +74,7 @@ export class Stream implements AsyncIterable { done = true; } catch (e) { // If the user calls `stream.controller.abort()`, we should exit without throwing. - if (e instanceof Error && e.name === 'AbortError') return; + if (isAbortError(e)) return; throw e; } finally { // If the user `break`s, abort the ongoing request. @@ -120,7 +121,7 @@ export class Stream implements AsyncIterable { done = true; } catch (e) { // If the user calls `stream.controller.abort()`, we should exit without throwing. - if (e instanceof Error && e.name === 'AbortError') return; + if (isAbortError(e)) return; throw e; } finally { // If the user `break`s, abort the ongoing request. @@ -204,6 +205,14 @@ export async function* _iterSSEMessages( ): AsyncGenerator { if (!response.body) { controller.abort(); + if ( + typeof (globalThis as any).navigator !== 'undefined' && + (globalThis as any).navigator.product === 'ReactNative' + ) { + throw new AnthropicError( + `The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`, + ); + } throw new AnthropicError(`Attempted to iterate over a response with no body`); } From fe71a7eaf98be1f7a3c984be0a1d5f50d016e93d Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:52:17 -0500 Subject: [PATCH 020/105] chore(api): update openapi spec url chore: unknown commit message --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 3ea9b07f..b1ba6c6a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-946022163d75ddc00f49883756b189412098aa07b600ee0890655eebcb3c440c.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-bda1c6bb3a8f16d4b0a936aa3a7b1618f23d38570547e7ef047a9c95265e6613.yml From bacfc3050e72df7a679fd8663ffbe0b3d959d111 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 30 Jan 2025 13:26:18 -0500 Subject: [PATCH 021/105] chore(client): detect node and deno timeout errors chore: unknown commit message --- src/client.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/client.ts b/src/client.ts index 288f7b9a..3629aca1 100644 --- a/src/client.ts +++ b/src/client.ts @@ -507,6 +507,13 @@ export class BaseAnthropic { if (isAbortError(response)) { throw new Errors.APIConnectionTimeoutError(); } + // detect native connection timeout errors + // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)" + // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)" + // others do not provide enough information to distinguish timeouts from other connection errors + if (/timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''))) { + throw new Errors.APIConnectionTimeoutError(); + } throw new Errors.APIConnectionError({ cause: response }); } From e1d95134ec08a50106cd185efbdcebb8417059cf Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 4 Feb 2025 12:30:37 -0500 Subject: [PATCH 022/105] chore(internal): remove unused `isRequestOptions()` function chore: unknown commit message --- src/internal/request-options.ts | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/src/internal/request-options.ts b/src/internal/request-options.ts index 8a862700..d46c3b33 100644 --- a/src/internal/request-options.ts +++ b/src/internal/request-options.ts @@ -3,9 +3,8 @@ import { NullableHeaders } from './headers'; import type { BodyInit } from './builtin-types'; -import { isEmptyObj, hasOwn } from './utils/values'; import { Stream } from '../streaming'; -import type { HTTPMethod, KeysEnum, MergedRequestInit } from './types'; +import type { HTTPMethod, MergedRequestInit } from './types'; import { type HeadersLike } from './headers'; export type FinalRequestOptions = RequestOptions & { method: HTTPMethod; path: string }; @@ -27,36 +26,6 @@ export type RequestOptions = { __streamClass?: typeof Stream; }; -// This is required so that we can determine if a given object matches the RequestOptions -// type at runtime. While this requires duplication, it is enforced by the TypeScript -// compiler such that any missing / extraneous keys will cause an error. -const requestOptionsKeys: KeysEnum = { - method: true, - path: true, - query: true, - body: true, - headers: true, - - maxRetries: true, - stream: true, - timeout: true, - fetchOptions: true, - signal: true, - idempotencyKey: true, - - __binaryResponse: true, - __streamClass: true, -}; - -export const isRequestOptions = (obj: unknown): obj is RequestOptions => { - return ( - typeof obj === 'object' && - obj !== null && - !isEmptyObj(obj) && - Object.keys(obj).every((k) => hasOwn(requestOptionsKeys, k)) - ); -}; - export type EncodedContent = { bodyHeaders: HeadersLike; body: BodyInit }; export type RequestEncoder = (request: { headers: NullableHeaders; body: unknown }) => EncodedContent; From 78f7b2cc9afff67789d4a068579da8f2e6c8cac7 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:36:03 -0500 Subject: [PATCH 023/105] feat(client): send `X-Stainless-Timeout` header chore: unknown commit message --- src/client.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index 3629aca1..f726a48d 100644 --- a/src/client.ts +++ b/src/client.ts @@ -676,11 +676,12 @@ export class BaseAnthropic { options: FinalRequestOptions, { retryCount = 0 }: { retryCount?: number } = {}, ): { req: FinalizedRequestInit; url: string; timeout: number } { + options = { ...options }; const { method, path, query } = options; const url = this.buildURL(path!, query as Record); if ('timeout' in options) validatePositiveInteger('timeout', options.timeout); - const timeout = options.timeout ?? this.timeout; + options.timeout = options.timeout ?? this.timeout; const { bodyHeaders, body } = this.buildBody({ options }); const reqHeaders = this.buildHeaders({ options, method, bodyHeaders, retryCount }); @@ -695,7 +696,7 @@ export class BaseAnthropic { ...((options.fetchOptions as any) ?? {}), }; - return { req, url, timeout }; + return { req, url, timeout: options.timeout }; } private buildHeaders({ @@ -721,6 +722,7 @@ export class BaseAnthropic { Accept: 'application/json', 'User-Agent': this.getUserAgent(), 'X-Stainless-Retry-Count': String(retryCount), + ...(options.timeout ? { 'X-Stainless-Timeout': String(options.timeout) } : {}), ...getPlatformHeaders(), ...(this._options.dangerouslyAllowBrowser ? { 'anthropic-dangerous-direct-browser-access': 'true' } From 943af34ea631fd0ce2f077bf4b86a7dacea1754c Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Wed, 5 Feb 2025 16:14:20 -0500 Subject: [PATCH 024/105] fix(client)!: uri encode path parameters chore: unknown commit message --- src/internal/utils/path.ts | 65 +++++ src/resources/beta/messages/batches.ts | 7 +- src/resources/beta/models.ts | 3 +- src/resources/messages/batches.ts | 8 +- src/resources/models.ts | 3 +- tests/path.test.ts | 318 +++++++++++++++++++++++++ 6 files changed, 395 insertions(+), 9 deletions(-) create mode 100644 src/internal/utils/path.ts create mode 100644 tests/path.test.ts diff --git a/src/internal/utils/path.ts b/src/internal/utils/path.ts new file mode 100644 index 00000000..cb12f8a2 --- /dev/null +++ b/src/internal/utils/path.ts @@ -0,0 +1,65 @@ +import { AnthropicError } from '../../error'; + +/** + * Percent-encode everything that isn't safe to have in a path without encoding safe chars. + * + * Taken from https://datatracker.ietf.org/doc/html/rfc3986#section-3.3: + * > unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * > sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "=" + * > pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + */ +export function encodeURIPath(str: string) { + return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent); +} + +export const createPathTagFunction = (pathEncoder = encodeURIPath) => + function path(statics: readonly string[], ...params: readonly unknown[]): string { + // If there are no params, no processing is needed. + if (statics.length === 1) return statics[0]!; + + let postPath = false; + const path = statics.reduce((previousValue, currentValue, index) => { + if (/[?#]/.test(currentValue)) { + postPath = true; + } + return ( + previousValue + + currentValue + + (index === params.length ? '' : (postPath ? encodeURIComponent : pathEncoder)(String(params[index]))) + ); + }, ''); + + const pathOnly = path.split(/[?#]/, 1)[0]!; + const invalidSegments = []; + const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi; + let match; + + // Find all invalid segments + while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) { + invalidSegments.push({ + start: match.index, + length: match[0].length, + }); + } + + if (invalidSegments.length > 0) { + let lastEnd = 0; + const underline = invalidSegments.reduce((acc, segment) => { + const spaces = ' '.repeat(segment.start - lastEnd); + const arrows = '^'.repeat(segment.length); + lastEnd = segment.start + segment.length; + return acc + spaces + arrows; + }, ''); + + throw new AnthropicError( + `Path parameters result in path with invalid segments:\n${path}\n${underline}`, + ); + } + + return path; + }; + +/** + * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced. + */ +export const path = createPathTagFunction(encodeURIPath); diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index f6794544..0a288202 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -9,6 +9,7 @@ import { buildHeaders } from '../../../internal/headers'; import { RequestOptions } from '../../../internal/request-options'; import { JSONLDecoder } from '../../../internal/decoders/jsonl'; import { AnthropicError } from '../../../error'; +import { path } from '../../../internal/utils/path'; export class Batches extends APIResource { /** @@ -41,7 +42,7 @@ export class Batches extends APIResource { options?: RequestOptions, ): APIPromise { const { betas } = params ?? {}; - return this._client.get(`/v1/messages/batches/${messageBatchID}?beta=true`, { + return this._client.get(path`/v1/messages/batches/${messageBatchID}?beta=true`, { ...options, headers: buildHeaders([ { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString() }, @@ -81,7 +82,7 @@ export class Batches extends APIResource { options?: RequestOptions, ): APIPromise { const { betas } = params ?? {}; - return this._client.delete(`/v1/messages/batches/${messageBatchID}?beta=true`, { + return this._client.delete(path`/v1/messages/batches/${messageBatchID}?beta=true`, { ...options, headers: buildHeaders([ { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString() }, @@ -107,7 +108,7 @@ export class Batches extends APIResource { options?: RequestOptions, ): APIPromise { const { betas } = params ?? {}; - return this._client.post(`/v1/messages/batches/${messageBatchID}/cancel?beta=true`, { + return this._client.post(path`/v1/messages/batches/${messageBatchID}/cancel?beta=true`, { ...options, headers: buildHeaders([ { 'anthropic-beta': [...(betas ?? []), 'message-batches-2024-09-24'].toString() }, diff --git a/src/resources/beta/models.ts b/src/resources/beta/models.ts index 4f8940f5..c929e517 100644 --- a/src/resources/beta/models.ts +++ b/src/resources/beta/models.ts @@ -4,6 +4,7 @@ import { APIResource } from '../../resource'; import { APIPromise } from '../../api-promise'; import { Page, type PageParams, PagePromise } from '../../pagination'; import { RequestOptions } from '../../internal/request-options'; +import { path } from '../../internal/utils/path'; export class Models extends APIResource { /** @@ -13,7 +14,7 @@ export class Models extends APIResource { * model or resolve a model alias to a model ID. */ retrieve(modelID: string, options?: RequestOptions): APIPromise { - return this._client.get(`/v1/models/${modelID}?beta=true`, options); + return this._client.get(path`/v1/models/${modelID}?beta=true`, options); } /** diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index a9f9fb29..5c17dd87 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -9,6 +9,7 @@ import { buildHeaders } from '../../internal/headers'; import { RequestOptions } from '../../internal/request-options'; import { JSONLDecoder } from '../../internal/decoders/jsonl'; import { AnthropicError } from '../../error'; +import { path } from '../../internal/utils/path'; export class Batches extends APIResource { /** @@ -28,7 +29,7 @@ export class Batches extends APIResource { * `results_url` field in the response. */ retrieve(messageBatchID: string, options?: RequestOptions): APIPromise { - return this._client.get(`/v1/messages/batches/${messageBatchID}`, options); + return this._client.get(path`/v1/messages/batches/${messageBatchID}`, options); } /** @@ -49,7 +50,7 @@ export class Batches extends APIResource { * like to delete an in-progress batch, you must first cancel it. */ delete(messageBatchID: string, options?: RequestOptions): APIPromise { - return this._client.delete(`/v1/messages/batches/${messageBatchID}`, options); + return this._client.delete(path`/v1/messages/batches/${messageBatchID}`, options); } /** @@ -64,7 +65,7 @@ export class Batches extends APIResource { * non-interruptible. */ cancel(messageBatchID: string, options?: RequestOptions): APIPromise { - return this._client.post(`/v1/messages/batches/${messageBatchID}/cancel`, options); + return this._client.post(path`/v1/messages/batches/${messageBatchID}/cancel`, options); } /** @@ -89,7 +90,6 @@ export class Batches extends APIResource { .get(batch.results_url, { ...options, headers: buildHeaders([{ Accept: 'application/x-jsonl' }, options?.headers]), - __binaryResponse: true, }) ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)); diff --git a/src/resources/models.ts b/src/resources/models.ts index da863b66..6153813b 100644 --- a/src/resources/models.ts +++ b/src/resources/models.ts @@ -4,6 +4,7 @@ import { APIResource } from '../resource'; import { APIPromise } from '../api-promise'; import { Page, type PageParams, PagePromise } from '../pagination'; import { RequestOptions } from '../internal/request-options'; +import { path } from '../internal/utils/path'; export class Models extends APIResource { /** @@ -13,7 +14,7 @@ export class Models extends APIResource { * model or resolve a model alias to a model ID. */ retrieve(modelID: string, options?: RequestOptions): APIPromise { - return this._client.get(`/v1/models/${modelID}`, options); + return this._client.get(path`/v1/models/${modelID}`, options); } /** diff --git a/tests/path.test.ts b/tests/path.test.ts new file mode 100644 index 00000000..15cbcbdb --- /dev/null +++ b/tests/path.test.ts @@ -0,0 +1,318 @@ +import { createPathTagFunction, encodeURIPath } from '@anthropic-ai/sdk/internal/utils/path'; +import { inspect } from 'node:util'; + +describe('path template tag function', () => { + test('validates input', () => { + const testParams = ['', '.', '..', 'x', '%2e', '%2E', '%2e%2e', '%2E%2e', '%2e%2E', '%2E%2E']; + const testCases = [ + ['/path_params/', '/a'], + ['/path_params/', '/'], + ['/path_params/', ''], + ['', '/a'], + ['', '/'], + ['', ''], + ['a'], + [''], + ['/path_params/', ':initiate'], + ['/path_params/', '.json'], + ['/path_params/', '?beta=true'], + ['/path_params/', '.?beta=true'], + ['/path_params/', '/', '/download'], + ['/path_params/', '-', '/download'], + ['/path_params/', '', '/download'], + ['/path_params/', '.', '/download'], + ['/path_params/', '..', '/download'], + ['/plain/path'], + ]; + + function paramPermutations(len: number): string[][] { + if (len === 0) return []; + if (len === 1) return testParams.map((e) => [e]); + const rest = paramPermutations(len - 1); + return testParams.flatMap((e) => rest.map((r) => [e, ...r])); + } + + // we need to test how %2E is handled so we use a custom encoder that does no escaping + const rawPath = createPathTagFunction((s) => s); + + const results: { + [pathParts: string]: { + [params: string]: { valid: boolean; result?: string; error?: string }; + }; + } = {}; + + for (const pathParts of testCases) { + const pathResults: Record = {}; + results[JSON.stringify(pathParts)] = pathResults; + for (const params of paramPermutations(pathParts.length - 1)) { + const stringRaw = String.raw({ raw: pathParts }, ...params); + const plainString = String.raw( + { raw: pathParts.map((e) => e.replace(/\./g, 'x')) }, + ...params.map((e) => 'X'.repeat(e.length)), + ); + const normalizedStringRaw = new URL(stringRaw, 'https://example.com').href; + const normalizedPlainString = new URL(plainString, 'https://example.com').href; + const pathResultsKey = JSON.stringify(params); + try { + const result = rawPath(pathParts, ...params); + expect(result).toBe(stringRaw); + // there are no special segments, so the length of the normalized path is + // equal to the length of the normalized plain path. + expect(normalizedStringRaw.length).toBe(normalizedPlainString.length); + pathResults[pathResultsKey] = { + valid: true, + result, + }; + } catch (e) { + const error = String(e); + expect(error).toMatch(/Path parameters result in path with invalid segment/); + // there are special segments, so the length of the normalized path is + // different than the length of the normalized plain path. + expect(normalizedStringRaw.length).not.toBe(normalizedPlainString.length); + pathResults[pathResultsKey] = { + valid: false, + error, + }; + } + } + } + + expect(results).toMatchObject({ + '["/path_params/","/a"]': { + '["x"]': { valid: true, result: '/path_params/x/a' }, + '[""]': { valid: true, result: '/path_params//a' }, + '["%2E%2e"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2E%2e/a\n' + + ' ^^^^^^', + }, + '["%2E"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2E/a\n' + + ' ^^^', + }, + }, + '["/path_params/","/"]': { + '["x"]': { valid: true, result: '/path_params/x/' }, + '[""]': { valid: true, result: '/path_params//' }, + '["%2e%2E"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2e%2E/\n' + + ' ^^^^^^', + }, + '["%2e"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2e/\n' + + ' ^^^', + }, + }, + '["/path_params/",""]': { + '[""]': { valid: true, result: '/path_params/' }, + '["x"]': { valid: true, result: '/path_params/x' }, + '["%2E"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2E\n' + + ' ^^^', + }, + '["%2E%2e"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2E%2e\n' + + ' ^^^^^^', + }, + }, + '["","/a"]': { + '[""]': { valid: true, result: '/a' }, + '["x"]': { valid: true, result: 'x/a' }, + '["%2E"]': { + valid: false, + error: 'Error: Path parameters result in path with invalid segments:\n%2E/a\n^^^', + }, + '["%2e%2E"]': { + valid: false, + error: 'Error: Path parameters result in path with invalid segments:\n' + '%2e%2E/a\n' + '^^^^^^', + }, + }, + '["","/"]': { + '["x"]': { valid: true, result: 'x/' }, + '[""]': { valid: true, result: '/' }, + '["%2E%2e"]': { + valid: false, + error: 'Error: Path parameters result in path with invalid segments:\n' + '%2E%2e/\n' + '^^^^^^', + }, + '["."]': { + valid: false, + error: 'Error: Path parameters result in path with invalid segments:\n./\n^', + }, + }, + '["",""]': { + '[""]': { valid: true, result: '' }, + '["x"]': { valid: true, result: 'x' }, + '[".."]': { + valid: false, + error: 'Error: Path parameters result in path with invalid segments:\n..\n^^', + }, + '["."]': { + valid: false, + error: 'Error: Path parameters result in path with invalid segments:\n.\n^', + }, + }, + '["a"]': {}, + '[""]': {}, + '["/path_params/",":initiate"]': { + '[""]': { valid: true, result: '/path_params/:initiate' }, + '["."]': { valid: true, result: '/path_params/.:initiate' }, + }, + '["/path_params/",".json"]': { + '["x"]': { valid: true, result: '/path_params/x.json' }, + '["."]': { valid: true, result: '/path_params/..json' }, + }, + '["/path_params/","?beta=true"]': { + '["x"]': { valid: true, result: '/path_params/x?beta=true' }, + '[""]': { valid: true, result: '/path_params/?beta=true' }, + '["%2E%2E"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2E%2E?beta=true\n' + + ' ^^^^^^', + }, + '["%2e%2E"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2e%2E?beta=true\n' + + ' ^^^^^^', + }, + }, + '["/path_params/",".?beta=true"]': { + '[".."]': { valid: true, result: '/path_params/...?beta=true' }, + '["x"]': { valid: true, result: '/path_params/x.?beta=true' }, + '[""]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/.?beta=true\n' + + ' ^', + }, + '["%2e"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2e.?beta=true\n' + + ' ^^^^', + }, + }, + '["/path_params/","/","/download"]': { + '["",""]': { valid: true, result: '/path_params///download' }, + '["","x"]': { valid: true, result: '/path_params//x/download' }, + '[".","%2e"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/./%2e/download\n' + + ' ^ ^^^', + }, + '["%2E%2e","%2e"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2E%2e/%2e/download\n' + + ' ^^^^^^ ^^^', + }, + }, + '["/path_params/","-","/download"]': { + '["","%2e"]': { valid: true, result: '/path_params/-%2e/download' }, + '["%2E",".."]': { valid: true, result: '/path_params/%2E-../download' }, + }, + '["/path_params/","","/download"]': { + '["%2E%2e","%2e%2E"]': { valid: true, result: '/path_params/%2E%2e%2e%2E/download' }, + '["%2E",".."]': { valid: true, result: '/path_params/%2E../download' }, + '["","%2E"]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2E/download\n' + + ' ^^^', + }, + '["%2E","."]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/%2E./download\n' + + ' ^^^^', + }, + }, + '["/path_params/",".","/download"]': { + '["%2e%2e",""]': { valid: true, result: '/path_params/%2e%2e./download' }, + '["","%2e%2e"]': { valid: true, result: '/path_params/.%2e%2e/download' }, + '["",""]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/./download\n' + + ' ^', + }, + '["","."]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/../download\n' + + ' ^^', + }, + }, + '["/path_params/","..","/download"]': { + '["","%2E"]': { valid: true, result: '/path_params/..%2E/download' }, + '["","x"]': { valid: true, result: '/path_params/..x/download' }, + '["",""]': { + valid: false, + error: + 'Error: Path parameters result in path with invalid segments:\n' + + '/path_params/../download\n' + + ' ^^', + }, + }, + }); + }); +}); + +describe('encodeURIPath', () => { + const testCases: string[] = [ + '', + // Every ASCII character + ...Array.from({ length: 0x7f }, (_, i) => String.fromCharCode(i)), + // Unicode BMP codepoint + 'å', + // Unicode supplementary codepoint + '😃', + ]; + + for (const param of testCases) { + test('properly encodes ' + inspect(param), () => { + const encoded = encodeURIPath(param); + const naiveEncoded = encodeURIComponent(param); + // we should never encode more characters than encodeURIComponent + expect(naiveEncoded.length).toBeGreaterThanOrEqual(encoded.length); + expect(decodeURIComponent(encoded)).toBe(param); + }); + } + + test("leaves ':' intact", () => { + expect(encodeURIPath(':')).toBe(':'); + }); + + test("leaves '@' intact", () => { + expect(encodeURIPath('@')).toBe('@'); + }); +}); From 845cd5d471e9e761510bca5c0dbfe43e268ffde1 Mon Sep 17 00:00:00 2001 From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com> Date: Thu, 6 Feb 2025 09:46:41 -0500 Subject: [PATCH 025/105] feat(pagination): avoid fetching when has_more: false chore: unknown commit message --- src/pagination.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pagination.ts b/src/pagination.ts index 107a8fc7..20dff07a 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -161,6 +161,14 @@ export class Page extends AbstractPage implements PageResponse return this.data ?? []; } + override hasNextPage() { + if (this.has_more === false) { + return false; + } + + return super.hasNextPage(); + } + nextPageRequestOptions(): PageRequestOptions | null { if ((this.options.query as Record)?.['before_id']) { // in reverse From 3b6caa7029f12a2836257b3d9950d13882e7f53f Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 10 Feb 2025 20:09:27 +0000 Subject: [PATCH 026/105] fix: correctly decode multi-byte characters over multiple chunks --- src/internal/decoders/line.ts | 107 ++++++++++++++++++++++------------ src/streaming.ts | 6 +- tests/streaming.test.ts | 53 ++++++++++++++++- 3 files changed, 126 insertions(+), 40 deletions(-) diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts index c786db78..1156fb78 100644 --- a/src/internal/decoders/line.ts +++ b/src/internal/decoders/line.ts @@ -13,8 +13,8 @@ export class LineDecoder { static NEWLINE_CHARS = new Set(['\n', '\r']); static NEWLINE_REGEXP = /\r\n|[\n\r]/g; - buffer: string[]; - trailingCR: boolean; + buffer: Uint8Array; + #carriageReturnIndex: number | null; textDecoder: | undefined | { @@ -22,47 +22,53 @@ export class LineDecoder { }; constructor() { - this.buffer = []; - this.trailingCR = false; + this.buffer = new Uint8Array(); + this.#carriageReturnIndex = null; } decode(chunk: Bytes): string[] { - let text = this.decodeText(chunk); - - if (this.trailingCR) { - text = '\r' + text; - this.trailingCR = false; - } - if (text.endsWith('\r')) { - this.trailingCR = true; - text = text.slice(0, -1); - } - - if (!text) { + if (chunk == null) { return []; } - const trailingNewline = LineDecoder.NEWLINE_CHARS.has(text[text.length - 1] || ''); - let lines = text.split(LineDecoder.NEWLINE_REGEXP); + const binaryChunk = + chunk instanceof ArrayBuffer ? new Uint8Array(chunk) + : typeof chunk === 'string' ? new TextEncoder().encode(chunk) + : chunk; + + let newData = new Uint8Array(this.buffer.length + binaryChunk.length); + newData.set(this.buffer); + newData.set(binaryChunk, this.buffer.length); + this.buffer = newData; + + const lines: string[] = []; + let patternIndex; + while ((patternIndex = findNewlineIndex(this.buffer, this.#carriageReturnIndex)) != null) { + if (patternIndex.carriage && this.#carriageReturnIndex == null) { + // skip until we either get a corresponding `\n`, a new `\r` or nothing + this.#carriageReturnIndex = patternIndex.index; + continue; + } - // if there is a trailing new line then the last entry will be an empty - // string which we don't care about - if (trailingNewline) { - lines.pop(); - } + // we got double \r or \rtext\n + if ( + this.#carriageReturnIndex != null && + (patternIndex.index !== this.#carriageReturnIndex + 1 || patternIndex.carriage) + ) { + lines.push(this.decodeText(this.buffer.slice(0, this.#carriageReturnIndex - 1))); + this.buffer = this.buffer.slice(this.#carriageReturnIndex); + this.#carriageReturnIndex = null; + continue; + } - if (lines.length === 1 && !trailingNewline) { - this.buffer.push(lines[0]!); - return []; - } + const endIndex = + this.#carriageReturnIndex !== null ? patternIndex.preceding - 1 : patternIndex.preceding; - if (this.buffer.length > 0) { - lines = [this.buffer.join('') + lines[0], ...lines.slice(1)]; - this.buffer = []; - } + const line = this.decodeText(this.buffer.slice(0, endIndex)); + lines.push(line); - if (!trailingNewline) { - this.buffer = [lines.pop() || '']; + this.buffer = this.buffer.slice(patternIndex.index); + this.#carriageReturnIndex = null; } return lines; @@ -106,13 +112,38 @@ export class LineDecoder { } flush(): string[] { - if (!this.buffer.length && !this.trailingCR) { + if (!this.buffer.length) { return []; } + return this.decode('\n'); + } +} - const lines = [this.buffer.join('')]; - this.buffer = []; - this.trailingCR = false; - return lines; +/** + * This function searches the buffer for the end patterns, (\r or \n) + * and returns an object with the index preceding the matched newline and the + * index after the newline char. `null` is returned if no new line is found. + * + * ```ts + * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 } + * ``` + */ +function findNewlineIndex( + buffer: Uint8Array, + startIndex: number | null, +): { preceding: number; index: number; carriage: boolean } | null { + const newline = 0x0a; // \n + const carriage = 0x0d; // \r + + for (let i = startIndex ?? 0; i < buffer.length; i++) { + if (buffer[i] === newline) { + return { preceding: i, index: i + 1, carriage: false }; + } + + if (buffer[i] === carriage) { + return { preceding: i, index: i + 1, carriage: true }; + } } + + return null; } diff --git a/src/streaming.ts b/src/streaming.ts index 92a5eff2..8fed4a9e 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -354,13 +354,17 @@ class SSEDecoder { } /** This is an internal helper function that's just used for testing */ -export function _decodeChunks(chunks: string[]): string[] { +export function _decodeChunks(chunks: string[], { flush }: { flush: boolean } = { flush: false }): string[] { const decoder = new LineDecoder(); const lines: string[] = []; for (const chunk of chunks) { lines.push(...decoder.decode(chunk)); } + if (flush) { + lines.push(...decoder.flush()); + } + return lines; } diff --git a/tests/streaming.test.ts b/tests/streaming.test.ts index 90967c32..6a05c446 100644 --- a/tests/streaming.test.ts +++ b/tests/streaming.test.ts @@ -2,6 +2,7 @@ import { PassThrough } from 'stream'; import assert from 'assert'; import { Stream, _iterSSEMessages, _decodeChunks as decodeChunks } from '@anthropic-ai/sdk/streaming'; import { APIConnectionError } from '@anthropic-ai/sdk/error'; +import { LineDecoder } from '@anthropic-ai/sdk/internal/decoders/line'; describe('line decoder', () => { test('basic', () => { @@ -10,8 +11,8 @@ describe('line decoder', () => { }); test('basic with \\r', () => { - // baz is not included because the line hasn't ended yet expect(decodeChunks(['foo', ' bar\r\nbaz'])).toEqual(['foo bar']); + expect(decodeChunks(['foo', ' bar\r\nbaz'], { flush: true })).toEqual(['foo bar', 'baz']); }); test('trailing new lines', () => { @@ -29,6 +30,56 @@ describe('line decoder', () => { test('escaped new lines with \\r', () => { expect(decodeChunks(['foo', ' bar\\r\\nbaz\n'])).toEqual(['foo bar\\r\\nbaz']); }); + + test('\\r & \\n split across multiple chunks', () => { + expect(decodeChunks(['foo\r', '\n', 'bar'], { flush: true })).toEqual(['foo', 'bar']); + }); + + test('single \\r', () => { + expect(decodeChunks(['foo\r', 'bar'], { flush: true })).toEqual(['foo', 'bar']); + }); + + test('double \\r', () => { + expect(decodeChunks(['foo\r', 'bar\r'], { flush: true })).toEqual(['foo', 'bar']); + expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + // implementation detail that we don't yield the single \r line until a new \r or \n is encountered + expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: false })).toEqual(['foo']); + }); + + test('double \\r then \\r\\n', () => { + expect(decodeChunks(['foo\r', '\r', '\r', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']); + expect(decodeChunks(['foo\n', '\n', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']); + }); + + test('double newline', () => { + expect(decodeChunks(['foo\n\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo', '\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo', '\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + }); + + test('multi-byte characters across chunks', () => { + const decoder = new LineDecoder(); + + // bytes taken from the string 'известни' and arbitrarily split + // so that some multi-byte characters span multiple chunks + expect(decoder.decode(new Uint8Array([0xd0]))).toHaveLength(0); + expect(decoder.decode(new Uint8Array([0xb8, 0xd0, 0xb7, 0xd0]))).toHaveLength(0); + expect( + decoder.decode(new Uint8Array([0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb8])), + ).toHaveLength(0); + + const decoded = decoder.decode(new Uint8Array([0xa])); + expect(decoded).toEqual(['известни']); + }); + + test('flushing trailing newlines', () => { + expect(decodeChunks(['foo\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + }); + + test('flushing empty buffer', () => { + expect(decodeChunks([], { flush: true })).toEqual([]); + }); }); describe('streaming decoding', () => { From 114166498a54e0b62cd9ea071fc736d714cefde6 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Thu, 13 Feb 2025 19:43:51 +0000 Subject: [PATCH 027/105] chore(internal): migrate to eslint v9 --- .eslintrc.js | 29 - eslint.config.mjs | 42 ++ package.json | 11 +- .../scripts/postprocess-dist-package-json.cjs | 2 +- .../scripts/postprocess-dist-package-json.cjs | 2 +- scripts/format | 2 +- scripts/lint | 2 +- src/client.ts | 18 - src/pagination.ts | 1 - yarn.lock | 680 +++++++----------- 10 files changed, 313 insertions(+), 476 deletions(-) delete mode 100644 .eslintrc.js create mode 100644 eslint.config.mjs diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index f1f2cdc3..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint', 'unused-imports', 'prettier'], - rules: { - 'no-unused-vars': 'off', - 'prettier/prettier': 'error', - 'unused-imports/no-unused-imports': 'error', - 'no-restricted-imports': [ - 'error', - { - patterns: [ - { - group: ['@anthropic-ai/sdk', '@anthropic-ai/sdk/*'], - message: 'Use a relative import, not a package import.', - }, - ], - }, - ], - }, - overrides: [ - { - files: ['tests/**', 'examples/**', 'packages/**'], - rules: { - 'no-restricted-imports': 'off', - }, - }, - ], - root: true, -}; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..ba676077 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,42 @@ +// @ts-check +import tseslint from 'typescript-eslint'; +import unusedImports from 'eslint-plugin-unused-imports'; +import prettier from 'eslint-plugin-prettier'; + +export default tseslint.config( + { + languageOptions: { + parser: tseslint.parser, + parserOptions: { sourceType: 'module' }, + }, + files: ['**/*.ts', '**/*.mts', '**/*.cts', '**/*.js', '**/*.mjs', '**/*.cjs'], + ignores: ['dist/**'], + plugins: { + '@typescript-eslint': tseslint.plugin, + 'unused-imports': unusedImports, + prettier, + }, + rules: { + 'no-unused-vars': 'off', + 'prettier/prettier': 'error', + 'unused-imports/no-unused-imports': 'error', + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + regex: '^@anthropic-ai/sdk(/.*)?', + message: 'Use a relative import, not a package import.', + }, + ], + }, + ], + }, + }, + { + files: ['tests/**', 'examples/**', 'packages/**'], + rules: { + 'no-restricted-imports': 'off', + }, + }, +); diff --git a/package.json b/package.json index 5504f094..3b55421c 100644 --- a/package.json +++ b/package.json @@ -30,11 +30,12 @@ "@swc/jest": "^0.2.29", "@types/jest": "^29.4.0", "@types/node": "^20.17.6", - "@typescript-eslint/eslint-plugin": "^6.7.0", - "@typescript-eslint/parser": "^6.0.0", - "eslint": "^8.49.0", - "eslint-plugin-prettier": "^5.0.1", - "eslint-plugin-unused-imports": "^3.0.0", + "typescript-eslint": "^8.24.0", + "@typescript-eslint/eslint-plugin": "^8.24.0", + "@typescript-eslint/parser": "^8.24.0", + "eslint": "^9.20.1", + "eslint-plugin-prettier": "^5.2.3", + "eslint-plugin-unused-imports": "^4.1.4", "iconv-lite": "^0.6.3", "jest": "^29.4.0", "prettier": "^3.0.0", diff --git a/packages/bedrock-sdk/scripts/postprocess-dist-package-json.cjs b/packages/bedrock-sdk/scripts/postprocess-dist-package-json.cjs index 12a41324..55d1cad2 100644 --- a/packages/bedrock-sdk/scripts/postprocess-dist-package-json.cjs +++ b/packages/bedrock-sdk/scripts/postprocess-dist-package-json.cjs @@ -8,4 +8,4 @@ for (const dep in pkgJson.dependencies) { } } -fs.writeFileSync('dist/package.json', JSON.stringify(pkgJson, null, 2)) +fs.writeFileSync('dist/package.json', JSON.stringify(pkgJson, null, 2)); diff --git a/packages/vertex-sdk/scripts/postprocess-dist-package-json.cjs b/packages/vertex-sdk/scripts/postprocess-dist-package-json.cjs index f8abd4b9..585f4f86 100644 --- a/packages/vertex-sdk/scripts/postprocess-dist-package-json.cjs +++ b/packages/vertex-sdk/scripts/postprocess-dist-package-json.cjs @@ -8,4 +8,4 @@ for (const dep in pkgJson.dependencies) { } } -fs.writeFileSync('dist/package.json', JSON.stringify(pkgJson, null, 2)) +fs.writeFileSync('dist/package.json', JSON.stringify(pkgJson, null, 2)); diff --git a/scripts/format b/scripts/format index a6bb9d03..903b1ef8 100755 --- a/scripts/format +++ b/scripts/format @@ -5,4 +5,4 @@ set -e cd "$(dirname "$0")/.." echo "==> Running eslint --fix" -ESLINT_USE_FLAT_CONFIG="false" ./node_modules/.bin/eslint --fix --ext ts,js . +./node_modules/.bin/eslint --fix . diff --git a/scripts/lint b/scripts/lint index 5aa027aa..726708c4 100755 --- a/scripts/lint +++ b/scripts/lint @@ -5,7 +5,7 @@ set -e cd "$(dirname "$0")/.." echo "==> Running eslint" -ESLINT_USE_FLAT_CONFIG="false" ./node_modules/.bin/eslint --ext ts,js . --ignore-pattern="packages/" +./node_modules/.bin/eslint . echo "==> Building" ./scripts/build # also checks types diff --git a/src/client.ts b/src/client.ts index f726a48d..ee237ee2 100644 --- a/src/client.ts +++ b/src/client.ts @@ -399,24 +399,6 @@ export class BaseAnthropic { return url.toString(); } - private calculateContentLength(body: unknown): string | null { - if (typeof body === 'string') { - if (typeof (globalThis as any).Buffer !== 'undefined') { - return (globalThis as any).Buffer.byteLength(body, 'utf8').toString(); - } - - if (typeof (globalThis as any).TextEncoder !== 'undefined') { - const encoder = new (globalThis as any).TextEncoder(); - const encoded = encoder.encode(body); - return encoded.length.toString(); - } - } else if (ArrayBuffer.isView(body)) { - return body.byteLength.toString(); - } - - return null; - } - /** * Used as a callback for mutating the given `FinalRequestOptions` object. */ diff --git a/src/pagination.ts b/src/pagination.ts index 20dff07a..04e574f7 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -46,7 +46,6 @@ export abstract class AbstractPage implements AsyncIterable { } async *iterPages(): AsyncGenerator { - // eslint-disable-next-line @typescript-eslint/no-this-alias let page: this = this; yield page; while (page.hasNextPage()) { diff --git a/yarn.lock b/yarn.lock index 475b81a7..30e61b11 100644 --- a/yarn.lock +++ b/yarn.lock @@ -357,54 +357,94 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.5.1": - version "4.11.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" - integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== -"@eslint-community/regexpp@^4.6.1": - version "4.6.2" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" - integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== +"@eslint/config-array@^0.19.0": + version "0.19.2" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.2.tgz#3060b809e111abfc97adb0bb1172778b90cb46aa" + integrity sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w== + dependencies: + "@eslint/object-schema" "^2.1.6" + debug "^4.3.1" + minimatch "^3.1.2" -"@eslint/eslintrc@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" - integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== +"@eslint/core@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.10.0.tgz#23727063c21b335f752dbb3a16450f6f9cbc9091" + integrity sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw== + dependencies: + "@types/json-schema" "^7.0.15" + +"@eslint/core@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.11.0.tgz#7a9226e850922e42cbd2ba71361eacbe74352a12" + integrity sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA== + dependencies: + "@types/json-schema" "^7.0.15" + +"@eslint/eslintrc@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c" + integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" + espree "^10.0.1" + globals "^14.0.0" ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.50.0": - version "8.50.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.50.0.tgz#9e93b850f0f3fa35f5fa59adfd03adae8488e484" - integrity sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ== +"@eslint/js@9.20.0": + version "9.20.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.20.0.tgz#7421bcbe74889fcd65d1be59f00130c289856eb4" + integrity sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ== + +"@eslint/object-schema@^2.1.6": + version "2.1.6" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f" + integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== -"@humanwhocodes/config-array@^0.11.11": - version "0.11.11" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.11.tgz#88a04c570dbbc7dd943e4712429c3df09bc32844" - integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA== +"@eslint/plugin-kit@^0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz#ee07372035539e7847ef834e3f5e7b79f09e3a81" + integrity sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A== dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" + "@eslint/core" "^0.10.0" + levn "^0.4.1" + +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.6": + version "0.16.6" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== + dependencies: + "@humanfs/core" "^0.19.1" + "@humanwhocodes/retry" "^0.3.0" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/retry@^0.3.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== + +"@humanwhocodes/retry@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b" + integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" @@ -666,7 +706,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": +"@nodelib/fs.walk@^1.2.3": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -674,17 +714,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@pkgr/utils@^2.4.2": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" - integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== - dependencies: - cross-spawn "^7.0.3" - fast-glob "^3.3.0" - is-glob "^4.0.3" - open "^9.1.0" - picocolors "^1.0.0" - tslib "^2.6.0" +"@pkgr/core@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" + integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== "@sinclair/typebox@^0.27.8": version "0.27.8" @@ -853,6 +886,11 @@ dependencies: "@babel/types" "^7.20.7" +"@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" @@ -887,7 +925,7 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/json-schema@^7.0.12": +"@types/json-schema@^7.0.15": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -906,11 +944,6 @@ dependencies: undici-types "~6.19.2" -"@types/semver@^7.5.0": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== - "@types/stack-utils@^2.0.0": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" @@ -928,91 +961,86 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^6.7.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" - integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== +"@typescript-eslint/eslint-plugin@8.24.0", "@typescript-eslint/eslint-plugin@^8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz#574a95d67660a1e4544ae131d672867a5b40abb3" + integrity sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ== dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/type-utils" "6.21.0" - "@typescript-eslint/utils" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - debug "^4.3.4" + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.24.0" + "@typescript-eslint/type-utils" "8.24.0" + "@typescript-eslint/utils" "8.24.0" + "@typescript-eslint/visitor-keys" "8.24.0" graphemer "^1.4.0" - ignore "^5.2.4" + ignore "^5.3.1" natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" + ts-api-utils "^2.0.1" -"@typescript-eslint/parser@^6.0.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" - integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== +"@typescript-eslint/parser@8.24.0", "@typescript-eslint/parser@^8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.24.0.tgz#bba837f9ee125b78f459ad947ff9b61be8139085" + integrity sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA== dependencies: - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/scope-manager" "8.24.0" + "@typescript-eslint/types" "8.24.0" + "@typescript-eslint/typescript-estree" "8.24.0" + "@typescript-eslint/visitor-keys" "8.24.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" - integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== +"@typescript-eslint/scope-manager@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz#2e34b3eb2ce768f2ffb109474174ced5417002b1" + integrity sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "8.24.0" + "@typescript-eslint/visitor-keys" "8.24.0" -"@typescript-eslint/type-utils@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" - integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== +"@typescript-eslint/type-utils@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz#6ee3ec4db06f9e5e7b01ca6c2b5dd5843a9fd1e8" + integrity sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA== dependencies: - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/typescript-estree" "8.24.0" + "@typescript-eslint/utils" "8.24.0" debug "^4.3.4" - ts-api-utils "^1.0.1" + ts-api-utils "^2.0.1" -"@typescript-eslint/types@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" - integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== +"@typescript-eslint/types@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.24.0.tgz#694e7fb18d70506c317b816de9521300b0f72c8e" + integrity sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw== -"@typescript-eslint/typescript-estree@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" - integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== +"@typescript-eslint/typescript-estree@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz#0487349be174097bb329a58273100a9629e03c6c" + integrity sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "8.24.0" + "@typescript-eslint/visitor-keys" "8.24.0" debug "^4.3.4" - globby "^11.1.0" + fast-glob "^3.3.2" is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^2.0.1" -"@typescript-eslint/utils@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" - integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== +"@typescript-eslint/utils@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.24.0.tgz#21cb1195ae79230af825bfeed59574f5cb70a749" + integrity sha512-07rLuUBElvvEb1ICnafYWr4hk8/U7X9RDCOqd9JcAMtjh/9oRmcfN4yGzbPVirgMR0+HLVHehmu19CWeh7fsmQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - semver "^7.5.4" + "@typescript-eslint/scope-manager" "8.24.0" + "@typescript-eslint/types" "8.24.0" + "@typescript-eslint/typescript-estree" "8.24.0" -"@typescript-eslint/visitor-keys@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" - integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== +"@typescript-eslint/visitor-keys@8.24.0": + version "8.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz#36ecf0b9b1d819ad88a3bd4157ab7d594cb797c9" + integrity sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg== dependencies: - "@typescript-eslint/types" "6.21.0" - eslint-visitor-keys "^3.4.1" + "@typescript-eslint/types" "8.24.0" + eslint-visitor-keys "^4.2.0" acorn-jsx@^5.3.2: version "5.3.2" @@ -1024,16 +1052,16 @@ acorn-walk@^8.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== +acorn@^8.14.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + acorn@^8.4.1: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== -acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -1125,11 +1153,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -1195,18 +1218,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -big-integer@^1.6.44: - version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" - integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== - -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1258,13 +1269,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -bundle-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" - integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== - dependencies: - run-applescript "^5.0.0" - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1438,7 +1442,7 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.3, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -1476,29 +1480,6 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-browser-id@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" - -default-browser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" - integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== - dependencies: - bundle-name "^3.0.0" - default-browser-id "^3.0.0" - execa "^7.1.1" - titleize "^3.0.0" - -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -1514,20 +1495,6 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - electron-to-chromium@^1.4.601: version "1.4.614" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz#2fe789d61fa09cb875569f37c309d0c2701f91c0" @@ -1580,100 +1547,95 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-plugin-prettier@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz#a3b399f04378f79f066379f544e42d6b73f11515" - integrity sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg== +eslint-plugin-prettier@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.3.tgz#c4af01691a6fa9905207f0fbba0d7bea0902cce5" + integrity sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw== dependencies: prettier-linter-helpers "^1.0.0" - synckit "^0.8.5" - -eslint-plugin-unused-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.0.0.tgz#d25175b0072ff16a91892c3aa72a09ca3a9e69e7" - integrity sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw== - dependencies: - eslint-rule-composer "^0.3.0" + synckit "^0.9.1" -eslint-rule-composer@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" - integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== +eslint-plugin-unused-imports@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz#62ddc7446ccbf9aa7b6f1f0b00a980423cda2738" + integrity sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ== -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== +eslint-scope@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" + integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.3.0: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@^8.49.0: - version "8.50.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.50.0.tgz#2ae6015fee0240fcd3f83e1e25df0287f487d6b2" - integrity sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg== +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + +eslint@^9.20.1: + version "9.20.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.20.1.tgz#923924c078f5226832449bac86662dd7e53c91d6" + integrity sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.50.0" - "@humanwhocodes/config-array" "^0.11.11" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.19.0" + "@eslint/core" "^0.11.0" + "@eslint/eslintrc" "^3.2.0" + "@eslint/js" "9.20.0" + "@eslint/plugin-kit" "^0.2.5" + "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" + "@humanwhocodes/retry" "^0.4.1" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" ajv "^6.12.4" chalk "^4.0.0" - cross-spawn "^7.0.2" + cross-spawn "^7.0.6" debug "^4.3.2" - doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" + eslint-scope "^8.2.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" + esquery "^1.5.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" + file-entry-cache "^8.0.0" find-up "^5.0.0" glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== +espree@^10.0.1, espree@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== dependencies: - acorn "^8.9.0" + acorn "^8.14.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" + eslint-visitor-keys "^4.2.0" esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== +esquery@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" @@ -1709,21 +1671,6 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" - integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^4.3.0" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -1750,7 +1697,7 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.2: +fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -1790,12 +1737,12 @@ fflate@^0.8.2: resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== dependencies: - flat-cache "^3.0.4" + flat-cache "^4.0.0" fill-range@^7.1.1: version "7.1.1" @@ -1820,18 +1767,18 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" + flatted "^3.2.9" + keyv "^4.5.4" -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flatted@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.2.tgz#adba1448a9841bec72b42c532ea23dbbedef1a27" + integrity sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA== fs.realpath@^1.0.0: version "1.0.0" @@ -1868,7 +1815,7 @@ get-stdin@^8.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== -get-stream@^6.0.0, get-stream@^6.0.1: +get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -1915,24 +1862,10 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== graceful-fs@^4.2.9: version "4.2.11" @@ -1976,11 +1909,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -human-signals@^4.3.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" - integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== - iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" @@ -1995,7 +1923,7 @@ ignore-walk@^5.0.1: dependencies: minimatch "^5.0.1" -ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.2.0, ignore@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== @@ -2051,16 +1979,6 @@ is-core-module@^2.13.0: dependencies: hasown "^2.0.0" -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-docker@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" - integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2083,40 +2001,16 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" -is-inside-container@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" - integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== - dependencies: - is-docker "^3.0.0" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2558,6 +2452,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -2583,6 +2482,13 @@ jsonc-parser@^3.2.0: resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" integrity sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA== +keyv@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -2691,7 +2597,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0, merge2@^1.4.1: +merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -2709,19 +2615,7 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -2735,6 +2629,13 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" @@ -2823,13 +2724,6 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - object-assign@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2849,23 +2743,6 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -open@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" - integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== - dependencies: - default-browser "^4.0.0" - define-lazy-prop "^3.0.0" - is-inside-container "^1.0.0" - is-wsl "^2.2.0" - optionator@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" @@ -2974,21 +2851,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -3129,20 +2996,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-applescript@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" - integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== - dependencies: - execa "^5.0.0" - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -3184,6 +3037,11 @@ semver@^7.5.4: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== +semver@^7.6.0: + version "7.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" + integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -3296,11 +3154,6 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -3345,12 +3198,12 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -synckit@^0.8.5: - version "0.8.6" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.6.tgz#b69b7fbce3917c2673cbdc0d87fb324db4a5b409" - integrity sha512-laHF2savN6sMeHCjLRkheIU4wo3Zg9Ln5YOjOo7sZ5dVQW8yF5pPE5SIw1dsPhq3TRp1jisKRCdPhfs/1WMqDA== +synckit@^0.9.1: + version "0.9.2" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.2.tgz#a3a935eca7922d48b9e7d6c61822ee6c3ae4ec62" + integrity sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw== dependencies: - "@pkgr/utils" "^2.4.2" + "@pkgr/core" "^0.1.0" tslib "^2.6.2" test-exclude@^6.0.0: @@ -3362,11 +3215,6 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - thenify-all@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" @@ -3381,11 +3229,6 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" -titleize@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" - integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== - tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -3403,10 +3246,10 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -ts-api-utils@^1.0.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" - integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== +ts-api-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.1.tgz#660729385b625b939aaa58054f45c058f33f10cd" + integrity sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w== ts-jest@^29.1.0: version "29.1.1" @@ -3465,7 +3308,7 @@ tsconfig-paths@^4.0.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.6.0, tslib@^2.6.2: +tslib@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -3487,16 +3330,20 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +typescript-eslint@^8.24.0: + version "8.24.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.24.0.tgz#cc655e71885ecb8280342b422ad839a2e2e46a96" + integrity sha512-/lmv4366en/qbB32Vz5+kCNZEMf6xYHwh1z48suBwZvAtnXKbP+YhGe8OLE2BqC67LMqKkCNLtjejdwsdW6uOQ== + dependencies: + "@typescript-eslint/eslint-plugin" "8.24.0" + "@typescript-eslint/parser" "8.24.0" + "@typescript-eslint/utils" "8.24.0" + typescript@5.6.1-rc: version "5.6.1-rc" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.1-rc.tgz#d5e4d7d8170174fed607b74cc32aba3d77018e02" @@ -3522,11 +3369,6 @@ unicode-emoji-modifier-base@^1.0.0: resolved "https://registry.yarnpkg.com/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz#dbbd5b54ba30f287e2a8d5a249da6c0cef369459" integrity sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g== -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" From 1aa0f00a8267f8bf5a153621f139bffd1801d9ff Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Thu, 13 Feb 2025 22:39:54 +0000 Subject: [PATCH 028/105] fix(client): fix export map for index exports, accept BunFile --- scripts/utils/postprocess-files.cjs | 8 ++++---- src/internal/uploads.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/utils/postprocess-files.cjs b/scripts/utils/postprocess-files.cjs index deae575e..d16c8641 100644 --- a/scripts/utils/postprocess-files.cjs +++ b/scripts/utils/postprocess-files.cjs @@ -50,14 +50,14 @@ async function postprocess() { if (entry.isDirectory() && entry.name !== 'src' && entry.name !== 'internal' && entry.name !== 'bin') { const subpath = './' + entry.name; newExports[subpath + '/*.mjs'] = { - default: subpath + '/*.mjs', + default: [subpath + '/*.mjs', subpath + '/*/index.mjs'], }; newExports[subpath + '/*.js'] = { - default: subpath + '/*.js', + default: [subpath + '/*.js', subpath + '/*/index.js'], }; newExports[subpath + '/*'] = { - import: subpath + '/*.mjs', - require: subpath + '/*.js', + import: [subpath + '/*.mjs', subpath + '/*/index.mjs'], + require: [subpath + '/*.js', subpath + '/*/index.js'], }; } else if (entry.isFile() && /\.[cm]?js$/.test(entry.name)) { const { name, ext } = path.parse(entry.name); diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index 02e1be49..2c64f7bb 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -52,7 +52,7 @@ interface FileLike extends BlobLike { /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */ readonly lastModified: number; /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */ - readonly name: string; + readonly name?: string | undefined; } declare var FileClass: { prototype: FileLike; @@ -126,7 +126,7 @@ export async function toFile( if (File && value instanceof File) { return value; } - return makeFile([await value.arrayBuffer()], value.name); + return makeFile([await value.arrayBuffer()], value.name ?? 'unknown_file'); } if (isResponseLike(value)) { From 2ab37e5d18d4d50ed780f23003eaf2cd9ae29d88 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Fri, 14 Feb 2025 10:26:57 +0000 Subject: [PATCH 029/105] chore(internal): add missing return type annotation --- src/pagination.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pagination.ts b/src/pagination.ts index 04e574f7..4bb2878c 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -160,7 +160,7 @@ export class Page extends AbstractPage implements PageResponse return this.data ?? []; } - override hasNextPage() { + override hasNextPage(): boolean { if (this.has_more === false) { return false; } From fa9213b7eba5435c8c371fdffdb0ee2900210d4c Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 17 Feb 2025 10:03:02 +0000 Subject: [PATCH 030/105] chore(internal): fix tests not always being type checked --- scripts/lint | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/lint b/scripts/lint index 726708c4..3ffb78a6 100755 --- a/scripts/lint +++ b/scripts/lint @@ -8,7 +8,10 @@ echo "==> Running eslint" ./node_modules/.bin/eslint . echo "==> Building" -./scripts/build # also checks types +./scripts/build + +echo "==> Checking types" +./node_modules/typescript/bin/tsc echo "==> Running Are The Types Wrong?" ./node_modules/.bin/attw --pack dist -f json >.attw.json || true From 0e53ab28447c99fbd949594f756cb18c16824840 Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Mon, 24 Feb 2025 15:02:24 +0000 Subject: [PATCH 031/105] chore(internal): fix tests --- tests/api-resources/MessageStream.test.ts | 38 ++++++++++--------- .../beta/messages/batches.test.ts | 12 ------ tests/api-resources/messages/batches.test.ts | 12 ------ 3 files changed, 21 insertions(+), 41 deletions(-) diff --git a/tests/api-resources/MessageStream.test.ts b/tests/api-resources/MessageStream.test.ts index 048dd7cc..8c46caa1 100644 --- a/tests/api-resources/MessageStream.test.ts +++ b/tests/api-resources/MessageStream.test.ts @@ -1,9 +1,12 @@ import { PassThrough } from 'stream'; import Anthropic, { APIConnectionError, APIUserAbortError } from '@anthropic-ai/sdk'; import { Message, MessageStreamEvent } from '@anthropic-ai/sdk/resources/messages'; -import { type RequestInfo, type RequestInit } from '@anthropic-ai/sdk/_shims/index'; - -type Fetch = typeof fetch; +import { + type Fetch, + type RequestInfo, + type RequestInit, + type Response, +} from '@anthropic-ai/sdk/internal/builtin-types'; function assertNever(x: never): never { throw new Error(`unreachable: ${x}`); @@ -21,7 +24,7 @@ async function* messageIterable(message: Message): AsyncGenerator { type: 'message', id: 'msg_01hhptzfxdaeehfxfv070yb6b8', role: 'assistant', - content: [{ type: 'text', text: 'Hello there!' }], + content: [{ type: 'text', text: 'Hello there!', citations: null }], model: 'claude-3-opus-20240229', stop_reason: 'end_turn', stop_sequence: null, @@ -224,15 +227,15 @@ describe('MessageStream class', () => { }, { "args": [ - "{"type":"content_block_start","content_block":{"type":"text","text":""},"index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":""}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"content_block_start","content_block":{"type":"text","text":"","citations":null},"index":0}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "streamEvent", }, { "args": [ "{"type":"content_block_delta","delta":{"type":"text_delta","text":"Hello"},"index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello"}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "streamEvent", }, @@ -246,7 +249,7 @@ describe('MessageStream class', () => { { "args": [ "{"type":"content_block_delta","delta":{"type":"text_delta","text":" ther"},"index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello ther"}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello ther","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "streamEvent", }, @@ -260,7 +263,7 @@ describe('MessageStream class', () => { { "args": [ "{"type":"content_block_delta","delta":{"type":"text_delta","text":"e!"},"index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!"}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "streamEvent", }, @@ -274,39 +277,39 @@ describe('MessageStream class', () => { { "args": [ "{"type":"content_block_stop","index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!"}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "streamEvent", }, { "args": [ - "{"type":"text","text":"Hello there!"}", + "{"type":"text","text":"Hello there!","citations":null}", ], "type": "contentBlock", }, { "args": [ "{"type":"message_delta","usage":{"output_tokens":6},"delta":{"stop_reason":"end_turn","stop_sequence":null}}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!"}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "streamEvent", }, { "args": [ "{"type":"message_stop"}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!"}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "streamEvent", }, { "args": [ - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!"}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "message", }, { "args": [ - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!"}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", ], "type": "finalMessage", }, @@ -323,6 +326,7 @@ describe('MessageStream class', () => { { "content": [ { + "citations": null, "text": "Hello there!", "type": "text", }, @@ -359,7 +363,7 @@ describe('MessageStream class', () => { type: 'message', id: 'msg_01hhptzfxdaeehfxfv070yb6b8', role: 'assistant', - content: [{ type: 'text', text: 'Hello there!' }], + content: [{ type: 'text', text: 'Hello there!', citations: null }], model: 'claude-3-opus-20240229', stop_reason: 'end_turn', stop_sequence: null, diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index 61c0bb7d..9809ee96 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -175,18 +175,6 @@ describe('resource batches', () => { ).rejects.toThrow(Anthropic.NotFoundError); }); - // Prism doesn't support JSONL responses yet - test.skip('results', async () => { - const responsePromise = client.beta.messages.batches.results('message_batch_id'); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - // Prism doesn't support JSONL responses yet test.skip('results: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index d77e510a..503e8ef7 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -138,16 +138,4 @@ describe('resource batches', () => { expect(dataAndResponse.data).toBe(response); expect(dataAndResponse.response).toBe(rawResponse); }); - - // Prism doesn't support JSONL responses yet - test.skip('results', async () => { - const responsePromise = client.messages.batches.results('message_batch_id'); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); }); From e0472251e76f0fb7f341afb73522b197442592bf Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Tue, 18 Feb 2025 18:08:12 +0000 Subject: [PATCH 032/105] fix: optimize sse chunk reading off-by-one error --- src/internal/decoders/line.ts | 31 +++++++ src/streaming.ts | 48 +--------- tests/internal/decoders/line.test.ts | 128 +++++++++++++++++++++++++++ tests/streaming.test.ts | 81 +---------------- 4 files changed, 161 insertions(+), 127 deletions(-) create mode 100644 tests/internal/decoders/line.test.ts diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts index 1156fb78..fcacf4b7 100644 --- a/src/internal/decoders/line.ts +++ b/src/internal/decoders/line.ts @@ -147,3 +147,34 @@ function findNewlineIndex( return null; } + +export function findDoubleNewlineIndex(buffer: Uint8Array): number { + // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n) + // and returns the index right after the first occurrence of any pattern, + // or -1 if none of the patterns are found. + const newline = 0x0a; // \n + const carriage = 0x0d; // \r + + for (let i = 0; i < buffer.length - 1; i++) { + if (buffer[i] === newline && buffer[i + 1] === newline) { + // \n\n + return i + 2; + } + if (buffer[i] === carriage && buffer[i + 1] === carriage) { + // \r\r + return i + 2; + } + if ( + buffer[i] === carriage && + buffer[i + 1] === newline && + i + 3 < buffer.length && + buffer[i + 2] === carriage && + buffer[i + 3] === newline + ) { + // \r\n\r\n + return i + 4; + } + } + + return -1; +} diff --git a/src/streaming.ts b/src/streaming.ts index 8fed4a9e..12347911 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -1,7 +1,7 @@ import { AnthropicError } from './error'; import { type ReadableStream } from './internal/shim-types'; import { makeReadableStream } from './internal/shims'; -import { LineDecoder } from './internal/decoders/line'; +import { findDoubleNewlineIndex, LineDecoder } from './internal/decoders/line'; import { ReadableStreamToAsyncIterable } from './internal/shims'; import { isAbortError } from './internal/errors'; @@ -267,37 +267,6 @@ async function* iterSSEChunks(iterator: AsyncIterableIterator): AsyncGene } } -function findDoubleNewlineIndex(buffer: Uint8Array): number { - // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n) - // and returns the index right after the first occurrence of any pattern, - // or -1 if none of the patterns are found. - const newline = 0x0a; // \n - const carriage = 0x0d; // \r - - for (let i = 0; i < buffer.length - 2; i++) { - if (buffer[i] === newline && buffer[i + 1] === newline) { - // \n\n - return i + 2; - } - if (buffer[i] === carriage && buffer[i + 1] === carriage) { - // \r\r - return i + 2; - } - if ( - buffer[i] === carriage && - buffer[i + 1] === newline && - i + 3 < buffer.length && - buffer[i + 2] === carriage && - buffer[i + 3] === newline - ) { - // \r\n\r\n - return i + 4; - } - } - - return -1; -} - class SSEDecoder { private data: string[]; private event: string | null; @@ -353,21 +322,6 @@ class SSEDecoder { } } -/** This is an internal helper function that's just used for testing */ -export function _decodeChunks(chunks: string[], { flush }: { flush: boolean } = { flush: false }): string[] { - const decoder = new LineDecoder(); - const lines: string[] = []; - for (const chunk of chunks) { - lines.push(...decoder.decode(chunk)); - } - - if (flush) { - lines.push(...decoder.flush()); - } - - return lines; -} - function partition(str: string, delimiter: string): [string, string, string] { const index = str.indexOf(delimiter); if (index !== -1) { diff --git a/tests/internal/decoders/line.test.ts b/tests/internal/decoders/line.test.ts new file mode 100644 index 00000000..8d288c85 --- /dev/null +++ b/tests/internal/decoders/line.test.ts @@ -0,0 +1,128 @@ +import { findDoubleNewlineIndex, LineDecoder } from '@anthropic-ai/sdk/internal/decoders/line'; + +function decodeChunks(chunks: string[], { flush }: { flush: boolean } = { flush: false }): string[] { + const decoder = new LineDecoder(); + const lines: string[] = []; + for (const chunk of chunks) { + lines.push(...decoder.decode(chunk)); + } + + if (flush) { + lines.push(...decoder.flush()); + } + + return lines; +} + +describe('line decoder', () => { + test('basic', () => { + // baz is not included because the line hasn't ended yet + expect(decodeChunks(['foo', ' bar\nbaz'])).toEqual(['foo bar']); + }); + + test('basic with \\r', () => { + expect(decodeChunks(['foo', ' bar\r\nbaz'])).toEqual(['foo bar']); + expect(decodeChunks(['foo', ' bar\r\nbaz'], { flush: true })).toEqual(['foo bar', 'baz']); + }); + + test('trailing new lines', () => { + expect(decodeChunks(['foo', ' bar', 'baz\n', 'thing\n'])).toEqual(['foo barbaz', 'thing']); + }); + + test('trailing new lines with \\r', () => { + expect(decodeChunks(['foo', ' bar', 'baz\r\n', 'thing\r\n'])).toEqual(['foo barbaz', 'thing']); + }); + + test('escaped new lines', () => { + expect(decodeChunks(['foo', ' bar\\nbaz\n'])).toEqual(['foo bar\\nbaz']); + }); + + test('escaped new lines with \\r', () => { + expect(decodeChunks(['foo', ' bar\\r\\nbaz\n'])).toEqual(['foo bar\\r\\nbaz']); + }); + + test('\\r & \\n split across multiple chunks', () => { + expect(decodeChunks(['foo\r', '\n', 'bar'], { flush: true })).toEqual(['foo', 'bar']); + }); + + test('single \\r', () => { + expect(decodeChunks(['foo\r', 'bar'], { flush: true })).toEqual(['foo', 'bar']); + }); + + test('double \\r', () => { + expect(decodeChunks(['foo\r', 'bar\r'], { flush: true })).toEqual(['foo', 'bar']); + expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + // implementation detail that we don't yield the single \r line until a new \r or \n is encountered + expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: false })).toEqual(['foo']); + }); + + test('double \\r then \\r\\n', () => { + expect(decodeChunks(['foo\r', '\r', '\r', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']); + expect(decodeChunks(['foo\n', '\n', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']); + }); + + test('double newline', () => { + expect(decodeChunks(['foo\n\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo', '\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + expect(decodeChunks(['foo', '\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); + }); + + test('multi-byte characters across chunks', () => { + const decoder = new LineDecoder(); + + // bytes taken from the string 'известни' and arbitrarily split + // so that some multi-byte characters span multiple chunks + expect(decoder.decode(new Uint8Array([0xd0]))).toHaveLength(0); + expect(decoder.decode(new Uint8Array([0xb8, 0xd0, 0xb7, 0xd0]))).toHaveLength(0); + expect( + decoder.decode(new Uint8Array([0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb8])), + ).toHaveLength(0); + + const decoded = decoder.decode(new Uint8Array([0xa])); + expect(decoded).toEqual(['известни']); + }); + + test('flushing trailing newlines', () => { + expect(decodeChunks(['foo\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); + }); + + test('flushing empty buffer', () => { + expect(decodeChunks([], { flush: true })).toEqual([]); + }); +}); + +describe('findDoubleNewlineIndex', () => { + test('finds \\n\\n', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\n\nbar'))).toBe(5); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\n\nbar'))).toBe(2); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\n\n'))).toBe(5); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\n\n'))).toBe(2); + }); + + test('finds \\r\\r', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\rbar'))).toBe(5); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\rbar'))).toBe(2); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\r'))).toBe(5); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\r'))).toBe(2); + }); + + test('finds \\r\\n\\r\\n', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r\nbar'))).toBe(7); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\n\r\nbar'))).toBe(4); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r\n'))).toBe(7); + expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\n\r\n'))).toBe(4); + }); + + test('returns -1 when no double newline found', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\nbar'))).toBe(-1); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\rbar'))).toBe(-1); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\nbar'))).toBe(-1); + expect(findDoubleNewlineIndex(new TextEncoder().encode(''))).toBe(-1); + }); + + test('handles incomplete patterns', () => { + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r'))).toBe(-1); + expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n'))).toBe(-1); + }); +}); diff --git a/tests/streaming.test.ts b/tests/streaming.test.ts index 6a05c446..98baa9c2 100644 --- a/tests/streaming.test.ts +++ b/tests/streaming.test.ts @@ -1,86 +1,7 @@ import { PassThrough } from 'stream'; import assert from 'assert'; -import { Stream, _iterSSEMessages, _decodeChunks as decodeChunks } from '@anthropic-ai/sdk/streaming'; +import { Stream, _iterSSEMessages } from '@anthropic-ai/sdk/streaming'; import { APIConnectionError } from '@anthropic-ai/sdk/error'; -import { LineDecoder } from '@anthropic-ai/sdk/internal/decoders/line'; - -describe('line decoder', () => { - test('basic', () => { - // baz is not included because the line hasn't ended yet - expect(decodeChunks(['foo', ' bar\nbaz'])).toEqual(['foo bar']); - }); - - test('basic with \\r', () => { - expect(decodeChunks(['foo', ' bar\r\nbaz'])).toEqual(['foo bar']); - expect(decodeChunks(['foo', ' bar\r\nbaz'], { flush: true })).toEqual(['foo bar', 'baz']); - }); - - test('trailing new lines', () => { - expect(decodeChunks(['foo', ' bar', 'baz\n', 'thing\n'])).toEqual(['foo barbaz', 'thing']); - }); - - test('trailing new lines with \\r', () => { - expect(decodeChunks(['foo', ' bar', 'baz\r\n', 'thing\r\n'])).toEqual(['foo barbaz', 'thing']); - }); - - test('escaped new lines', () => { - expect(decodeChunks(['foo', ' bar\\nbaz\n'])).toEqual(['foo bar\\nbaz']); - }); - - test('escaped new lines with \\r', () => { - expect(decodeChunks(['foo', ' bar\\r\\nbaz\n'])).toEqual(['foo bar\\r\\nbaz']); - }); - - test('\\r & \\n split across multiple chunks', () => { - expect(decodeChunks(['foo\r', '\n', 'bar'], { flush: true })).toEqual(['foo', 'bar']); - }); - - test('single \\r', () => { - expect(decodeChunks(['foo\r', 'bar'], { flush: true })).toEqual(['foo', 'bar']); - }); - - test('double \\r', () => { - expect(decodeChunks(['foo\r', 'bar\r'], { flush: true })).toEqual(['foo', 'bar']); - expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); - // implementation detail that we don't yield the single \r line until a new \r or \n is encountered - expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: false })).toEqual(['foo']); - }); - - test('double \\r then \\r\\n', () => { - expect(decodeChunks(['foo\r', '\r', '\r', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']); - expect(decodeChunks(['foo\n', '\n', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']); - }); - - test('double newline', () => { - expect(decodeChunks(['foo\n\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); - expect(decodeChunks(['foo', '\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); - expect(decodeChunks(['foo\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); - expect(decodeChunks(['foo', '\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']); - }); - - test('multi-byte characters across chunks', () => { - const decoder = new LineDecoder(); - - // bytes taken from the string 'известни' and arbitrarily split - // so that some multi-byte characters span multiple chunks - expect(decoder.decode(new Uint8Array([0xd0]))).toHaveLength(0); - expect(decoder.decode(new Uint8Array([0xb8, 0xd0, 0xb7, 0xd0]))).toHaveLength(0); - expect( - decoder.decode(new Uint8Array([0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb8])), - ).toHaveLength(0); - - const decoded = decoder.decode(new Uint8Array([0xa])); - expect(decoded).toEqual(['известни']); - }); - - test('flushing trailing newlines', () => { - expect(decodeChunks(['foo\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']); - }); - - test('flushing empty buffer', () => { - expect(decodeChunks([], { flush: true })).toEqual([]); - }); -}); describe('streaming decoding', () => { test('basic', async () => { From b4da3407107c76c1291989e727eaf949db248758 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Fri, 21 Feb 2025 11:24:54 +0000 Subject: [PATCH 033/105] feat(client): improve logging --- README.md | 76 ++++++++++----- src/client.ts | 176 +++++++++++++++++++++++++++-------- src/internal/errors.ts | 11 +++ src/internal/parse.ts | 90 ++++++++++-------- src/internal/shims.ts | 18 ++++ src/internal/utils/log.ts | 94 ++++++++++++++----- src/internal/utils/values.ts | 2 +- tests/index.test.ts | 52 ++++++++++- 8 files changed, 395 insertions(+), 124 deletions(-) diff --git a/README.md b/README.md index cbd043a2..5438bba8 100644 --- a/README.md +++ b/README.md @@ -368,6 +368,59 @@ console.log(raw.headers.get('X-My-Header')); console.log(message.content); ``` +### Logging + +> [!IMPORTANT] +> All log messages are intended for debugging only. The format and content of log messages +> may change between releases. + +#### Log levels + +The log level can be configured in two ways: + +1. Via the `ANTHROPIC_LOG` environment variable +2. Using the `logLevel` client option (overrides the environment variable if set) + +```ts +import Anthropic from '@anthropic-ai/sdk'; + +const client = new Anthropic({ + logLevel: 'debug', // Show all log messages +}); +``` + +Available log levels, from most to least verbose: + +- `'debug'` - Show debug messages, info, warnings, and errors +- `'info'` - Show info messages, warnings, and errors +- `'warn'` - Show warnings and errors (default) +- `'error'` - Show only errors +- `'off'` - Disable all logging + +At the `'debug'` level, all HTTP requests and responses are logged, including headers and bodies. +Some authentication-related headers are redacted, but sensitive data in request and response bodies +may still be visible. + +#### Custom logger + +By default, this library logs to `globalThis.console`. You can also provide a custom logger. +Most logging libraries are supported, including [pino](https://www.npmjs.com/package/pino), [winston](https://www.npmjs.com/package/winston), [bunyan](https://www.npmjs.com/package/bunyan), [consola](https://www.npmjs.com/package/consola), [signale](https://www.npmjs.com/package/signale), and [@std/log](https://jsr.io/@std/log). If your logger doesn't work, please open an issue. + +When providing a custom logger, the `logLevel` option still controls which messages are emitted, messages +below the configured level will not be sent to your logger. + +```ts +import Anthropic from '@anthropic-ai/sdk'; +import pino from 'pino'; + +const logger = pino(); + +const client = new Anthropic({ + logger: logger.child({ name: 'Anthropic' }), + logLevel: 'debug', // Send all messages to pino, allowing it to filter +}); +``` + ### Making custom/undocumented requests This library is typed for convenient access to the documented API. If you need to access undocumented @@ -427,33 +480,12 @@ globalThis.fetch = fetch; Or pass it to the client: ```ts +import Anthropic from '@anthropic-ai/sdk'; import fetch from 'my-fetch'; const client = new Anthropic({ fetch }); ``` -### Logging and middleware - -You may also provide a custom `fetch` function when instantiating the client, -which can be used to inspect or alter the `Request` or `Response` before/after each request: - -```ts -import { fetch } from 'undici'; // as one example -import Anthropic from '@anthropic-ai/sdk'; - -const client = new Anthropic({ - fetch: async (url: RequestInfo, init?: RequestInit): Promise => { - console.log('About to make a request', url, init); - const response = await fetch(url, init); - console.log('Got response', response); - return response; - }, -}); -``` - -Note that if given a `ANTHROPIC_LOG=debug` environment variable, this library will log all requests and responses automatically. -This is intended for debugging purposes only and may change in the future without notice. - ### Fetch options If you want to set custom `fetch` options without overriding the `fetch` function, you can provide a `fetchOptions` object when instantiating the client or making a request. (Request-specific options override client options.) diff --git a/src/client.ts b/src/client.ts index ee237ee2..01484aa3 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3,7 +3,7 @@ import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types'; import type { HTTPMethod, PromiseOrValue, MergedRequestInit } from './internal/types'; import { uuid4 } from './internal/utils/uuid'; -import { validatePositiveInteger, isAbsoluteURL } from './internal/utils/values'; +import { validatePositiveInteger, isAbsoluteURL, hasOwn } from './internal/utils/values'; import { sleep } from './internal/utils/sleep'; import { castToError, isAbortError } from './internal/errors'; import type { APIResponseProps } from './internal/parse'; @@ -30,7 +30,7 @@ import { } from './resources/completions'; import { ModelInfo, ModelInfosPage, ModelListParams, Models } from './resources/models'; import { readEnv } from './internal/utils/env'; -import { logger } from './internal/utils/log'; +import { formatRequestDetails, loggerFor } from './internal/utils/log'; import { isEmptyObj } from './internal/utils/values'; import { AnthropicBeta, @@ -124,7 +124,14 @@ export type Logger = { debug: LogFn; }; export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug'; -const isLogLevel = (key: string | undefined): key is LogLevel => { +const parseLogLevel = ( + maybeLevel: string | undefined, + sourceName: string, + client: BaseAnthropic, +): LogLevel | undefined => { + if (!maybeLevel) { + return undefined; + } const levels: Record = { off: true, error: true, @@ -132,7 +139,15 @@ const isLogLevel = (key: string | undefined): key is LogLevel => { info: true, debug: true, }; - return key! in levels; + if (hasOwn(levels, maybeLevel)) { + return maybeLevel; + } + loggerFor(client).warn( + `${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify( + Object.keys(levels), + )}`, + ); + return undefined; }; export interface ClientOptions { @@ -207,16 +222,16 @@ export interface ClientOptions { /** * Set the log level. * - * Defaults to process.env['ANTHROPIC_LOG']. + * Defaults to process.env['ANTHROPIC_LOG'] or 'warn' if it isn't set. */ - logLevel?: LogLevel | undefined | null; + logLevel?: LogLevel | undefined; /** * Set the logger. * * Defaults to globalThis.console. */ - logger?: Logger | undefined | null; + logger?: Logger | undefined; } type FinalizedRequestInit = RequestInit & { headers: Headers }; @@ -273,14 +288,13 @@ export class BaseAnthropic { this.baseURL = options.baseURL!; this.timeout = options.timeout ?? Anthropic.DEFAULT_TIMEOUT /* 10 minutes */; this.logger = options.logger ?? console; - if (options.logLevel != null) { - this.logLevel = options.logLevel; - } else { - const envLevel = readEnv('ANTHROPIC_LOG'); - if (isLogLevel(envLevel)) { - this.logLevel = envLevel; - } - } + const defaultLogLevel = 'warn'; + // Set default logLevel early so that we can log a warning in parseLogLevel. + this.logLevel = defaultLogLevel; + this.logLevel = + parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ?? + parseLogLevel(readEnv('ANTHROPIC_LOG'), "process.env['ANTHROPIC_LOG']", this) ?? + defaultLogLevel; this.fetchOptions = options.fetchOptions; this.maxRetries = options.maxRetries ?? 2; this.fetch = options.fetch ?? Shims.getDefaultFetch(); @@ -451,12 +465,13 @@ export class BaseAnthropic { options: PromiseOrValue, remainingRetries: number | null = null, ): APIPromise { - return new APIPromise(this, this.makeRequest(options, remainingRetries)); + return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined)); } private async makeRequest( optionsInput: PromiseOrValue, retriesRemaining: number | null, + retryOfRequestLogID: string | undefined, ): Promise { const options = await optionsInput; const maxRetries = options.maxRetries ?? this.maxRetries; @@ -470,7 +485,21 @@ export class BaseAnthropic { await this.prepareRequest(req, { url, options }); - logger(this).debug('request', url, options, req.headers); + /** Not an API request ID, just for correlating local log entries. */ + const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0'); + const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`; + const startTime = Date.now(); + + loggerFor(this).debug( + `[${requestLogID}] sending request`, + formatRequestDetails({ + retryOfRequestLogID, + method: options.method, + url, + options, + headers: req.headers, + }), + ); if (options.signal?.aborted) { throw new Errors.APIUserAbortError(); @@ -478,52 +507,124 @@ export class BaseAnthropic { const controller = new AbortController(); const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError); + const headersTime = Date.now(); if (response instanceof Error) { + const retryMessage = `retrying, ${retriesRemaining} attempts remaining`; if (options.signal?.aborted) { throw new Errors.APIUserAbortError(); } - if (retriesRemaining) { - return this.retryRequest(options, retriesRemaining); - } - if (isAbortError(response)) { - throw new Errors.APIConnectionTimeoutError(); - } // detect native connection timeout errors // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)" // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)" // others do not provide enough information to distinguish timeouts from other connection errors - if (/timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''))) { + const isTimeout = + isAbortError(response) || + /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : '')); + if (retriesRemaining) { + loggerFor(this).info( + `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`, + ); + loggerFor(this).debug( + `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, + formatRequestDetails({ + retryOfRequestLogID, + url, + durationMs: headersTime - startTime, + message: response.message, + }), + ); + return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID); + } + loggerFor(this).info( + `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`, + ); + loggerFor(this).debug( + `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, + formatRequestDetails({ + retryOfRequestLogID, + url, + durationMs: headersTime - startTime, + message: response.message, + }), + ); + if (isTimeout) { throw new Errors.APIConnectionTimeoutError(); } throw new Errors.APIConnectionError({ cause: response }); } + const specialHeaders = [...response.headers.entries()] + .filter(([name]) => name === 'request-id') + .map(([name, value]) => ', ' + name + ': ' + JSON.stringify(value)) + .join(''); + const responseInfo = `[${requestLogID}${retryLogStr}${specialHeaders}] ${req.method} ${url} ${ + response.ok ? 'succeeded' : 'failed' + } with status ${response.status} in ${headersTime - startTime}ms`; + if (!response.ok) { - if (retriesRemaining && this.shouldRetry(response)) { + const shouldRetry = this.shouldRetry(response); + if (retriesRemaining && shouldRetry) { const retryMessage = `retrying, ${retriesRemaining} attempts remaining`; - logger(this).debug(`response (error; ${retryMessage})`, response.status, url, response.headers); - return this.retryRequest(options, retriesRemaining, response.headers); + + // We don't need the body of this response. + await Shims.CancelReadableStream(response.body); + loggerFor(this).info(`${responseInfo} - ${retryMessage}`); + loggerFor(this).debug( + `[${requestLogID}] response error (${retryMessage})`, + formatRequestDetails({ + retryOfRequestLogID, + url: response.url, + status: response.status, + headers: response.headers, + durationMs: headersTime - startTime, + }), + ); + return this.retryRequest( + options, + retriesRemaining, + retryOfRequestLogID ?? requestLogID, + response.headers, + ); } + const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`; + + loggerFor(this).info(`${responseInfo} - ${retryMessage}`); + const errText = await response.text().catch((err: any) => castToError(err).message); const errJSON = safeJSON(errText); const errMessage = errJSON ? undefined : errText; - const retryMessage = retriesRemaining ? `(error; no more retries left)` : `(error; not retryable)`; - logger(this).debug( - `response (error; ${retryMessage})`, - response.status, - url, - response.headers, - errMessage, + loggerFor(this).debug( + `[${requestLogID}] response error (${retryMessage})`, + formatRequestDetails({ + retryOfRequestLogID, + url: response.url, + status: response.status, + headers: response.headers, + message: errMessage, + durationMs: Date.now() - startTime, + }), ); const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers); throw err; } - return { response, options, controller }; + loggerFor(this).info(responseInfo); + loggerFor(this).debug( + `[${requestLogID}] response start`, + formatRequestDetails({ + retryOfRequestLogID, + url: response.url, + status: response.status, + headers: response.headers, + durationMs: headersTime - startTime, + }), + ); + + return { response, options, controller, requestLogID, retryOfRequestLogID, startTime }; } getAPIList = Pagination.AbstractPage>( @@ -541,7 +642,7 @@ export class BaseAnthropic { Page: new (...args: ConstructorParameters) => PageClass, options: FinalRequestOptions, ): Pagination.PagePromise { - const request = this.makeRequest(options, null); + const request = this.makeRequest(options, null, undefined); return new Pagination.PagePromise(this as any as Anthropic, request, Page); } @@ -604,6 +705,7 @@ export class BaseAnthropic { private async retryRequest( options: FinalRequestOptions, retriesRemaining: number, + requestLogID: string, responseHeaders?: Headers | undefined, ): Promise { let timeoutMillis: number | undefined; @@ -636,7 +738,7 @@ export class BaseAnthropic { } await sleep(timeoutMillis); - return this.makeRequest(options, retriesRemaining - 1); + return this.makeRequest(options, retriesRemaining - 1, requestLogID); } private calculateDefaultRetryTimeoutMillis(retriesRemaining: number, maxRetries: number): number { diff --git a/src/internal/errors.ts b/src/internal/errors.ts index 2e625bda..653a6ecb 100644 --- a/src/internal/errors.ts +++ b/src/internal/errors.ts @@ -14,6 +14,17 @@ export function isAbortError(err: unknown) { export const castToError = (err: any): Error => { if (err instanceof Error) return err; if (typeof err === 'object' && err !== null) { + try { + if (Object.prototype.toString.call(err) === '[object Error]') { + // @ts-ignore - not all envs have native support for cause yet + const error = new Error(err.message, err.cause ? { cause: err.cause } : {}); + if (err.stack) error.stack = err.stack; + // @ts-ignore - not all envs have native support for cause yet + if (err.cause && !error.cause) error.cause = err.cause; + if (err.name) error.name = err.name; + throw error; + } + } catch {} try { return new Error(JSON.stringify(err)); } catch {} diff --git a/src/internal/parse.ts b/src/internal/parse.ts index 7755e27e..cd0e217a 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -3,65 +3,77 @@ import type { FinalRequestOptions } from './request-options'; import { Stream } from '../streaming'; import { type BaseAnthropic } from '../client'; -import { logger } from './utils/log'; -import { type AbstractPage } from '../pagination'; +import { formatRequestDetails, loggerFor } from './utils/log'; +import type { AbstractPage } from '../pagination'; export type APIResponseProps = { response: Response; options: FinalRequestOptions; controller: AbortController; + requestLogID: string; + retryOfRequestLogID: string | undefined; + startTime: number; }; -export type WithRequestID = - T extends Array | Response | AbstractPage ? T - : T extends Record ? T & { _request_id?: string | null } - : T; - export async function defaultParseResponse( client: BaseAnthropic, props: APIResponseProps, ): Promise> { - const { response } = props; - if (props.options.stream) { - logger(client).debug('response', response.status, response.url, response.headers, response.body); - - // Note: there is an invariant here that isn't represented in the type system - // that if you set `stream: true` the response type must also be `Stream` + const { response, requestLogID, retryOfRequestLogID, startTime } = props; + const body = await (async () => { + if (props.options.stream) { + loggerFor(client).debug('response', response.status, response.url, response.headers, response.body); - if (props.options.__streamClass) { - return props.options.__streamClass.fromSSEResponse(response, props.controller) as any; - } - - return Stream.fromSSEResponse(response, props.controller) as any; - } - - // fetch refuses to read the body when the status code is 204. - if (response.status === 204) { - return null as WithRequestID; - } + // Note: there is an invariant here that isn't represented in the type system + // that if you set `stream: true` the response type must also be `Stream` - if (props.options.__binaryResponse) { - return response as unknown as WithRequestID; - } + if (props.options.__streamClass) { + return props.options.__streamClass.fromSSEResponse(response, props.controller) as any; + } - const contentType = response.headers.get('content-type'); - const isJSON = - contentType?.includes('application/json') || contentType?.includes('application/vnd.api+json'); - if (isJSON) { - const json = await response.json(); + return Stream.fromSSEResponse(response, props.controller) as any; + } - logger(client).debug('response', response.status, response.url, response.headers, json); + // fetch refuses to read the body when the status code is 204. + if (response.status === 204) { + return null as T; + } - return addRequestID(json as T, response); - } + if (props.options.__binaryResponse) { + return response as unknown as T; + } - const text = await response.text(); - logger(client).debug('response', response.status, response.url, response.headers, text); + const contentType = response.headers.get('content-type'); + const isJSON = + contentType?.includes('application/json') || contentType?.includes('application/vnd.api+json'); + if (isJSON) { + const json = await response.json(); + return addRequestID(json as T, response); + } - // TODO handle blob, arraybuffer, other content types, etc. - return text as unknown as WithRequestID; + const text = await response.text(); + + // TODO handle blob, arraybuffer, other content types, etc. + return text as unknown as T; + })(); + loggerFor(client).debug( + `[${requestLogID}] response parsed`, + formatRequestDetails({ + retryOfRequestLogID, + url: response.url, + status: response.status, + body, + durationMs: Date.now() - startTime, + }), + ); + return body; } +export type WithRequestID = + T extends Array | Response | AbstractPage ? T + : T extends Record ? T & { _request_id?: string | null } + : T; + export function addRequestID(value: T, response: Response): WithRequestID { if (!value || typeof value !== 'object' || Array.isArray(value)) { return value as WithRequestID; diff --git a/src/internal/shims.ts b/src/internal/shims.ts index ada548ce..e70031e4 100644 --- a/src/internal/shims.ts +++ b/src/internal/shims.ts @@ -143,3 +143,21 @@ export function ReadableStreamToAsyncIterable(stream: any): AsyncIterableIter }, }; } + +/** + * Cancels a ReadableStream we don't need to consume. + * See https://undici.nodejs.org/#/?id=garbage-collection + */ +export async function CancelReadableStream(stream: any): Promise { + if (stream === null || typeof stream !== 'object') return; + + if (stream[Symbol.asyncIterator]) { + await stream[Symbol.asyncIterator]().return?.(); + return; + } + + const reader = stream.getReader(); + const cancelPromise = reader.cancel(); + reader.releaseLock(); + await cancelPromise; +} diff --git a/src/internal/utils/log.ts b/src/internal/utils/log.ts index 157a584c..4909b1fd 100644 --- a/src/internal/utils/log.ts +++ b/src/internal/utils/log.ts @@ -2,6 +2,7 @@ import type { LogLevel, Logger } from '../../client'; import { type BaseAnthropic } from '../../client'; +import { RequestOptions } from '../request-options'; const levelNumbers = { off: 0, @@ -13,37 +14,86 @@ const levelNumbers = { function noop() {} -function logFn(logger: Logger | undefined, clientLevel: LogLevel | undefined, level: keyof Logger) { - if (!logger || levelNumbers[level] > levelNumbers[clientLevel!]!) { +function makeLogFn(fnLevel: keyof Logger, logger: Logger | undefined, logLevel: LogLevel) { + if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) { return noop; } else { // Don't wrap logger functions, we want the stacktrace intact! - return logger[level].bind(logger); + return logger[fnLevel].bind(logger); } } -let lastLogger: { deref(): Logger } | undefined; -let lastLevel: LogLevel | undefined; -let lastLevelLogger: Logger; +const noopLogger = { + error: noop, + warn: noop, + info: noop, + debug: noop, +}; + +let cachedLoggers = new WeakMap(); + +export function loggerFor(client: BaseAnthropic): Logger { + const logger = client.logger; + const logLevel = client.logLevel ?? 'off'; + if (!logger) { + return noopLogger; + } -export function logger(client: BaseAnthropic): Logger { - let { logger, logLevel: clientLevel } = client; - if (lastLevel === clientLevel && (logger === lastLogger || logger === lastLogger?.deref())) { - return lastLevelLogger; + const cachedLogger = cachedLoggers.get(logger); + if (cachedLogger && cachedLogger[0] === logLevel) { + return cachedLogger[1]; } + const levelLogger = { - error: logFn(logger, clientLevel, 'error'), - warn: logFn(logger, clientLevel, 'warn'), - info: logFn(logger, clientLevel, 'info'), - debug: logFn(logger, clientLevel, 'debug'), + error: makeLogFn('error', logger, logLevel), + warn: makeLogFn('warn', logger, logLevel), + info: makeLogFn('info', logger, logLevel), + debug: makeLogFn('debug', logger, logLevel), }; - const { WeakRef } = globalThis as any; - lastLogger = - logger ? - WeakRef ? new WeakRef(logger) - : { deref: () => logger } - : undefined; - lastLevel = clientLevel; - lastLevelLogger = levelLogger; + + cachedLoggers.set(logger, [logLevel, levelLogger]); + return levelLogger; } + +export const formatRequestDetails = (details: { + options?: RequestOptions | undefined; + headers?: Headers | Record | undefined; + retryOfRequestLogID?: string | undefined; + retryOf?: string | undefined; + url?: string | undefined; + status?: number | undefined; + method?: string | undefined; + durationMs?: number | undefined; + message?: unknown; + body?: unknown; +}) => { + if (details.options) { + details.options = { ...details.options }; + delete details.options['headers']; // redundant + leaks internals + } + if (details.headers) { + details.headers = Object.fromEntries( + (details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map( + ([name, value]) => [ + name, + ( + name.toLowerCase() === 'x-api-key' || + name.toLowerCase() === 'authorization' || + name.toLowerCase() === 'cookie' || + name.toLowerCase() === 'set-cookie' + ) ? + '***' + : value, + ], + ), + ); + } + if ('retryOfRequestLogID' in details) { + if (details.retryOfRequestLogID) { + details.retryOf = details.retryOfRequestLogID; + } + delete details.retryOfRequestLogID; + } + return details; +}; diff --git a/src/internal/utils/values.ts b/src/internal/utils/values.ts index 68b55f9c..e2b6b4a8 100644 --- a/src/internal/utils/values.ts +++ b/src/internal/utils/values.ts @@ -26,7 +26,7 @@ export function isEmptyObj(obj: Object | null | undefined): boolean { } // https://eslint.org/docs/latest/rules/no-prototype-builtins -export function hasOwn(obj: Object, key: string): boolean { +export function hasOwn(obj: T, key: PropertyKey): key is keyof T { return Object.prototype.hasOwnProperty.call(obj, key); } diff --git a/tests/index.test.ts b/tests/index.test.ts index e90b140f..c7fd713a 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -13,8 +13,6 @@ describe('instantiate client', () => { beforeEach(() => { jest.resetModules(); process.env = { ...env }; - - console.warn = jest.fn(); }); afterEach(() => { @@ -52,16 +50,26 @@ describe('instantiate client', () => { }); }); describe('logging', () => { - afterEach(() => { + const env = process.env; + + beforeEach(() => { + process.env = { ...env }; process.env['ANTHROPIC_LOG'] = undefined; }); + afterEach(() => { + process.env = env; + }); + const forceAPIResponseForClient = async (client: Anthropic) => { await new APIPromise( client, Promise.resolve({ response: new Response(), controller: new AbortController(), + requestLogID: 'log_000000', + retryOfRequestLogID: undefined, + startTime: Date.now(), options: { method: 'get', path: '/', @@ -85,6 +93,11 @@ describe('instantiate client', () => { expect(debugMock).toHaveBeenCalled(); }); + test('default logLevel is warn', async () => { + const client = new Anthropic({ apiKey: 'my-anthropic-api-key' }); + expect(client.logLevel).toBe('warn'); + }); + test('debug logs are skipped when log level is info', async () => { const debugMock = jest.fn(); const logger = { @@ -111,11 +124,29 @@ describe('instantiate client', () => { process.env['ANTHROPIC_LOG'] = 'debug'; const client = new Anthropic({ logger: logger, apiKey: 'my-anthropic-api-key' }); + expect(client.logLevel).toBe('debug'); await forceAPIResponseForClient(client); expect(debugMock).toHaveBeenCalled(); }); + test('warn when env var level is invalid', async () => { + const warnMock = jest.fn(); + const logger = { + debug: jest.fn(), + info: jest.fn(), + warn: warnMock, + error: jest.fn(), + }; + + process.env['ANTHROPIC_LOG'] = 'not a log level'; + const client = new Anthropic({ logger: logger, apiKey: 'my-anthropic-api-key' }); + expect(client.logLevel).toBe('warn'); + expect(warnMock).toHaveBeenCalledWith( + 'process.env[\'ANTHROPIC_LOG\'] was set to "not a log level", expected one of ["off","error","warn","info","debug"]', + ); + }); + test('client log level overrides env var', async () => { const debugMock = jest.fn(); const logger = { @@ -131,6 +162,21 @@ describe('instantiate client', () => { await forceAPIResponseForClient(client); expect(debugMock).not.toHaveBeenCalled(); }); + + test('no warning logged for invalid env var level + valid client level', async () => { + const warnMock = jest.fn(); + const logger = { + debug: jest.fn(), + info: jest.fn(), + warn: warnMock, + error: jest.fn(), + }; + + process.env['ANTHROPIC_LOG'] = 'not a log level'; + const client = new Anthropic({ logger: logger, logLevel: 'debug', apiKey: 'my-anthropic-api-key' }); + expect(client.logLevel).toBe('debug'); + expect(warnMock).not.toHaveBeenCalled(); + }); }); describe('defaultQuery', () => { From 28d3e35dc9d275e5d1f655b359107085f64e11ac Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Fri, 21 Feb 2025 15:08:06 +0000 Subject: [PATCH 034/105] chore(internal): fix devcontainers setup --- .devcontainer/Dockerfile | 23 ----------------------- .devcontainer/devcontainer.json | 27 ++++++++++++--------------- 2 files changed, 12 insertions(+), 38 deletions(-) delete mode 100644 .devcontainer/Dockerfile diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 8ea34be9..00000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# syntax=docker/dockerfile:1 -FROM debian:bookworm-slim AS stainless - -RUN apt-get update && apt-get install -y \ - nodejs \ - npm \ - yarnpkg \ - && apt-get clean autoclean - -# Ensure UTF-8 encoding -ENV LANG=C.UTF-8 -ENV LC_ALL=C.UTF-8 - -# Yarn -RUN ln -sf /usr/bin/yarnpkg /usr/bin/yarn - -WORKDIR /workspace - -COPY package.json yarn.lock /workspace/ - -RUN yarn install - -COPY . /workspace diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d55fc4d6..763462fa 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,20 +1,17 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the // README at: https://github.com/devcontainers/templates/tree/main/src/debian { - "name": "Debian", - "build": { - "dockerfile": "Dockerfile" + "name": "Development", + "image": "mcr.microsoft.com/devcontainers/typescript-node:latest", + "features": { + "ghcr.io/devcontainers/features/node:1": {} + }, + "postCreateCommand": "yarn install", + "customizations": { + "vscode": { + "extensions": [ + "esbenp.prettier-vscode" + ] + } } - - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Configure tool-specific properties. - // "customizations": {}, - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" } From 569e55e8557a8731083f5de1af158c05f226f489 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Fri, 21 Feb 2025 15:17:51 +0000 Subject: [PATCH 035/105] chore(internal): remove unnecessary todo --- src/internal/errors.ts | 2 +- src/internal/parse.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/internal/errors.ts b/src/internal/errors.ts index 653a6ecb..82c7b14d 100644 --- a/src/internal/errors.ts +++ b/src/internal/errors.ts @@ -22,7 +22,7 @@ export const castToError = (err: any): Error => { // @ts-ignore - not all envs have native support for cause yet if (err.cause && !error.cause) error.cause = err.cause; if (err.name) error.name = err.name; - throw error; + return error; } } catch {} try { diff --git a/src/internal/parse.ts b/src/internal/parse.ts index cd0e217a..6eaf973c 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -52,8 +52,6 @@ export async function defaultParseResponse( } const text = await response.text(); - - // TODO handle blob, arraybuffer, other content types, etc. return text as unknown as T; })(); loggerFor(client).debug( From 521d6cda1c43bad9b0ef110809e0d3e7cd411a0d Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Wed, 26 Feb 2025 10:33:29 +0000 Subject: [PATCH 036/105] fix(streaming): handle more AbortError cases --- packages/bedrock-sdk/src/streaming.ts | 13 ++++++++++++- src/lib/MessageStream.ts | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/bedrock-sdk/src/streaming.ts b/packages/bedrock-sdk/src/streaming.ts index 01f0956b..7f054c39 100644 --- a/packages/bedrock-sdk/src/streaming.ts +++ b/packages/bedrock-sdk/src/streaming.ts @@ -90,7 +90,7 @@ export class Stream extends CoreStream { done = true; } catch (e) { // If the user calls `stream.controller.abort()`, we should exit without throwing. - if (e instanceof Error && e.name === 'AbortError') return; + if (isAbortError(e)) return; throw e; } finally { // If the user `break`s, abort the ongoing request. @@ -101,3 +101,14 @@ export class Stream extends CoreStream { return new Stream(iterator, controller); } } + +function isAbortError(err: unknown) { + return ( + typeof err === 'object' && + err !== null && + // Spec-compliant fetch implementations + (('name' in err && (err as any).name === 'AbortError') || + // Expo fetch + ('message' in err && String((err as any).message).includes('FetchRequestCanceledException'))) + ); +} diff --git a/src/lib/MessageStream.ts b/src/lib/MessageStream.ts index 6e55f72d..083aa24b 100644 --- a/src/lib/MessageStream.ts +++ b/src/lib/MessageStream.ts @@ -1,3 +1,4 @@ +import { isAbortError } from '../internal/errors'; import { AnthropicError, APIUserAbortError } from '../error'; import { type ContentBlock, @@ -289,7 +290,7 @@ export class MessageStream implements AsyncIterable { #handleError = (error: unknown) => { this.#errored = true; - if (error instanceof Error && error.name === 'AbortError') { + if (isAbortError(error)) { error = new APIUserAbortError(); } if (error instanceof APIUserAbortError) { From 75f4afe53ca49e5a3bf3ec064c85c5b097b68fe4 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 24 Feb 2025 18:10:26 +0000 Subject: [PATCH 037/105] feat(api): add claude-3.7 + support for thinking --- .stats.yml | 2 +- api.md | 25 ++ src/client.ts | 26 ++ src/resources/beta/beta.ts | 29 ++- src/resources/beta/index.ts | 12 + src/resources/beta/messages/batches.ts | 18 ++ src/resources/beta/messages/index.ts | 12 + src/resources/beta/messages/messages.ts | 222 +++++++++++++++++- src/resources/index.ts | 13 + src/resources/messages/batches.ts | 18 ++ src/resources/messages/index.ts | 13 + src/resources/messages/messages.ts | 184 ++++++++++++++- .../beta/messages/batches.test.ts | 23 +- .../beta/messages/messages.test.ts | 40 ++-- tests/api-resources/completions.test.ts | 4 +- tests/api-resources/messages/batches.test.ts | 23 +- tests/api-resources/messages/messages.test.ts | 40 +--- 17 files changed, 585 insertions(+), 119 deletions(-) diff --git a/.stats.yml b/.stats.yml index b1ba6c6a..9bbd4b86 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-bda1c6bb3a8f16d4b0a936aa3a7b1618f23d38570547e7ef047a9c95265e6613.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-e1328d31b4446324096fb948bd5074b5ac00d7c7e3ce89b6974a1c5aebf5a64d.yml diff --git a/api.md b/api.md index c4454a79..79a0c211 100644 --- a/api.md +++ b/api.md @@ -41,6 +41,7 @@ Types: - ImageBlockParam - InputJSONDelta - Message +- MessageCountTokensTool - MessageDeltaEvent - MessageDeltaUsage - MessageParam @@ -58,17 +59,29 @@ Types: - RawMessageStartEvent - RawMessageStopEvent - RawMessageStreamEvent +- RedactedThinkingBlock +- RedactedThinkingBlockParam +- SignatureDelta - TextBlock - TextBlockParam - TextCitation - TextCitationParam - TextDelta +- ThinkingBlock +- ThinkingBlockParam +- ThinkingConfigDisabled +- ThinkingConfigEnabled +- ThinkingConfigParam +- ThinkingDelta - Tool +- ToolBash20250124 - ToolChoice - ToolChoiceAny - ToolChoiceAuto - ToolChoiceTool - ToolResultBlockParam +- ToolTextEditor20250124 +- ToolUnion - ToolUseBlock - ToolUseBlockParam - Usage @@ -175,20 +188,32 @@ Types: - BetaRawMessageStartEvent - BetaRawMessageStopEvent - BetaRawMessageStreamEvent +- BetaRedactedThinkingBlock +- BetaRedactedThinkingBlockParam +- BetaSignatureDelta - BetaTextBlock - BetaTextBlockParam - BetaTextCitation - BetaTextCitationParam - BetaTextDelta +- BetaThinkingBlock +- BetaThinkingBlockParam +- BetaThinkingConfigDisabled +- BetaThinkingConfigEnabled +- BetaThinkingConfigParam +- BetaThinkingDelta - BetaTool - BetaToolBash20241022 +- BetaToolBash20250124 - BetaToolChoice - BetaToolChoiceAny - BetaToolChoiceAuto - BetaToolChoiceTool - BetaToolComputerUse20241022 +- BetaToolComputerUse20250124 - BetaToolResultBlockParam - BetaToolTextEditor20241022 +- BetaToolTextEditor20250124 - BetaToolUnion - BetaToolUseBlock - BetaToolUseBlockParam diff --git a/src/client.ts b/src/client.ts index 01484aa3..4c2e5b2c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -71,6 +71,7 @@ import { Message, MessageStreamParams, MessageCountTokensParams, + MessageCountTokensTool, MessageCreateParams, MessageCreateParamsNonStreaming, MessageCreateParamsStreaming, @@ -92,17 +93,29 @@ import { RawMessageStartEvent, RawMessageStopEvent, RawMessageStreamEvent, + RedactedThinkingBlock, + RedactedThinkingBlockParam, + SignatureDelta, TextBlock, TextBlockParam, TextCitation, TextCitationParam, TextDelta, + ThinkingBlock, + ThinkingBlockParam, + ThinkingConfigDisabled, + ThinkingConfigEnabled, + ThinkingConfigParam, + ThinkingDelta, Tool, + ToolBash20250124, ToolChoice, ToolChoiceAny, ToolChoiceAuto, ToolChoiceTool, ToolResultBlockParam, + ToolTextEditor20250124, + ToolUnion, ToolUseBlock, ToolUseBlockParam, Usage, @@ -933,6 +946,7 @@ export declare namespace Anthropic { type ImageBlockParam as ImageBlockParam, type InputJSONDelta as InputJSONDelta, type Message as Message, + type MessageCountTokensTool as MessageCountTokensTool, type MessageDeltaEvent as MessageDeltaEvent, type MessageDeltaUsage as MessageDeltaUsage, type MessageParam as MessageParam, @@ -950,17 +964,29 @@ export declare namespace Anthropic { type RawMessageStartEvent as RawMessageStartEvent, type RawMessageStopEvent as RawMessageStopEvent, type RawMessageStreamEvent as RawMessageStreamEvent, + type RedactedThinkingBlock as RedactedThinkingBlock, + type RedactedThinkingBlockParam as RedactedThinkingBlockParam, + type SignatureDelta as SignatureDelta, type TextBlock as TextBlock, type TextBlockParam as TextBlockParam, type TextCitation as TextCitation, type TextCitationParam as TextCitationParam, type TextDelta as TextDelta, + type ThinkingBlock as ThinkingBlock, + type ThinkingBlockParam as ThinkingBlockParam, + type ThinkingConfigDisabled as ThinkingConfigDisabled, + type ThinkingConfigEnabled as ThinkingConfigEnabled, + type ThinkingConfigParam as ThinkingConfigParam, + type ThinkingDelta as ThinkingDelta, type Tool as Tool, + type ToolBash20250124 as ToolBash20250124, type ToolChoice as ToolChoice, type ToolChoiceAny as ToolChoiceAny, type ToolChoiceAuto as ToolChoiceAuto, type ToolChoiceTool as ToolChoiceTool, type ToolResultBlockParam as ToolResultBlockParam, + type ToolTextEditor20250124 as ToolTextEditor20250124, + type ToolUnion as ToolUnion, type ToolUseBlock as ToolUseBlock, type ToolUseBlockParam as ToolUseBlockParam, type Usage as Usage, diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index 3193d108..70ba4403 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -35,20 +35,32 @@ import { BetaRawMessageStartEvent, BetaRawMessageStopEvent, BetaRawMessageStreamEvent, + BetaRedactedThinkingBlock, + BetaRedactedThinkingBlockParam, + BetaSignatureDelta, BetaTextBlock, BetaTextBlockParam, BetaTextCitation, BetaTextCitationParam, BetaTextDelta, + BetaThinkingBlock, + BetaThinkingBlockParam, + BetaThinkingConfigDisabled, + BetaThinkingConfigEnabled, + BetaThinkingConfigParam, + BetaThinkingDelta, BetaTool, BetaToolBash20241022, + BetaToolBash20250124, BetaToolChoice, BetaToolChoiceAny, BetaToolChoiceAuto, BetaToolChoiceTool, BetaToolComputerUse20241022, + BetaToolComputerUse20250124, BetaToolResultBlockParam, BetaToolTextEditor20241022, + BetaToolTextEditor20250124, BetaToolUnion, BetaToolUseBlock, BetaToolUseBlockParam, @@ -70,8 +82,11 @@ export type AnthropicBeta = | 'message-batches-2024-09-24' | 'prompt-caching-2024-07-31' | 'computer-use-2024-10-22' + | 'computer-use-2025-01-24' | 'pdfs-2024-09-25' - | 'token-counting-2024-11-01'; + | 'token-counting-2024-11-01' + | 'token-efficient-tools-2025-02-19' + | 'output-128k-2025-02-19'; export interface BetaAPIError { message: string; @@ -202,20 +217,32 @@ export declare namespace Beta { type BetaRawMessageStartEvent as BetaRawMessageStartEvent, type BetaRawMessageStopEvent as BetaRawMessageStopEvent, type BetaRawMessageStreamEvent as BetaRawMessageStreamEvent, + type BetaRedactedThinkingBlock as BetaRedactedThinkingBlock, + type BetaRedactedThinkingBlockParam as BetaRedactedThinkingBlockParam, + type BetaSignatureDelta as BetaSignatureDelta, type BetaTextBlock as BetaTextBlock, type BetaTextBlockParam as BetaTextBlockParam, type BetaTextCitation as BetaTextCitation, type BetaTextCitationParam as BetaTextCitationParam, type BetaTextDelta as BetaTextDelta, + type BetaThinkingBlock as BetaThinkingBlock, + type BetaThinkingBlockParam as BetaThinkingBlockParam, + type BetaThinkingConfigDisabled as BetaThinkingConfigDisabled, + type BetaThinkingConfigEnabled as BetaThinkingConfigEnabled, + type BetaThinkingConfigParam as BetaThinkingConfigParam, + type BetaThinkingDelta as BetaThinkingDelta, type BetaTool as BetaTool, type BetaToolBash20241022 as BetaToolBash20241022, + type BetaToolBash20250124 as BetaToolBash20250124, type BetaToolChoice as BetaToolChoice, type BetaToolChoiceAny as BetaToolChoiceAny, type BetaToolChoiceAuto as BetaToolChoiceAuto, type BetaToolChoiceTool as BetaToolChoiceTool, type BetaToolComputerUse20241022 as BetaToolComputerUse20241022, + type BetaToolComputerUse20250124 as BetaToolComputerUse20250124, type BetaToolResultBlockParam as BetaToolResultBlockParam, type BetaToolTextEditor20241022 as BetaToolTextEditor20241022, + type BetaToolTextEditor20250124 as BetaToolTextEditor20250124, type BetaToolUnion as BetaToolUnion, type BetaToolUseBlock as BetaToolUseBlock, type BetaToolUseBlockParam as BetaToolUseBlockParam, diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts index e7ae649a..8bfb7c8e 100644 --- a/src/resources/beta/index.ts +++ b/src/resources/beta/index.ts @@ -47,20 +47,32 @@ export { type BetaRawMessageStartEvent, type BetaRawMessageStopEvent, type BetaRawMessageStreamEvent, + type BetaRedactedThinkingBlock, + type BetaRedactedThinkingBlockParam, + type BetaSignatureDelta, type BetaTextBlock, type BetaTextBlockParam, type BetaTextCitation, type BetaTextCitationParam, type BetaTextDelta, + type BetaThinkingBlock, + type BetaThinkingBlockParam, + type BetaThinkingConfigDisabled, + type BetaThinkingConfigEnabled, + type BetaThinkingConfigParam, + type BetaThinkingDelta, type BetaTool, type BetaToolBash20241022, + type BetaToolBash20250124, type BetaToolChoice, type BetaToolChoiceAny, type BetaToolChoiceAuto, type BetaToolChoiceTool, type BetaToolComputerUse20241022, + type BetaToolComputerUse20250124, type BetaToolResultBlockParam, type BetaToolTextEditor20241022, + type BetaToolTextEditor20250124, type BetaToolUnion, type BetaToolUseBlock, type BetaToolUseBlockParam, diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index 0a288202..4a0c91a0 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -18,6 +18,9 @@ export class Batches extends APIResource { * The Message Batches API can be used to process multiple Messages API requests at * once. Once a Message Batch is created, it begins processing immediately. Batches * can take up to 24 hours to complete. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ create(params: BatchCreateParams, options?: RequestOptions): APIPromise { const { betas, ...body } = params; @@ -35,6 +38,9 @@ export class Batches extends APIResource { * This endpoint is idempotent and can be used to poll for Message Batch * completion. To access the results of a Message Batch, make a request to the * `results_url` field in the response. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ retrieve( messageBatchID: string, @@ -54,6 +60,9 @@ export class Batches extends APIResource { /** * List all Message Batches within a Workspace. Most recently created batches are * returned first. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ list( params: BatchListParams | null | undefined = {}, @@ -75,6 +84,9 @@ export class Batches extends APIResource { * * Message Batches can only be deleted once they've finished processing. If you'd * like to delete an in-progress batch, you must first cancel it. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ delete( messageBatchID: string, @@ -101,6 +113,9 @@ export class Batches extends APIResource { * which requests were canceled, check the individual results within the batch. * Note that cancellation may not result in any canceled requests if they were * non-interruptible. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ cancel( messageBatchID: string, @@ -123,6 +138,9 @@ export class Batches extends APIResource { * Each line in the file is a JSON object containing the result of a single request * in the Message Batch. Results are not guaranteed to be in the same order as * requests. Use the `custom_id` field to match results to requests. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ async results( messageBatchID: string, diff --git a/src/resources/beta/messages/index.ts b/src/resources/beta/messages/index.ts index 31c4e519..127849bb 100644 --- a/src/resources/beta/messages/index.ts +++ b/src/resources/beta/messages/index.ts @@ -51,20 +51,32 @@ export { type BetaRawMessageStartEvent, type BetaRawMessageStopEvent, type BetaRawMessageStreamEvent, + type BetaRedactedThinkingBlock, + type BetaRedactedThinkingBlockParam, + type BetaSignatureDelta, type BetaTextBlock, type BetaTextBlockParam, type BetaTextCitation, type BetaTextCitationParam, type BetaTextDelta, + type BetaThinkingBlock, + type BetaThinkingBlockParam, + type BetaThinkingConfigDisabled, + type BetaThinkingConfigEnabled, + type BetaThinkingConfigParam, + type BetaThinkingDelta, type BetaTool, type BetaToolBash20241022, + type BetaToolBash20250124, type BetaToolChoice, type BetaToolChoiceAny, type BetaToolChoiceAuto, type BetaToolChoiceTool, type BetaToolComputerUse20241022, + type BetaToolComputerUse20250124, type BetaToolResultBlockParam, type BetaToolTextEditor20241022, + type BetaToolTextEditor20250124, type BetaToolUnion, type BetaToolUseBlock, type BetaToolUseBlockParam, diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index 4e6f4dde..d27d9a9a 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -38,6 +38,8 @@ export class Messages extends APIResource { * * The Messages API can be used for either single queries or stateless multi-turn * conversations. + * + * Learn more about the Messages API in our [user guide](/en/docs/initial-setup) */ create(params: MessageCreateParamsNonStreaming, options?: RequestOptions): APIPromise; create( @@ -70,6 +72,9 @@ export class Messages extends APIResource { * * The Token Count API can be used to count the number of tokens in a Message, * including tools, images, and documents, without creating it. + * + * Learn more about token counting in our + * [user guide](/en/docs/build-with-claude/token-counting) */ countTokens( params: MessageCountTokensParams, @@ -207,14 +212,20 @@ export interface BetaCitationsDelta { type: 'citations_delta'; } -export type BetaContentBlock = BetaTextBlock | BetaToolUseBlock; +export type BetaContentBlock = + | BetaTextBlock + | BetaToolUseBlock + | BetaThinkingBlock + | BetaRedactedThinkingBlock; export type BetaContentBlockParam = | BetaTextBlockParam | BetaImageBlockParam | BetaToolUseBlockParam | BetaToolResultBlockParam - | BetaBase64PDFBlock; + | BetaBase64PDFBlock + | BetaThinkingBlockParam + | BetaRedactedThinkingBlockParam; export interface BetaContentBlockSource { content: string | Array; @@ -349,6 +360,9 @@ export interface BetaMessage { * * For example, `output_tokens` will be non-zero, even for an empty string response * from Claude. + * + * Total input tokens in a request is the summation of `input_tokens`, + * `cache_creation_input_tokens`, and `cache_read_input_tokens`. */ usage: BetaUsage; } @@ -394,7 +408,7 @@ export interface BetaPlainTextSource { } export interface BetaRawContentBlockDeltaEvent { - delta: BetaTextDelta | BetaInputJSONDelta | BetaCitationsDelta; + delta: BetaTextDelta | BetaInputJSONDelta | BetaCitationsDelta | BetaThinkingDelta | BetaSignatureDelta; index: number; @@ -402,7 +416,7 @@ export interface BetaRawContentBlockDeltaEvent { } export interface BetaRawContentBlockStartEvent { - content_block: BetaTextBlock | BetaToolUseBlock; + content_block: BetaTextBlock | BetaToolUseBlock | BetaThinkingBlock | BetaRedactedThinkingBlock; index: number; @@ -433,6 +447,9 @@ export interface BetaRawMessageDeltaEvent { * * For example, `output_tokens` will be non-zero, even for an empty string response * from Claude. + * + * Total input tokens in a request is the summation of `input_tokens`, + * `cache_creation_input_tokens`, and `cache_read_input_tokens`. */ usage: BetaMessageDeltaUsage; } @@ -463,6 +480,24 @@ export type BetaRawMessageStreamEvent = | BetaRawContentBlockDeltaEvent | BetaRawContentBlockStopEvent; +export interface BetaRedactedThinkingBlock { + data: string; + + type: 'redacted_thinking'; +} + +export interface BetaRedactedThinkingBlockParam { + data: string; + + type: 'redacted_thinking'; +} + +export interface BetaSignatureDelta { + signature: string; + + type: 'signature_delta'; +} + export interface BetaTextBlock { /** * Citations supporting the text block. @@ -504,9 +539,65 @@ export interface BetaTextDelta { type: 'text_delta'; } +export interface BetaThinkingBlock { + signature: string; + + thinking: string; + + type: 'thinking'; +} + +export interface BetaThinkingBlockParam { + signature: string; + + thinking: string; + + type: 'thinking'; +} + +export interface BetaThinkingConfigDisabled { + type: 'disabled'; +} + +export interface BetaThinkingConfigEnabled { + /** + * Determines how many tokens Claude can use for its internal reasoning process. + * Larger budgets can enable more thorough analysis for complex problems, improving + * response quality. + * + * Must be ≥1024 and less than `max_tokens`. + * + * See + * [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + * for details. + */ + budget_tokens: number; + + type: 'enabled'; +} + +/** + * Configuration for enabling Claude's extended thinking. + * + * When enabled, responses include `thinking` content blocks showing Claude's + * thinking process before the final answer. Requires a minimum budget of 1,024 + * tokens and counts towards your `max_tokens` limit. + * + * See + * [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + * for details. + */ +export type BetaThinkingConfigParam = BetaThinkingConfigEnabled | BetaThinkingConfigDisabled; + +export interface BetaThinkingDelta { + thinking: string; + + type: 'thinking_delta'; +} + export interface BetaTool { /** - * [JSON schema](https://json-schema.org/) for this tool's input. + * [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. * * This defines the shape of the `input` that your tool accepts and that the model * will produce. @@ -537,7 +628,7 @@ export interface BetaTool { export namespace BetaTool { /** - * [JSON schema](https://json-schema.org/) for this tool's input. + * [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. * * This defines the shape of the `input` that your tool accepts and that the model * will produce. @@ -563,6 +654,19 @@ export interface BetaToolBash20241022 { cache_control?: BetaCacheControlEphemeral | null; } +export interface BetaToolBash20250124 { + /** + * Name of the tool. + * + * This is how the tool will be called by the model and in tool_use blocks. + */ + name: 'bash'; + + type: 'bash_20250124'; + + cache_control?: BetaCacheControlEphemeral | null; +} + /** * How the model should use the provided tools. The model can use a specific tool, * any available tool, or decide by itself. @@ -647,6 +751,34 @@ export interface BetaToolComputerUse20241022 { display_number?: number | null; } +export interface BetaToolComputerUse20250124 { + /** + * The height of the display in pixels. + */ + display_height_px: number; + + /** + * The width of the display in pixels. + */ + display_width_px: number; + + /** + * Name of the tool. + * + * This is how the tool will be called by the model and in tool_use blocks. + */ + name: 'computer'; + + type: 'computer_20250124'; + + cache_control?: BetaCacheControlEphemeral | null; + + /** + * The X11 display number (e.g. 0, 1) for the display. + */ + display_number?: number | null; +} + export interface BetaToolResultBlockParam { tool_use_id: string; @@ -672,11 +804,27 @@ export interface BetaToolTextEditor20241022 { cache_control?: BetaCacheControlEphemeral | null; } +export interface BetaToolTextEditor20250124 { + /** + * Name of the tool. + * + * This is how the tool will be called by the model and in tool_use blocks. + */ + name: 'str_replace_editor'; + + type: 'text_editor_20250124'; + + cache_control?: BetaCacheControlEphemeral | null; +} + export type BetaToolUnion = - | BetaTool | BetaToolComputerUse20241022 | BetaToolBash20241022 - | BetaToolTextEditor20241022; + | BetaToolTextEditor20241022 + | BetaToolComputerUse20250124 + | BetaToolBash20250124 + | BetaToolTextEditor20250124 + | BetaTool; export interface BetaToolUseBlock { id: string; @@ -881,6 +1029,19 @@ export interface MessageCreateParamsBase { */ temperature?: number; + /** + * Body param: Configuration for enabling Claude's extended thinking. + * + * When enabled, responses include `thinking` content blocks showing Claude's + * thinking process before the final answer. Requires a minimum budget of 1,024 + * tokens and counts towards your `max_tokens` limit. + * + * See + * [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + * for details. + */ + thinking?: BetaThinkingConfigParam; + /** * Body param: How the model should use the provided tools. The model can use a * specific tool, any available tool, or decide by itself. @@ -899,8 +1060,9 @@ export interface MessageCreateParamsBase { * * - `name`: Name of the tool. * - `description`: Optional, but strongly-recommended description of the tool. - * - `input_schema`: [JSON schema](https://json-schema.org/) for the tool `input` - * shape that the model will produce in `tool_use` output content blocks. + * - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the + * tool `input` shape that the model will produce in `tool_use` output content + * blocks. * * For example, if you defined `tools` as: * @@ -1123,6 +1285,19 @@ export interface MessageCountTokensParams { */ system?: string | Array; + /** + * Body param: Configuration for enabling Claude's extended thinking. + * + * When enabled, responses include `thinking` content blocks showing Claude's + * thinking process before the final answer. Requires a minimum budget of 1,024 + * tokens and counts towards your `max_tokens` limit. + * + * See + * [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + * for details. + */ + thinking?: BetaThinkingConfigParam; + /** * Body param: How the model should use the provided tools. The model can use a * specific tool, any available tool, or decide by itself. @@ -1141,8 +1316,9 @@ export interface MessageCountTokensParams { * * - `name`: Name of the tool. * - `description`: Optional, but strongly-recommended description of the tool. - * - `input_schema`: [JSON schema](https://json-schema.org/) for the tool `input` - * shape that the model will produce in `tool_use` output content blocks. + * - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the + * tool `input` shape that the model will produce in `tool_use` output content + * blocks. * * For example, if you defined `tools` as: * @@ -1199,7 +1375,15 @@ export interface MessageCountTokensParams { * * See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. */ - tools?: Array; + tools?: Array< + | BetaToolComputerUse20241022 + | BetaToolBash20241022 + | BetaToolTextEditor20241022 + | BetaToolComputerUse20250124 + | BetaToolBash20250124 + | BetaToolTextEditor20250124 + | BetaTool + >; /** * Header param: Optional header to specify the beta version(s) you want to use. @@ -1241,20 +1425,32 @@ export declare namespace Messages { type BetaRawMessageStartEvent as BetaRawMessageStartEvent, type BetaRawMessageStopEvent as BetaRawMessageStopEvent, type BetaRawMessageStreamEvent as BetaRawMessageStreamEvent, + type BetaRedactedThinkingBlock as BetaRedactedThinkingBlock, + type BetaRedactedThinkingBlockParam as BetaRedactedThinkingBlockParam, + type BetaSignatureDelta as BetaSignatureDelta, type BetaTextBlock as BetaTextBlock, type BetaTextBlockParam as BetaTextBlockParam, type BetaTextCitation as BetaTextCitation, type BetaTextCitationParam as BetaTextCitationParam, type BetaTextDelta as BetaTextDelta, + type BetaThinkingBlock as BetaThinkingBlock, + type BetaThinkingBlockParam as BetaThinkingBlockParam, + type BetaThinkingConfigDisabled as BetaThinkingConfigDisabled, + type BetaThinkingConfigEnabled as BetaThinkingConfigEnabled, + type BetaThinkingConfigParam as BetaThinkingConfigParam, + type BetaThinkingDelta as BetaThinkingDelta, type BetaTool as BetaTool, type BetaToolBash20241022 as BetaToolBash20241022, + type BetaToolBash20250124 as BetaToolBash20250124, type BetaToolChoice as BetaToolChoice, type BetaToolChoiceAny as BetaToolChoiceAny, type BetaToolChoiceAuto as BetaToolChoiceAuto, type BetaToolChoiceTool as BetaToolChoiceTool, type BetaToolComputerUse20241022 as BetaToolComputerUse20241022, + type BetaToolComputerUse20250124 as BetaToolComputerUse20250124, type BetaToolResultBlockParam as BetaToolResultBlockParam, type BetaToolTextEditor20241022 as BetaToolTextEditor20241022, + type BetaToolTextEditor20250124 as BetaToolTextEditor20250124, type BetaToolUnion as BetaToolUnion, type BetaToolUseBlock as BetaToolUseBlock, type BetaToolUseBlockParam as BetaToolUseBlockParam, diff --git a/src/resources/index.ts b/src/resources/index.ts index 0bd0fa05..a6cce09c 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -47,6 +47,7 @@ export { type InputJsonDelta, type InputJSONDelta, type Message, + type MessageCountTokensTool, type MessageDeltaEvent, type MessageDeltaUsage, type MessageParam, @@ -65,17 +66,29 @@ export { type RawMessageStartEvent, type RawMessageStopEvent, type RawMessageStreamEvent, + type RedactedThinkingBlock, + type RedactedThinkingBlockParam, + type SignatureDelta, type TextBlock, type TextBlockParam, type TextCitation, type TextCitationParam, type TextDelta, + type ThinkingBlock, + type ThinkingBlockParam, + type ThinkingConfigDisabled, + type ThinkingConfigEnabled, + type ThinkingConfigParam, + type ThinkingDelta, type Tool, + type ToolBash20250124, type ToolChoice, type ToolChoiceAny, type ToolChoiceAuto, type ToolChoiceTool, type ToolResultBlockParam, + type ToolTextEditor20250124, + type ToolUnion, type ToolUseBlock, type ToolUseBlockParam, type Usage, diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index 5c17dd87..f2212dc3 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -18,6 +18,9 @@ export class Batches extends APIResource { * The Message Batches API can be used to process multiple Messages API requests at * once. Once a Message Batch is created, it begins processing immediately. Batches * can take up to 24 hours to complete. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ create(body: BatchCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/v1/messages/batches', { body, ...options }); @@ -27,6 +30,9 @@ export class Batches extends APIResource { * This endpoint is idempotent and can be used to poll for Message Batch * completion. To access the results of a Message Batch, make a request to the * `results_url` field in the response. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ retrieve(messageBatchID: string, options?: RequestOptions): APIPromise { return this._client.get(path`/v1/messages/batches/${messageBatchID}`, options); @@ -35,6 +41,9 @@ export class Batches extends APIResource { /** * List all Message Batches within a Workspace. Most recently created batches are * returned first. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ list( query: BatchListParams | null | undefined = {}, @@ -48,6 +57,9 @@ export class Batches extends APIResource { * * Message Batches can only be deleted once they've finished processing. If you'd * like to delete an in-progress batch, you must first cancel it. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ delete(messageBatchID: string, options?: RequestOptions): APIPromise { return this._client.delete(path`/v1/messages/batches/${messageBatchID}`, options); @@ -63,6 +75,9 @@ export class Batches extends APIResource { * which requests were canceled, check the individual results within the batch. * Note that cancellation may not result in any canceled requests if they were * non-interruptible. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ cancel(messageBatchID: string, options?: RequestOptions): APIPromise { return this._client.post(path`/v1/messages/batches/${messageBatchID}/cancel`, options); @@ -74,6 +89,9 @@ export class Batches extends APIResource { * Each line in the file is a JSON object containing the result of a single request * in the Message Batch. Results are not guaranteed to be in the same order as * requests. Use the `custom_id` field to match results to requests. + * + * Learn more about the Message Batches API in our + * [user guide](/en/docs/build-with-claude/batch-processing) */ async results( messageBatchID: string, diff --git a/src/resources/messages/index.ts b/src/resources/messages/index.ts index 9468a983..4988daab 100644 --- a/src/resources/messages/index.ts +++ b/src/resources/messages/index.ts @@ -38,6 +38,7 @@ export { type ImageBlockParam, type InputJSONDelta, type Message, + type MessageCountTokensTool, type MessageDeltaEvent, type MessageDeltaUsage, type MessageParam, @@ -55,17 +56,29 @@ export { type RawMessageStartEvent, type RawMessageStopEvent, type RawMessageStreamEvent, + type RedactedThinkingBlock, + type RedactedThinkingBlockParam, + type SignatureDelta, type TextBlock, type TextBlockParam, type TextCitation, type TextCitationParam, type TextDelta, + type ThinkingBlock, + type ThinkingBlockParam, + type ThinkingConfigDisabled, + type ThinkingConfigEnabled, + type ThinkingConfigParam, + type ThinkingDelta, type Tool, + type ToolBash20250124, type ToolChoice, type ToolChoiceAny, type ToolChoiceAuto, type ToolChoiceTool, type ToolResultBlockParam, + type ToolTextEditor20250124, + type ToolUnion, type ToolUseBlock, type ToolUseBlockParam, type Usage, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index 0af67c54..c1ebd18a 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -34,6 +34,8 @@ export class Messages extends APIResource { * * The Messages API can be used for either single queries or stateless multi-turn * conversations. + * + * Learn more about the Messages API in our [user guide](/en/docs/initial-setup) */ create(body: MessageCreateParamsNonStreaming, options?: RequestOptions): APIPromise; create( @@ -75,6 +77,9 @@ export class Messages extends APIResource { * * The Token Count API can be used to count the number of tokens in a Message, * including tools, images, and documents, without creating it. + * + * Learn more about token counting in our + * [user guide](/en/docs/build-with-claude/token-counting) */ countTokens(body: MessageCountTokensParams, options?: RequestOptions): APIPromise { return this._client.post('/v1/messages/count_tokens', { body, ...options }); @@ -187,7 +192,7 @@ export interface CitationsDelta { type: 'citations_delta'; } -export type ContentBlock = TextBlock | ToolUseBlock; +export type ContentBlock = TextBlock | ToolUseBlock | ThinkingBlock | RedactedThinkingBlock; export type ContentBlockDeltaEvent = RawContentBlockDeltaEvent; @@ -196,7 +201,9 @@ export type ContentBlockParam = | ImageBlockParam | ToolUseBlockParam | ToolResultBlockParam - | DocumentBlockParam; + | DocumentBlockParam + | ThinkingBlockParam + | RedactedThinkingBlockParam; export type ContentBlockStartEvent = RawContentBlockStartEvent; @@ -351,10 +358,15 @@ export interface Message { * * For example, `output_tokens` will be non-zero, even for an empty string response * from Claude. + * + * Total input tokens in a request is the summation of `input_tokens`, + * `cache_creation_input_tokens`, and `cache_read_input_tokens`. */ usage: Usage; } +export type MessageCountTokensTool = ToolBash20250124 | ToolTextEditor20250124 | Tool; + export type MessageDeltaEvent = RawMessageDeltaEvent; export interface MessageDeltaUsage { @@ -401,6 +413,8 @@ export interface Metadata { * details and options. */ export type Model = + | 'claude-3-7-sonnet-latest' + | 'claude-3-7-sonnet-20250219' | 'claude-3-5-haiku-latest' | 'claude-3-5-haiku-20241022' | 'claude-3-5-sonnet-latest' @@ -435,7 +449,7 @@ export interface PlainTextSource { } export interface RawContentBlockDeltaEvent { - delta: TextDelta | InputJSONDelta | CitationsDelta; + delta: TextDelta | InputJSONDelta | CitationsDelta | ThinkingDelta | SignatureDelta; index: number; @@ -443,7 +457,7 @@ export interface RawContentBlockDeltaEvent { } export interface RawContentBlockStartEvent { - content_block: TextBlock | ToolUseBlock; + content_block: TextBlock | ToolUseBlock | ThinkingBlock | RedactedThinkingBlock; index: number; @@ -474,6 +488,9 @@ export interface RawMessageDeltaEvent { * * For example, `output_tokens` will be non-zero, even for an empty string response * from Claude. + * + * Total input tokens in a request is the summation of `input_tokens`, + * `cache_creation_input_tokens`, and `cache_read_input_tokens`. */ usage: MessageDeltaUsage; } @@ -504,6 +521,24 @@ export type RawMessageStreamEvent = | RawContentBlockDeltaEvent | RawContentBlockStopEvent; +export interface RedactedThinkingBlock { + data: string; + + type: 'redacted_thinking'; +} + +export interface RedactedThinkingBlockParam { + data: string; + + type: 'redacted_thinking'; +} + +export interface SignatureDelta { + signature: string; + + type: 'signature_delta'; +} + export interface TextBlock { /** * Citations supporting the text block. @@ -542,9 +577,65 @@ export interface TextDelta { type: 'text_delta'; } +export interface ThinkingBlock { + signature: string; + + thinking: string; + + type: 'thinking'; +} + +export interface ThinkingBlockParam { + signature: string; + + thinking: string; + + type: 'thinking'; +} + +export interface ThinkingConfigDisabled { + type: 'disabled'; +} + +export interface ThinkingConfigEnabled { + /** + * Determines how many tokens Claude can use for its internal reasoning process. + * Larger budgets can enable more thorough analysis for complex problems, improving + * response quality. + * + * Must be ≥1024 and less than `max_tokens`. + * + * See + * [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + * for details. + */ + budget_tokens: number; + + type: 'enabled'; +} + +/** + * Configuration for enabling Claude's extended thinking. + * + * When enabled, responses include `thinking` content blocks showing Claude's + * thinking process before the final answer. Requires a minimum budget of 1,024 + * tokens and counts towards your `max_tokens` limit. + * + * See + * [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + * for details. + */ +export type ThinkingConfigParam = ThinkingConfigEnabled | ThinkingConfigDisabled; + +export interface ThinkingDelta { + thinking: string; + + type: 'thinking_delta'; +} + export interface Tool { /** - * [JSON schema](https://json-schema.org/) for this tool's input. + * [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. * * This defines the shape of the `input` that your tool accepts and that the model * will produce. @@ -573,7 +664,7 @@ export interface Tool { export namespace Tool { /** - * [JSON schema](https://json-schema.org/) for this tool's input. + * [JSON schema](https://json-schema.org/draft/2020-12) for this tool's input. * * This defines the shape of the `input` that your tool accepts and that the model * will produce. @@ -586,6 +677,19 @@ export namespace Tool { } } +export interface ToolBash20250124 { + /** + * Name of the tool. + * + * This is how the tool will be called by the model and in tool_use blocks. + */ + name: 'bash'; + + type: 'bash_20250124'; + + cache_control?: CacheControlEphemeral | null; +} + /** * How the model should use the provided tools. The model can use a specific tool, * any available tool, or decide by itself. @@ -654,6 +758,21 @@ export interface ToolResultBlockParam { is_error?: boolean; } +export interface ToolTextEditor20250124 { + /** + * Name of the tool. + * + * This is how the tool will be called by the model and in tool_use blocks. + */ + name: 'str_replace_editor'; + + type: 'text_editor_20250124'; + + cache_control?: CacheControlEphemeral | null; +} + +export type ToolUnion = ToolBash20250124 | ToolTextEditor20250124 | Tool; + export interface ToolUseBlock { id: string; @@ -856,6 +975,19 @@ export interface MessageCreateParamsBase { */ temperature?: number; + /** + * Configuration for enabling Claude's extended thinking. + * + * When enabled, responses include `thinking` content blocks showing Claude's + * thinking process before the final answer. Requires a minimum budget of 1,024 + * tokens and counts towards your `max_tokens` limit. + * + * See + * [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + * for details. + */ + thinking?: ThinkingConfigParam; + /** * How the model should use the provided tools. The model can use a specific tool, * any available tool, or decide by itself. @@ -874,8 +1006,9 @@ export interface MessageCreateParamsBase { * * - `name`: Name of the tool. * - `description`: Optional, but strongly-recommended description of the tool. - * - `input_schema`: [JSON schema](https://json-schema.org/) for the tool `input` - * shape that the model will produce in `tool_use` output content blocks. + * - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the + * tool `input` shape that the model will produce in `tool_use` output content + * blocks. * * For example, if you defined `tools` as: * @@ -932,7 +1065,7 @@ export interface MessageCreateParamsBase { * * See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. */ - tools?: Array; + tools?: Array; /** * Only sample from the top K options for each subsequent token. @@ -1113,6 +1246,19 @@ export interface MessageCountTokensParams { */ system?: string | Array; + /** + * Configuration for enabling Claude's extended thinking. + * + * When enabled, responses include `thinking` content blocks showing Claude's + * thinking process before the final answer. Requires a minimum budget of 1,024 + * tokens and counts towards your `max_tokens` limit. + * + * See + * [extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking) + * for details. + */ + thinking?: ThinkingConfigParam; + /** * How the model should use the provided tools. The model can use a specific tool, * any available tool, or decide by itself. @@ -1131,8 +1277,9 @@ export interface MessageCountTokensParams { * * - `name`: Name of the tool. * - `description`: Optional, but strongly-recommended description of the tool. - * - `input_schema`: [JSON schema](https://json-schema.org/) for the tool `input` - * shape that the model will produce in `tool_use` output content blocks. + * - `input_schema`: [JSON schema](https://json-schema.org/draft/2020-12) for the + * tool `input` shape that the model will produce in `tool_use` output content + * blocks. * * For example, if you defined `tools` as: * @@ -1189,7 +1336,7 @@ export interface MessageCountTokensParams { * * See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. */ - tools?: Array; + tools?: Array; } Messages.Batches = Batches; @@ -1218,6 +1365,7 @@ export declare namespace Messages { type InputJsonDelta as InputJsonDelta, type InputJSONDelta as InputJSONDelta, type Message as Message, + type MessageCountTokensTool as MessageCountTokensTool, type MessageDeltaEvent as MessageDeltaEvent, type MessageDeltaUsage as MessageDeltaUsage, type MessageParam as MessageParam, @@ -1235,17 +1383,29 @@ export declare namespace Messages { type RawMessageStartEvent as RawMessageStartEvent, type RawMessageStopEvent as RawMessageStopEvent, type RawMessageStreamEvent as RawMessageStreamEvent, + type RedactedThinkingBlock as RedactedThinkingBlock, + type RedactedThinkingBlockParam as RedactedThinkingBlockParam, + type SignatureDelta as SignatureDelta, type TextBlock as TextBlock, type TextBlockParam as TextBlockParam, type TextCitation as TextCitation, type TextCitationParam as TextCitationParam, type TextDelta as TextDelta, + type ThinkingBlock as ThinkingBlock, + type ThinkingBlockParam as ThinkingBlockParam, + type ThinkingConfigDisabled as ThinkingConfigDisabled, + type ThinkingConfigEnabled as ThinkingConfigEnabled, + type ThinkingConfigParam as ThinkingConfigParam, + type ThinkingDelta as ThinkingDelta, type Tool as Tool, + type ToolBash20250124 as ToolBash20250124, type ToolChoice as ToolChoice, type ToolChoiceAny as ToolChoiceAny, type ToolChoiceAuto as ToolChoiceAuto, type ToolChoiceTool as ToolChoiceTool, type ToolResultBlockParam as ToolResultBlockParam, + type ToolTextEditor20250124 as ToolTextEditor20250124, + type ToolUnion as ToolUnion, type ToolUseBlock as ToolUseBlock, type ToolUseBlockParam as ToolUseBlockParam, type Usage as Usage, diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index 9809ee96..d7242749 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -16,7 +16,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', }, }, ], @@ -38,7 +38,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, @@ -60,23 +60,16 @@ describe('resource batches', () => { }, ], temperature: 1, + thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { - description: 'Unit for the output - one of (celsius, fahrenheit)', - type: 'string', - }, - }, - }, - name: 'name', + display_height_px: 1, + display_width_px: 1, + name: 'computer', + type: 'computer_20241022', cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - type: 'custom', + display_number: 0, }, ], top_k: 5, diff --git a/tests/api-resources/beta/messages/messages.test.ts b/tests/api-resources/beta/messages/messages.test.ts index d9e55ef2..bc4b9c32 100644 --- a/tests/api-resources/beta/messages/messages.test.ts +++ b/tests/api-resources/beta/messages/messages.test.ts @@ -12,7 +12,7 @@ describe('resource messages', () => { const responsePromise = client.beta.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -27,7 +27,7 @@ describe('resource messages', () => { const response = await client.beta.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, @@ -49,20 +49,16 @@ describe('resource messages', () => { }, ], temperature: 1, + thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, - }, - }, - name: 'name', + display_height_px: 1, + display_width_px: 1, + name: 'computer', + type: 'computer_20241022', cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - type: 'custom', + display_number: 0, }, ], top_k: 5, @@ -74,7 +70,7 @@ describe('resource messages', () => { test('countTokens: only required params', async () => { const responsePromise = client.beta.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -88,7 +84,7 @@ describe('resource messages', () => { test('countTokens: required and optional params', async () => { const response = await client.beta.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', system: [ { text: "Today's date is 2024-06-01.", @@ -106,20 +102,16 @@ describe('resource messages', () => { ], }, ], + thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, - }, - }, - name: 'name', + display_height_px: 1, + display_width_px: 1, + name: 'computer', + type: 'computer_20241022', cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - type: 'custom', + display_number: 0, }, ], betas: ['string'], diff --git a/tests/api-resources/completions.test.ts b/tests/api-resources/completions.test.ts index 272bd8c7..c451afb9 100644 --- a/tests/api-resources/completions.test.ts +++ b/tests/api-resources/completions.test.ts @@ -11,7 +11,7 @@ describe('resource completions', () => { test('create: only required params', async () => { const responsePromise = client.completions.create({ max_tokens_to_sample: 256, - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', prompt: '\n\nHuman: Hello, world!\n\nAssistant:', }); const rawResponse = await responsePromise.asResponse(); @@ -26,7 +26,7 @@ describe('resource completions', () => { test('create: required and optional params', async () => { const response = await client.completions.create({ max_tokens_to_sample: 256, - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', prompt: '\n\nHuman: Hello, world!\n\nAssistant:', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index 503e8ef7..ba6e9d57 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -16,7 +16,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', }, }, ], @@ -38,7 +38,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], system: [ @@ -59,24 +59,9 @@ describe('resource batches', () => { }, ], temperature: 1, + thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [ - { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { - description: 'Unit for the output - one of (celsius, fahrenheit)', - type: 'string', - }, - }, - }, - name: 'name', - cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - }, - ], + tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], top_k: 5, top_p: 0.7, }, diff --git a/tests/api-resources/messages/messages.test.ts b/tests/api-resources/messages/messages.test.ts index e7d2a4c2..0b56715d 100644 --- a/tests/api-resources/messages/messages.test.ts +++ b/tests/api-resources/messages/messages.test.ts @@ -12,7 +12,7 @@ describe('resource messages', () => { const responsePromise = client.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -27,7 +27,7 @@ describe('resource messages', () => { const response = await client.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, @@ -49,21 +49,9 @@ describe('resource messages', () => { }, ], temperature: 1, + thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [ - { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, - }, - }, - name: 'name', - cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - }, - ], + tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], top_k: 5, top_p: 0.7, }); @@ -72,7 +60,7 @@ describe('resource messages', () => { test('countTokens: only required params', async () => { const responsePromise = client.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -86,7 +74,7 @@ describe('resource messages', () => { test('countTokens: required and optional params', async () => { const response = await client.messages.countTokens({ messages: [{ content: 'string', role: 'user' }], - model: 'claude-3-5-haiku-latest', + model: 'claude-3-7-sonnet-latest', system: [ { text: "Today's date is 2024-06-01.", @@ -104,21 +92,9 @@ describe('resource messages', () => { ], }, ], + thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [ - { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, - }, - }, - name: 'name', - cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - }, - ], + tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], }); }); }); From b10d942a45e17182f3a99e8b97a1c36e5433d820 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 24 Feb 2025 20:33:19 +0000 Subject: [PATCH 038/105] feat: add migration guide --- MIGRATION.md | 306 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 MIGRATION.md diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 00000000..15750167 --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,306 @@ +# Migration guide + +This guide outlines the changes and steps needed to migrate your codebase to the latest version of the Anthropic TypeScript SDK. + +The main changes are that the SDK now relies on the [builtin Web fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) instead of `node-fetch` and has zero dependencies. + +## Environment requirements + +The minimum supported runtime and tooling versions are now: + +- Node.js 18.x last LTS (Required for built-in fetch support) + - This was previously documented as the minimum supported Node.js version but Node.js 16.x mostly worked at runtime; now it will not. +- TypeScript 4.9 +- Jest 28 + +## Minimum types requirements + +### DOM + +`tsconfig.json` + +```jsonc +{ + "target": "ES2015", // note: we recommend ES2020 or higher + "lib": ["DOM", "DOM.Iterable", "ES2018"] +} +``` + +### Node.js + +`tsconfig.json` + +```jsonc +{ + "target": "ES2015" // note: we recommend ES2020 or higher +} +``` + +`package.json` + +```json +{ + "devDependencies": { + "@types/node": ">= 18.18.7" + } +} +``` + +### Cloudflare Workers + +`tsconfig.json` + +```jsonc +{ + "target": "ES2015", // note: we recommend ES2020 or higher + "lib": ["ES2020"], // <- needed by @cloudflare/workers-types + "types": ["@cloudflare/workers-types"] +} +``` + +`package.json` + +```json +{ + "devDependencies": { + "@cloudflare/workers-types": ">= 0.20221111.0" + } +} +``` + +### Bun + +`tsconfig.json` + +```jsonc +{ + "target": "ES2015" // note: we recommend ES2020 or higher +} +``` + +`package.json` + +```json +{ + "devDependencies": { + "@types/bun": ">= 1.2.0" + } +} +``` + +### Deno + +No config needed! + +## Breaking changes + +### URI encoded path parameters + +Path params are now properly encoded by default. If you were manually encoding path parameters before giving them to the SDK, you must now stop doing that and pass the +param without any encoding applied. + +For example: + +```diff +- client.example.retrieve(encodeURIComponent('string/with/slash')) ++ client.example.retrieve('string/with/slash') // renders example/string%2Fwith%2Fslash +``` + +Previously without the `encodeURIComponent()` call we would have used the path `/example/string/with/slash`; now we'll use `/example/string%2Fwith%2Fslash`. + +### Removed `httpAgent` in favor of `fetchOptions` + +The `httpAgent` client option has been removed in favor of a [platform-specific `fetchOptions` property](https://github.com/stainless-sdks/anthropic-typescript#fetch-options). +This change was made as `httpAgent` relied on `node:http` agents which are not supported by any runtime's builtin fetch implementation. + +If you were using `httpAgent` for proxy support, check out the [new proxy documentation](https://github.com/stainless-sdks/anthropic-typescript#configuring-proxies). + +Before: + +```ts +import Anthropic from '@anthropic-ai/sdk'; +import http from 'http'; +import { HttpsProxyAgent } from 'https-proxy-agent'; + +// Configure the default for all requests: +const client = new Anthropic({ + httpAgent: new HttpsProxyAgent(process.env.PROXY_URL), +}); +``` + +After: + +```ts +import Anthropic from '@anthropic-ai/sdk'; +import * as undici from 'undici'; + +const proxyAgent = new undici.ProxyAgent(process.env.PROXY_URL); +const client = new Anthropic({ + fetchOptions: { + dispatcher: proxyAgent, + }, +}); +``` + +### Removed request options overloads + +When making requests with no required body, query or header parameters, you must now explicitly pass `null`, `undefined` or an empty object `{}` to the params argument in order to customise request options. + +```diff +client.example.list(); +client.example.list({}, { headers: { ... } }); +client.example.list(null, { headers: { ... } }); +client.example.list(undefined, { headers: { ... } }); +- client.example.list({ headers: { ... } }); ++ client.example.list({}, { headers: { ... } }); +``` + +This affects the following methods: + +- `client.messages.batches.list()` +- `client.models.list()` +- `client.beta.models.list()` +- `client.beta.messages.batches.retrieve()` +- `client.beta.messages.batches.list()` +- `client.beta.messages.batches.delete()` +- `client.beta.messages.batches.cancel()` +- `client.beta.messages.batches.results()` + +### Pagination changes + +Note that the `for await` syntax is _not_ affected. This still works as-is: + +```ts +// Automatically fetches more pages as needed. +for await (const betaMessageBatch of client.beta.messages.batches.list()) { + console.log(betaMessageBatch); +} +``` + +#### Simplified interface + +The pagination interface has been simplified: + +```ts +// Before +page.nextPageParams(); +page.nextPageInfo(); +// Required manually handling { url } | { params } type + +// After +page.nextPageRequestOptions(); +``` + +#### Removed unnecessary classes + +Page classes for individual methods are now type aliases: + +```ts +// Before +export class BetaMessageBatchesPage extends Page {} + +// After +export type BetaMessageBatchesPage = Page; +``` + +If you were importing these classes at runtime, you'll need to switch to importing the base class or only import them at the type-level. + +### File handling + +The deprecated `fileFromPath` helper has been removed in favor of native Node.js streams: + +```ts +// Before +Anthropic.fileFromPath('path/to/file'); + +// After +import fs from 'fs'; +fs.createReadStream('path/to/file'); +``` + +Note that this function previously only worked on Node.j. If you're using Bun, you can use [`Bun.file`](https://bun.sh/docs/api/file-io) instead. + +### Shims removal + +Previously you could configure the types that the SDK used like this: + +```ts +// Tell TypeScript and the package to use the global Web fetch instead of node-fetch. +import '@anthropic-ai/sdk/shims/web'; +import Anthropic from '@anthropic-ai/sdk'; +``` + +The `@anthropic-ai/sdk/shims` imports have been removed. Your global types must now be [correctly configured](#minimum-types-requirements). + +### `@anthropic-ai/sdk/src` directory removed + +Previously IDEs may have auto-completed imports from the `@anthropic-ai/sdk/src` directory, however this +directory was only included for an improved go-to-definition experience and should not have been used at runtime. + +If you have any `@anthropic-ai/sdk/src` imports, you must replace it with `@anthropic-ai/sdk`. + +```ts +// Before +import Anthropic from '@anthropic-ai/sdk/src'; + +// After +import Anthropic from '@anthropic-ai/sdk'; +``` + +### Headers + +The `headers` property on `APIError` objects is now an instance of the Web [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) class. It was previously just `Record`. + +### Removed exports + +#### `Response` + +```typescript +// Before +import { Response } from '@anthropic-ai/sdk'; + +// After +// `Response` must now come from the builtin types +``` + +#### Resource classes + +If you were importing resource classes from the root package then you must now import them from the file they are defined in: + +```typescript +// Before +import { Completions } from '@anthropic-ai/sdk'; + +// After +import { Completions } from '@anthropic-ai/sdk/resources/completions'; +``` + +#### `@anthropic-ai/sdk/core` + +The `@anthropic-ai/sdk/core` file was intended to be internal-only but it was publicly accessible, as such it has been refactored and split up into internal files. + +If you were relying on anything that was only exported from `@anthropic-ai/sdk/core` and is also not accessible anywhere else, please open an issue and we'll consider adding it to the public API. + +#### Cleaned up `@anthropic-ai/sdk/uploads` exports + +The following exports have been removed from `@anthropic-ai/sdk/uploads` as they were not intended to be a part of the public API: + +- `fileFromPath` +- `BlobPart` +- `BlobLike` +- `FileLike` +- `ResponseLike` +- `isResponseLike` +- `isBlobLike` +- `isFileLike` +- `isUploadable` +- `isMultipartBody` +- `maybeMultipartFormRequestOptions` +- `multipartFormRequestOptions` +- `createForm` + +Note that `Uploadable` & `toFile` **are** still exported: + +```typescript +import { type Uploadable, toFile } from '@anthropic-ai/sdk/uploads'; +``` From 2260eaff79daf054b750c80ef7343c5c92d8af1e Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Tue, 25 Feb 2025 20:56:08 +0000 Subject: [PATCH 039/105] fix(tests): stop using node:stream --- tests/streaming.test.ts | 44 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/tests/streaming.test.ts b/tests/streaming.test.ts index 98baa9c2..1629049a 100644 --- a/tests/streaming.test.ts +++ b/tests/streaming.test.ts @@ -1,7 +1,7 @@ -import { PassThrough } from 'stream'; import assert from 'assert'; import { Stream, _iterSSEMessages } from '@anthropic-ai/sdk/streaming'; import { APIConnectionError } from '@anthropic-ai/sdk/error'; +import { ReadableStreamFrom } from '@anthropic-ai/sdk/internal/shims'; describe('streaming decoding', () => { test('basic', async () => { @@ -11,7 +11,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -29,7 +29,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -48,7 +48,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -69,7 +69,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -97,7 +97,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -126,7 +126,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -147,7 +147,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -172,7 +172,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -205,7 +205,7 @@ describe('streaming decoding', () => { yield Buffer.from('\n'); } - const stream = _iterSSEMessages(new Response(await iteratorToStream(body())), new AbortController())[ + const stream = _iterSSEMessages(new Response(ReadableStreamFrom(body())), new AbortController())[ Symbol.asyncIterator ](); @@ -240,27 +240,3 @@ test('error handling', async () => { ); await err.toBeInstanceOf(APIConnectionError); }); - -async function iteratorToStream(iterator: AsyncGenerator): Promise { - const parts: unknown[] = []; - - for await (const chunk of iterator) { - parts.push(chunk); - } - - let index = 0; - - const stream = new PassThrough({ - read() { - const value = parts[index]; - if (value === undefined) { - stream.end(); - } else { - index += 1; - stream.write(value); - } - }, - }); - - return stream; -} From 102fc2248965bcbac42cb1046e047f9537f924bc Mon Sep 17 00:00:00 2001 From: stainless-em Date: Tue, 25 Feb 2025 15:58:40 -0500 Subject: [PATCH 040/105] fix(tests): migrate last ReadableStreamFrom --- tests/streaming.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/streaming.test.ts b/tests/streaming.test.ts index 1629049a..b674a14b 100644 --- a/tests/streaming.test.ts +++ b/tests/streaming.test.ts @@ -226,7 +226,10 @@ test('error handling', async () => { yield Buffer.from('\n\n'); } - const stream = Stream.fromSSEResponse(new Response(await iteratorToStream(body())), new AbortController()); + const stream = Stream.fromSSEResponse( + new Response(await ReadableStreamFrom(body())), + new AbortController(), + ); const err = expect( (async () => { From 32f565929fd64bcb5a582f5824a91a56543ac1d0 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Thu, 27 Feb 2025 19:12:13 +0000 Subject: [PATCH 041/105] feat(api): add URL source blocks for images and PDFs --- .stats.yml | 2 +- api.md | 6 +++ src/client.ts | 6 +++ src/resources/beta/beta.ts | 6 +++ src/resources/beta/index.ts | 3 ++ src/resources/beta/messages/index.ts | 3 ++ src/resources/beta/messages/messages.ts | 43 ++++++++++++------- src/resources/index.ts | 3 ++ src/resources/messages/index.ts | 3 ++ src/resources/messages/messages.ts | 43 ++++++++++++------- .../beta/messages/batches.test.ts | 18 +++++--- .../beta/messages/messages.test.ts | 30 ++++++++----- tests/api-resources/messages/batches.test.ts | 18 +++++++- tests/api-resources/messages/messages.test.ts | 30 ++++++++++++- 14 files changed, 164 insertions(+), 50 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9bbd4b86..00ee8cf6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-e1328d31b4446324096fb948bd5074b5ac00d7c7e3ce89b6974a1c5aebf5a64d.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-129d8719c17bc9ea6e310a63400f60e7ad3ef828e54265eb8a8035684187210b.yml diff --git a/api.md b/api.md index 79a0c211..78c2cf96 100644 --- a/api.md +++ b/api.md @@ -20,6 +20,7 @@ Types: Types: +- Base64ImageSource - Base64PDFSource - CacheControlEphemeral - CitationCharLocation @@ -84,6 +85,8 @@ Types: - ToolUnion - ToolUseBlock - ToolUseBlockParam +- URLImageSource +- URLPDFSource - Usage Methods: @@ -158,6 +161,7 @@ Methods: Types: +- BetaBase64ImageSource - BetaBase64PDFBlock - BetaBase64PDFSource - BetaCacheControlEphemeral @@ -217,6 +221,8 @@ Types: - BetaToolUnion - BetaToolUseBlock - BetaToolUseBlockParam +- BetaURLImageSource +- BetaURLPDFSource - BetaUsage Methods: diff --git a/src/client.ts b/src/client.ts index 4c2e5b2c..761c33d5 100644 --- a/src/client.ts +++ b/src/client.ts @@ -48,6 +48,7 @@ import { BetaRateLimitError, } from './resources/beta/beta'; import { + Base64ImageSource, Base64PDFSource, CacheControlEphemeral, CitationCharLocation, @@ -118,6 +119,8 @@ import { ToolUnion, ToolUseBlock, ToolUseBlockParam, + URLImageSource, + URLPDFSource, Usage, } from './resources/messages/messages'; @@ -925,6 +928,7 @@ export declare namespace Anthropic { export { Messages as Messages, + type Base64ImageSource as Base64ImageSource, type Base64PDFSource as Base64PDFSource, type CacheControlEphemeral as CacheControlEphemeral, type CitationCharLocation as CitationCharLocation, @@ -989,6 +993,8 @@ export declare namespace Anthropic { type ToolUnion as ToolUnion, type ToolUseBlock as ToolUseBlock, type ToolUseBlockParam as ToolUseBlockParam, + type URLImageSource as URLImageSource, + type URLPDFSource as URLPDFSource, type Usage as Usage, type MessageCreateParams as MessageCreateParams, type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming, diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index 70ba4403..484ff414 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -5,6 +5,7 @@ import * as ModelsAPI from './models'; import { BetaModelInfo, BetaModelInfosPage, ModelListParams, Models } from './models'; import * as MessagesAPI from './messages/messages'; import { + BetaBase64ImageSource, BetaBase64PDFBlock, BetaBase64PDFSource, BetaCacheControlEphemeral, @@ -64,6 +65,8 @@ import { BetaToolUnion, BetaToolUseBlock, BetaToolUseBlockParam, + BetaURLImageSource, + BetaURLPDFSource, BetaUsage, MessageCountTokensParams, MessageCreateParams, @@ -187,6 +190,7 @@ export declare namespace Beta { export { Messages as Messages, + type BetaBase64ImageSource as BetaBase64ImageSource, type BetaBase64PDFBlock as BetaBase64PDFBlock, type BetaBase64PDFSource as BetaBase64PDFSource, type BetaCacheControlEphemeral as BetaCacheControlEphemeral, @@ -246,6 +250,8 @@ export declare namespace Beta { type BetaToolUnion as BetaToolUnion, type BetaToolUseBlock as BetaToolUseBlock, type BetaToolUseBlockParam as BetaToolUseBlockParam, + type BetaURLImageSource as BetaURLImageSource, + type BetaURLPDFSource as BetaURLPDFSource, type BetaUsage as BetaUsage, type MessageCreateParams as MessageCreateParams, type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming, diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts index 8bfb7c8e..2e044c94 100644 --- a/src/resources/beta/index.ts +++ b/src/resources/beta/index.ts @@ -17,6 +17,7 @@ export { } from './beta'; export { Messages, + type BetaBase64ImageSource, type BetaBase64PDFBlock, type BetaBase64PDFSource, type BetaCacheControlEphemeral, @@ -76,6 +77,8 @@ export { type BetaToolUnion, type BetaToolUseBlock, type BetaToolUseBlockParam, + type BetaURLImageSource, + type BetaURLPDFSource, type BetaUsage, type MessageCreateParams, type MessageCreateParamsNonStreaming, diff --git a/src/resources/beta/messages/index.ts b/src/resources/beta/messages/index.ts index 127849bb..daa3b4d6 100644 --- a/src/resources/beta/messages/index.ts +++ b/src/resources/beta/messages/index.ts @@ -21,6 +21,7 @@ export { } from './batches'; export { Messages, + type BetaBase64ImageSource, type BetaBase64PDFBlock, type BetaBase64PDFSource, type BetaCacheControlEphemeral, @@ -80,6 +81,8 @@ export { type BetaToolUnion, type BetaToolUseBlock, type BetaToolUseBlockParam, + type BetaURLImageSource, + type BetaURLPDFSource, type BetaUsage, type MessageCreateParams, type MessageCreateParamsNonStreaming, diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index d27d9a9a..1886300b 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -92,8 +92,16 @@ export class Messages extends APIResource { } } +export interface BetaBase64ImageSource { + data: string; + + media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp'; + + type: 'base64'; +} + export interface BetaBase64PDFBlock { - source: BetaBase64PDFSource | BetaPlainTextSource | BetaContentBlockSource; + source: BetaBase64PDFSource | BetaPlainTextSource | BetaContentBlockSource | BetaURLPDFSource; type: 'document'; @@ -236,23 +244,13 @@ export interface BetaContentBlockSource { export type BetaContentBlockSourceContent = BetaTextBlockParam | BetaImageBlockParam; export interface BetaImageBlockParam { - source: BetaImageBlockParam.Source; + source: BetaBase64ImageSource | BetaURLImageSource; type: 'image'; cache_control?: BetaCacheControlEphemeral | null; } -export namespace BetaImageBlockParam { - export interface Source { - data: string; - - media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp'; - - type: 'base64'; - } -} - export interface BetaInputJSONDelta { partial_json: string; @@ -818,13 +816,13 @@ export interface BetaToolTextEditor20250124 { } export type BetaToolUnion = + | BetaTool | BetaToolComputerUse20241022 | BetaToolBash20241022 | BetaToolTextEditor20241022 | BetaToolComputerUse20250124 | BetaToolBash20250124 - | BetaToolTextEditor20250124 - | BetaTool; + | BetaToolTextEditor20250124; export interface BetaToolUseBlock { id: string; @@ -848,6 +846,18 @@ export interface BetaToolUseBlockParam { cache_control?: BetaCacheControlEphemeral | null; } +export interface BetaURLImageSource { + type: 'url'; + + url: string; +} + +export interface BetaURLPDFSource { + type: 'url'; + + url: string; +} + export interface BetaUsage { /** * The number of input tokens used to create the cache entry. @@ -1376,13 +1386,13 @@ export interface MessageCountTokensParams { * See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. */ tools?: Array< + | BetaTool | BetaToolComputerUse20241022 | BetaToolBash20241022 | BetaToolTextEditor20241022 | BetaToolComputerUse20250124 | BetaToolBash20250124 | BetaToolTextEditor20250124 - | BetaTool >; /** @@ -1395,6 +1405,7 @@ Messages.Batches = Batches; export declare namespace Messages { export { + type BetaBase64ImageSource as BetaBase64ImageSource, type BetaBase64PDFBlock as BetaBase64PDFBlock, type BetaBase64PDFSource as BetaBase64PDFSource, type BetaCacheControlEphemeral as BetaCacheControlEphemeral, @@ -1454,6 +1465,8 @@ export declare namespace Messages { type BetaToolUnion as BetaToolUnion, type BetaToolUseBlock as BetaToolUseBlock, type BetaToolUseBlockParam as BetaToolUseBlockParam, + type BetaURLImageSource as BetaURLImageSource, + type BetaURLPDFSource as BetaURLPDFSource, type BetaUsage as BetaUsage, type MessageCreateParams as MessageCreateParams, type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming, diff --git a/src/resources/index.ts b/src/resources/index.ts index a6cce09c..dbeb02b2 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -25,6 +25,7 @@ export { } from './completions'; export { Messages, + type Base64ImageSource, type Base64PDFSource, type CacheControlEphemeral, type CitationCharLocation, @@ -91,6 +92,8 @@ export { type ToolUnion, type ToolUseBlock, type ToolUseBlockParam, + type URLImageSource, + type URLPDFSource, type Usage, type MessageCreateParams, type MessageCreateParamsNonStreaming, diff --git a/src/resources/messages/index.ts b/src/resources/messages/index.ts index 4988daab..0d210c7a 100644 --- a/src/resources/messages/index.ts +++ b/src/resources/messages/index.ts @@ -17,6 +17,7 @@ export { } from './batches'; export { Messages, + type Base64ImageSource, type Base64PDFSource, type CacheControlEphemeral, type CitationCharLocation, @@ -81,6 +82,8 @@ export { type ToolUnion, type ToolUseBlock, type ToolUseBlockParam, + type URLImageSource, + type URLPDFSource, type Usage, type MessageCreateParams, type MessageCreateParamsBase, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index c1ebd18a..dd2d6b24 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -86,6 +86,14 @@ export class Messages extends APIResource { } } +export interface Base64ImageSource { + data: string; + + media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp'; + + type: 'base64'; +} + export interface Base64PDFSource { data: string; @@ -218,7 +226,7 @@ export interface ContentBlockSource { export type ContentBlockSourceContent = TextBlockParam | ImageBlockParam; export interface DocumentBlockParam { - source: Base64PDFSource | PlainTextSource | ContentBlockSource; + source: Base64PDFSource | PlainTextSource | ContentBlockSource | URLPDFSource; type: 'document'; @@ -232,25 +240,13 @@ export interface DocumentBlockParam { } export interface ImageBlockParam { - source: ImageBlockParam.Source; + source: Base64ImageSource | URLImageSource; type: 'image'; cache_control?: CacheControlEphemeral | null; } -export namespace ImageBlockParam { - export interface Source { - data: string; - - media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp'; - - type: 'base64'; - } -} - -export type InputJsonDelta = InputJSONDelta; - export interface InputJSONDelta { partial_json: string; @@ -365,7 +361,7 @@ export interface Message { usage: Usage; } -export type MessageCountTokensTool = ToolBash20250124 | ToolTextEditor20250124 | Tool; +export type MessageCountTokensTool = Tool | ToolBash20250124 | ToolTextEditor20250124; export type MessageDeltaEvent = RawMessageDeltaEvent; @@ -771,7 +767,7 @@ export interface ToolTextEditor20250124 { cache_control?: CacheControlEphemeral | null; } -export type ToolUnion = ToolBash20250124 | ToolTextEditor20250124 | Tool; +export type ToolUnion = Tool | ToolBash20250124 | ToolTextEditor20250124; export interface ToolUseBlock { id: string; @@ -795,6 +791,18 @@ export interface ToolUseBlockParam { cache_control?: CacheControlEphemeral | null; } +export interface URLImageSource { + type: 'url'; + + url: string; +} + +export interface URLPDFSource { + type: 'url'; + + url: string; +} + export interface Usage { /** * The number of input tokens used to create the cache entry. @@ -1343,6 +1351,7 @@ Messages.Batches = Batches; export declare namespace Messages { export { + type Base64ImageSource as Base64ImageSource, type Base64PDFSource as Base64PDFSource, type CacheControlEphemeral as CacheControlEphemeral, type CitationCharLocation as CitationCharLocation, @@ -1408,6 +1417,8 @@ export declare namespace Messages { type ToolUnion as ToolUnion, type ToolUseBlock as ToolUseBlock, type ToolUseBlockParam as ToolUseBlockParam, + type URLImageSource as URLImageSource, + type URLPDFSource as URLPDFSource, type Usage as Usage, type MessageCreateParams as MessageCreateParams, type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming, diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index d7242749..e00e4e65 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -64,12 +64,20 @@ describe('resource batches', () => { tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - display_height_px: 1, - display_width_px: 1, - name: 'computer', - type: 'computer_20241022', + input_schema: { + type: 'object', + properties: { + location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, + unit: { + description: 'Unit for the output - one of (celsius, fahrenheit)', + type: 'string', + }, + }, + }, + name: 'name', cache_control: { type: 'ephemeral' }, - display_number: 0, + description: 'Get the current weather in a given location', + type: 'custom', }, ], top_k: 5, diff --git a/tests/api-resources/beta/messages/messages.test.ts b/tests/api-resources/beta/messages/messages.test.ts index bc4b9c32..23703606 100644 --- a/tests/api-resources/beta/messages/messages.test.ts +++ b/tests/api-resources/beta/messages/messages.test.ts @@ -53,12 +53,17 @@ describe('resource messages', () => { tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - display_height_px: 1, - display_width_px: 1, - name: 'computer', - type: 'computer_20241022', + input_schema: { + type: 'object', + properties: { + location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, + unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, + }, + }, + name: 'name', cache_control: { type: 'ephemeral' }, - display_number: 0, + description: 'Get the current weather in a given location', + type: 'custom', }, ], top_k: 5, @@ -106,12 +111,17 @@ describe('resource messages', () => { tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - display_height_px: 1, - display_width_px: 1, - name: 'computer', - type: 'computer_20241022', + input_schema: { + type: 'object', + properties: { + location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, + unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, + }, + }, + name: 'name', cache_control: { type: 'ephemeral' }, - display_number: 0, + description: 'Get the current weather in a given location', + type: 'custom', }, ], betas: ['string'], diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index ba6e9d57..1f0fdc23 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -61,7 +61,23 @@ describe('resource batches', () => { temperature: 1, thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], + tools: [ + { + input_schema: { + type: 'object', + properties: { + location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, + unit: { + description: 'Unit for the output - one of (celsius, fahrenheit)', + type: 'string', + }, + }, + }, + name: 'name', + cache_control: { type: 'ephemeral' }, + description: 'Get the current weather in a given location', + }, + ], top_k: 5, top_p: 0.7, }, diff --git a/tests/api-resources/messages/messages.test.ts b/tests/api-resources/messages/messages.test.ts index 0b56715d..3739d7f0 100644 --- a/tests/api-resources/messages/messages.test.ts +++ b/tests/api-resources/messages/messages.test.ts @@ -51,7 +51,20 @@ describe('resource messages', () => { temperature: 1, thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], + tools: [ + { + input_schema: { + type: 'object', + properties: { + location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, + unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, + }, + }, + name: 'name', + cache_control: { type: 'ephemeral' }, + description: 'Get the current weather in a given location', + }, + ], top_k: 5, top_p: 0.7, }); @@ -94,7 +107,20 @@ describe('resource messages', () => { ], thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], + tools: [ + { + input_schema: { + type: 'object', + properties: { + location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, + unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, + }, + }, + name: 'name', + cache_control: { type: 'ephemeral' }, + description: 'Get the current weather in a given location', + }, + ], }); }); }); From a3dabfdbd4e6dcf9fb119afbca343f9373b5cd84 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Thu, 27 Feb 2025 22:01:06 +0000 Subject: [PATCH 042/105] docs: update URLs from stainlessapi.com to stainless.com More details at https://www.stainless.com/changelog/stainless-com --- SECURITY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 22815321..fd6ced3d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,9 +2,9 @@ ## Reporting Security Issues -This SDK is generated by [Stainless Software Inc](http://stainlessapi.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. +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@stainlessapi.com. +To report a security issue, please contact the Stainless team at security@stainless.com. ## Responsible Disclosure From 58d6b52805a4d3ea63fd2364260b2631a95956d1 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Fri, 28 Feb 2025 18:19:50 +0000 Subject: [PATCH 043/105] feat(api): add support for disabling tool calls --- .stats.yml | 2 +- api.md | 2 ++ src/client.ts | 2 ++ src/resources/beta/beta.ts | 2 ++ src/resources/beta/index.ts | 1 + src/resources/beta/messages/index.ts | 1 + src/resources/beta/messages/messages.ts | 16 ++++++++++++---- src/resources/index.ts | 1 + src/resources/messages/index.ts | 1 + src/resources/messages/messages.ts | 16 ++++++++++++---- 10 files changed, 35 insertions(+), 9 deletions(-) diff --git a/.stats.yml b/.stats.yml index 00ee8cf6..756a3632 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-129d8719c17bc9ea6e310a63400f60e7ad3ef828e54265eb8a8035684187210b.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-fd7537a41646cd9253c04f350436c5471e4762750fce8ca8f1909a3052d98608.yml diff --git a/api.md b/api.md index 78c2cf96..be2186bf 100644 --- a/api.md +++ b/api.md @@ -79,6 +79,7 @@ Types: - ToolChoice - ToolChoiceAny - ToolChoiceAuto +- ToolChoiceNone - ToolChoiceTool - ToolResultBlockParam - ToolTextEditor20250124 @@ -212,6 +213,7 @@ Types: - BetaToolChoice - BetaToolChoiceAny - BetaToolChoiceAuto +- BetaToolChoiceNone - BetaToolChoiceTool - BetaToolComputerUse20241022 - BetaToolComputerUse20250124 diff --git a/src/client.ts b/src/client.ts index 761c33d5..f85eef92 100644 --- a/src/client.ts +++ b/src/client.ts @@ -113,6 +113,7 @@ import { ToolChoice, ToolChoiceAny, ToolChoiceAuto, + ToolChoiceNone, ToolChoiceTool, ToolResultBlockParam, ToolTextEditor20250124, @@ -987,6 +988,7 @@ export declare namespace Anthropic { type ToolChoice as ToolChoice, type ToolChoiceAny as ToolChoiceAny, type ToolChoiceAuto as ToolChoiceAuto, + type ToolChoiceNone as ToolChoiceNone, type ToolChoiceTool as ToolChoiceTool, type ToolResultBlockParam as ToolResultBlockParam, type ToolTextEditor20250124 as ToolTextEditor20250124, diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index 484ff414..eb4c5a86 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -56,6 +56,7 @@ import { BetaToolChoice, BetaToolChoiceAny, BetaToolChoiceAuto, + BetaToolChoiceNone, BetaToolChoiceTool, BetaToolComputerUse20241022, BetaToolComputerUse20250124, @@ -241,6 +242,7 @@ export declare namespace Beta { type BetaToolChoice as BetaToolChoice, type BetaToolChoiceAny as BetaToolChoiceAny, type BetaToolChoiceAuto as BetaToolChoiceAuto, + type BetaToolChoiceNone as BetaToolChoiceNone, type BetaToolChoiceTool as BetaToolChoiceTool, type BetaToolComputerUse20241022 as BetaToolComputerUse20241022, type BetaToolComputerUse20250124 as BetaToolComputerUse20250124, diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts index 2e044c94..fdd6a0f3 100644 --- a/src/resources/beta/index.ts +++ b/src/resources/beta/index.ts @@ -68,6 +68,7 @@ export { type BetaToolChoice, type BetaToolChoiceAny, type BetaToolChoiceAuto, + type BetaToolChoiceNone, type BetaToolChoiceTool, type BetaToolComputerUse20241022, type BetaToolComputerUse20250124, diff --git a/src/resources/beta/messages/index.ts b/src/resources/beta/messages/index.ts index daa3b4d6..9d372139 100644 --- a/src/resources/beta/messages/index.ts +++ b/src/resources/beta/messages/index.ts @@ -72,6 +72,7 @@ export { type BetaToolChoice, type BetaToolChoiceAny, type BetaToolChoiceAuto, + type BetaToolChoiceNone, type BetaToolChoiceTool, type BetaToolComputerUse20241022, type BetaToolComputerUse20250124, diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index 1886300b..c5d48864 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -667,9 +667,9 @@ export interface BetaToolBash20250124 { /** * How the model should use the provided tools. The model can use a specific tool, - * any available tool, or decide by itself. + * any available tool, decide by itself, or not use tools at all. */ -export type BetaToolChoice = BetaToolChoiceAuto | BetaToolChoiceAny | BetaToolChoiceTool; +export type BetaToolChoice = BetaToolChoiceAuto | BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceNone; /** * The model will use any available tools. @@ -701,6 +701,13 @@ export interface BetaToolChoiceAuto { disable_parallel_tool_use?: boolean; } +/** + * The model will not be allowed to use tools. + */ +export interface BetaToolChoiceNone { + type: 'none'; +} + /** * The model will use the specified tool with `tool_choice.name`. */ @@ -1054,7 +1061,7 @@ export interface MessageCreateParamsBase { /** * Body param: How the model should use the provided tools. The model can use a - * specific tool, any available tool, or decide by itself. + * specific tool, any available tool, decide by itself, or not use tools at all. */ tool_choice?: BetaToolChoice; @@ -1310,7 +1317,7 @@ export interface MessageCountTokensParams { /** * Body param: How the model should use the provided tools. The model can use a - * specific tool, any available tool, or decide by itself. + * specific tool, any available tool, decide by itself, or not use tools at all. */ tool_choice?: BetaToolChoice; @@ -1456,6 +1463,7 @@ export declare namespace Messages { type BetaToolChoice as BetaToolChoice, type BetaToolChoiceAny as BetaToolChoiceAny, type BetaToolChoiceAuto as BetaToolChoiceAuto, + type BetaToolChoiceNone as BetaToolChoiceNone, type BetaToolChoiceTool as BetaToolChoiceTool, type BetaToolComputerUse20241022 as BetaToolComputerUse20241022, type BetaToolComputerUse20250124 as BetaToolComputerUse20250124, diff --git a/src/resources/index.ts b/src/resources/index.ts index dbeb02b2..7fb092b9 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -86,6 +86,7 @@ export { type ToolChoice, type ToolChoiceAny, type ToolChoiceAuto, + type ToolChoiceNone, type ToolChoiceTool, type ToolResultBlockParam, type ToolTextEditor20250124, diff --git a/src/resources/messages/index.ts b/src/resources/messages/index.ts index 0d210c7a..4a571139 100644 --- a/src/resources/messages/index.ts +++ b/src/resources/messages/index.ts @@ -76,6 +76,7 @@ export { type ToolChoice, type ToolChoiceAny, type ToolChoiceAuto, + type ToolChoiceNone, type ToolChoiceTool, type ToolResultBlockParam, type ToolTextEditor20250124, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index dd2d6b24..ffc5e084 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -688,9 +688,9 @@ export interface ToolBash20250124 { /** * How the model should use the provided tools. The model can use a specific tool, - * any available tool, or decide by itself. + * any available tool, decide by itself, or not use tools at all. */ -export type ToolChoice = ToolChoiceAuto | ToolChoiceAny | ToolChoiceTool; +export type ToolChoice = ToolChoiceAuto | ToolChoiceAny | ToolChoiceTool | ToolChoiceNone; /** * The model will use any available tools. @@ -722,6 +722,13 @@ export interface ToolChoiceAuto { disable_parallel_tool_use?: boolean; } +/** + * The model will not be allowed to use tools. + */ +export interface ToolChoiceNone { + type: 'none'; +} + /** * The model will use the specified tool with `tool_choice.name`. */ @@ -998,7 +1005,7 @@ export interface MessageCreateParamsBase { /** * How the model should use the provided tools. The model can use a specific tool, - * any available tool, or decide by itself. + * any available tool, decide by itself, or not use tools at all. */ tool_choice?: ToolChoice; @@ -1269,7 +1276,7 @@ export interface MessageCountTokensParams { /** * How the model should use the provided tools. The model can use a specific tool, - * any available tool, or decide by itself. + * any available tool, decide by itself, or not use tools at all. */ tool_choice?: ToolChoice; @@ -1411,6 +1418,7 @@ export declare namespace Messages { type ToolChoice as ToolChoice, type ToolChoiceAny as ToolChoiceAny, type ToolChoiceAuto as ToolChoiceAuto, + type ToolChoiceNone as ToolChoiceNone, type ToolChoiceTool as ToolChoiceTool, type ToolResultBlockParam as ToolResultBlockParam, type ToolTextEditor20250124 as ToolTextEditor20250124, From b9509a100e8746b9d40f9e99efe42953139768cf Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Wed, 26 Feb 2025 14:36:49 +0000 Subject: [PATCH 044/105] docs: add thinking examples --- examples/thinking-stream.ts | 35 +++++++++++++++++++++++++++++++++++ examples/thinking.ts | 22 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 examples/thinking-stream.ts create mode 100644 examples/thinking.ts diff --git a/examples/thinking-stream.ts b/examples/thinking-stream.ts new file mode 100644 index 00000000..f1680158 --- /dev/null +++ b/examples/thinking-stream.ts @@ -0,0 +1,35 @@ +import Anthropic from '@anthropic-ai/sdk'; + +const client = new Anthropic(); // gets API Key from environment variable ANTHROPIC_API_KEY + +async function main() { + let thinkingState = 'not-started'; + + const stream = client.messages + .stream({ + model: 'claude-3-7-sonnet-20250219', + max_tokens: 3200, + thinking: { type: 'enabled', budget_tokens: 1600 }, + messages: [{ role: 'user', content: 'Create a haiku about Anthropic.' }], + }) + .on('thinking', (thinking) => { + if (thinkingState === 'not-started') { + console.log('Thinking:\n---------'); + thinkingState = 'started'; + } + + process.stdout.write(thinking); + }) + .on('text', (text) => { + if (thinkingState !== 'finished') { + console.log('\n\nText:\n-----'); + thinkingState = 'finished'; + } + process.stdout.write(text); + }); + + const finalMessage = await stream.finalMessage(); + console.log('\n\nFinal message object:\n--------------------', finalMessage); +} + +main(); diff --git a/examples/thinking.ts b/examples/thinking.ts new file mode 100644 index 00000000..bdbcc3c6 --- /dev/null +++ b/examples/thinking.ts @@ -0,0 +1,22 @@ +import Anthropic from '@anthropic-ai/sdk'; + +const client = new Anthropic(); + +async function main() { + const message = await client.messages.create({ + model: 'claude-3-7-sonnet-20250219', + max_tokens: 3200, + thinking: { type: 'enabled', budget_tokens: 1600 }, + messages: [{ role: 'user', content: 'Create a haiku about Anthropic.' }], + }); + + for (const block of message.content) { + if (block.type === 'thinking') { + console.log(`Thinking: ${block.thinking}`); + } else if (block.type === 'text') { + console.log(`Text: ${block.text}`); + } + } +} + +main(); From b4cea5a29fe5ae957ff5c21b2d6c0126b5bae929 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 3 Mar 2025 17:46:52 +0000 Subject: [PATCH 045/105] chore(client): only accept standard types for file uploads --- scripts/build | 4 +- src/client.ts | 4 +- src/internal/polyfill/file.node.d.ts | 9 - src/internal/polyfill/file.node.js | 17 -- src/internal/polyfill/file.node.mjs | 9 - src/internal/shims.ts | 56 ----- .../{polyfill => shims}/crypto.node.d.ts | 0 .../{polyfill => shims}/crypto.node.js | 0 .../{polyfill => shims}/crypto.node.mjs | 0 src/internal/shims/file.node.d.ts | 20 ++ src/internal/shims/file.node.js | 11 + src/internal/shims/file.node.mjs | 2 + src/internal/to-file.ts | 152 ++++++++++++ src/internal/uploads.ts | 220 ++++-------------- src/internal/utils/uuid.ts | 2 +- src/uploads.ts | 3 +- tests/uploads.test.ts | 38 ++- 17 files changed, 267 insertions(+), 280 deletions(-) delete mode 100644 src/internal/polyfill/file.node.d.ts delete mode 100644 src/internal/polyfill/file.node.js delete mode 100644 src/internal/polyfill/file.node.mjs rename src/internal/{polyfill => shims}/crypto.node.d.ts (100%) rename src/internal/{polyfill => shims}/crypto.node.js (100%) rename src/internal/{polyfill => shims}/crypto.node.mjs (100%) create mode 100644 src/internal/shims/file.node.d.ts create mode 100644 src/internal/shims/file.node.js create mode 100644 src/internal/shims/file.node.mjs create mode 100644 src/internal/to-file.ts diff --git a/scripts/build b/scripts/build index 5ffbb766..42d0b893 100755 --- a/scripts/build +++ b/scripts/build @@ -40,8 +40,8 @@ cp dist/index.d.ts dist/index.d.mts cp tsconfig.dist-src.json dist/src/tsconfig.json cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts -mkdir -p dist/internal/polyfill -cp src/internal/polyfill/*.{mjs,js,d.ts} dist/internal/polyfill +mkdir -p dist/internal/shims +cp src/internal/shims/*.{mjs,js,d.ts} dist/internal/shims node scripts/utils/postprocess-files.cjs diff --git a/src/client.ts b/src/client.ts index f85eef92..a879e5b8 100644 --- a/src/client.ts +++ b/src/client.ts @@ -674,7 +674,9 @@ export class BaseAnthropic { const timeout = setTimeout(() => controller.abort(), ms); - const isReadableBody = Shims.isReadableLike(options.body); + const isReadableBody = + ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) || + (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body); const fetchOptions: RequestInit = { signal: controller.signal as any, diff --git a/src/internal/polyfill/file.node.d.ts b/src/internal/polyfill/file.node.d.ts deleted file mode 100644 index b2a59bfd..00000000 --- a/src/internal/polyfill/file.node.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This file polyfills the global `File` object for you if it's not already defined - * when running on Node.js - * - * This is only needed on Node.js v18 & v19. Newer versions already define `File` - * as a global. - */ - -export {}; diff --git a/src/internal/polyfill/file.node.js b/src/internal/polyfill/file.node.js deleted file mode 100644 index eba997e1..00000000 --- a/src/internal/polyfill/file.node.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * This file polyfills the global `File` object for you if it's not already defined - * when running on Node.js - * - * This is only needed on Node.js v18 & v19. Newer versions already define `File` - * as a global. - */ - -if (typeof require !== 'undefined') { - if (!globalThis.File) { - try { - // Use [require][0](...) and not require(...) so bundlers don't try to bundle the - // buffer module. - globalThis.File = [require][0]('node:buffer').File; - } catch (e) {} - } -} diff --git a/src/internal/polyfill/file.node.mjs b/src/internal/polyfill/file.node.mjs deleted file mode 100644 index 520dcb84..00000000 --- a/src/internal/polyfill/file.node.mjs +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This file polyfills the global `File` object for you if it's not already defined - * when running on Node.js - * - * This is only needed on Node.js v18 & v19. Newer versions already define `File` - * as a global. - */ - -import './file.node.js'; diff --git a/src/internal/shims.ts b/src/internal/shims.ts index e70031e4..ce702385 100644 --- a/src/internal/shims.ts +++ b/src/internal/shims.ts @@ -20,62 +20,6 @@ export function getDefaultFetch(): Fetch { ); } -/** - * A minimal copy of the NodeJS `stream.Readable` class so that we can - * accept the NodeJS types in certain places, e.g. file uploads - * - * https://nodejs.org/api/stream.html#class-streamreadable - */ -export interface ReadableLike { - readable: boolean; - readonly readableEnded: boolean; - readonly readableFlowing: boolean | null; - readonly readableHighWaterMark: number; - readonly readableLength: number; - readonly readableObjectMode: boolean; - destroyed: boolean; - read(size?: number): any; - pause(): this; - resume(): this; - isPaused(): boolean; - destroy(error?: Error): this; - [Symbol.asyncIterator](): AsyncIterableIterator; -} - -/** - * Determines if the given value looks like a NodeJS `stream.Readable` - * object and that it is readable, i.e. has not been consumed. - * - * https://nodejs.org/api/stream.html#class-streamreadable - */ -export function isReadableLike(value: any) { - // We declare our own class of Readable here, so it's not feasible to - // do an 'instanceof' check. Instead, check for Readable-like properties. - return !!value && value.readable === true && typeof value.read === 'function'; -} - -/** - * A minimal copy of the NodeJS `fs.ReadStream` class for usage within file uploads. - * - * https://nodejs.org/api/fs.html#class-fsreadstream - */ -export interface FsReadStreamLike extends ReadableLike { - path: {}; // real type is string | Buffer but we can't reference `Buffer` here -} - -/** - * Determines if the given value looks like a NodeJS `fs.ReadStream` - * object. - * - * This just checks if the object matches our `Readable` interface - * and defines a `path` property, there may be false positives. - * - * https://nodejs.org/api/fs.html#class-fsreadstream - */ -export function isFsReadStreamLike(value: any): value is FsReadStreamLike { - return isReadableLike(value) && 'path' in value; -} - type ReadableStreamArgs = ConstructorParameters; export function makeReadableStream(...args: ReadableStreamArgs): ReadableStream { diff --git a/src/internal/polyfill/crypto.node.d.ts b/src/internal/shims/crypto.node.d.ts similarity index 100% rename from src/internal/polyfill/crypto.node.d.ts rename to src/internal/shims/crypto.node.d.ts diff --git a/src/internal/polyfill/crypto.node.js b/src/internal/shims/crypto.node.js similarity index 100% rename from src/internal/polyfill/crypto.node.js rename to src/internal/shims/crypto.node.js diff --git a/src/internal/polyfill/crypto.node.mjs b/src/internal/shims/crypto.node.mjs similarity index 100% rename from src/internal/polyfill/crypto.node.mjs rename to src/internal/shims/crypto.node.mjs diff --git a/src/internal/shims/file.node.d.ts b/src/internal/shims/file.node.d.ts new file mode 100644 index 00000000..9dc6b2fc --- /dev/null +++ b/src/internal/shims/file.node.d.ts @@ -0,0 +1,20 @@ +// The infer is to make TS show it as a nice union type, +// instead of literally `ConstructorParameters[0]` +type FallbackBlobSource = ConstructorParameters[0] extends infer T ? T : never; +/** + * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files. + */ +declare class FallbackFile extends Blob { + constructor(sources: FallbackBlobSource, fileName: string, options?: any); + /** + * The name of the `File`. + */ + readonly name: string; + /** + * The last modified date of the `File`. + */ + readonly lastModified: number; +} +export type File = InstanceType; +export const File: typeof globalThis extends { File: infer fileConstructor } ? fileConstructor +: typeof FallbackFile; diff --git a/src/internal/shims/file.node.js b/src/internal/shims/file.node.js new file mode 100644 index 00000000..3f8c2ed6 --- /dev/null +++ b/src/internal/shims/file.node.js @@ -0,0 +1,11 @@ +if (typeof require !== 'undefined') { + if (globalThis.File) { + exports.File = globalThis.File; + } else { + try { + // Use [require][0](...) and not require(...) so bundlers don't try to bundle the + // buffer module. + exports.File = [require][0]('node:buffer').File; + } catch (e) {} + } +} diff --git a/src/internal/shims/file.node.mjs b/src/internal/shims/file.node.mjs new file mode 100644 index 00000000..1f103f5d --- /dev/null +++ b/src/internal/shims/file.node.mjs @@ -0,0 +1,2 @@ +import * as mod from './file.node.js'; +export const File = globalThis.File || mod.File; diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts new file mode 100644 index 00000000..69b76d3a --- /dev/null +++ b/src/internal/to-file.ts @@ -0,0 +1,152 @@ +import { File } from './shims/file.node.js'; +import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads'; +import type { FilePropertyBag } from './builtin-types'; + +type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView; + +/** + * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc. + * Don't add arrayBuffer here, node-fetch doesn't have it + */ +interface BlobLike { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */ + readonly size: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */ + readonly type: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */ + text(): Promise; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */ + slice(start?: number, end?: number): BlobLike; +} + +/** + * This check adds the arrayBuffer() method type because it is available and used at runtime + */ +const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise } => + value != null && + typeof value === 'object' && + typeof value.size === 'number' && + typeof value.type === 'string' && + typeof value.text === 'function' && + typeof value.slice === 'function' && + typeof value.arrayBuffer === 'function'; + +/** + * Intended to match DOM File, node:buffer File, undici File, etc. + */ +interface FileLike extends BlobLike { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */ + readonly lastModified: number; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */ + readonly name?: string | undefined; +} + +/** + * This check adds the arrayBuffer() method type because it is available and used at runtime + */ +const isFileLike = (value: any): value is FileLike & { arrayBuffer(): Promise } => + value != null && + typeof value === 'object' && + typeof value.name === 'string' && + typeof value.lastModified === 'number' && + isBlobLike(value); + +/** + * Intended to match DOM Response, node-fetch Response, undici Response, etc. + */ +export interface ResponseLike { + url: string; + blob(): Promise; +} + +const isResponseLike = (value: any): value is ResponseLike => + value != null && + typeof value === 'object' && + typeof value.url === 'string' && + typeof value.blob === 'function'; + +export type ToFileInput = + | FileLike + | ResponseLike + | Exclude + | AsyncIterable; + +/** + * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats + * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s + * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible + * @param {Object=} options additional properties + * @param {string=} options.type the MIME type of the content + * @param {number=} options.lastModified the last modified timestamp + * @returns a {@link File} with the given properties + */ +export async function toFile( + value: ToFileInput | PromiseLike, + name?: string | null | undefined, + options?: FilePropertyBag | undefined, +): Promise { + // If it's a promise, resolve it. + value = await value; + + // If we've been given a `File` we don't need to do anything + if (isFileLike(value)) { + if (File && value instanceof File) { + return value; + } + return makeFile([await value.arrayBuffer()], value.name); + } + + if (isResponseLike(value)) { + const blob = await value.blob(); + name ||= new URL(value.url).pathname.split(/[\\/]/).pop(); + + return makeFile(await getBytes(blob), name, options); + } + + const parts = await getBytes(value); + + name ||= getName(value); + + if (!options?.type) { + const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type); + if (typeof type === 'string') { + options = { ...options, type }; + } + } + + return makeFile(parts, name, options); +} + +async function getBytes(value: BlobLikePart | AsyncIterable): Promise> { + let parts: Array = []; + if ( + typeof value === 'string' || + ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc. + value instanceof ArrayBuffer + ) { + parts.push(value); + } else if (isBlobLike(value)) { + parts.push(value instanceof Blob ? value : await value.arrayBuffer()); + } else if ( + isAsyncIterable(value) // includes Readable, ReadableStream, etc. + ) { + for await (const chunk of value) { + parts.push(...(await getBytes(chunk as BlobLikePart))); // TODO, consider validating? + } + } else { + const constructor = value?.constructor?.name; + throw new Error( + `Unexpected data type: ${typeof value}${ + constructor ? `; constructor: ${constructor}` : '' + }${propsForError(value)}`, + ); + } + + return parts; +} + +function propsForError(value: unknown): string { + if (typeof value !== 'object' || value === null) return ''; + const props = Object.getOwnPropertyNames(value); + return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`; +} diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index 2c64f7bb..b07ac53e 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -1,11 +1,16 @@ import { type RequestOptions } from './request-options'; import type { FilePropertyBag, Fetch } from './builtin-types'; -import { isFsReadStreamLike, type FsReadStreamLike } from './shims'; import type { BaseAnthropic } from '../client'; -import './polyfill/file.node.js'; +import { File } from './shims/file.node.js'; +import { ReadableStreamFrom } from './shims'; -type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView; -type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; +export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; +type FsReadStream = AsyncIterable & { path: string | { toString(): string } }; + +// https://github.com/oven-sh/bun/issues/5980 +interface BunFile extends Blob { + readonly name?: string | undefined; +} /** * Typically, this is a native "File" class. @@ -16,188 +21,41 @@ type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; * For convenience, you can also pass a fetch Response, or in Node, * the result of fs.createReadStream(). */ -export type Uploadable = FileLike | ResponseLike | FsReadStreamLike; - -/** - * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc. - * Don't add arrayBuffer here, node-fetch doesn't have it - */ -interface BlobLike { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */ - readonly size: number; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */ - readonly type: string; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */ - text(): Promise; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */ - slice(start?: number, end?: number): BlobLike; -} - -/** - * This check adds the arrayBuffer() method type because it is available and used at runtime - */ -const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise } => - value != null && - typeof value === 'object' && - typeof value.size === 'number' && - typeof value.type === 'string' && - typeof value.text === 'function' && - typeof value.slice === 'function' && - typeof value.arrayBuffer === 'function'; - -/** - * Intended to match DOM File, node:buffer File, undici File, etc. - */ -interface FileLike extends BlobLike { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */ - readonly lastModified: number; - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */ - readonly name?: string | undefined; -} -declare var FileClass: { - prototype: FileLike; - new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike; -}; - -/** - * This check adds the arrayBuffer() method type because it is available and used at runtime - */ -const isFileLike = (value: any): value is FileLike & { arrayBuffer(): Promise } => - value != null && - typeof value === 'object' && - typeof value.name === 'string' && - typeof value.lastModified === 'number' && - isBlobLike(value); - -/** - * Intended to match DOM Response, node-fetch Response, undici Response, etc. - */ -export interface ResponseLike { - url: string; - blob(): Promise; -} - -const isResponseLike = (value: any): value is ResponseLike => - value != null && - typeof value === 'object' && - typeof value.url === 'string' && - typeof value.blob === 'function'; - -const isUploadable = (value: any): value is Uploadable => { - return isFileLike(value) || isResponseLike(value) || isFsReadStreamLike(value); -}; - -type ToFileInput = Uploadable | Exclude | AsyncIterable; +export type Uploadable = File | Response | FsReadStream | BunFile; /** * Construct a `File` instance. This is used to ensure a helpful error is thrown - * for environments that don't define a global `File` yet and so that we don't - * accidentally rely on a global `File` type in our annotations. + * for environments that don't define a global `File` yet. */ -function makeFile(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike { - const File = (globalThis as any).File as typeof FileClass | undefined; +export function makeFile( + fileBits: BlobPart[], + fileName: string | undefined, + options?: FilePropertyBag, +): File { if (typeof File === 'undefined') { throw new Error('`File` is not defined as a global which is required for file uploads'); } - return new File(fileBits, fileName, options); + return new File(fileBits as any, fileName ?? 'unknown_file', options); } -/** - * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats - * @param value the raw content of the file. Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s - * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible - * @param {Object=} options additional properties - * @param {string=} options.type the MIME type of the content - * @param {number=} options.lastModified the last modified timestamp - * @returns a {@link File} with the given properties - */ -export async function toFile( - value: ToFileInput | PromiseLike, - name?: string | null | undefined, - options?: FilePropertyBag | undefined, -): Promise { - // If it's a promise, resolve it. - value = await value; - - // If we've been given a `File` we don't need to do anything - if (isFileLike(value)) { - const File = (globalThis as any).File as typeof FileClass | undefined; - if (File && value instanceof File) { - return value; - } - return makeFile([await value.arrayBuffer()], value.name ?? 'unknown_file'); - } - - if (isResponseLike(value)) { - const blob = await value.blob(); - name ||= new URL(value.url).pathname.split(/[\\/]/).pop() ?? 'unknown_file'; - - return makeFile(await getBytes(blob), name, options); - } - - const parts = await getBytes(value); - - name ||= getName(value) ?? 'unknown_file'; - - if (!options?.type) { - const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type); - if (typeof type === 'string') { - options = { ...options, type }; - } - } - - return makeFile(parts, name, options); -} - -export async function getBytes( - value: Uploadable | BlobLikePart | AsyncIterable, -): Promise> { - let parts: Array = []; - if ( - typeof value === 'string' || - ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc. - value instanceof ArrayBuffer - ) { - parts.push(value); - } else if (isBlobLike(value)) { - parts.push(value instanceof Blob ? value : await value.arrayBuffer()); - } else if ( - isAsyncIterableIterator(value) // includes Readable, ReadableStream, etc. - ) { - for await (const chunk of value) { - parts.push(...(await getBytes(chunk as BlobLikePart))); // TODO, consider validating? - } - } else { - const constructor = value?.constructor?.name; - throw new Error( - `Unexpected data type: ${typeof value}${ - constructor ? `; constructor: ${constructor}` : '' - }${propsForError(value)}`, - ); - } - - return parts; -} - -function propsForError(value: unknown): string { - if (typeof value !== 'object' || value === null) return ''; - const props = Object.getOwnPropertyNames(value); - return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`; -} - -function getName(value: unknown): string | undefined { +export function getName(value: any): string | undefined { return ( - (typeof value === 'object' && - value !== null && - (('name' in value && String(value.name)) || - ('filename' in value && String(value.filename)) || - ('path' in value && String(value.path).split(/[\\/]/).pop()))) || - undefined + ( + (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 ); } -const isAsyncIterableIterator = (value: any): value is AsyncIterableIterator => +export const isAsyncIterable = (value: any): value is AsyncIterable => value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function'; /** @@ -268,6 +126,15 @@ export const createForm = async >( return form; }; +// We check for Blob not File because Bun.File doesn't inherit from File, +// but they both inherit from Blob and have a `name` property at runtime. +const isNamedBlob = (value: object) => value instanceof File || (value instanceof Blob && 'name' in value); + +const isUploadable = (value: unknown) => + typeof value === 'object' && + value !== null && + (value instanceof Response || isAsyncIterable(value) || isNamedBlob(value)); + const hasUploadableValue = (value: unknown): boolean => { if (isUploadable(value)) return true; if (Array.isArray(value)) return value.some(hasUploadableValue); @@ -290,9 +157,12 @@ const addFormValue = async (form: FormData, key: string, value: unknown): Promis // TODO: make nested formats configurable if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { form.append(key, String(value)); - } else if (isUploadable(value)) { - const file = await toFile(value); - form.append(key, file as any); + } else if (value instanceof Response) { + form.append(key, makeFile([await value.blob()], getName(value))); + } else if (isAsyncIterable(value)) { + form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value))); + } else if (isNamedBlob(value)) { + form.append(key, value, getName(value)); } else if (Array.isArray(value)) { await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry))); } else if (typeof value === 'object') { diff --git a/src/internal/utils/uuid.ts b/src/internal/utils/uuid.ts index 6c43f81d..1349c42c 100644 --- a/src/internal/utils/uuid.ts +++ b/src/internal/utils/uuid.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { crypto } from '../polyfill/crypto.node'; +import { crypto } from '../shims/crypto.node.js'; /** * https://stackoverflow.com/a/2117523 diff --git a/src/uploads.ts b/src/uploads.ts index 77b65766..79d3073e 100644 --- a/src/uploads.ts +++ b/src/uploads.ts @@ -1 +1,2 @@ -export { type Uploadable, toFile } from './internal/uploads'; +export { type Uploadable } from './internal/uploads'; +export { toFile, type ToFileInput } from './internal/to-file'; diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 3defd6fa..6a4c9433 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import type { ResponseLike } from '@anthropic-ai/sdk/internal/uploads'; +import type { ResponseLike } from '@anthropic-ai/sdk/internal/to-file'; import { toFile } from '@anthropic-ai/sdk/uploads'; class MyClass { @@ -13,6 +13,12 @@ function mockResponse({ url, content }: { url: string; content?: Blob }): Respon }; } +beforeEach(() => { + // The file shim captures the global File object when it's first imported. + // Reset modules before each test so we can test the error thrown when it's undefined. + jest.resetModules(); +}); + describe('toFile', () => { it('throws a helpful error for mismatched types', async () => { await expect( @@ -62,15 +68,29 @@ describe('toFile', () => { expect(file.name).toEqual('input.jsonl'); expect(file.type).toBe('jsonl'); }); + + it('is assignable to File and Blob', async () => { + const input = new File(['foo'], 'input.jsonl', { type: 'jsonl' }); + const result = await toFile(input); + const file: File = result; + const blob: Blob = result; + void file, blob; + }); }); -test('missing File error message', async () => { - // @ts-ignore - globalThis.File = undefined; +describe('missing File error message', () => { + beforeEach(() => { + // @ts-ignore + globalThis.File = undefined; + require('node:buffer').File = undefined; + }); - await expect( - toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })), - ).rejects.toMatchInlineSnapshot( - `[Error: \`File\` is not defined as a global which is required for file uploads]`, - ); + test('is thrown', async () => { + const uploads = await import('@anthropic-ai/sdk/uploads'); + await expect( + uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })), + ).rejects.toMatchInlineSnapshot( + `[Error: \`File\` is not defined as a global which is required for file uploads]`, + ); + }); }); From fa6378ea5a94ca8399dc0839c48044ba904d1c6b Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Mon, 3 Mar 2025 13:00:57 -0500 Subject: [PATCH 046/105] chore: bump version to 0.40.0-beta.0 --- .release-please-manifest.json | 2 +- package.json | 2 +- src/version.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1c924e72..d8f84e1e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,5 +1,5 @@ { - ".": "0.34.0-alpha.0", + ".": "0.40.0-beta.0", "packages/vertex-sdk": "0.6.1", "packages/bedrock-sdk": "0.12.0" } diff --git a/package.json b/package.json index 3b55421c..1a8779c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@anthropic-ai/sdk", - "version": "0.34.0-alpha.0", + "version": "0.40.0-beta.0", "description": "The official TypeScript library for the Anthropic API", "author": "Anthropic ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 0ef4aa74..af15ed8a 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.34.0-alpha.0'; // x-release-please-version +export const VERSION = '0.40.0-beta.0'; // x-release-please-version From 4cebdf1f5d6b89f375748ddb07cbac5f5dcc880a Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Mon, 3 Mar 2025 13:07:48 -0500 Subject: [PATCH 047/105] chore: remove InputJsonDelta properly --- MIGRATION.md | 2 ++ src/resources/index.ts | 1 - src/resources/messages/messages.ts | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 15750167..fffef50c 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -263,6 +263,8 @@ import { Response } from '@anthropic-ai/sdk'; // `Response` must now come from the builtin types ``` +We've also removed `InputJsonDelta` in favour of `InputJSONDelta`. `Anthropic.InputJsonDelta` -> `Anthropic.InputJSONDelta` + #### Resource classes If you were importing resource classes from the root package then you must now import them from the file they are defined in: diff --git a/src/resources/index.ts b/src/resources/index.ts index 7fb092b9..99b7c215 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -45,7 +45,6 @@ export { type ContentBlockSourceContent, type DocumentBlockParam, type ImageBlockParam, - type InputJsonDelta, type InputJSONDelta, type Message, type MessageCountTokensTool, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index ffc5e084..c484219a 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -1378,7 +1378,6 @@ export declare namespace Messages { type ContentBlockSourceContent as ContentBlockSourceContent, type DocumentBlockParam as DocumentBlockParam, type ImageBlockParam as ImageBlockParam, - type InputJsonDelta as InputJsonDelta, type InputJSONDelta as InputJSONDelta, type Message as Message, type MessageCountTokensTool as MessageCountTokensTool, From 456e7d5ce518d773914e47db4b46ddd9805806bb Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Mon, 24 Feb 2025 17:59:22 +0000 Subject: [PATCH 048/105] feat(api): add claude-3.7 + support for thinking --- README.md | 29 +- packages/vertex-sdk/yarn.lock | 6 - src/client.ts | 13 + src/lib/BetaMessageStream.ts | 665 ++++++++++++++++++ src/lib/MessageStream.ts | 170 ++++- src/resources/beta/messages/messages.ts | 10 +- src/resources/messages/messages.ts | 8 +- tests/api-resources/MessageStream.test.ts | 6 + .../beta/messages/batches.test.ts | 18 +- .../beta/messages/messages.test.ts | 30 +- tests/api-resources/messages/batches.test.ts | 18 +- tests/api-resources/messages/messages.test.ts | 30 +- tests/responses.test.ts | 9 + 13 files changed, 887 insertions(+), 125 deletions(-) create mode 100644 src/lib/BetaMessageStream.ts diff --git a/README.md b/README.md index 5438bba8..63c2d7a7 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,16 @@ await client.messages.create({ max_tokens: 1024, messages: [{ role: 'user', cont ### Timeouts -Requests time out after 10 minutes by default. You can configure this with a `timeout` option: +By default requests time out after 10 minutes. However if you have specified a large `max_tokens` value and are +*not* streaming, the default timeout will be calculated dynamically using the formula: +```typescript +const minimum = 10 * 60; +const calculated = (60 * 60 * maxTokens) / 128_000; +return calculated < minimum ? minimum * 1000 : calculated * 1000; +``` +which will result in a timeout up to 60 minutes, scaled by the `max_tokens` parameter, unless overriden at the request or client level. + +You can configure this with a `timeout` option: ```ts @@ -281,6 +290,24 @@ On timeout, an `APIConnectionTimeoutError` is thrown. Note that requests which time out will be [retried twice by default](#retries). +### Long Requests + +> [!IMPORTANT] +> We highly encourage you use the streaming [Messages API](#streaming-responses) for longer running requests. + +We do not recommend setting a large `max_tokens` values without using streaming. +Some networks may drop idle connections after a certain period of time, which +can cause the request to fail or [timeout](#timeouts) without receiving a response from Anthropic. + +This SDK will also throw an error if a non-streaming request is expected to be above roughly 10 minutes long. +Passing `stream: true` or [overriding](#timeouts) the `timeout` option at the client or request level disables this error. + +An expected request latency longer than the [timeout](#timeouts) for a non-streaming request +will result in the client terminating the connection and retrying without receiving a response. + +When supported by the `fetch` implementation, we set a [TCP socket keep-alive](https://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html) +option in order to reduce the impact of idle connection timeouts on some networks. + ## Auto-pagination List methods in the Anthropic API are paginated. diff --git a/packages/vertex-sdk/yarn.lock b/packages/vertex-sdk/yarn.lock index 01fc2a7a..efc703d6 100644 --- a/packages/vertex-sdk/yarn.lock +++ b/packages/vertex-sdk/yarn.lock @@ -27,7 +27,6 @@ form-data-encoder "1.7.2" formdata-node "^4.3.2" node-fetch "^2.6.7" - web-streams-polyfill "^3.2.1" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": version "7.23.5" @@ -3257,11 +3256,6 @@ web-streams-polyfill@4.0.0-beta.3: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38" integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug== -web-streams-polyfill@^3.2.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz#32e26522e05128203a7de59519be3c648004343b" - integrity sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ== - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" diff --git a/src/client.ts b/src/client.ts index a879e5b8..39798ff5 100644 --- a/src/client.ts +++ b/src/client.ts @@ -13,6 +13,7 @@ import * as Opts from './internal/request-options'; import { VERSION } from './version'; import * as Errors from './error'; import * as Pagination from './pagination'; +import { AnthropicError } from './error'; import { AbstractPage, type PageParams, PageResponse } from './pagination'; import * as Uploads from './uploads'; import * as API from './resources/index'; @@ -430,6 +431,18 @@ export class BaseAnthropic { return url.toString(); } + _calculateNonstreamingTimeout(maxTokens: number): number { + const defaultTimeout = 10 * 60; + const expectedTimeout = (60 * 60 * maxTokens) / 128_000; + if (expectedTimeout > defaultTimeout) { + throw new AnthropicError( + 'Streaming is strongly recommended for operations that may take longer than 10 minutes. ' + + 'See https://github.com/anthropics/anthropic-sdk-python#streaming-responses for more details', + ); + } + return defaultTimeout * 1000; + } + /** * Used as a callback for mutating the given `FinalRequestOptions` object. */ diff --git a/src/lib/BetaMessageStream.ts b/src/lib/BetaMessageStream.ts new file mode 100644 index 00000000..06ba3dd3 --- /dev/null +++ b/src/lib/BetaMessageStream.ts @@ -0,0 +1,665 @@ +import { isAbortError } from '../internal/errors'; +import { AnthropicError, APIUserAbortError } from '../error'; +import { + type BetaContentBlock, + Messages as BetaMessages, + type BetaMessage, + type BetaRawMessageStreamEvent as BetaMessageStreamEvent, + type BetaMessageParam, + type MessageCreateParams as BetaMessageCreateParams, + type MessageCreateParamsBase as BetaMessageCreateParamsBase, + type BetaTextBlock, + type BetaTextCitation, +} from '../resources/beta/messages/messages'; +import { Stream } from '../streaming'; +import { partialParse } from '../_vendor/partial-json-parser/parser'; +import { type RequestOptions } from '../internal/request-options'; +import { type ReadableStream } from '../internal/shim-types'; + +export interface MessageStreamEvents { + connect: () => void; + streamEvent: (event: BetaMessageStreamEvent, snapshot: BetaMessage) => void; + text: (textDelta: string, textSnapshot: string) => void; + citation: (citation: BetaTextCitation, citationsSnapshot: BetaTextCitation[]) => void; + inputJson: (partialJson: string, jsonSnapshot: unknown) => void; + thinking: (thinkingDelta: string, thinkingSnapshot: string) => void; + signature: (signature: string) => void; + message: (message: BetaMessage) => void; + contentBlock: (content: BetaContentBlock) => void; + finalMessage: (message: BetaMessage) => void; + error: (error: AnthropicError) => void; + abort: (error: APIUserAbortError) => void; + end: () => void; +} + +type MessageStreamEventListeners = { + listener: MessageStreamEvents[Event]; + once?: boolean; +}[]; + +const JSON_BUF_PROPERTY = '__json_buf'; + +export class BetaMessageStream implements AsyncIterable { + messages: BetaMessageParam[] = []; + receivedMessages: BetaMessage[] = []; + #currentMessageSnapshot: BetaMessage | undefined; + + controller: AbortController = new AbortController(); + + #connectedPromise: Promise; + #resolveConnectedPromise: (response: Response | null) => void = () => {}; + #rejectConnectedPromise: (error: AnthropicError) => void = () => {}; + + #endPromise: Promise; + #resolveEndPromise: () => void = () => {}; + #rejectEndPromise: (error: AnthropicError) => void = () => {}; + + #listeners: { [Event in keyof MessageStreamEvents]?: MessageStreamEventListeners } = {}; + + #ended = false; + #errored = false; + #aborted = false; + #catchingPromiseCreated = false; + #response: Response | null | undefined; + #request_id: string | null | undefined; + + constructor() { + this.#connectedPromise = new Promise((resolve, reject) => { + this.#resolveConnectedPromise = resolve; + this.#rejectConnectedPromise = reject; + }); + + this.#endPromise = new Promise((resolve, reject) => { + this.#resolveEndPromise = resolve; + this.#rejectEndPromise = reject; + }); + + // Don't let these promises cause unhandled rejection errors. + // we will manually cause an unhandled rejection error later + // if the user hasn't registered any error listener or called + // any promise-returning method. + this.#connectedPromise.catch(() => {}); + this.#endPromise.catch(() => {}); + } + + get response(): Response | null | undefined { + return this.#response; + } + + get request_id(): string | null | undefined { + return this.#request_id; + } + + /** + * Returns the `MessageStream` data, the raw `Response` instance and the ID of the request, + * returned vie the `request-id` header which is useful for debugging requests and resporting + * issues to Anthropic. + * + * This is the same as the `APIPromise.withResponse()` method. + * + * This method will raise an error if you created the stream using `MessageStream.fromReadableStream` + * as no `Response` is available. + */ + async withResponse(): Promise<{ + data: BetaMessageStream; + response: Response; + request_id: string | null | undefined; + }> { + const response = await this.#connectedPromise; + if (!response) { + throw new Error('Could not resolve a `Response` object'); + } + + return { + data: this, + response, + request_id: response.headers.get('request-id'), + }; + } + + /** + * Intended for use on the frontend, consuming a stream produced with + * `.toReadableStream()` on the backend. + * + * Note that messages sent to the model do not appear in `.on('message')` + * in this context. + */ + static fromReadableStream(stream: ReadableStream): BetaMessageStream { + const runner = new BetaMessageStream(); + runner._run(() => runner._fromReadableStream(stream)); + return runner; + } + + static createMessage( + messages: BetaMessages, + params: BetaMessageCreateParamsBase, + options?: RequestOptions, + ): BetaMessageStream { + const runner = new BetaMessageStream(); + for (const message of params.messages) { + runner._addMessageParam(message); + } + runner._run(() => + runner._createMessage( + messages, + { ...params, stream: true }, + { ...options, headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' } }, + ), + ); + return runner; + } + + protected _run(executor: () => Promise) { + executor().then(() => { + this._emitFinal(); + this._emit('end'); + }, this.#handleError); + } + + protected _addMessageParam(message: BetaMessageParam) { + this.messages.push(message); + } + + protected _addMessage(message: BetaMessage, emit = true) { + this.receivedMessages.push(message); + if (emit) { + this._emit('message', message); + } + } + + protected async _createMessage( + messages: BetaMessages, + params: BetaMessageCreateParams, + options?: RequestOptions, + ): Promise { + const signal = options?.signal; + if (signal) { + if (signal.aborted) this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + this.#beginRequest(); + const { response, data: stream } = await messages + .create({ ...params, stream: true }, { ...options, signal: this.controller.signal }) + .withResponse(); + this._connected(response); + for await (const event of stream) { + this.#addStreamEvent(event); + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + this.#endRequest(); + } + + protected _connected(response: Response | null) { + if (this.ended) return; + this.#response = response; + this.#request_id = response?.headers.get('request-id'); + this.#resolveConnectedPromise(response); + this._emit('connect'); + } + + get ended(): boolean { + return this.#ended; + } + + get errored(): boolean { + return this.#errored; + } + + get aborted(): boolean { + return this.#aborted; + } + + abort() { + this.controller.abort(); + } + + /** + * Adds the listener function to the end of the listeners array for the event. + * No checks are made to see if the listener has already been added. Multiple calls passing + * the same combination of event and listener will result in the listener being added, and + * called, multiple times. + * @returns this MessageStream, so that calls can be chained + */ + on(event: Event, listener: MessageStreamEvents[Event]): this { + const listeners: MessageStreamEventListeners = + this.#listeners[event] || (this.#listeners[event] = []); + listeners.push({ listener }); + return this; + } + + /** + * Removes the specified listener from the listener array for the event. + * off() will remove, at most, one instance of a listener from the listener array. If any single + * listener has been added multiple times to the listener array for the specified event, then + * off() must be called multiple times to remove each instance. + * @returns this MessageStream, so that calls can be chained + */ + off(event: Event, listener: MessageStreamEvents[Event]): this { + const listeners = this.#listeners[event]; + if (!listeners) return this; + const index = listeners.findIndex((l) => l.listener === listener); + if (index >= 0) listeners.splice(index, 1); + return this; + } + + /** + * Adds a one-time listener function for the event. The next time the event is triggered, + * this listener is removed and then invoked. + * @returns this MessageStream, so that calls can be chained + */ + once(event: Event, listener: MessageStreamEvents[Event]): this { + const listeners: MessageStreamEventListeners = + this.#listeners[event] || (this.#listeners[event] = []); + listeners.push({ listener, once: true }); + return this; + } + + /** + * This is similar to `.once()`, but returns a Promise that resolves the next time + * the event is triggered, instead of calling a listener callback. + * @returns a Promise that resolves the next time given event is triggered, + * or rejects if an error is emitted. (If you request the 'error' event, + * returns a promise that resolves with the error). + * + * Example: + * + * const message = await stream.emitted('message') // rejects if the stream errors + */ + emitted( + event: Event, + ): Promise< + Parameters extends [infer Param] ? Param + : Parameters extends [] ? void + : Parameters + > { + return new Promise((resolve, reject) => { + this.#catchingPromiseCreated = true; + if (event !== 'error') this.once('error', reject); + this.once(event, resolve as any); + }); + } + + async done(): Promise { + this.#catchingPromiseCreated = true; + await this.#endPromise; + } + + get currentMessage(): BetaMessage | undefined { + return this.#currentMessageSnapshot; + } + + #getFinalMessage(): BetaMessage { + if (this.receivedMessages.length === 0) { + throw new AnthropicError('stream ended without producing a Message with role=assistant'); + } + return this.receivedMessages.at(-1)!; + } + + /** + * @returns a promise that resolves with the the final assistant Message response, + * or rejects if an error occurred or the stream ended prematurely without producing a Message. + */ + async finalMessage(): Promise { + await this.done(); + return this.#getFinalMessage(); + } + + #getFinalText(): string { + if (this.receivedMessages.length === 0) { + throw new AnthropicError('stream ended without producing a Message with role=assistant'); + } + const textBlocks = this.receivedMessages + .at(-1)! + .content.filter((block): block is BetaTextBlock => block.type === 'text') + .map((block) => block.text); + if (textBlocks.length === 0) { + throw new AnthropicError('stream ended without producing a content block with type=text'); + } + return textBlocks.join(' '); + } + + /** + * @returns a promise that resolves with the the final assistant Message's text response, concatenated + * together if there are more than one text blocks. + * Rejects if an error occurred or the stream ended prematurely without producing a Message. + */ + async finalText(): Promise { + await this.done(); + return this.#getFinalText(); + } + + #handleError = (error: unknown) => { + this.#errored = true; + if (isAbortError(error)) { + error = new APIUserAbortError(); + } + if (error instanceof APIUserAbortError) { + this.#aborted = true; + return this._emit('abort', error); + } + if (error instanceof AnthropicError) { + return this._emit('error', error); + } + if (error instanceof Error) { + const anthropicError: AnthropicError = new AnthropicError(error.message); + // @ts-ignore + anthropicError.cause = error; + return this._emit('error', anthropicError); + } + return this._emit('error', new AnthropicError(String(error))); + }; + + protected _emit( + event: Event, + ...args: Parameters + ) { + // make sure we don't emit any MessageStreamEvents after end + if (this.#ended) return; + + if (event === 'end') { + this.#ended = true; + this.#resolveEndPromise(); + } + + const listeners: MessageStreamEventListeners | undefined = this.#listeners[event]; + if (listeners) { + this.#listeners[event] = listeners.filter((l) => !l.once) as any; + listeners.forEach(({ listener }: any) => listener(...args)); + } + + if (event === 'abort') { + const error = args[0] as APIUserAbortError; + if (!this.#catchingPromiseCreated && !listeners?.length) { + Promise.reject(error); + } + this.#rejectConnectedPromise(error); + this.#rejectEndPromise(error); + this._emit('end'); + return; + } + + if (event === 'error') { + // NOTE: _emit('error', error) should only be called from #handleError(). + + const error = args[0] as AnthropicError; + if (!this.#catchingPromiseCreated && !listeners?.length) { + // Trigger an unhandled rejection if the user hasn't registered any error handlers. + // If you are seeing stack traces here, make sure to handle errors via either: + // - runner.on('error', () => ...) + // - await runner.done() + // - await runner.final...() + // - etc. + Promise.reject(error); + } + this.#rejectConnectedPromise(error); + this.#rejectEndPromise(error); + this._emit('end'); + } + } + + protected _emitFinal() { + const finalMessage = this.receivedMessages.at(-1); + if (finalMessage) { + this._emit('finalMessage', this.#getFinalMessage()); + } + } + + #beginRequest() { + if (this.ended) return; + this.#currentMessageSnapshot = undefined; + } + #addStreamEvent(event: BetaMessageStreamEvent) { + if (this.ended) return; + const messageSnapshot = this.#accumulateMessage(event); + this._emit('streamEvent', event, messageSnapshot); + + switch (event.type) { + case 'content_block_delta': { + const content = messageSnapshot.content.at(-1)!; + switch (event.delta.type) { + case 'text_delta': { + if (content.type === 'text') { + this._emit('text', event.delta.text, content.text || ''); + } + break; + } + case 'citations_delta': { + if (content.type === 'text') { + this._emit('citation', event.delta.citation, content.citations ?? []); + } + break; + } + case 'input_json_delta': { + if (content.type === 'tool_use' && content.input) { + this._emit('inputJson', event.delta.partial_json, content.input); + } + break; + } + case 'thinking_delta': { + if (content.type === 'thinking') { + this._emit('thinking', event.delta.thinking, content.thinking); + } + break; + } + case 'signature_delta': { + if (content.type === 'thinking') { + this._emit('signature', content.signature); + } + break; + } + default: + checkNever(event.delta); + } + break; + } + case 'message_stop': { + this._addMessageParam(messageSnapshot); + this._addMessage(messageSnapshot, true); + break; + } + case 'content_block_stop': { + this._emit('contentBlock', messageSnapshot.content.at(-1)!); + break; + } + case 'message_start': { + this.#currentMessageSnapshot = messageSnapshot; + break; + } + case 'content_block_start': + case 'message_delta': + break; + } + } + #endRequest(): BetaMessage { + if (this.ended) { + throw new AnthropicError(`stream has ended, this shouldn't happen`); + } + const snapshot = this.#currentMessageSnapshot; + if (!snapshot) { + throw new AnthropicError(`request ended without sending any chunks`); + } + this.#currentMessageSnapshot = undefined; + return snapshot; + } + + protected async _fromReadableStream( + readableStream: ReadableStream, + options?: RequestOptions, + ): Promise { + const signal = options?.signal; + if (signal) { + if (signal.aborted) this.controller.abort(); + signal.addEventListener('abort', () => this.controller.abort()); + } + this.#beginRequest(); + this._connected(null); + const stream = Stream.fromReadableStream(readableStream, this.controller); + for await (const event of stream) { + this.#addStreamEvent(event); + } + if (stream.controller.signal?.aborted) { + throw new APIUserAbortError(); + } + this.#endRequest(); + } + + /** + * Mutates this.#currentMessage with the current event. Handling the accumulation of multiple messages + * will be needed to be handled by the caller, this method will throw if you try to accumulate for multiple + * messages. + */ + #accumulateMessage(event: BetaMessageStreamEvent): BetaMessage { + let snapshot = this.#currentMessageSnapshot; + + if (event.type === 'message_start') { + if (snapshot) { + throw new AnthropicError(`Unexpected event order, got ${event.type} before receiving "message_stop"`); + } + return event.message; + } + + if (!snapshot) { + throw new AnthropicError(`Unexpected event order, got ${event.type} before "message_start"`); + } + + switch (event.type) { + case 'message_stop': + return snapshot; + case 'message_delta': + snapshot.stop_reason = event.delta.stop_reason; + snapshot.stop_sequence = event.delta.stop_sequence; + snapshot.usage.output_tokens = event.usage.output_tokens; + return snapshot; + case 'content_block_start': + snapshot.content.push(event.content_block); + return snapshot; + case 'content_block_delta': { + const snapshotContent = snapshot.content.at(event.index); + + switch (event.delta.type) { + case 'text_delta': { + if (snapshotContent?.type === 'text') { + snapshotContent.text += event.delta.text; + } + break; + } + case 'citations_delta': { + if (snapshotContent?.type === 'text') { + snapshotContent.citations ??= []; + snapshotContent.citations.push(event.delta.citation); + } + break; + } + case 'input_json_delta': { + if (snapshotContent?.type === 'tool_use') { + // we need to keep track of the raw JSON string as well so that we can + // re-parse it for each delta, for now we just store it as an untyped + // non-enumerable property on the snapshot + let jsonBuf = (snapshotContent as any)[JSON_BUF_PROPERTY] || ''; + jsonBuf += event.delta.partial_json; + + Object.defineProperty(snapshotContent, JSON_BUF_PROPERTY, { + value: jsonBuf, + enumerable: false, + writable: true, + }); + + if (jsonBuf) { + snapshotContent.input = partialParse(jsonBuf); + } + } + break; + } + case 'thinking_delta': { + if (snapshotContent?.type === 'thinking') { + snapshotContent.thinking += event.delta.thinking; + } + break; + } + case 'signature_delta': { + if (snapshotContent?.type === 'thinking') { + snapshotContent.signature = event.delta.signature; + } + break; + } + default: + checkNever(event.delta); + } + return snapshot; + } + case 'content_block_stop': + return snapshot; + } + } + + [Symbol.asyncIterator](): AsyncIterator { + const pushQueue: BetaMessageStreamEvent[] = []; + const readQueue: { + resolve: (chunk: BetaMessageStreamEvent | undefined) => void; + reject: (error: unknown) => void; + }[] = []; + let done = false; + + this.on('streamEvent', (event) => { + const reader = readQueue.shift(); + if (reader) { + reader.resolve(event); + } else { + pushQueue.push(event); + } + }); + + this.on('end', () => { + done = true; + for (const reader of readQueue) { + reader.resolve(undefined); + } + readQueue.length = 0; + }); + + this.on('abort', (err) => { + done = true; + for (const reader of readQueue) { + reader.reject(err); + } + readQueue.length = 0; + }); + + this.on('error', (err) => { + done = true; + for (const reader of readQueue) { + reader.reject(err); + } + readQueue.length = 0; + }); + + return { + next: async (): Promise> => { + if (!pushQueue.length) { + if (done) { + return { value: undefined, done: true }; + } + return new Promise((resolve, reject) => + readQueue.push({ resolve, reject }), + ).then((chunk) => (chunk ? { value: chunk, done: false } : { value: undefined, done: true })); + } + const chunk = pushQueue.shift()!; + return { value: chunk, done: false }; + }, + return: async () => { + this.abort(); + return { value: undefined, done: true }; + }, + }; + } + + toReadableStream(): ReadableStream { + const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller); + return stream.toReadableStream(); + } +} + +// used to ensure exhaustive case matching without throwing a runtime error +function checkNever(x: never) {} diff --git a/src/lib/MessageStream.ts b/src/lib/MessageStream.ts index 083aa24b..5d1e8096 100644 --- a/src/lib/MessageStream.ts +++ b/src/lib/MessageStream.ts @@ -9,6 +9,7 @@ import { type MessageCreateParams, type MessageCreateParamsBase, type TextBlock, + type TextCitation, } from '../resources/messages'; import { Stream } from '../streaming'; import { partialParse } from '../_vendor/partial-json-parser/parser'; @@ -19,7 +20,10 @@ export interface MessageStreamEvents { connect: () => void; streamEvent: (event: MessageStreamEvent, snapshot: Message) => void; text: (textDelta: string, textSnapshot: string) => void; + citation: (citation: TextCitation, citationsSnapshot: TextCitation[]) => void; inputJson: (partialJson: string, jsonSnapshot: unknown) => void; + thinking: (thinkingDelta: string, thinkingSnapshot: string) => void; + signature: (signature: string) => void; message: (message: Message) => void; contentBlock: (content: ContentBlock) => void; finalMessage: (message: Message) => void; @@ -42,8 +46,8 @@ export class MessageStream implements AsyncIterable { controller: AbortController = new AbortController(); - #connectedPromise: Promise; - #resolveConnectedPromise: () => void = () => {}; + #connectedPromise: Promise; + #resolveConnectedPromise: (response: Response | null) => void = () => {}; #rejectConnectedPromise: (error: AnthropicError) => void = () => {}; #endPromise: Promise; @@ -56,9 +60,11 @@ export class MessageStream implements AsyncIterable { #errored = false; #aborted = false; #catchingPromiseCreated = false; + #response: Response | null | undefined; + #request_id: string | null | undefined; constructor() { - this.#connectedPromise = new Promise((resolve, reject) => { + this.#connectedPromise = new Promise((resolve, reject) => { this.#resolveConnectedPromise = resolve; this.#rejectConnectedPromise = reject; }); @@ -76,6 +82,41 @@ export class MessageStream implements AsyncIterable { this.#endPromise.catch(() => {}); } + get response(): Response | null | undefined { + return this.#response; + } + + get request_id(): string | null | undefined { + return this.#request_id; + } + + /** + * Returns the `MessageStream` data, the raw `Response` instance and the ID of the request, + * returned vie the `request-id` header which is useful for debugging requests and resporting + * issues to Anthropic. + * + * This is the same as the `APIPromise.withResponse()` method. + * + * This method will raise an error if you created the stream using `MessageStream.fromReadableStream` + * as no `Response` is available. + */ + async withResponse(): Promise<{ + data: MessageStream; + response: Response; + request_id: string | null | undefined; + }> { + const response = await this.#connectedPromise; + if (!response) { + throw new Error('Could not resolve a `Response` object'); + } + + return { + data: this, + response, + request_id: response.headers.get('request-id'), + }; + } + /** * Intended for use on the frontend, consuming a stream produced with * `.toReadableStream()` on the backend. @@ -137,11 +178,10 @@ export class MessageStream implements AsyncIterable { signal.addEventListener('abort', () => this.controller.abort()); } this.#beginRequest(); - const stream = await messages.create( - { ...params, stream: true }, - { ...options, signal: this.controller.signal }, - ); - this._connected(); + const { response, data: stream } = await messages + .create({ ...params, stream: true }, { ...options, signal: this.controller.signal }) + .withResponse(); + this._connected(response); for await (const event of stream) { this.#addStreamEvent(event); } @@ -151,9 +191,11 @@ export class MessageStream implements AsyncIterable { this.#endRequest(); } - protected _connected() { + protected _connected(response: Response | null) { if (this.ended) return; - this.#resolveConnectedPromise(); + this.#response = response; + this.#request_id = response?.headers.get('request-id'); + this.#resolveConnectedPromise(response); this._emit('connect'); } @@ -376,12 +418,39 @@ export class MessageStream implements AsyncIterable { switch (event.type) { case 'content_block_delta': { const content = messageSnapshot.content.at(-1)!; - if (event.delta.type === 'text_delta' && content.type === 'text') { - this._emit('text', event.delta.text, content.text || ''); - } else if (event.delta.type === 'input_json_delta' && content.type === 'tool_use') { - if (content.input) { - this._emit('inputJson', event.delta.partial_json, content.input); + switch (event.delta.type) { + case 'text_delta': { + if (content.type === 'text') { + this._emit('text', event.delta.text, content.text || ''); + } + break; + } + case 'citations_delta': { + if (content.type === 'text') { + this._emit('citation', event.delta.citation, content.citations ?? []); + } + break; + } + case 'input_json_delta': { + if (content.type === 'tool_use' && content.input) { + this._emit('inputJson', event.delta.partial_json, content.input); + } + break; } + case 'thinking_delta': { + if (content.type === 'thinking') { + this._emit('thinking', event.delta.thinking, content.thinking); + } + break; + } + case 'signature_delta': { + if (content.type === 'thinking') { + this._emit('signature', content.signature); + } + break; + } + default: + checkNever(event.delta); } break; } @@ -425,7 +494,7 @@ export class MessageStream implements AsyncIterable { signal.addEventListener('abort', () => this.controller.abort()); } this.#beginRequest(); - this._connected(); + this._connected(null); const stream = Stream.fromReadableStream(readableStream, this.controller); for await (const event of stream) { this.#addStreamEvent(event); @@ -468,25 +537,57 @@ export class MessageStream implements AsyncIterable { return snapshot; case 'content_block_delta': { const snapshotContent = snapshot.content.at(event.index); - if (snapshotContent?.type === 'text' && event.delta.type === 'text_delta') { - snapshotContent.text += event.delta.text; - } else if (snapshotContent?.type === 'tool_use' && event.delta.type === 'input_json_delta') { - // we need to keep track of the raw JSON string as well so that we can - // re-parse it for each delta, for now we just store it as an untyped - // non-enumerable property on the snapshot - let jsonBuf = (snapshotContent as any)[JSON_BUF_PROPERTY] || ''; - jsonBuf += event.delta.partial_json; - - Object.defineProperty(snapshotContent, JSON_BUF_PROPERTY, { - value: jsonBuf, - enumerable: false, - writable: true, - }); - - if (jsonBuf) { - snapshotContent.input = partialParse(jsonBuf); + + switch (event.delta.type) { + case 'text_delta': { + if (snapshotContent?.type === 'text') { + snapshotContent.text += event.delta.text; + } + break; } + case 'citations_delta': { + if (snapshotContent?.type === 'text') { + snapshotContent.citations ??= []; + snapshotContent.citations.push(event.delta.citation); + } + break; + } + case 'input_json_delta': { + if (snapshotContent?.type === 'tool_use') { + // we need to keep track of the raw JSON string as well so that we can + // re-parse it for each delta, for now we just store it as an untyped + // non-enumerable property on the snapshot + let jsonBuf = (snapshotContent as any)[JSON_BUF_PROPERTY] || ''; + jsonBuf += event.delta.partial_json; + + Object.defineProperty(snapshotContent, JSON_BUF_PROPERTY, { + value: jsonBuf, + enumerable: false, + writable: true, + }); + + if (jsonBuf) { + snapshotContent.input = partialParse(jsonBuf); + } + } + break; + } + case 'thinking_delta': { + if (snapshotContent?.type === 'thinking') { + snapshotContent.thinking += event.delta.thinking; + } + break; + } + case 'signature_delta': { + if (snapshotContent?.type === 'thinking') { + snapshotContent.signature = event.delta.signature; + } + break; + } + default: + checkNever(event.delta); } + return snapshot; } case 'content_block_stop': @@ -560,3 +661,6 @@ export class MessageStream implements AsyncIterable { return stream.toReadableStream(); } } + +// used to ensure exhaustive case matching without throwing a runtime error +function checkNever(x: never) {} diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index c5d48864..9c1e24b1 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -57,7 +57,9 @@ export class Messages extends APIResource { const { betas, ...body } = params; return this._client.post('/v1/messages?beta=true', { body, - timeout: (this._client as any)._options.timeout ?? 600000, + timeout: + (this._client as any)._options.timeout ?? + (body.stream ? 600000 : this._client._calculateNonstreamingTimeout(body.max_tokens)), ...options, headers: buildHeaders([ { ...(betas?.toString() != null ? { 'anthropic-beta': betas?.toString() } : undefined) }, @@ -823,13 +825,13 @@ export interface BetaToolTextEditor20250124 { } export type BetaToolUnion = - | BetaTool | BetaToolComputerUse20241022 | BetaToolBash20241022 | BetaToolTextEditor20241022 | BetaToolComputerUse20250124 | BetaToolBash20250124 - | BetaToolTextEditor20250124; + | BetaToolTextEditor20250124 + | BetaTool; export interface BetaToolUseBlock { id: string; @@ -1393,13 +1395,13 @@ export interface MessageCountTokensParams { * See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. */ tools?: Array< - | BetaTool | BetaToolComputerUse20241022 | BetaToolBash20241022 | BetaToolTextEditor20241022 | BetaToolComputerUse20250124 | BetaToolBash20250124 | BetaToolTextEditor20250124 + | BetaTool >; /** diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index c484219a..fc0a9f10 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -59,7 +59,9 @@ export class Messages extends APIResource { } return this._client.post('/v1/messages', { body, - timeout: (this._client as any)._options.timeout ?? 600000, + timeout: + (this._client as any)._options.timeout ?? + (body.stream ? 600000 : this._client._calculateNonstreamingTimeout(body.max_tokens)), ...options, stream: body.stream ?? false, }) as APIPromise | APIPromise>; @@ -361,7 +363,7 @@ export interface Message { usage: Usage; } -export type MessageCountTokensTool = Tool | ToolBash20250124 | ToolTextEditor20250124; +export type MessageCountTokensTool = ToolBash20250124 | ToolTextEditor20250124 | Tool; export type MessageDeltaEvent = RawMessageDeltaEvent; @@ -774,7 +776,7 @@ export interface ToolTextEditor20250124 { cache_control?: CacheControlEphemeral | null; } -export type ToolUnion = Tool | ToolBash20250124 | ToolTextEditor20250124; +export type ToolUnion = ToolBash20250124 | ToolTextEditor20250124 | Tool; export interface ToolUseBlock { id: string; diff --git a/tests/api-resources/MessageStream.test.ts b/tests/api-resources/MessageStream.test.ts index 8c46caa1..5b21615f 100644 --- a/tests/api-resources/MessageStream.test.ts +++ b/tests/api-resources/MessageStream.test.ts @@ -32,6 +32,8 @@ async function* messageIterable(message: Message): AsyncGenerator { tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { - description: 'Unit for the output - one of (celsius, fahrenheit)', - type: 'string', - }, - }, - }, - name: 'name', + display_height_px: 1, + display_width_px: 1, + name: 'computer', + type: 'computer_20241022', cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - type: 'custom', + display_number: 0, }, ], top_k: 5, diff --git a/tests/api-resources/beta/messages/messages.test.ts b/tests/api-resources/beta/messages/messages.test.ts index 23703606..bc4b9c32 100644 --- a/tests/api-resources/beta/messages/messages.test.ts +++ b/tests/api-resources/beta/messages/messages.test.ts @@ -53,17 +53,12 @@ describe('resource messages', () => { tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, - }, - }, - name: 'name', + display_height_px: 1, + display_width_px: 1, + name: 'computer', + type: 'computer_20241022', cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - type: 'custom', + display_number: 0, }, ], top_k: 5, @@ -111,17 +106,12 @@ describe('resource messages', () => { tool_choice: { type: 'auto', disable_parallel_tool_use: true }, tools: [ { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, - }, - }, - name: 'name', + display_height_px: 1, + display_width_px: 1, + name: 'computer', + type: 'computer_20241022', cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - type: 'custom', + display_number: 0, }, ], betas: ['string'], diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index 1f0fdc23..ba6e9d57 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -61,23 +61,7 @@ describe('resource batches', () => { temperature: 1, thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [ - { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { - description: 'Unit for the output - one of (celsius, fahrenheit)', - type: 'string', - }, - }, - }, - name: 'name', - cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - }, - ], + tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], top_k: 5, top_p: 0.7, }, diff --git a/tests/api-resources/messages/messages.test.ts b/tests/api-resources/messages/messages.test.ts index 3739d7f0..0b56715d 100644 --- a/tests/api-resources/messages/messages.test.ts +++ b/tests/api-resources/messages/messages.test.ts @@ -51,20 +51,7 @@ describe('resource messages', () => { temperature: 1, thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [ - { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, - }, - }, - name: 'name', - cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - }, - ], + tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], top_k: 5, top_p: 0.7, }); @@ -107,20 +94,7 @@ describe('resource messages', () => { ], thinking: { budget_tokens: 1024, type: 'enabled' }, tool_choice: { type: 'auto', disable_parallel_tool_use: true }, - tools: [ - { - input_schema: { - type: 'object', - properties: { - location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' }, - unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' }, - }, - }, - name: 'name', - cache_control: { type: 'ephemeral' }, - description: 'Get the current weather in a given location', - }, - ], + tools: [{ name: 'bash', type: 'bash_20250124', cache_control: { type: 'ephemeral' } }], }); }); }); diff --git a/tests/responses.test.ts b/tests/responses.test.ts index 5000e68b..fb9b9dd6 100644 --- a/tests/responses.test.ts +++ b/tests/responses.test.ts @@ -70,6 +70,9 @@ describe('request id', () => { }), controller: {} as any, options: {} as any, + requestLogID: 'log_000000', + retryOfRequestLogID: undefined, + startTime: Date.now(), }; })(), )._thenUnwrap((d) => d.data); @@ -103,6 +106,9 @@ describe('request id', () => { }), controller: {} as any, options: {} as any, + requestLogID: 'log_000000', + retryOfRequestLogID: undefined, + startTime: Date.now(), }; })(), ); @@ -123,6 +129,9 @@ describe('request id', () => { }), controller: {} as any, options: {} as any, + requestLogID: 'log_000000', + retryOfRequestLogID: undefined, + startTime: Date.now(), }; })(), ); From 4c217aa6a0bca1e649d1ea525e1b8f220dcce81a Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Mon, 3 Mar 2025 13:42:11 -0500 Subject: [PATCH 049/105] chore(internal): fix tests failing on node v18 --- tests/uploads.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 6a4c9433..0f80bc8d 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,6 +1,7 @@ import fs from 'fs'; import type { ResponseLike } from '@anthropic-ai/sdk/internal/to-file'; import { toFile } from '@anthropic-ai/sdk/uploads'; +import { File } from 'node:buffer'; class MyClass { name: string = 'foo'; From 9e617f1745db414176b34fa1b533fcd2feb6e747 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 3 Mar 2025 21:23:02 +0000 Subject: [PATCH 050/105] fix(client): fix TypeError with undefined File --- package.json | 3 +++ src/internal/uploads.ts | 3 ++- yarn.lock | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1a8779c8..a2a186e3 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,9 @@ "tsconfig-paths": "^4.0.0", "typescript": "^4.8.2" }, + "resolutions": { + "synckit": "0.8.8" + }, "imports": { "@anthropic-ai/sdk": ".", "@anthropic-ai/sdk/*": "./src/*" diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index b07ac53e..15e579e4 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -128,7 +128,8 @@ export const createForm = async >( // We check for Blob not File because Bun.File doesn't inherit from File, // but they both inherit from Blob and have a `name` property at runtime. -const isNamedBlob = (value: object) => value instanceof File || (value instanceof Blob && 'name' in value); +const isNamedBlob = (value: object) => + (File && value instanceof File) || (value instanceof Blob && 'name' in value); const isUploadable = (value: unknown) => typeof value === 'object' && diff --git a/yarn.lock b/yarn.lock index 30e61b11..b40f3dc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3198,10 +3198,10 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -synckit@^0.9.1: - version "0.9.2" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.2.tgz#a3a935eca7922d48b9e7d6c61822ee6c3ae4ec62" - integrity sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw== +synckit@0.8.8, synckit@^0.9.1: + version "0.8.8" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" + integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== dependencies: "@pkgr/core" "^0.1.0" tslib "^2.6.2" From 6c44d9c0bbece918fed843bbf75f4ca56dd3b76c Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 3 Mar 2025 22:26:44 +0000 Subject: [PATCH 051/105] fix(internal): clean up undefined File test --- tests/uploads.test.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 0f80bc8d..b004fd6e 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -14,12 +14,6 @@ function mockResponse({ url, content }: { url: string; content?: Blob }): Respon }; } -beforeEach(() => { - // The file shim captures the global File object when it's first imported. - // Reset modules before each test so we can test the error thrown when it's undefined. - jest.resetModules(); -}); - describe('toFile', () => { it('throws a helpful error for mismatched types', async () => { await expect( @@ -80,11 +74,23 @@ describe('toFile', () => { }); describe('missing File error message', () => { + let prevFile: unknown; beforeEach(() => { + // The file shim captures the global File object when it's first imported. + // Reset modules before each test so we can test the error thrown when it's undefined. + jest.resetModules(); + // @ts-ignore + prevFile = globalThis.File; // @ts-ignore globalThis.File = undefined; require('node:buffer').File = undefined; }); + afterEach(() => { + // Clean up + // @ts-ignore + globalThis.File = prevFile; + jest.resetModules(); + }); test('is thrown', async () => { const uploads = await import('@anthropic-ai/sdk/uploads'); From e7ec7871240e07861c54a2f482645d895fd24c61 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 3 Mar 2025 23:03:35 +0000 Subject: [PATCH 052/105] fix(tests): manually reset node:buffer File --- tests/uploads.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index b004fd6e..ec2a2e23 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -74,21 +74,25 @@ describe('toFile', () => { }); describe('missing File error message', () => { - let prevFile: unknown; + let prevGlobalFile: unknown; + let prevNodeFile: unknown; beforeEach(() => { // The file shim captures the global File object when it's first imported. // Reset modules before each test so we can test the error thrown when it's undefined. jest.resetModules(); + const buffer = require('node:buffer'); // @ts-ignore - prevFile = globalThis.File; + prevGlobalFile = globalThis.File; + prevNodeFile = buffer.File; // @ts-ignore globalThis.File = undefined; - require('node:buffer').File = undefined; + buffer.File = undefined; }); afterEach(() => { // Clean up // @ts-ignore - globalThis.File = prevFile; + globalThis.File = prevGlobalFile; + require('node:buffer').File = prevNodeFile; jest.resetModules(); }); From ad2e92b5fd8f2182efaa4f1cef221c21997dbbda Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Tue, 4 Mar 2025 18:53:38 +0000 Subject: [PATCH 053/105] chore(types): improved go to definition on fetchOptions --- src/internal/types.ts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/internal/types.ts b/src/internal/types.ts index 50c16e9d..c3bce5a2 100644 --- a/src/internal/types.ts +++ b/src/internal/types.ts @@ -6,14 +6,6 @@ export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'; export type KeysEnum = { [P in keyof Required]: true }; type NotAny = [unknown] extends [T] ? never : T; -type Literal = PropertyKey extends T ? never : T; -type MappedLiteralKeys = T extends any ? Literal : never; -type MappedIndex = - T extends any ? - K extends keyof T ? - T[K] - : never - : never; /** * Some environments overload the global fetch function, and Parameters only gets the last signature. @@ -93,6 +85,6 @@ type RequestInits = * This type contains `RequestInit` options that may be available on the current runtime, * including per-platform extensions like `dispatcher`, `agent`, `client`, etc. */ -export type MergedRequestInit = { - [K in MappedLiteralKeys]?: MappedIndex | undefined; -}; +export type MergedRequestInit = RequestInits & + /** We don't include these in the types as they'll be overridden for every request. */ + Partial>; From e99912308ae3ebcf0b7fa8a6c9e474b4be73de1e Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Tue, 4 Mar 2025 23:53:14 +0000 Subject: [PATCH 054/105] chore(docs): improve docs for withResponse/asResponse --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 63c2d7a7..62066377 100644 --- a/README.md +++ b/README.md @@ -367,8 +367,10 @@ const message = await client.messages.create( ### Accessing raw Response data (e.g., headers) The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return. +This method returns as soon as the headers for a successful response are received and does not consume the response body, so you are free to write custom parsing or streaming logic. You can also use the `.withResponse()` method to get the raw `Response` along with the parsed data. +Unlike `.asResponse()` this method consumes the body, returning once it is parsed. ```ts From fc020ee83131dde0716df40cd7ea0fc29a3c06cf Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Sat, 8 Mar 2025 18:20:18 +0000 Subject: [PATCH 055/105] feat: add SKIP_BREW env var to ./scripts/bootstrap --- scripts/bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bootstrap b/scripts/bootstrap index 05dd47a6..0af58e25 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -4,7 +4,7 @@ set -e cd "$(dirname "$0")/.." -if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then +if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ]; then brew bundle check >/dev/null 2>&1 || { echo "==> Installing Homebrew dependencies…" brew bundle From 9d3411a2d26c29202d498fdab29d034e6129a2b8 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Mon, 10 Mar 2025 20:06:05 +0000 Subject: [PATCH 056/105] feat(client): accept RFC6838 JSON content types --- src/internal/parse.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal/parse.ts b/src/internal/parse.ts index 6eaf973c..ece00cbf 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -44,8 +44,8 @@ export async function defaultParseResponse( } const contentType = response.headers.get('content-type'); - const isJSON = - contentType?.includes('application/json') || contentType?.includes('application/vnd.api+json'); + const mediaType = contentType?.split(';')[0]?.trim(); + const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json'); if (isJSON) { const json = await response.json(); return addRequestID(json as T, response); From 64a8e40dc8746df366ce0a1f963961de79d50654 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Thu, 13 Mar 2025 23:06:44 +0000 Subject: [PATCH 057/105] fix(exports): ensure resource imports don't require /index --- src/resources/beta.ts | 3 +++ src/resources/beta/messages.ts | 3 +++ src/resources/messages.ts | 3 +++ 3 files changed, 9 insertions(+) create mode 100644 src/resources/beta.ts create mode 100644 src/resources/beta/messages.ts create mode 100644 src/resources/messages.ts diff --git a/src/resources/beta.ts b/src/resources/beta.ts new file mode 100644 index 00000000..1542e942 --- /dev/null +++ b/src/resources/beta.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './beta/index'; diff --git a/src/resources/beta/messages.ts b/src/resources/beta/messages.ts new file mode 100644 index 00000000..eb175230 --- /dev/null +++ b/src/resources/beta/messages.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './messages/index'; diff --git a/src/resources/messages.ts b/src/resources/messages.ts new file mode 100644 index 00000000..eb175230 --- /dev/null +++ b/src/resources/messages.ts @@ -0,0 +1,3 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export * from './messages/index'; From 3786fd01f251087eff231f038586d1ee728c3bd2 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Fri, 14 Mar 2025 19:43:06 +0000 Subject: [PATCH 058/105] fix(internal): add mts file + crypto shim types --- scripts/build | 11 +++-------- src/internal/shims/crypto.node.d.mts | 1 + src/internal/shims/file.node.d.mts | 1 + 3 files changed, 5 insertions(+), 8 deletions(-) create mode 100644 src/internal/shims/crypto.node.d.mts create mode 100644 src/internal/shims/file.node.d.mts diff --git a/scripts/build b/scripts/build index 42d0b893..9572f803 100755 --- a/scripts/build +++ b/scripts/build @@ -28,20 +28,15 @@ node scripts/utils/make-dist-package-json.cjs > dist/package.json # build to .js/.mjs/.d.ts files npm exec tsc-multi -# we need to add exports = module.exports = Anthropic to index.js; -# No way to get that from index.ts because it would cause compile errors +# we need to patch index.js so that `new module.exports()` works for cjs backwards +# compat. No way to get that from index.ts because it would cause compile errors # when building .mjs node scripts/utils/fix-index-exports.cjs -# with "moduleResolution": "nodenext", if ESM resolves to index.d.ts, -# it'll have TS errors on the default import. But if it resolves to -# index.d.mts the default import will work (even though both files have -# the same export default statement) -cp dist/index.d.ts dist/index.d.mts cp tsconfig.dist-src.json dist/src/tsconfig.json cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts mkdir -p dist/internal/shims -cp src/internal/shims/*.{mjs,js,d.ts} dist/internal/shims +cp src/internal/shims/*.{mjs,js,d.ts,d.mts} dist/internal/shims node scripts/utils/postprocess-files.cjs diff --git a/src/internal/shims/crypto.node.d.mts b/src/internal/shims/crypto.node.d.mts new file mode 100644 index 00000000..5cc19630 --- /dev/null +++ b/src/internal/shims/crypto.node.d.mts @@ -0,0 +1 @@ +export { crypto } from './crypto.node.js'; diff --git a/src/internal/shims/file.node.d.mts b/src/internal/shims/file.node.d.mts new file mode 100644 index 00000000..38cc9ff7 --- /dev/null +++ b/src/internal/shims/file.node.d.mts @@ -0,0 +1 @@ +export { File } from './file.node.js'; From af7911d6f802950927bee5d1172255e220b1a4a6 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Tue, 18 Mar 2025 14:37:08 +0000 Subject: [PATCH 059/105] chore(internal): minor client file refactoring --- src/client.ts | 50 +++--------------------------------- src/internal/types.ts | 2 ++ src/internal/utils/log.ts | 30 +++++++++++++++++++++- src/internal/utils/values.ts | 8 ++++++ 4 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/client.ts b/src/client.ts index 39798ff5..abe0a193 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,10 +1,12 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types'; -import type { HTTPMethod, PromiseOrValue, MergedRequestInit } from './internal/types'; +import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestInit } from './internal/types'; import { uuid4 } from './internal/utils/uuid'; -import { validatePositiveInteger, isAbsoluteURL, hasOwn } from './internal/utils/values'; +import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values'; import { sleep } from './internal/utils/sleep'; +import { type Logger, type LogLevel, parseLogLevel } from './internal/utils/log'; +export type { Logger, LogLevel } from './internal/utils/log'; import { castToError, isAbortError } from './internal/errors'; import type { APIResponseProps } from './internal/parse'; import { getPlatformHeaders } from './internal/detect-platform'; @@ -126,48 +128,6 @@ import { Usage, } from './resources/messages/messages'; -const safeJSON = (text: string) => { - try { - return JSON.parse(text); - } catch (err) { - return undefined; - } -}; - -type LogFn = (message: string, ...rest: unknown[]) => void; -export type Logger = { - error: LogFn; - warn: LogFn; - info: LogFn; - debug: LogFn; -}; -export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug'; -const parseLogLevel = ( - maybeLevel: string | undefined, - sourceName: string, - client: BaseAnthropic, -): LogLevel | undefined => { - if (!maybeLevel) { - return undefined; - } - const levels: Record = { - off: true, - error: true, - warn: true, - info: true, - debug: true, - }; - if (hasOwn(levels, maybeLevel)) { - return maybeLevel; - } - loggerFor(client).warn( - `${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify( - Object.keys(levels), - )}`, - ); - return undefined; -}; - export interface ClientOptions { /** * Defaults to process.env['ANTHROPIC_API_KEY']. @@ -252,8 +212,6 @@ export interface ClientOptions { logger?: Logger | undefined; } -type FinalizedRequestInit = RequestInit & { headers: Headers }; - export class BaseAnthropic { apiKey: string | null; authToken: string | null; diff --git a/src/internal/types.ts b/src/internal/types.ts index c3bce5a2..d7928cd3 100644 --- a/src/internal/types.ts +++ b/src/internal/types.ts @@ -5,6 +5,8 @@ export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'; export type KeysEnum = { [P in keyof Required]: true }; +export type FinalizedRequestInit = RequestInit & { headers: Headers }; + type NotAny = [unknown] extends [T] ? never : T; /** diff --git a/src/internal/utils/log.ts b/src/internal/utils/log.ts index 4909b1fd..143862af 100644 --- a/src/internal/utils/log.ts +++ b/src/internal/utils/log.ts @@ -1,9 +1,18 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import type { LogLevel, Logger } from '../../client'; +import { hasOwn } from './values'; import { type BaseAnthropic } from '../../client'; import { RequestOptions } from '../request-options'; +type LogFn = (message: string, ...rest: unknown[]) => void; +export type Logger = { + error: LogFn; + warn: LogFn; + info: LogFn; + debug: LogFn; +}; +export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug'; + const levelNumbers = { off: 0, error: 200, @@ -12,6 +21,25 @@ const levelNumbers = { debug: 500, }; +export const parseLogLevel = ( + maybeLevel: string | undefined, + sourceName: string, + client: BaseAnthropic, +): LogLevel | undefined => { + if (!maybeLevel) { + return undefined; + } + if (hasOwn(levelNumbers, maybeLevel)) { + return maybeLevel; + } + loggerFor(client).warn( + `${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify( + Object.keys(levelNumbers), + )}`, + ); + return undefined; +}; + function noop() {} function makeLogFn(fnLevel: keyof Logger, logger: Logger | undefined, logLevel: LogLevel) { diff --git a/src/internal/utils/values.ts b/src/internal/utils/values.ts index e2b6b4a8..12b4a435 100644 --- a/src/internal/utils/values.ts +++ b/src/internal/utils/values.ts @@ -92,3 +92,11 @@ export const maybeCoerceBoolean = (value: unknown): boolean | undefined => { } return coerceBoolean(value); }; + +export const safeJSON = (text: string) => { + try { + return JSON.parse(text); + } catch (err) { + return undefined; + } +}; From 8c3685cb1be797c1b1d51c8203644851f4fe5f23 Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Fri, 14 Mar 2025 14:26:24 -0400 Subject: [PATCH 060/105] fix: remove duplicate exports --- src/resources/index.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/resources/index.ts b/src/resources/index.ts index 99b7c215..b1426926 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -51,9 +51,6 @@ export { type MessageDeltaEvent, type MessageDeltaUsage, type MessageParam, - type MessageStartEvent, - type MessageStopEvent, - type MessageStreamEvent, type MessageStreamParams, type MessageTokensCount, type Metadata, From 9d8725412ab1c8e1f7263611646fc359586d095a Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Wed, 19 Mar 2025 20:44:43 +0000 Subject: [PATCH 061/105] chore: remove redundant index exports --- scripts/utils/postprocess-files.cjs | 8 ++++---- src/resources.ts | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 src/resources.ts diff --git a/scripts/utils/postprocess-files.cjs b/scripts/utils/postprocess-files.cjs index d16c8641..deae575e 100644 --- a/scripts/utils/postprocess-files.cjs +++ b/scripts/utils/postprocess-files.cjs @@ -50,14 +50,14 @@ async function postprocess() { if (entry.isDirectory() && entry.name !== 'src' && entry.name !== 'internal' && entry.name !== 'bin') { const subpath = './' + entry.name; newExports[subpath + '/*.mjs'] = { - default: [subpath + '/*.mjs', subpath + '/*/index.mjs'], + default: subpath + '/*.mjs', }; newExports[subpath + '/*.js'] = { - default: [subpath + '/*.js', subpath + '/*/index.js'], + default: subpath + '/*.js', }; newExports[subpath + '/*'] = { - import: [subpath + '/*.mjs', subpath + '/*/index.mjs'], - require: [subpath + '/*.js', subpath + '/*/index.js'], + import: subpath + '/*.mjs', + require: subpath + '/*.js', }; } else if (entry.isFile() && /\.[cm]?js$/.test(entry.name)) { const { name, ext } = path.parse(entry.name); diff --git a/src/resources.ts b/src/resources.ts new file mode 100644 index 00000000..b283d578 --- /dev/null +++ b/src/resources.ts @@ -0,0 +1 @@ +export * from './resources/index'; From c8fb3ea2658d9435e4e5bb9340e0b106e8d2f232 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Thu, 20 Mar 2025 21:55:53 +0000 Subject: [PATCH 062/105] chore(docs): fix typo --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index fffef50c..4d14df22 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -218,7 +218,7 @@ import fs from 'fs'; fs.createReadStream('path/to/file'); ``` -Note that this function previously only worked on Node.j. If you're using Bun, you can use [`Bun.file`](https://bun.sh/docs/api/file-io) instead. +Note that this function previously only worked on Node.js. If you're using Bun, you can use [`Bun.file`](https://bun.sh/docs/api/file-io) instead. ### Shims removal From 635dc4f23e8b182c443e2d630d9d70a2d0ae3572 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Wed, 26 Mar 2025 17:35:25 +0000 Subject: [PATCH 063/105] chore: add hash of OpenAPI spec/config inputs to .stats.yml --- .stats.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.stats.yml b/.stats.yml index 756a3632..2c1bac2b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-fd7537a41646cd9253c04f350436c5471e4762750fce8ca8f1909a3052d98608.yml +openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 +config_hash: 92dd03fd872d52f9707c9e7a7953c3d1 From 48e758572184c8f34c5129c41d9ded94d20980ee Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Wed, 26 Mar 2025 18:52:14 +0000 Subject: [PATCH 064/105] fix(client): deduplicate stop reason type --- .stats.yml | 4 ++-- api.md | 2 ++ src/client.ts | 2 ++ src/resources/beta/beta.ts | 2 ++ src/resources/beta/index.ts | 1 + src/resources/beta/messages/index.ts | 1 + src/resources/beta/messages/messages.ts | 7 +++++-- src/resources/index.ts | 1 + src/resources/messages/index.ts | 1 + src/resources/messages/messages.ts | 7 +++++-- 10 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2c1bac2b..b4a020e8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-fd7537a41646cd9253c04f350436c5471e4762750fce8ca8f1909a3052d98608.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 -config_hash: 92dd03fd872d52f9707c9e7a7953c3d1 +config_hash: 188e45a82f6284619dd4a7bddf875907 diff --git a/api.md b/api.md index be2186bf..ed1ac960 100644 --- a/api.md +++ b/api.md @@ -63,6 +63,7 @@ Types: - RedactedThinkingBlock - RedactedThinkingBlockParam - SignatureDelta +- StopReason - TextBlock - TextBlockParam - TextCitation @@ -196,6 +197,7 @@ Types: - BetaRedactedThinkingBlock - BetaRedactedThinkingBlockParam - BetaSignatureDelta +- BetaStopReason - BetaTextBlock - BetaTextBlockParam - BetaTextCitation diff --git a/src/client.ts b/src/client.ts index abe0a193..cab792e2 100644 --- a/src/client.ts +++ b/src/client.ts @@ -100,6 +100,7 @@ import { RedactedThinkingBlock, RedactedThinkingBlockParam, SignatureDelta, + StopReason, TextBlock, TextBlockParam, TextCitation, @@ -945,6 +946,7 @@ export declare namespace Anthropic { type RedactedThinkingBlock as RedactedThinkingBlock, type RedactedThinkingBlockParam as RedactedThinkingBlockParam, type SignatureDelta as SignatureDelta, + type StopReason as StopReason, type TextBlock as TextBlock, type TextBlockParam as TextBlockParam, type TextCitation as TextCitation, diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index eb4c5a86..b910a03a 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -39,6 +39,7 @@ import { BetaRedactedThinkingBlock, BetaRedactedThinkingBlockParam, BetaSignatureDelta, + BetaStopReason, BetaTextBlock, BetaTextBlockParam, BetaTextCitation, @@ -225,6 +226,7 @@ export declare namespace Beta { type BetaRedactedThinkingBlock as BetaRedactedThinkingBlock, type BetaRedactedThinkingBlockParam as BetaRedactedThinkingBlockParam, type BetaSignatureDelta as BetaSignatureDelta, + type BetaStopReason as BetaStopReason, type BetaTextBlock as BetaTextBlock, type BetaTextBlockParam as BetaTextBlockParam, type BetaTextCitation as BetaTextCitation, diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts index fdd6a0f3..7afe57bc 100644 --- a/src/resources/beta/index.ts +++ b/src/resources/beta/index.ts @@ -51,6 +51,7 @@ export { type BetaRedactedThinkingBlock, type BetaRedactedThinkingBlockParam, type BetaSignatureDelta, + type BetaStopReason, type BetaTextBlock, type BetaTextBlockParam, type BetaTextCitation, diff --git a/src/resources/beta/messages/index.ts b/src/resources/beta/messages/index.ts index 9d372139..851b8432 100644 --- a/src/resources/beta/messages/index.ts +++ b/src/resources/beta/messages/index.ts @@ -55,6 +55,7 @@ export { type BetaRedactedThinkingBlock, type BetaRedactedThinkingBlockParam, type BetaSignatureDelta, + type BetaStopReason, type BetaTextBlock, type BetaTextBlockParam, type BetaTextCitation, diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index 9c1e24b1..015981a5 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -330,7 +330,7 @@ export interface BetaMessage { * In non-streaming mode this value is always non-null. In streaming mode, it is * null in the `message_start` event and non-null otherwise. */ - stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null; + stop_reason: BetaStopReason | null; /** * Which custom stop sequence was generated, if any. @@ -456,7 +456,7 @@ export interface BetaRawMessageDeltaEvent { export namespace BetaRawMessageDeltaEvent { export interface Delta { - stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null; + stop_reason: MessagesMessagesAPI.BetaStopReason | null; stop_sequence: string | null; } @@ -498,6 +498,8 @@ export interface BetaSignatureDelta { type: 'signature_delta'; } +export type BetaStopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use'; + export interface BetaTextBlock { /** * Citations supporting the text block. @@ -1448,6 +1450,7 @@ export declare namespace Messages { type BetaRedactedThinkingBlock as BetaRedactedThinkingBlock, type BetaRedactedThinkingBlockParam as BetaRedactedThinkingBlockParam, type BetaSignatureDelta as BetaSignatureDelta, + type BetaStopReason as BetaStopReason, type BetaTextBlock as BetaTextBlock, type BetaTextBlockParam as BetaTextBlockParam, type BetaTextCitation as BetaTextCitation, diff --git a/src/resources/index.ts b/src/resources/index.ts index b1426926..c8331d8d 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -66,6 +66,7 @@ export { type RedactedThinkingBlock, type RedactedThinkingBlockParam, type SignatureDelta, + type StopReason, type TextBlock, type TextBlockParam, type TextCitation, diff --git a/src/resources/messages/index.ts b/src/resources/messages/index.ts index 4a571139..091226ae 100644 --- a/src/resources/messages/index.ts +++ b/src/resources/messages/index.ts @@ -60,6 +60,7 @@ export { type RedactedThinkingBlock, type RedactedThinkingBlockParam, type SignatureDelta, + type StopReason, type TextBlock, type TextBlockParam, type TextCitation, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index fc0a9f10..42294d12 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -326,7 +326,7 @@ export interface Message { * In non-streaming mode this value is always non-null. In streaming mode, it is * null in the `message_start` event and non-null otherwise. */ - stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null; + stop_reason: StopReason | null; /** * Which custom stop sequence was generated, if any. @@ -495,7 +495,7 @@ export interface RawMessageDeltaEvent { export namespace RawMessageDeltaEvent { export interface Delta { - stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null; + stop_reason: MessagesAPI.StopReason | null; stop_sequence: string | null; } @@ -537,6 +537,8 @@ export interface SignatureDelta { type: 'signature_delta'; } +export type StopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use'; + export interface TextBlock { /** * Citations supporting the text block. @@ -1403,6 +1405,7 @@ export declare namespace Messages { type RedactedThinkingBlock as RedactedThinkingBlock, type RedactedThinkingBlockParam as RedactedThinkingBlockParam, type SignatureDelta as SignatureDelta, + type StopReason as StopReason, type TextBlock as TextBlock, type TextBlockParam as TextBlockParam, type TextCitation as TextCitation, From cbd31b4df3d43bf8e07399bf04601b1649804426 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Wed, 26 Mar 2025 19:36:52 +0000 Subject: [PATCH 065/105] chore(client): more accurate streaming errors --- src/streaming.ts | 7 ++++--- tests/streaming.test.ts | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/streaming.ts b/src/streaming.ts index 12347911..542cbc28 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -4,6 +4,7 @@ import { makeReadableStream } from './internal/shims'; import { findDoubleNewlineIndex, LineDecoder } from './internal/decoders/line'; import { ReadableStreamToAsyncIterable } from './internal/shims'; import { isAbortError } from './internal/errors'; +import { safeJSON } from './internal/utils/values'; import { APIError } from './error'; @@ -30,7 +31,7 @@ export class Stream implements AsyncIterable { async function* iterator(): AsyncIterator { if (consumed) { - throw new Error('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); + throw new AnthropicError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); } consumed = true; let done = false; @@ -68,7 +69,7 @@ export class Stream implements AsyncIterable { } if (sse.event === 'error') { - throw APIError.generate(undefined, `SSE Error: ${sse.data}`, sse.data, response.headers); + throw new APIError(undefined, safeJSON(sse.data) ?? sse.data, undefined, response.headers); } } done = true; @@ -109,7 +110,7 @@ export class Stream implements AsyncIterable { async function* iterator(): AsyncIterator { if (consumed) { - throw new Error('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); + throw new AnthropicError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); } consumed = true; let done = false; diff --git a/tests/streaming.test.ts b/tests/streaming.test.ts index b674a14b..fc52d895 100644 --- a/tests/streaming.test.ts +++ b/tests/streaming.test.ts @@ -1,6 +1,6 @@ import assert from 'assert'; import { Stream, _iterSSEMessages } from '@anthropic-ai/sdk/streaming'; -import { APIConnectionError } from '@anthropic-ai/sdk/error'; +import { APIError } from '@anthropic-ai/sdk/error'; import { ReadableStreamFrom } from '@anthropic-ai/sdk/internal/shims'; describe('streaming decoding', () => { @@ -241,5 +241,5 @@ test('error handling', async () => { await err.toMatchInlineSnapshot( `[Error: {"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}]`, ); - await err.toBeInstanceOf(APIConnectionError); + await err.toBeInstanceOf(APIError); }); From 32332545b661cfaf5806e7f13826da5c5d102087 Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Wed, 26 Mar 2025 20:02:19 +0000 Subject: [PATCH 066/105] chore(client): move misc public files to new `core/` directory, deprecate old paths --- MIGRATION.md | 51 ++-- src/api-promise.ts | 103 +------- src/client.ts | 13 +- src/core/README.md | 3 + src/core/api-promise.ts | 101 +++++++ src/core/error.ts | 133 ++++++++++ src/core/pagination.ts | 201 ++++++++++++++ src/core/resource.ts | 11 + src/core/streaming.ts | 333 +++++++++++++++++++++++ src/core/uploads.ts | 2 + src/error.ts | 135 +--------- src/index.ts | 8 +- src/internal/README.md | 3 + src/internal/decoders/jsonl.ts | 2 +- src/internal/decoders/line.ts | 2 +- src/internal/parse.ts | 2 +- src/internal/request-options.ts | 2 +- src/internal/utils/base64.ts | 2 +- src/internal/utils/path.ts | 2 +- src/internal/utils/values.ts | 2 +- src/pagination.ts | 203 +------------- src/resource.ts | 13 +- src/resources/beta/beta.ts | 2 +- src/resources/beta/messages/batches.ts | 6 +- src/resources/beta/messages/messages.ts | 6 +- src/resources/beta/models.ts | 6 +- src/resources/completions.ts | 6 +- src/resources/messages/batches.ts | 6 +- src/resources/messages/messages.ts | 6 +- src/resources/models.ts | 6 +- src/streaming.ts | 335 +----------------------- src/uploads.ts | 4 +- tests/form.test.ts | 2 +- tests/index.test.ts | 2 +- tests/streaming.test.ts | 4 +- tests/uploads.test.ts | 4 +- 36 files changed, 880 insertions(+), 842 deletions(-) create mode 100644 src/core/README.md create mode 100644 src/core/api-promise.ts create mode 100644 src/core/error.ts create mode 100644 src/core/pagination.ts create mode 100644 src/core/resource.ts create mode 100644 src/core/streaming.ts create mode 100644 src/core/uploads.ts create mode 100644 src/internal/README.md diff --git a/MIGRATION.md b/MIGRATION.md index 4d14df22..67eed90b 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -253,39 +253,48 @@ The `headers` property on `APIError` objects is now an instance of the Web [Head ### Removed exports -#### `Response` +#### Resource classes + +If you were importing resource classes from the root package then you must now import them from the file they are defined in. +This was never valid at the type level and only worked in CommonJS files. ```typescript // Before -import { Response } from '@anthropic-ai/sdk'; +const { Completions } = require('@anthropic-ai/sdk'); // After -// `Response` must now come from the builtin types +const { Anthropic } = require('@anthropic-ai/sdk'); +Anthropic.Completions; // or import directly from @anthropic-ai/sdk/resources/completions ``` -We've also removed `InputJsonDelta` in favour of `InputJSONDelta`. `Anthropic.InputJsonDelta` -> `Anthropic.InputJSONDelta` +#### Refactor of `@anthropic-ai/sdk/core`, `error`, `pagination`, `resource`, `streaming` and `uploads` -#### Resource classes +Much of the `@anthropic-ai/sdk/core` file was intended to be internal-only but it was publicly accessible, as such it has been refactored and split up into internal and public files, with public-facing code moved to a new `core` folder and internal code moving to the private `internal` folder. -If you were importing resource classes from the root package then you must now import them from the file they are defined in: +At the same time, we moved some public-facing files which were previously at the top level into `core` to make the file structure cleaner and more clear: ```typescript // Before -import { Completions } from '@anthropic-ai/sdk'; +import '@anthropic-ai/sdk/error'; +import '@anthropic-ai/sdk/pagination'; +import '@anthropic-ai/sdk/resource'; +import '@anthropic-ai/sdk/streaming'; +import '@anthropic-ai/sdk/uploads'; // After -import { Completions } from '@anthropic-ai/sdk/resources/completions'; +import '@anthropic-ai/sdk/core/error'; +import '@anthropic-ai/sdk/core/pagination'; +import '@anthropic-ai/sdk/core/resource'; +import '@anthropic-ai/sdk/core/streaming'; +import '@anthropic-ai/sdk/core/uploads'; ``` -#### `@anthropic-ai/sdk/core` - -The `@anthropic-ai/sdk/core` file was intended to be internal-only but it was publicly accessible, as such it has been refactored and split up into internal files. - If you were relying on anything that was only exported from `@anthropic-ai/sdk/core` and is also not accessible anywhere else, please open an issue and we'll consider adding it to the public API. -#### Cleaned up `@anthropic-ai/sdk/uploads` exports +#### Cleaned up `uploads` exports -The following exports have been removed from `@anthropic-ai/sdk/uploads` as they were not intended to be a part of the public API: +As part of the `core` refactor, `@anthropic-ai/sdk/uploads` was moved to `@anthropic-ai/sdk/core/uploads` +and the following exports were removed, as they were not intended to be a part of the public API: - `fileFromPath` - `BlobPart` @@ -304,5 +313,17 @@ The following exports have been removed from `@anthropic-ai/sdk/uploads` as they Note that `Uploadable` & `toFile` **are** still exported: ```typescript -import { type Uploadable, toFile } from '@anthropic-ai/sdk/uploads'; +import { type Uploadable, toFile } from '@anthropic-ai/sdk/core/uploads'; +``` + +#### `APIClient` + +The `APIClient` base client class has been replaced with a new `BaseAnthropic` class: + +```typescript +// Before +import { APIClient } from '@anthropic-ai/sdk/core'; + +// After +import { BaseAnthropic } from '@anthropic-ai/sdk/client'; ``` diff --git a/src/api-promise.ts b/src/api-promise.ts index 33c0a240..8c775ee6 100644 --- a/src/api-promise.ts +++ b/src/api-promise.ts @@ -1,101 +1,2 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import { type BaseAnthropic } from './client'; - -import { type PromiseOrValue } from './internal/types'; -import { - type APIResponseProps, - type WithRequestID, - defaultParseResponse, - addRequestID, -} from './internal/parse'; - -/** - * A subclass of `Promise` providing additional helper methods - * for interacting with the SDK. - */ -export class APIPromise extends Promise> { - private parsedPromise: Promise> | undefined; - #client: BaseAnthropic; - - constructor( - client: BaseAnthropic, - private responsePromise: Promise, - private parseResponse: ( - client: BaseAnthropic, - props: APIResponseProps, - ) => PromiseOrValue> = defaultParseResponse, - ) { - super((resolve) => { - // this is maybe a bit weird but this has to be a no-op to not implicitly - // parse the response body; instead .then, .catch, .finally are overridden - // to parse the response - resolve(null as any); - }); - this.#client = client; - } - - _thenUnwrap(transform: (data: T, props: APIResponseProps) => U): APIPromise { - return new APIPromise(this.#client, this.responsePromise, async (client, props) => - addRequestID(transform(await this.parseResponse(client, props), props), props.response), - ); - } - - /** - * Gets the raw `Response` instance instead of parsing the response - * data. - * - * If you want to parse the response body but still get the `Response` - * instance, you can use {@link withResponse()}. - * - * 👋 Getting the wrong TypeScript type for `Response`? - * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` - * to your `tsconfig.json`. - */ - asResponse(): Promise { - return this.responsePromise.then((p) => p.response); - } - - /** - * Gets the parsed response data, the raw `Response` instance and the ID of the request, - * returned via the `request-id` header which is useful for debugging requests and resporting - * issues to Anthropic. - * - * If you just want to get the raw `Response` instance without parsing it, - * you can use {@link asResponse()}. - * - * 👋 Getting the wrong TypeScript type for `Response`? - * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` - * to your `tsconfig.json`. - */ - async withResponse(): Promise<{ data: T; response: Response; request_id: string | null | undefined }> { - const [data, response] = await Promise.all([this.parse(), this.asResponse()]); - return { data, response, request_id: response.headers.get('request-id') }; - } - - private parse(): Promise> { - if (!this.parsedPromise) { - this.parsedPromise = this.responsePromise.then( - (data) => this.parseResponse(this.#client, data) as any as Promise>, - ); - } - return this.parsedPromise; - } - - override then, TResult2 = never>( - onfulfilled?: ((value: WithRequestID) => TResult1 | PromiseLike) | undefined | null, - onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null, - ): Promise { - return this.parse().then(onfulfilled, onrejected); - } - - override catch( - onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null, - ): Promise | TResult> { - return this.parse().catch(onrejected); - } - - override finally(onfinally?: (() => void) | undefined | null): Promise> { - return this.parse().finally(onfinally); - } -} +/** @deprecated Import from ./core/api-promise instead */ +export * from './core/api-promise'; diff --git a/src/client.ts b/src/client.ts index cab792e2..9f57e064 100644 --- a/src/client.ts +++ b/src/client.ts @@ -13,13 +13,12 @@ import { getPlatformHeaders } from './internal/detect-platform'; import * as Shims from './internal/shims'; import * as Opts from './internal/request-options'; import { VERSION } from './version'; -import * as Errors from './error'; -import * as Pagination from './pagination'; -import { AnthropicError } from './error'; -import { AbstractPage, type PageParams, PageResponse } from './pagination'; -import * as Uploads from './uploads'; +import * as Errors from './core/error'; +import * as Pagination from './core/pagination'; +import { type PageParams, PageResponse } from './core/pagination'; +import * as Uploads from './core/uploads'; import * as API from './resources/index'; -import { APIPromise } from './api-promise'; +import { APIPromise } from './core/api-promise'; import { type Fetch } from './internal/builtin-types'; import { isRunningInBrowser } from './internal/detect-platform'; import { HeadersLike, NullableHeaders, buildHeaders, isEmptyHeaders } from './internal/headers'; @@ -394,7 +393,7 @@ export class BaseAnthropic { const defaultTimeout = 10 * 60; const expectedTimeout = (60 * 60 * maxTokens) / 128_000; if (expectedTimeout > defaultTimeout) { - throw new AnthropicError( + throw new Errors.AnthropicError( 'Streaming is strongly recommended for operations that may take longer than 10 minutes. ' + 'See https://github.com/anthropics/anthropic-sdk-python#streaming-responses for more details', ); diff --git a/src/core/README.md b/src/core/README.md new file mode 100644 index 00000000..485fce86 --- /dev/null +++ b/src/core/README.md @@ -0,0 +1,3 @@ +# `core` + +This directory holds public modules implementing non-resource-specific SDK functionality. diff --git a/src/core/api-promise.ts b/src/core/api-promise.ts new file mode 100644 index 00000000..3baea03a --- /dev/null +++ b/src/core/api-promise.ts @@ -0,0 +1,101 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { type BaseAnthropic } from '../client'; + +import { type PromiseOrValue } from '../internal/types'; +import { + type APIResponseProps, + type WithRequestID, + defaultParseResponse, + addRequestID, +} from '../internal/parse'; + +/** + * A subclass of `Promise` providing additional helper methods + * for interacting with the SDK. + */ +export class APIPromise extends Promise> { + private parsedPromise: Promise> | undefined; + #client: BaseAnthropic; + + constructor( + client: BaseAnthropic, + private responsePromise: Promise, + private parseResponse: ( + client: BaseAnthropic, + props: APIResponseProps, + ) => PromiseOrValue> = defaultParseResponse, + ) { + super((resolve) => { + // this is maybe a bit weird but this has to be a no-op to not implicitly + // parse the response body; instead .then, .catch, .finally are overridden + // to parse the response + resolve(null as any); + }); + this.#client = client; + } + + _thenUnwrap(transform: (data: T, props: APIResponseProps) => U): APIPromise { + return new APIPromise(this.#client, this.responsePromise, async (client, props) => + addRequestID(transform(await this.parseResponse(client, props), props), props.response), + ); + } + + /** + * Gets the raw `Response` instance instead of parsing the response + * data. + * + * If you want to parse the response body but still get the `Response` + * instance, you can use {@link withResponse()}. + * + * 👋 Getting the wrong TypeScript type for `Response`? + * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` + * to your `tsconfig.json`. + */ + asResponse(): Promise { + return this.responsePromise.then((p) => p.response); + } + + /** + * Gets the parsed response data, the raw `Response` instance and the ID of the request, + * returned via the `request-id` header which is useful for debugging requests and resporting + * issues to Anthropic. + * + * If you just want to get the raw `Response` instance without parsing it, + * you can use {@link asResponse()}. + * + * 👋 Getting the wrong TypeScript type for `Response`? + * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]` + * to your `tsconfig.json`. + */ + async withResponse(): Promise<{ data: T; response: Response; request_id: string | null | undefined }> { + const [data, response] = await Promise.all([this.parse(), this.asResponse()]); + return { data, response, request_id: response.headers.get('request-id') }; + } + + private parse(): Promise> { + if (!this.parsedPromise) { + this.parsedPromise = this.responsePromise.then( + (data) => this.parseResponse(this.#client, data) as any as Promise>, + ); + } + return this.parsedPromise; + } + + override then, TResult2 = never>( + onfulfilled?: ((value: WithRequestID) => TResult1 | PromiseLike) | undefined | null, + onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null, + ): Promise { + return this.parse().then(onfulfilled, onrejected); + } + + override catch( + onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null, + ): Promise | TResult> { + return this.parse().catch(onrejected); + } + + override finally(onfinally?: (() => void) | undefined | null): Promise> { + return this.parse().finally(onfinally); + } +} diff --git a/src/core/error.ts b/src/core/error.ts new file mode 100644 index 00000000..89ffec90 --- /dev/null +++ b/src/core/error.ts @@ -0,0 +1,133 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { castToError } from '../internal/errors'; + +export class AnthropicError extends Error {} + +export class APIError< + TStatus extends number | undefined = number | undefined, + THeaders extends Headers | undefined = Headers | undefined, + TError extends Object | undefined = Object | undefined, +> extends AnthropicError { + /** HTTP status for the response that caused the error */ + readonly status: TStatus; + /** HTTP headers for the response that caused the error */ + readonly headers: THeaders; + /** JSON body of the response that caused the error */ + readonly error: TError; + + readonly requestID: string | null | undefined; + + constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) { + super(`${APIError.makeMessage(status, error, message)}`); + this.status = status; + this.headers = headers; + this.requestID = headers?.get('request-id'); + this.error = error; + } + + private static makeMessage(status: number | undefined, error: any, message: string | undefined) { + const msg = + error?.message ? + typeof error.message === 'string' ? + error.message + : JSON.stringify(error.message) + : error ? JSON.stringify(error) + : message; + + if (status && msg) { + return `${status} ${msg}`; + } + if (status) { + return `${status} status code (no body)`; + } + if (msg) { + return msg; + } + return '(no status code or body)'; + } + + static generate( + status: number | undefined, + errorResponse: Object | undefined, + message: string | undefined, + headers: Headers | undefined, + ): APIError { + if (!status || !headers) { + return new APIConnectionError({ message, cause: castToError(errorResponse) }); + } + + const error = errorResponse as Record; + + if (status === 400) { + return new BadRequestError(status, error, message, headers); + } + + if (status === 401) { + return new AuthenticationError(status, error, message, headers); + } + + if (status === 403) { + return new PermissionDeniedError(status, error, message, headers); + } + + if (status === 404) { + return new NotFoundError(status, error, message, headers); + } + + if (status === 409) { + return new ConflictError(status, error, message, headers); + } + + if (status === 422) { + return new UnprocessableEntityError(status, error, message, headers); + } + + if (status === 429) { + return new RateLimitError(status, error, message, headers); + } + + if (status >= 500) { + return new InternalServerError(status, error, message, headers); + } + + return new APIError(status, error, message, headers); + } +} + +export class APIUserAbortError extends APIError { + constructor({ message }: { message?: string } = {}) { + super(undefined, undefined, message || 'Request was aborted.', undefined); + } +} + +export class APIConnectionError extends APIError { + constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) { + super(undefined, undefined, message || 'Connection error.', undefined); + // in some environments the 'cause' property is already declared + // @ts-ignore + if (cause) this.cause = cause; + } +} + +export class APIConnectionTimeoutError extends APIConnectionError { + constructor({ message }: { message?: string } = {}) { + super({ message: message ?? 'Request timed out.' }); + } +} + +export class BadRequestError extends APIError<400, Headers> {} + +export class AuthenticationError extends APIError<401, Headers> {} + +export class PermissionDeniedError extends APIError<403, Headers> {} + +export class NotFoundError extends APIError<404, Headers> {} + +export class ConflictError extends APIError<409, Headers> {} + +export class UnprocessableEntityError extends APIError<422, Headers> {} + +export class RateLimitError extends APIError<429, Headers> {} + +export class InternalServerError extends APIError {} diff --git a/src/core/pagination.ts b/src/core/pagination.ts new file mode 100644 index 00000000..5a2e3121 --- /dev/null +++ b/src/core/pagination.ts @@ -0,0 +1,201 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { AnthropicError } from './error'; +import { FinalRequestOptions } from '../internal/request-options'; +import { defaultParseResponse, WithRequestID } from '../internal/parse'; +import { type BaseAnthropic } from '../client'; +import { APIPromise } from './api-promise'; +import { type APIResponseProps } from '../internal/parse'; +import { maybeObj } from '../internal/utils/values'; + +export type PageRequestOptions = Pick; + +export abstract class AbstractPage implements AsyncIterable { + #client: BaseAnthropic; + protected options: FinalRequestOptions; + + protected response: Response; + protected body: unknown; + + constructor(client: BaseAnthropic, response: Response, body: unknown, options: FinalRequestOptions) { + this.#client = client; + this.options = options; + this.response = response; + this.body = body; + } + + abstract nextPageRequestOptions(): PageRequestOptions | null; + + abstract getPaginatedItems(): Item[]; + + hasNextPage(): boolean { + const items = this.getPaginatedItems(); + if (!items.length) return false; + return this.nextPageRequestOptions() != null; + } + + async getNextPage(): Promise { + const nextOptions = this.nextPageRequestOptions(); + if (!nextOptions) { + throw new AnthropicError( + 'No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.', + ); + } + + return await this.#client.requestAPIList(this.constructor as any, nextOptions); + } + + async *iterPages(): AsyncGenerator { + let page: this = this; + yield page; + while (page.hasNextPage()) { + page = await page.getNextPage(); + yield page; + } + } + + async *[Symbol.asyncIterator](): AsyncGenerator { + for await (const page of this.iterPages()) { + for (const item of page.getPaginatedItems()) { + yield item; + } + } + } +} + +/** + * This subclass of Promise will resolve to an instantiated Page once the request completes. + * + * It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg: + * + * for await (const item of client.items.list()) { + * console.log(item) + * } + */ +export class PagePromise< + PageClass extends AbstractPage, + Item = ReturnType[number], + > + extends APIPromise + implements AsyncIterable +{ + constructor( + client: BaseAnthropic, + request: Promise, + Page: new (...args: ConstructorParameters) => PageClass, + ) { + super( + client, + request, + async (client, props) => + new Page( + client, + props.response, + await defaultParseResponse(client, props), + props.options, + ) as WithRequestID, + ); + } + + /** + * Allow auto-paginating iteration on an unawaited list call, eg: + * + * for await (const item of client.items.list()) { + * console.log(item) + * } + */ + async *[Symbol.asyncIterator]() { + const page = await this; + for await (const item of page) { + yield item; + } + } +} + +export interface PageResponse { + data: Array; + + has_more: boolean; + + first_id: string | null; + + last_id: string | null; +} + +export interface PageParams { + /** + * Number of items per page. + */ + limit?: number; + + before_id?: string; + + after_id?: string; +} + +export class Page extends AbstractPage implements PageResponse { + data: Array; + + has_more: boolean; + + first_id: string | null; + + last_id: string | null; + + constructor( + client: BaseAnthropic, + response: Response, + body: PageResponse, + options: FinalRequestOptions, + ) { + super(client, response, body, options); + + this.data = body.data || []; + this.has_more = body.has_more || false; + this.first_id = body.first_id || null; + this.last_id = body.last_id || null; + } + + getPaginatedItems(): Item[] { + return this.data ?? []; + } + + override hasNextPage(): boolean { + if (this.has_more === false) { + return false; + } + + return super.hasNextPage(); + } + + nextPageRequestOptions(): PageRequestOptions | null { + if ((this.options.query as Record)?.['before_id']) { + // in reverse + const first_id = this.first_id; + if (!first_id) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + before_id: first_id, + }, + }; + } + + const cursor = this.last_id; + if (!cursor) { + return null; + } + + return { + ...this.options, + query: { + ...maybeObj(this.options.query), + after_id: cursor, + }, + }; + } +} diff --git a/src/core/resource.ts b/src/core/resource.ts new file mode 100644 index 00000000..9de4b677 --- /dev/null +++ b/src/core/resource.ts @@ -0,0 +1,11 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { BaseAnthropic } from '../client'; + +export class APIResource { + protected _client: BaseAnthropic; + + constructor(client: BaseAnthropic) { + this._client = client; + } +} diff --git a/src/core/streaming.ts b/src/core/streaming.ts new file mode 100644 index 00000000..daf54458 --- /dev/null +++ b/src/core/streaming.ts @@ -0,0 +1,333 @@ +import { AnthropicError } from './error'; +import { type ReadableStream } from '../internal/shim-types'; +import { makeReadableStream } from '../internal/shims'; +import { findDoubleNewlineIndex, LineDecoder } from '../internal/decoders/line'; +import { ReadableStreamToAsyncIterable } from '../internal/shims'; +import { isAbortError } from '../internal/errors'; +import { safeJSON } from '../internal/utils/values'; + +import { APIError } from './error'; + +type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; + +export type ServerSentEvent = { + event: string | null; + data: string; + raw: string[]; +}; + +export class Stream implements AsyncIterable { + controller: AbortController; + + constructor( + private iterator: () => AsyncIterator, + controller: AbortController, + ) { + this.controller = controller; + } + + static fromSSEResponse(response: Response, controller: AbortController): Stream { + let consumed = false; + + async function* iterator(): AsyncIterator { + if (consumed) { + throw new AnthropicError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); + } + consumed = true; + let done = false; + try { + for await (const sse of _iterSSEMessages(response, controller)) { + if (sse.event === 'completion') { + try { + yield JSON.parse(sse.data); + } catch (e) { + console.error(`Could not parse message into JSON:`, sse.data); + console.error(`From chunk:`, sse.raw); + throw e; + } + } + + if ( + sse.event === 'message_start' || + sse.event === 'message_delta' || + sse.event === 'message_stop' || + sse.event === 'content_block_start' || + sse.event === 'content_block_delta' || + sse.event === 'content_block_stop' + ) { + try { + yield JSON.parse(sse.data); + } catch (e) { + console.error(`Could not parse message into JSON:`, sse.data); + console.error(`From chunk:`, sse.raw); + throw e; + } + } + + if (sse.event === 'ping') { + continue; + } + + if (sse.event === 'error') { + throw new APIError(undefined, safeJSON(sse.data) ?? sse.data, undefined, response.headers); + } + } + done = true; + } catch (e) { + // If the user calls `stream.controller.abort()`, we should exit without throwing. + if (isAbortError(e)) return; + throw e; + } finally { + // If the user `break`s, abort the ongoing request. + if (!done) controller.abort(); + } + } + + return new Stream(iterator, controller); + } + + /** + * Generates a Stream from a newline-separated ReadableStream + * where each item is a JSON value. + */ + static fromReadableStream(readableStream: ReadableStream, controller: AbortController): Stream { + let consumed = false; + + async function* iterLines(): AsyncGenerator { + const lineDecoder = new LineDecoder(); + + const iter = ReadableStreamToAsyncIterable(readableStream); + for await (const chunk of iter) { + for (const line of lineDecoder.decode(chunk)) { + yield line; + } + } + + for (const line of lineDecoder.flush()) { + yield line; + } + } + + async function* iterator(): AsyncIterator { + if (consumed) { + throw new AnthropicError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); + } + consumed = true; + let done = false; + try { + for await (const line of iterLines()) { + if (done) continue; + if (line) yield JSON.parse(line); + } + done = true; + } catch (e) { + // If the user calls `stream.controller.abort()`, we should exit without throwing. + if (isAbortError(e)) return; + throw e; + } finally { + // If the user `break`s, abort the ongoing request. + if (!done) controller.abort(); + } + } + + return new Stream(iterator, controller); + } + + [Symbol.asyncIterator](): AsyncIterator { + return this.iterator(); + } + + /** + * Splits the stream into two streams which can be + * independently read from at different speeds. + */ + tee(): [Stream, Stream] { + const left: Array>> = []; + const right: Array>> = []; + const iterator = this.iterator(); + + const teeIterator = (queue: Array>>): AsyncIterator => { + return { + next: () => { + if (queue.length === 0) { + const result = iterator.next(); + left.push(result); + right.push(result); + } + return queue.shift()!; + }, + }; + }; + + return [ + new Stream(() => teeIterator(left), this.controller), + new Stream(() => teeIterator(right), this.controller), + ]; + } + + /** + * Converts this stream to a newline-separated ReadableStream of + * JSON stringified values in the stream + * which can be turned back into a Stream with `Stream.fromReadableStream()`. + */ + toReadableStream(): ReadableStream { + const self = this; + let iter: AsyncIterator; + const encoder: { + encode(str: string): Uint8Array; + } = new (globalThis as any).TextEncoder(); + + return makeReadableStream({ + async start() { + iter = self[Symbol.asyncIterator](); + }, + async pull(ctrl: any) { + try { + const { value, done } = await iter.next(); + if (done) return ctrl.close(); + + const bytes = encoder.encode(JSON.stringify(value) + '\n'); + + ctrl.enqueue(bytes); + } catch (err) { + ctrl.error(err); + } + }, + async cancel() { + await iter.return?.(); + }, + }); + } +} + +export async function* _iterSSEMessages( + response: Response, + controller: AbortController, +): AsyncGenerator { + if (!response.body) { + controller.abort(); + if ( + typeof (globalThis as any).navigator !== 'undefined' && + (globalThis as any).navigator.product === 'ReactNative' + ) { + throw new AnthropicError( + `The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`, + ); + } + throw new AnthropicError(`Attempted to iterate over a response with no body`); + } + + const sseDecoder = new SSEDecoder(); + const lineDecoder = new LineDecoder(); + + const iter = ReadableStreamToAsyncIterable(response.body); + for await (const sseChunk of iterSSEChunks(iter)) { + for (const line of lineDecoder.decode(sseChunk)) { + const sse = sseDecoder.decode(line); + if (sse) yield sse; + } + } + + for (const line of lineDecoder.flush()) { + const sse = sseDecoder.decode(line); + if (sse) yield sse; + } +} + +/** + * Given an async iterable iterator, iterates over it and yields full + * SSE chunks, i.e. yields when a double new-line is encountered. + */ +async function* iterSSEChunks(iterator: AsyncIterableIterator): AsyncGenerator { + let data = new Uint8Array(); + + for await (const chunk of iterator) { + if (chunk == null) { + continue; + } + + const binaryChunk = + chunk instanceof ArrayBuffer ? new Uint8Array(chunk) + : typeof chunk === 'string' ? new (globalThis as any).TextEncoder().encode(chunk) + : chunk; + + let newData = new Uint8Array(data.length + binaryChunk.length); + newData.set(data); + newData.set(binaryChunk, data.length); + data = newData; + + let patternIndex; + while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) { + yield data.slice(0, patternIndex); + data = data.slice(patternIndex); + } + } + + if (data.length > 0) { + yield data; + } +} + +class SSEDecoder { + private data: string[]; + private event: string | null; + private chunks: string[]; + + constructor() { + this.event = null; + this.data = []; + this.chunks = []; + } + + decode(line: string) { + if (line.endsWith('\r')) { + line = line.substring(0, line.length - 1); + } + + if (!line) { + // empty line and we didn't previously encounter any messages + if (!this.event && !this.data.length) return null; + + const sse: ServerSentEvent = { + event: this.event, + data: this.data.join('\n'), + raw: this.chunks, + }; + + this.event = null; + this.data = []; + this.chunks = []; + + return sse; + } + + this.chunks.push(line); + + if (line.startsWith(':')) { + return null; + } + + let [fieldname, _, value] = partition(line, ':'); + + if (value.startsWith(' ')) { + value = value.substring(1); + } + + if (fieldname === 'event') { + this.event = value; + } else if (fieldname === 'data') { + this.data.push(value); + } + + return null; + } +} + +function partition(str: string, delimiter: string): [string, string, string] { + const index = str.indexOf(delimiter); + if (index !== -1) { + return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)]; + } + + return [str, '', '']; +} diff --git a/src/core/uploads.ts b/src/core/uploads.ts new file mode 100644 index 00000000..2882ca6d --- /dev/null +++ b/src/core/uploads.ts @@ -0,0 +1,2 @@ +export { type Uploadable } from '../internal/uploads'; +export { toFile, type ToFileInput } from '../internal/to-file'; diff --git a/src/error.ts b/src/error.ts index 1c1d9a58..fc55f46c 100644 --- a/src/error.ts +++ b/src/error.ts @@ -1,133 +1,2 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import { castToError } from './internal/errors'; - -export class AnthropicError extends Error {} - -export class APIError< - TStatus extends number | undefined = number | undefined, - THeaders extends Headers | undefined = Headers | undefined, - TError extends Object | undefined = Object | undefined, -> extends AnthropicError { - /** HTTP status for the response that caused the error */ - readonly status: TStatus; - /** HTTP headers for the response that caused the error */ - readonly headers: THeaders; - /** JSON body of the response that caused the error */ - readonly error: TError; - - readonly requestID: string | null | undefined; - - constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) { - super(`${APIError.makeMessage(status, error, message)}`); - this.status = status; - this.headers = headers; - this.requestID = headers?.get('request-id'); - this.error = error; - } - - private static makeMessage(status: number | undefined, error: any, message: string | undefined) { - const msg = - error?.message ? - typeof error.message === 'string' ? - error.message - : JSON.stringify(error.message) - : error ? JSON.stringify(error) - : message; - - if (status && msg) { - return `${status} ${msg}`; - } - if (status) { - return `${status} status code (no body)`; - } - if (msg) { - return msg; - } - return '(no status code or body)'; - } - - static generate( - status: number | undefined, - errorResponse: Object | undefined, - message: string | undefined, - headers: Headers | undefined, - ): APIError { - if (!status || !headers) { - return new APIConnectionError({ message, cause: castToError(errorResponse) }); - } - - const error = errorResponse as Record; - - if (status === 400) { - return new BadRequestError(status, error, message, headers); - } - - if (status === 401) { - return new AuthenticationError(status, error, message, headers); - } - - if (status === 403) { - return new PermissionDeniedError(status, error, message, headers); - } - - if (status === 404) { - return new NotFoundError(status, error, message, headers); - } - - if (status === 409) { - return new ConflictError(status, error, message, headers); - } - - if (status === 422) { - return new UnprocessableEntityError(status, error, message, headers); - } - - if (status === 429) { - return new RateLimitError(status, error, message, headers); - } - - if (status >= 500) { - return new InternalServerError(status, error, message, headers); - } - - return new APIError(status, error, message, headers); - } -} - -export class APIUserAbortError extends APIError { - constructor({ message }: { message?: string } = {}) { - super(undefined, undefined, message || 'Request was aborted.', undefined); - } -} - -export class APIConnectionError extends APIError { - constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) { - super(undefined, undefined, message || 'Connection error.', undefined); - // in some environments the 'cause' property is already declared - // @ts-ignore - if (cause) this.cause = cause; - } -} - -export class APIConnectionTimeoutError extends APIConnectionError { - constructor({ message }: { message?: string } = {}) { - super({ message: message ?? 'Request timed out.' }); - } -} - -export class BadRequestError extends APIError<400, Headers> {} - -export class AuthenticationError extends APIError<401, Headers> {} - -export class PermissionDeniedError extends APIError<403, Headers> {} - -export class NotFoundError extends APIError<404, Headers> {} - -export class ConflictError extends APIError<409, Headers> {} - -export class UnprocessableEntityError extends APIError<422, Headers> {} - -export class RateLimitError extends APIError<429, Headers> {} - -export class InternalServerError extends APIError {} +/** @deprecated Import from ./core/error instead */ +export * from './core/error'; diff --git a/src/index.ts b/src/index.ts index 53a4df4b..8594f41b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,10 +2,10 @@ export { Anthropic as default } from './client'; -export { type Uploadable, toFile } from './uploads'; -export { APIPromise } from './api-promise'; +export { type Uploadable, toFile } from './core/uploads'; +export { APIPromise } from './core/api-promise'; export { BaseAnthropic, Anthropic, type ClientOptions, HUMAN_PROMPT, AI_PROMPT } from './client'; -export { PagePromise } from './pagination'; +export { PagePromise } from './core/pagination'; export { AnthropicError, APIError, @@ -20,4 +20,4 @@ export { InternalServerError, PermissionDeniedError, UnprocessableEntityError, -} from './error'; +} from './core/error'; diff --git a/src/internal/README.md b/src/internal/README.md new file mode 100644 index 00000000..3ef5a25b --- /dev/null +++ b/src/internal/README.md @@ -0,0 +1,3 @@ +# `internal` + +The modules in this directory are not importable outside this package and will change between releases. diff --git a/src/internal/decoders/jsonl.ts b/src/internal/decoders/jsonl.ts index fb4e4699..ba0cb8f4 100644 --- a/src/internal/decoders/jsonl.ts +++ b/src/internal/decoders/jsonl.ts @@ -1,4 +1,4 @@ -import { AnthropicError } from '../../error'; +import { AnthropicError } from '../../core/error'; import { ReadableStreamToAsyncIterable } from '../shims'; import { LineDecoder, type Bytes } from './line'; diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts index fcacf4b7..42559e22 100644 --- a/src/internal/decoders/line.ts +++ b/src/internal/decoders/line.ts @@ -1,4 +1,4 @@ -import { AnthropicError } from '../../error'; +import { AnthropicError } from '../../core/error'; export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; diff --git a/src/internal/parse.ts b/src/internal/parse.ts index ece00cbf..f17e38ca 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import type { FinalRequestOptions } from './request-options'; -import { Stream } from '../streaming'; +import { Stream } from '../core/streaming'; import { type BaseAnthropic } from '../client'; import { formatRequestDetails, loggerFor } from './utils/log'; import type { AbstractPage } from '../pagination'; diff --git a/src/internal/request-options.ts b/src/internal/request-options.ts index d46c3b33..ef099310 100644 --- a/src/internal/request-options.ts +++ b/src/internal/request-options.ts @@ -3,7 +3,7 @@ import { NullableHeaders } from './headers'; import type { BodyInit } from './builtin-types'; -import { Stream } from '../streaming'; +import { Stream } from '../core/streaming'; import type { HTTPMethod, MergedRequestInit } from './types'; import { type HeadersLike } from './headers'; diff --git a/src/internal/utils/base64.ts b/src/internal/utils/base64.ts index ee4a2817..f7288658 100644 --- a/src/internal/utils/base64.ts +++ b/src/internal/utils/base64.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { AnthropicError } from '../../error'; +import { AnthropicError } from '../../core/error'; export const toBase64 = (data: string | Uint8Array | null | undefined): string => { if (!data) return ''; diff --git a/src/internal/utils/path.ts b/src/internal/utils/path.ts index cb12f8a2..4a7648ca 100644 --- a/src/internal/utils/path.ts +++ b/src/internal/utils/path.ts @@ -1,4 +1,4 @@ -import { AnthropicError } from '../../error'; +import { AnthropicError } from '../../core/error'; /** * Percent-encode everything that isn't safe to have in a path without encoding safe chars. diff --git a/src/internal/utils/values.ts b/src/internal/utils/values.ts index 12b4a435..d151bd0d 100644 --- a/src/internal/utils/values.ts +++ b/src/internal/utils/values.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { AnthropicError } from '../../error'; +import { AnthropicError } from '../../core/error'; // https://url.spec.whatwg.org/#url-scheme-string const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i; diff --git a/src/pagination.ts b/src/pagination.ts index 4bb2878c..90bf015e 100644 --- a/src/pagination.ts +++ b/src/pagination.ts @@ -1,201 +1,2 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import { AnthropicError } from './error'; -import { FinalRequestOptions } from './internal/request-options'; -import { defaultParseResponse, type WithRequestID } from './internal/parse'; -import { APIPromise } from './api-promise'; -import { type BaseAnthropic } from './client'; -import { type APIResponseProps } from './internal/parse'; -import { maybeObj } from './internal/utils/values'; - -export type PageRequestOptions = Pick; - -export abstract class AbstractPage implements AsyncIterable { - #client: BaseAnthropic; - protected options: FinalRequestOptions; - - protected response: Response; - protected body: unknown; - - constructor(client: BaseAnthropic, response: Response, body: unknown, options: FinalRequestOptions) { - this.#client = client; - this.options = options; - this.response = response; - this.body = body; - } - - abstract nextPageRequestOptions(): PageRequestOptions | null; - - abstract getPaginatedItems(): Item[]; - - hasNextPage(): boolean { - const items = this.getPaginatedItems(); - if (!items.length) return false; - return this.nextPageRequestOptions() != null; - } - - async getNextPage(): Promise { - const nextOptions = this.nextPageRequestOptions(); - if (!nextOptions) { - throw new AnthropicError( - 'No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.', - ); - } - - return await this.#client.requestAPIList(this.constructor as any, nextOptions); - } - - async *iterPages(): AsyncGenerator { - let page: this = this; - yield page; - while (page.hasNextPage()) { - page = await page.getNextPage(); - yield page; - } - } - - async *[Symbol.asyncIterator](): AsyncGenerator { - for await (const page of this.iterPages()) { - for (const item of page.getPaginatedItems()) { - yield item; - } - } - } -} - -/** - * This subclass of Promise will resolve to an instantiated Page once the request completes. - * - * It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg: - * - * for await (const item of client.items.list()) { - * console.log(item) - * } - */ -export class PagePromise< - PageClass extends AbstractPage, - Item = ReturnType[number], - > - extends APIPromise - implements AsyncIterable -{ - constructor( - client: BaseAnthropic, - request: Promise, - Page: new (...args: ConstructorParameters) => PageClass, - ) { - super( - client, - request, - async (client, props) => - new Page( - client, - props.response, - await defaultParseResponse(client, props), - props.options, - ) as WithRequestID, - ); - } - - /** - * Allow auto-paginating iteration on an unawaited list call, eg: - * - * for await (const item of client.items.list()) { - * console.log(item) - * } - */ - async *[Symbol.asyncIterator]() { - const page = await this; - for await (const item of page) { - yield item; - } - } -} - -export interface PageResponse { - data: Array; - - has_more: boolean; - - first_id: string | null; - - last_id: string | null; -} - -export interface PageParams { - /** - * Number of items per page. - */ - limit?: number; - - before_id?: string; - - after_id?: string; -} - -export class Page extends AbstractPage implements PageResponse { - data: Array; - - has_more: boolean; - - first_id: string | null; - - last_id: string | null; - - constructor( - client: BaseAnthropic, - response: Response, - body: PageResponse, - options: FinalRequestOptions, - ) { - super(client, response, body, options); - - this.data = body.data || []; - this.has_more = body.has_more || false; - this.first_id = body.first_id || null; - this.last_id = body.last_id || null; - } - - getPaginatedItems(): Item[] { - return this.data ?? []; - } - - override hasNextPage(): boolean { - if (this.has_more === false) { - return false; - } - - return super.hasNextPage(); - } - - nextPageRequestOptions(): PageRequestOptions | null { - if ((this.options.query as Record)?.['before_id']) { - // in reverse - const first_id = this.first_id; - if (!first_id) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - before_id: first_id, - }, - }; - } - - const cursor = this.last_id; - if (!cursor) { - return null; - } - - return { - ...this.options, - query: { - ...maybeObj(this.options.query), - after_id: cursor, - }, - }; - } -} +/** @deprecated Import from ./core/pagination instead */ +export * from './core/pagination'; diff --git a/src/resource.ts b/src/resource.ts index 19d27e77..363e3516 100644 --- a/src/resource.ts +++ b/src/resource.ts @@ -1,11 +1,2 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import { BaseAnthropic } from './client'; - -export class APIResource { - protected _client: BaseAnthropic; - - constructor(client: BaseAnthropic) { - this._client = client; - } -} +/** @deprecated Import from ./core/resource instead */ +export * from './core/resource'; diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index b910a03a..d716077b 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as ModelsAPI from './models'; import { BetaModelInfo, BetaModelInfosPage, ModelListParams, Models } from './models'; import * as MessagesAPI from './messages/messages'; diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index 4a0c91a0..f578818d 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -1,10 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; +import { APIResource } from '../../../core/resource'; import * as BetaAPI from '../beta'; +import { APIPromise } from '../../../core/api-promise'; import * as BetaMessagesAPI from './messages'; -import { APIPromise } from '../../../api-promise'; -import { Page, type PageParams, PagePromise } from '../../../pagination'; +import { Page, type PageParams, PagePromise } from '../../../core/pagination'; import { buildHeaders } from '../../../internal/headers'; import { RequestOptions } from '../../../internal/request-options'; import { JSONLDecoder } from '../../../internal/decoders/jsonl'; diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index 015981a5..2bfb99a4 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../../resource'; +import { APIResource } from '../../../core/resource'; import * as MessagesMessagesAPI from './messages'; import * as BetaAPI from '../beta'; import * as MessagesAPI from '../../messages/messages'; @@ -24,8 +24,8 @@ import { BetaMessageBatchSucceededResult, BetaMessageBatchesPage, } from './batches'; -import { APIPromise } from '../../../api-promise'; -import { Stream } from '../../../streaming'; +import { APIPromise } from '../../../core/api-promise'; +import { Stream } from '../../../core/streaming'; import { buildHeaders } from '../../../internal/headers'; import { RequestOptions } from '../../../internal/request-options'; diff --git a/src/resources/beta/models.ts b/src/resources/beta/models.ts index c929e517..8f7213f4 100644 --- a/src/resources/beta/models.ts +++ b/src/resources/beta/models.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; -import { APIPromise } from '../../api-promise'; -import { Page, type PageParams, PagePromise } from '../../pagination'; +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { Page, type PageParams, PagePromise } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; import { path } from '../../internal/utils/path'; diff --git a/src/resources/completions.ts b/src/resources/completions.ts index 23e4bb16..68f70344 100644 --- a/src/resources/completions.ts +++ b/src/resources/completions.ts @@ -1,10 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../resource'; +import { APIResource } from '../core/resource'; import * as CompletionsAPI from './completions'; import * as MessagesAPI from './messages/messages'; -import { APIPromise } from '../api-promise'; -import { Stream } from '../streaming'; +import { APIPromise } from '../core/api-promise'; +import { Stream } from '../core/streaming'; import { RequestOptions } from '../internal/request-options'; export class Completions extends APIResource { diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index f2212dc3..a412abb6 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -1,10 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as Shared from '../shared'; import * as MessagesAPI from './messages'; -import { APIPromise } from '../../api-promise'; -import { Page, type PageParams, PagePromise } from '../../pagination'; +import { APIPromise } from '../../core/api-promise'; +import { Page, type PageParams, PagePromise } from '../../core/pagination'; import { buildHeaders } from '../../internal/headers'; import { RequestOptions } from '../../internal/request-options'; import { JSONLDecoder } from '../../internal/decoders/jsonl'; diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index 42294d12..6932d0bb 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; +import { APIResource } from '../../core/resource'; import * as MessagesAPI from './messages'; import * as BatchesAPI from './batches'; import { @@ -18,8 +18,8 @@ import { MessageBatchSucceededResult, MessageBatchesPage, } from './batches'; -import { APIPromise } from '../../api-promise'; -import { Stream } from '../../streaming'; +import { APIPromise } from '../../core/api-promise'; +import { Stream } from '../../core/streaming'; import { RequestOptions } from '../../internal/request-options'; import { MessageStream } from '../../lib/MessageStream'; diff --git a/src/resources/models.ts b/src/resources/models.ts index 6153813b..df65f9b9 100644 --- a/src/resources/models.ts +++ b/src/resources/models.ts @@ -1,8 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../resource'; -import { APIPromise } from '../api-promise'; -import { Page, type PageParams, PagePromise } from '../pagination'; +import { APIResource } from '../core/resource'; +import { APIPromise } from '../core/api-promise'; +import { Page, type PageParams, PagePromise } from '../core/pagination'; import { RequestOptions } from '../internal/request-options'; import { path } from '../internal/utils/path'; diff --git a/src/streaming.ts b/src/streaming.ts index 542cbc28..9e6da106 100644 --- a/src/streaming.ts +++ b/src/streaming.ts @@ -1,333 +1,2 @@ -import { AnthropicError } from './error'; -import { type ReadableStream } from './internal/shim-types'; -import { makeReadableStream } from './internal/shims'; -import { findDoubleNewlineIndex, LineDecoder } from './internal/decoders/line'; -import { ReadableStreamToAsyncIterable } from './internal/shims'; -import { isAbortError } from './internal/errors'; -import { safeJSON } from './internal/utils/values'; - -import { APIError } from './error'; - -type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; - -export type ServerSentEvent = { - event: string | null; - data: string; - raw: string[]; -}; - -export class Stream implements AsyncIterable { - controller: AbortController; - - constructor( - private iterator: () => AsyncIterator, - controller: AbortController, - ) { - this.controller = controller; - } - - static fromSSEResponse(response: Response, controller: AbortController): Stream { - let consumed = false; - - async function* iterator(): AsyncIterator { - if (consumed) { - throw new AnthropicError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); - } - consumed = true; - let done = false; - try { - for await (const sse of _iterSSEMessages(response, controller)) { - if (sse.event === 'completion') { - try { - yield JSON.parse(sse.data); - } catch (e) { - console.error(`Could not parse message into JSON:`, sse.data); - console.error(`From chunk:`, sse.raw); - throw e; - } - } - - if ( - sse.event === 'message_start' || - sse.event === 'message_delta' || - sse.event === 'message_stop' || - sse.event === 'content_block_start' || - sse.event === 'content_block_delta' || - sse.event === 'content_block_stop' - ) { - try { - yield JSON.parse(sse.data); - } catch (e) { - console.error(`Could not parse message into JSON:`, sse.data); - console.error(`From chunk:`, sse.raw); - throw e; - } - } - - if (sse.event === 'ping') { - continue; - } - - if (sse.event === 'error') { - throw new APIError(undefined, safeJSON(sse.data) ?? sse.data, undefined, response.headers); - } - } - done = true; - } catch (e) { - // If the user calls `stream.controller.abort()`, we should exit without throwing. - if (isAbortError(e)) return; - throw e; - } finally { - // If the user `break`s, abort the ongoing request. - if (!done) controller.abort(); - } - } - - return new Stream(iterator, controller); - } - - /** - * Generates a Stream from a newline-separated ReadableStream - * where each item is a JSON value. - */ - static fromReadableStream(readableStream: ReadableStream, controller: AbortController): Stream { - let consumed = false; - - async function* iterLines(): AsyncGenerator { - const lineDecoder = new LineDecoder(); - - const iter = ReadableStreamToAsyncIterable(readableStream); - for await (const chunk of iter) { - for (const line of lineDecoder.decode(chunk)) { - yield line; - } - } - - for (const line of lineDecoder.flush()) { - yield line; - } - } - - async function* iterator(): AsyncIterator { - if (consumed) { - throw new AnthropicError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.'); - } - consumed = true; - let done = false; - try { - for await (const line of iterLines()) { - if (done) continue; - if (line) yield JSON.parse(line); - } - done = true; - } catch (e) { - // If the user calls `stream.controller.abort()`, we should exit without throwing. - if (isAbortError(e)) return; - throw e; - } finally { - // If the user `break`s, abort the ongoing request. - if (!done) controller.abort(); - } - } - - return new Stream(iterator, controller); - } - - [Symbol.asyncIterator](): AsyncIterator { - return this.iterator(); - } - - /** - * Splits the stream into two streams which can be - * independently read from at different speeds. - */ - tee(): [Stream, Stream] { - const left: Array>> = []; - const right: Array>> = []; - const iterator = this.iterator(); - - const teeIterator = (queue: Array>>): AsyncIterator => { - return { - next: () => { - if (queue.length === 0) { - const result = iterator.next(); - left.push(result); - right.push(result); - } - return queue.shift()!; - }, - }; - }; - - return [ - new Stream(() => teeIterator(left), this.controller), - new Stream(() => teeIterator(right), this.controller), - ]; - } - - /** - * Converts this stream to a newline-separated ReadableStream of - * JSON stringified values in the stream - * which can be turned back into a Stream with `Stream.fromReadableStream()`. - */ - toReadableStream(): ReadableStream { - const self = this; - let iter: AsyncIterator; - const encoder: { - encode(str: string): Uint8Array; - } = new (globalThis as any).TextEncoder(); - - return makeReadableStream({ - async start() { - iter = self[Symbol.asyncIterator](); - }, - async pull(ctrl: any) { - try { - const { value, done } = await iter.next(); - if (done) return ctrl.close(); - - const bytes = encoder.encode(JSON.stringify(value) + '\n'); - - ctrl.enqueue(bytes); - } catch (err) { - ctrl.error(err); - } - }, - async cancel() { - await iter.return?.(); - }, - }); - } -} - -export async function* _iterSSEMessages( - response: Response, - controller: AbortController, -): AsyncGenerator { - if (!response.body) { - controller.abort(); - if ( - typeof (globalThis as any).navigator !== 'undefined' && - (globalThis as any).navigator.product === 'ReactNative' - ) { - throw new AnthropicError( - `The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`, - ); - } - throw new AnthropicError(`Attempted to iterate over a response with no body`); - } - - const sseDecoder = new SSEDecoder(); - const lineDecoder = new LineDecoder(); - - const iter = ReadableStreamToAsyncIterable(response.body); - for await (const sseChunk of iterSSEChunks(iter)) { - for (const line of lineDecoder.decode(sseChunk)) { - const sse = sseDecoder.decode(line); - if (sse) yield sse; - } - } - - for (const line of lineDecoder.flush()) { - const sse = sseDecoder.decode(line); - if (sse) yield sse; - } -} - -/** - * Given an async iterable iterator, iterates over it and yields full - * SSE chunks, i.e. yields when a double new-line is encountered. - */ -async function* iterSSEChunks(iterator: AsyncIterableIterator): AsyncGenerator { - let data = new Uint8Array(); - - for await (const chunk of iterator) { - if (chunk == null) { - continue; - } - - const binaryChunk = - chunk instanceof ArrayBuffer ? new Uint8Array(chunk) - : typeof chunk === 'string' ? new (globalThis as any).TextEncoder().encode(chunk) - : chunk; - - let newData = new Uint8Array(data.length + binaryChunk.length); - newData.set(data); - newData.set(binaryChunk, data.length); - data = newData; - - let patternIndex; - while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) { - yield data.slice(0, patternIndex); - data = data.slice(patternIndex); - } - } - - if (data.length > 0) { - yield data; - } -} - -class SSEDecoder { - private data: string[]; - private event: string | null; - private chunks: string[]; - - constructor() { - this.event = null; - this.data = []; - this.chunks = []; - } - - decode(line: string) { - if (line.endsWith('\r')) { - line = line.substring(0, line.length - 1); - } - - if (!line) { - // empty line and we didn't previously encounter any messages - if (!this.event && !this.data.length) return null; - - const sse: ServerSentEvent = { - event: this.event, - data: this.data.join('\n'), - raw: this.chunks, - }; - - this.event = null; - this.data = []; - this.chunks = []; - - return sse; - } - - this.chunks.push(line); - - if (line.startsWith(':')) { - return null; - } - - let [fieldname, _, value] = partition(line, ':'); - - if (value.startsWith(' ')) { - value = value.substring(1); - } - - if (fieldname === 'event') { - this.event = value; - } else if (fieldname === 'data') { - this.data.push(value); - } - - return null; - } -} - -function partition(str: string, delimiter: string): [string, string, string] { - const index = str.indexOf(delimiter); - if (index !== -1) { - return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)]; - } - - return [str, '', '']; -} +/** @deprecated Import from ./core/streaming instead */ +export * from './core/streaming'; diff --git a/src/uploads.ts b/src/uploads.ts index 79d3073e..b2ef6471 100644 --- a/src/uploads.ts +++ b/src/uploads.ts @@ -1,2 +1,2 @@ -export { type Uploadable } from './internal/uploads'; -export { toFile, type ToFileInput } from './internal/to-file'; +/** @deprecated Import from ./core/uploads instead */ +export * from './core/uploads'; diff --git a/tests/form.test.ts b/tests/form.test.ts index 2dc667ff..d2a086b0 100644 --- a/tests/form.test.ts +++ b/tests/form.test.ts @@ -1,5 +1,5 @@ import { multipartFormRequestOptions, createForm } from '@anthropic-ai/sdk/internal/uploads'; -import { toFile } from '@anthropic-ai/sdk/uploads'; +import { toFile } from '@anthropic-ai/sdk/core/uploads'; describe('form data validation', () => { test('valid values do not error', async () => { diff --git a/tests/index.test.ts b/tests/index.test.ts index c7fd713a..39a605bf 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,6 +1,6 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIPromise } from '@anthropic-ai/sdk/api-promise'; +import { APIPromise } from '@anthropic-ai/sdk/core/api-promise'; import util from 'node:util'; import Anthropic from '@anthropic-ai/sdk'; diff --git a/tests/streaming.test.ts b/tests/streaming.test.ts index fc52d895..0977884e 100644 --- a/tests/streaming.test.ts +++ b/tests/streaming.test.ts @@ -1,6 +1,6 @@ import assert from 'assert'; -import { Stream, _iterSSEMessages } from '@anthropic-ai/sdk/streaming'; -import { APIError } from '@anthropic-ai/sdk/error'; +import { Stream, _iterSSEMessages } from '@anthropic-ai/sdk/core/streaming'; +import { APIError } from '@anthropic-ai/sdk/core/error'; import { ReadableStreamFrom } from '@anthropic-ai/sdk/internal/shims'; describe('streaming decoding', () => { diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index ec2a2e23..5246aac7 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import type { ResponseLike } from '@anthropic-ai/sdk/internal/to-file'; -import { toFile } from '@anthropic-ai/sdk/uploads'; +import { toFile } from '@anthropic-ai/sdk/core/uploads'; import { File } from 'node:buffer'; class MyClass { @@ -97,7 +97,7 @@ describe('missing File error message', () => { }); test('is thrown', async () => { - const uploads = await import('@anthropic-ai/sdk/uploads'); + const uploads = await import('@anthropic-ai/sdk/core/uploads'); await expect( uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })), ).rejects.toMatchInlineSnapshot( From be3406a775b9e8b1c791b100c9556e18e1e23f9c Mon Sep 17 00:00:00 2001 From: Stainless Bot Date: Thu, 27 Mar 2025 18:29:50 +0000 Subject: [PATCH 067/105] chore(internal): update config --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index b4a020e8..8c0e4ff1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 -config_hash: 188e45a82f6284619dd4a7bddf875907 +config_hash: f6e255d50f3d990f7b1171eb84304315 From 7db3acdbe80d3bb2b98cea0cde959cf4943af51e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 22:38:03 +0000 Subject: [PATCH 068/105] chore(internal): remove CI condition --- .github/workflows/ci.yml | 3 --- .stats.yml | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b5123d7c..1e81000b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,6 @@ jobs: lint: name: lint runs-on: ubuntu-latest - if: github.repository == 'anthropics/anthropic-sdk-typescript' steps: - uses: actions/checkout@v4 @@ -33,7 +32,6 @@ jobs: build: name: build runs-on: ubuntu-latest - if: github.repository == 'anthropics/anthropic-sdk-typescript' steps: - uses: actions/checkout@v4 @@ -51,7 +49,6 @@ jobs: test: name: test runs-on: ubuntu-latest - if: github.repository == 'anthropics/anthropic-sdk-typescript' steps: - uses: actions/checkout@v4 diff --git a/.stats.yml b/.stats.yml index 8c0e4ff1..6ee37be1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 config_hash: f6e255d50f3d990f7b1171eb84304315 From c95a8508a4a555b0f29c6d87e6988bd3cfe7709d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 16:02:44 +0000 Subject: [PATCH 069/105] feat(api): extract ContentBlockDelta events into their own schemas --- .stats.yml | 2 +- api.md | 2 ++ src/client.ts | 2 ++ src/resources/beta/beta.ts | 2 ++ src/resources/beta/index.ts | 1 + src/resources/beta/messages/index.ts | 1 + src/resources/beta/messages/messages.ts | 10 +++++++++- src/resources/index.ts | 1 + src/resources/messages/index.ts | 1 + src/resources/messages/messages.ts | 10 +++++++++- 10 files changed, 29 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6ee37be1..0be796ab 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 -config_hash: f6e255d50f3d990f7b1171eb84304315 +config_hash: cefe3994b221b9021b772a882b106710 diff --git a/api.md b/api.md index ed1ac960..e2682df1 100644 --- a/api.md +++ b/api.md @@ -53,6 +53,7 @@ Types: - Metadata - Model - PlainTextSource +- RawContentBlockDelta - RawContentBlockDeltaEvent - RawContentBlockStartEvent - RawContentBlockStopEvent @@ -187,6 +188,7 @@ Types: - BetaMessageTokensCount - BetaMetadata - BetaPlainTextSource +- BetaRawContentBlockDelta - BetaRawContentBlockDeltaEvent - BetaRawContentBlockStartEvent - BetaRawContentBlockStopEvent diff --git a/src/client.ts b/src/client.ts index 9f57e064..8e4aecca 100644 --- a/src/client.ts +++ b/src/client.ts @@ -89,6 +89,7 @@ import { Metadata, Model, PlainTextSource, + RawContentBlockDelta, RawContentBlockDeltaEvent, RawContentBlockStartEvent, RawContentBlockStopEvent, @@ -935,6 +936,7 @@ export declare namespace Anthropic { type Metadata as Metadata, type Model as Model, type PlainTextSource as PlainTextSource, + type RawContentBlockDelta as RawContentBlockDelta, type RawContentBlockDeltaEvent as RawContentBlockDeltaEvent, type RawContentBlockStartEvent as RawContentBlockStartEvent, type RawContentBlockStopEvent as RawContentBlockStopEvent, diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index d716077b..64e330e1 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -29,6 +29,7 @@ import { BetaMessageTokensCount, BetaMetadata, BetaPlainTextSource, + BetaRawContentBlockDelta, BetaRawContentBlockDeltaEvent, BetaRawContentBlockStartEvent, BetaRawContentBlockStopEvent, @@ -216,6 +217,7 @@ export declare namespace Beta { type BetaMessageTokensCount as BetaMessageTokensCount, type BetaMetadata as BetaMetadata, type BetaPlainTextSource as BetaPlainTextSource, + type BetaRawContentBlockDelta as BetaRawContentBlockDelta, type BetaRawContentBlockDeltaEvent as BetaRawContentBlockDeltaEvent, type BetaRawContentBlockStartEvent as BetaRawContentBlockStartEvent, type BetaRawContentBlockStopEvent as BetaRawContentBlockStopEvent, diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts index 7afe57bc..84dfd803 100644 --- a/src/resources/beta/index.ts +++ b/src/resources/beta/index.ts @@ -41,6 +41,7 @@ export { type BetaMessageTokensCount, type BetaMetadata, type BetaPlainTextSource, + type BetaRawContentBlockDelta, type BetaRawContentBlockDeltaEvent, type BetaRawContentBlockStartEvent, type BetaRawContentBlockStopEvent, diff --git a/src/resources/beta/messages/index.ts b/src/resources/beta/messages/index.ts index 851b8432..28442b78 100644 --- a/src/resources/beta/messages/index.ts +++ b/src/resources/beta/messages/index.ts @@ -45,6 +45,7 @@ export { type BetaMessageTokensCount, type BetaMetadata, type BetaPlainTextSource, + type BetaRawContentBlockDelta, type BetaRawContentBlockDeltaEvent, type BetaRawContentBlockStartEvent, type BetaRawContentBlockStopEvent, diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index 2bfb99a4..8d539550 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -407,8 +407,15 @@ export interface BetaPlainTextSource { type: 'text'; } +export type BetaRawContentBlockDelta = + | BetaTextDelta + | BetaInputJSONDelta + | BetaCitationsDelta + | BetaThinkingDelta + | BetaSignatureDelta; + export interface BetaRawContentBlockDeltaEvent { - delta: BetaTextDelta | BetaInputJSONDelta | BetaCitationsDelta | BetaThinkingDelta | BetaSignatureDelta; + delta: BetaRawContentBlockDelta; index: number; @@ -1440,6 +1447,7 @@ export declare namespace Messages { type BetaMessageTokensCount as BetaMessageTokensCount, type BetaMetadata as BetaMetadata, type BetaPlainTextSource as BetaPlainTextSource, + type BetaRawContentBlockDelta as BetaRawContentBlockDelta, type BetaRawContentBlockDeltaEvent as BetaRawContentBlockDeltaEvent, type BetaRawContentBlockStartEvent as BetaRawContentBlockStartEvent, type BetaRawContentBlockStopEvent as BetaRawContentBlockStopEvent, diff --git a/src/resources/index.ts b/src/resources/index.ts index c8331d8d..6a9c77f6 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -56,6 +56,7 @@ export { type Metadata, type Model, type PlainTextSource, + type RawContentBlockDelta, type RawContentBlockDeltaEvent, type RawContentBlockStartEvent, type RawContentBlockStopEvent, diff --git a/src/resources/messages/index.ts b/src/resources/messages/index.ts index 091226ae..a02640e3 100644 --- a/src/resources/messages/index.ts +++ b/src/resources/messages/index.ts @@ -50,6 +50,7 @@ export { type Metadata, type Model, type PlainTextSource, + type RawContentBlockDelta, type RawContentBlockDeltaEvent, type RawContentBlockStartEvent, type RawContentBlockStopEvent, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index 6932d0bb..f472551f 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -446,8 +446,15 @@ export interface PlainTextSource { type: 'text'; } +export type RawContentBlockDelta = + | TextDelta + | InputJSONDelta + | CitationsDelta + | ThinkingDelta + | SignatureDelta; + export interface RawContentBlockDeltaEvent { - delta: TextDelta | InputJSONDelta | CitationsDelta | ThinkingDelta | SignatureDelta; + delta: RawContentBlockDelta; index: number; @@ -1395,6 +1402,7 @@ export declare namespace Messages { type Metadata as Metadata, type Model as Model, type PlainTextSource as PlainTextSource, + type RawContentBlockDelta as RawContentBlockDelta, type RawContentBlockDeltaEvent as RawContentBlockDeltaEvent, type RawContentBlockStartEvent as RawContentBlockStartEvent, type RawContentBlockStopEvent as RawContentBlockStopEvent, From 4eb2fea3bc5ccee2802a3dda74db7bf30f29d8e1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 00:34:01 +0000 Subject: [PATCH 070/105] feat(api): manual updates --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 0be796ab..09ecae7c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 -config_hash: cefe3994b221b9021b772a882b106710 +config_hash: ae6d8532cb810b6ba9741c7cb8909570 From 1fa560afb288d1486326af69fcba50208f8855d5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:31:12 +0000 Subject: [PATCH 071/105] fix(client): send `X-Stainless-Timeout` in seconds --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index 8e4aecca..234a040e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -797,7 +797,7 @@ export class BaseAnthropic { Accept: 'application/json', 'User-Agent': this.getUserAgent(), 'X-Stainless-Retry-Count': String(retryCount), - ...(options.timeout ? { 'X-Stainless-Timeout': String(options.timeout) } : {}), + ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}), ...getPlatformHeaders(), ...(this._options.dangerouslyAllowBrowser ? { 'anthropic-dangerous-direct-browser-access': 'true' } From 18c5b409e2d6c4ac1a7f82853d7e24a0c5abc13c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 20:57:07 +0000 Subject: [PATCH 072/105] chore(internal): add aliases for Record and Array --- src/internal/builtin-types.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/internal/builtin-types.ts b/src/internal/builtin-types.ts index b2e598a8..c23d3bde 100644 --- a/src/internal/builtin-types.ts +++ b/src/internal/builtin-types.ts @@ -39,9 +39,23 @@ type _HeadersInit = RequestInit['headers']; */ type _BodyInit = RequestInit['body']; +/** + * An alias to the builtin `Array` type so we can + * easily alias it in import statements if there are name clashes. + */ +type _Array = Array; + +/** + * An alias to the builtin `Record` type so we can + * easily alias it in import statements if there are name clashes. + */ +type _Record = Record; + export type { + _Array as Array, _BodyInit as BodyInit, _HeadersInit as HeadersInit, + _Record as Record, _RequestInfo as RequestInfo, _RequestInit as RequestInit, _Response as Response, From 38f264cc513c55a7db23ea0fae0e5c30f14070f5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 17:10:01 +0000 Subject: [PATCH 073/105] chore(client): make jsonl methods consistent with other streaming methods --- api.md | 4 ++-- src/resources/beta/messages/batches.ts | 7 +++++-- src/resources/messages/batches.ts | 5 ++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/api.md b/api.md index e2682df1..49ea4e12 100644 --- a/api.md +++ b/api.md @@ -119,7 +119,7 @@ Methods: - client.messages.batches.list({ ...params }) -> MessageBatchesPage - client.messages.batches.delete(messageBatchID) -> DeletedMessageBatch - client.messages.batches.cancel(messageBatchID) -> MessageBatch -- client.messages.batches.results(messageBatchID) -> JSONLDecoder<MessageBatchIndividualResponse> +- client.messages.batches.results(messageBatchID) -> MessageBatchIndividualResponse # Models @@ -257,4 +257,4 @@ Methods: - client.beta.messages.batches.list({ ...params }) -> BetaMessageBatchesPage - client.beta.messages.batches.delete(messageBatchID, { ...params }) -> BetaDeletedMessageBatch - client.beta.messages.batches.cancel(messageBatchID, { ...params }) -> BetaMessageBatch -- client.beta.messages.batches.results(messageBatchID, { ...params }) -> JSONLDecoder<BetaMessageBatchIndividualResponse> +- client.beta.messages.batches.results(messageBatchID, { ...params }) -> BetaMessageBatchIndividualResponse diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index f578818d..bd279fc6 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -144,7 +144,7 @@ export class Batches extends APIResource { */ async results( messageBatchID: string, - params: BatchResultsParams | null | undefined = {}, + params: BatchResultsParams | undefined = {}, options?: RequestOptions, ): Promise> { const batch = await this.retrieve(messageBatchID); @@ -165,9 +165,12 @@ export class Batches extends APIResource { }, options?.headers, ]), + stream: true, __binaryResponse: true, }) - ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)); + ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)) as APIPromise< + JSONLDecoder + >; } } diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index a412abb6..5a7b2020 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -108,9 +108,12 @@ export class Batches extends APIResource { .get(batch.results_url, { ...options, headers: buildHeaders([{ Accept: 'application/x-jsonl' }, options?.headers]), + stream: true, __binaryResponse: true, }) - ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)); + ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)) as APIPromise< + JSONLDecoder + >; } } From 59bac509284741a57f22f572563ee6fa2d719e60 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:22:55 +0000 Subject: [PATCH 074/105] fix(api): improve type resolution when importing as a package --- packages/mcp-server/src/tools.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/mcp-server/src/tools.ts diff --git a/packages/mcp-server/src/tools.ts b/packages/mcp-server/src/tools.ts new file mode 100644 index 00000000..7e516de7 --- /dev/null +++ b/packages/mcp-server/src/tools.ts @@ -0,0 +1 @@ +export * from './tools/index'; From 0b78711ec0ecde081dc093feab8852750152233f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 18:23:35 +0000 Subject: [PATCH 075/105] feat(api): manual updates --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 09ecae7c..fded59ec 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 -config_hash: ae6d8532cb810b6ba9741c7cb8909570 +config_hash: 697560b514864f2b78206c694b73269b From a115b94c0e6b1da04a77756605018e19493955b5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 3 Apr 2025 19:57:13 +0000 Subject: [PATCH 076/105] chore(docs): improve migration doc --- MIGRATION.md | 220 +++++++++++++++++++++++++-------------------------- 1 file changed, 109 insertions(+), 111 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 67eed90b..573125c8 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -103,11 +103,35 @@ For example: ```diff - client.example.retrieve(encodeURIComponent('string/with/slash')) -+ client.example.retrieve('string/with/slash') // renders example/string%2Fwith%2Fslash ++ client.example.retrieve('string/with/slash') // retrieves /example/string%2Fwith%2Fslash ``` Previously without the `encodeURIComponent()` call we would have used the path `/example/string/with/slash`; now we'll use `/example/string%2Fwith%2Fslash`. +### Removed request options overloads + +When making requests with no required body, query or header parameters, you must now explicitly pass `null`, `undefined` or an empty object `{}` to the params argument in order to customise request options. + +```diff +client.example.list(); +client.example.list({}, { headers: { ... } }); +client.example.list(null, { headers: { ... } }); +client.example.list(undefined, { headers: { ... } }); +- client.example.list({ headers: { ... } }); ++ client.example.list({}, { headers: { ... } }); +``` + +This affects the following methods: + +- `client.messages.batches.list()` +- `client.models.list()` +- `client.beta.models.list()` +- `client.beta.messages.batches.retrieve()` +- `client.beta.messages.batches.list()` +- `client.beta.messages.batches.delete()` +- `client.beta.messages.batches.cancel()` +- `client.beta.messages.batches.results()` + ### Removed `httpAgent` in favor of `fetchOptions` The `httpAgent` client option has been removed in favor of a [platform-specific `fetchOptions` property](https://github.com/stainless-sdks/anthropic-typescript#fetch-options). @@ -142,69 +166,83 @@ const client = new Anthropic({ }); ``` -### Removed request options overloads +### Changed exports -When making requests with no required body, query or header parameters, you must now explicitly pass `null`, `undefined` or an empty object `{}` to the params argument in order to customise request options. +#### Refactor of `@anthropic-ai/sdk/core`, `error`, `pagination`, `resource`, `streaming` and `uploads` -```diff -client.example.list(); -client.example.list({}, { headers: { ... } }); -client.example.list(null, { headers: { ... } }); -client.example.list(undefined, { headers: { ... } }); -- client.example.list({ headers: { ... } }); -+ client.example.list({}, { headers: { ... } }); +Much of the `@anthropic-ai/sdk/core` file was intended to be internal-only but it was publicly accessible, as such it has been refactored and split up into internal and public files, with public-facing code moved to a new `core` folder and internal code moving to the private `internal` folder. + +At the same time, we moved some public-facing files which were previously at the top level into `core` to make the file structure cleaner and more clear: + +```typescript +// Before +import '@anthropic-ai/sdk/error'; +import '@anthropic-ai/sdk/pagination'; +import '@anthropic-ai/sdk/resource'; +import '@anthropic-ai/sdk/streaming'; +import '@anthropic-ai/sdk/uploads'; + +// After +import '@anthropic-ai/sdk/core/error'; +import '@anthropic-ai/sdk/core/pagination'; +import '@anthropic-ai/sdk/core/resource'; +import '@anthropic-ai/sdk/core/streaming'; +import '@anthropic-ai/sdk/core/uploads'; ``` -This affects the following methods: +If you were relying on anything that was only exported from `@anthropic-ai/sdk/core` and is also not accessible anywhere else, please open an issue and we'll consider adding it to the public API. -- `client.messages.batches.list()` -- `client.models.list()` -- `client.beta.models.list()` -- `client.beta.messages.batches.retrieve()` -- `client.beta.messages.batches.list()` -- `client.beta.messages.batches.delete()` -- `client.beta.messages.batches.cancel()` -- `client.beta.messages.batches.results()` +#### Resource classes -### Pagination changes +Previously under certain circumstances it was possible to import resource classes like `Completions` directly from the root of the package. This was never valid at the type level and only worked in CommonJS files. +Now you must always either reference them as static class properties or import them directly from the files in which they are defined. -Note that the `for await` syntax is _not_ affected. This still works as-is: +```typescript +// Before +const { Completions } = require('@anthropic-ai/sdk'); -```ts -// Automatically fetches more pages as needed. -for await (const betaMessageBatch of client.beta.messages.batches.list()) { - console.log(betaMessageBatch); -} +// After +const { Anthropic } = require('@anthropic-ai/sdk'); +Anthropic.Completions; // or import directly from @anthropic-ai/sdk/resources/completions ``` -#### Simplified interface +#### Cleaned up `uploads` exports -The pagination interface has been simplified: +As part of the `core` refactor, `@anthropic-ai/sdk/uploads` was moved to `@anthropic-ai/sdk/core/uploads` +and the following exports were removed, as they were not intended to be a part of the public API: -```ts -// Before -page.nextPageParams(); -page.nextPageInfo(); -// Required manually handling { url } | { params } type +- `fileFromPath` +- `BlobPart` +- `BlobLike` +- `FileLike` +- `ResponseLike` +- `isResponseLike` +- `isBlobLike` +- `isFileLike` +- `isUploadable` +- `isMultipartBody` +- `maybeMultipartFormRequestOptions` +- `multipartFormRequestOptions` +- `createForm` -// After -page.nextPageRequestOptions(); +Note that `Uploadable` & `toFile` **are** still exported: + +```typescript +import { type Uploadable, toFile } from '@anthropic-ai/sdk/core/uploads'; ``` -#### Removed unnecessary classes +#### `APIClient` -Page classes for individual methods are now type aliases: +The `APIClient` base client class has been replaced with a new `BaseAnthropic` class: -```ts +```typescript // Before -export class BetaMessageBatchesPage extends Page {} +import { APIClient } from '@anthropic-ai/sdk/core'; // After -export type BetaMessageBatchesPage = Page; +import { BaseAnthropic } from '@anthropic-ai/sdk/client'; ``` -If you were importing these classes at runtime, you'll need to switch to importing the base class or only import them at the type-level. - ### File handling The deprecated `fileFromPath` helper has been removed in favor of native Node.js streams: @@ -232,98 +270,58 @@ import Anthropic from '@anthropic-ai/sdk'; The `@anthropic-ai/sdk/shims` imports have been removed. Your global types must now be [correctly configured](#minimum-types-requirements). -### `@anthropic-ai/sdk/src` directory removed - -Previously IDEs may have auto-completed imports from the `@anthropic-ai/sdk/src` directory, however this -directory was only included for an improved go-to-definition experience and should not have been used at runtime. +### Pagination changes -If you have any `@anthropic-ai/sdk/src` imports, you must replace it with `@anthropic-ai/sdk`. +The `for await` syntax **is not affected**. This still works as-is: ```ts -// Before -import Anthropic from '@anthropic-ai/sdk/src'; - -// After -import Anthropic from '@anthropic-ai/sdk'; +// Automatically fetches more pages as needed. +for await (const betaMessageBatch of client.beta.messages.batches.list()) { + console.log(betaMessageBatch); +} ``` -### Headers +The interface for manually paginating through list results has been simplified: -The `headers` property on `APIError` objects is now an instance of the Web [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) class. It was previously just `Record`. - -### Removed exports - -#### Resource classes - -If you were importing resource classes from the root package then you must now import them from the file they are defined in. -This was never valid at the type level and only worked in CommonJS files. - -```typescript +```ts // Before -const { Completions } = require('@anthropic-ai/sdk'); +page.nextPageParams(); +page.nextPageInfo(); +// Required manually handling { url } | { params } type // After -const { Anthropic } = require('@anthropic-ai/sdk'); -Anthropic.Completions; // or import directly from @anthropic-ai/sdk/resources/completions +page.nextPageRequestOptions(); ``` -#### Refactor of `@anthropic-ai/sdk/core`, `error`, `pagination`, `resource`, `streaming` and `uploads` - -Much of the `@anthropic-ai/sdk/core` file was intended to be internal-only but it was publicly accessible, as such it has been refactored and split up into internal and public files, with public-facing code moved to a new `core` folder and internal code moving to the private `internal` folder. +#### Removed unnecessary classes -At the same time, we moved some public-facing files which were previously at the top level into `core` to make the file structure cleaner and more clear: +Page classes for individual methods are now type aliases: -```typescript +```ts // Before -import '@anthropic-ai/sdk/error'; -import '@anthropic-ai/sdk/pagination'; -import '@anthropic-ai/sdk/resource'; -import '@anthropic-ai/sdk/streaming'; -import '@anthropic-ai/sdk/uploads'; +export class BetaMessageBatchesPage extends Page {} // After -import '@anthropic-ai/sdk/core/error'; -import '@anthropic-ai/sdk/core/pagination'; -import '@anthropic-ai/sdk/core/resource'; -import '@anthropic-ai/sdk/core/streaming'; -import '@anthropic-ai/sdk/core/uploads'; +export type BetaMessageBatchesPage = Page; ``` -If you were relying on anything that was only exported from `@anthropic-ai/sdk/core` and is also not accessible anywhere else, please open an issue and we'll consider adding it to the public API. - -#### Cleaned up `uploads` exports - -As part of the `core` refactor, `@anthropic-ai/sdk/uploads` was moved to `@anthropic-ai/sdk/core/uploads` -and the following exports were removed, as they were not intended to be a part of the public API: - -- `fileFromPath` -- `BlobPart` -- `BlobLike` -- `FileLike` -- `ResponseLike` -- `isResponseLike` -- `isBlobLike` -- `isFileLike` -- `isUploadable` -- `isMultipartBody` -- `maybeMultipartFormRequestOptions` -- `multipartFormRequestOptions` -- `createForm` - -Note that `Uploadable` & `toFile` **are** still exported: +If you were importing these classes at runtime, you'll need to switch to importing the base class or only import them at the type-level. -```typescript -import { type Uploadable, toFile } from '@anthropic-ai/sdk/core/uploads'; -``` +### `@anthropic-ai/sdk/src` directory removed -#### `APIClient` +Previously IDEs may have auto-completed imports from the `@anthropic-ai/sdk/src` directory, however this +directory was only included for an improved go-to-definition experience and should not have been used at runtime. -The `APIClient` base client class has been replaced with a new `BaseAnthropic` class: +If you have any `@anthropic-ai/sdk/src/*` imports, you will need to replace them with `@anthropic-ai/sdk/*`. -```typescript +```ts // Before -import { APIClient } from '@anthropic-ai/sdk/core'; +import Anthropic from '@anthropic-ai/sdk/src'; // After -import { BaseAnthropic } from '@anthropic-ai/sdk/client'; +import Anthropic from '@anthropic-ai/sdk'; ``` + +### Headers + +The `headers` property on `APIError` objects is now an instance of the Web [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) class. It was previously just `Record`. From 7dc3e190c854623c030d20530cef2f16798dae50 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 21:01:45 +0000 Subject: [PATCH 077/105] chore(internal): improve index signature formatting --- src/resources/beta/messages/messages.ts | 1 + src/resources/messages/messages.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index 8d539550..fb1ad9ee 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -646,6 +646,7 @@ export namespace BetaTool { type: 'object'; properties?: unknown | null; + [k: string]: unknown; } } diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index f472551f..613b9d7f 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -680,6 +680,7 @@ export namespace Tool { type: 'object'; properties?: unknown | null; + [k: string]: unknown; } } From 4c4d7635bf6c6ef3fd810adefb3a290ad0f59576 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 21:08:40 +0000 Subject: [PATCH 078/105] fix(mcp): remove unused tools.ts --- packages/mcp-server/src/tools.ts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 packages/mcp-server/src/tools.ts diff --git a/packages/mcp-server/src/tools.ts b/packages/mcp-server/src/tools.ts deleted file mode 100644 index 7e516de7..00000000 --- a/packages/mcp-server/src/tools.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './tools/index'; From 3961628811d807cc967b9f0f781e55415b578f5d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 12:35:13 +0000 Subject: [PATCH 079/105] fix(client): send all configured auth headers --- src/client.ts | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/client.ts b/src/client.ts index 234a040e..27fa43d7 100644 --- a/src/client.ts +++ b/src/client.ts @@ -21,7 +21,7 @@ import * as API from './resources/index'; import { APIPromise } from './core/api-promise'; import { type Fetch } from './internal/builtin-types'; import { isRunningInBrowser } from './internal/detect-platform'; -import { HeadersLike, NullableHeaders, buildHeaders, isEmptyHeaders } from './internal/headers'; +import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers'; import { FinalRequestOptions, RequestOptions } from './internal/request-options'; import { Completion, @@ -307,32 +307,22 @@ export class BaseAnthropic { ); } - protected authHeaders(opts: FinalRequestOptions): Headers | undefined { - const apiKeyAuth = this.apiKeyAuth(opts); - const bearerAuth = this.bearerAuth(opts); - - if (apiKeyAuth != null && !isEmptyHeaders(apiKeyAuth)) { - return apiKeyAuth; - } - - if (bearerAuth != null && !isEmptyHeaders(bearerAuth)) { - return bearerAuth; - } - return undefined; + protected authHeaders(opts: FinalRequestOptions): NullableHeaders | undefined { + return buildHeaders([this.apiKeyAuth(opts), this.bearerAuth(opts)]); } - protected apiKeyAuth(opts: FinalRequestOptions): Headers | undefined { + protected apiKeyAuth(opts: FinalRequestOptions): NullableHeaders | undefined { if (this.apiKey == null) { return undefined; } - return new Headers({ 'X-Api-Key': this.apiKey }); + return buildHeaders([{ 'X-Api-Key': this.apiKey }]); } - protected bearerAuth(opts: FinalRequestOptions): Headers | undefined { + protected bearerAuth(opts: FinalRequestOptions): NullableHeaders | undefined { if (this.authToken == null) { return undefined; } - return new Headers({ Authorization: `Bearer ${this.authToken}` }); + return buildHeaders([{ Authorization: `Bearer ${this.authToken}` }]); } /** From 3124e2b5fc5d279403f409168186cb08de3b0d13 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 01:46:19 +0000 Subject: [PATCH 080/105] feat(api): manual updates --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index fded59ec..18fa0ed7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 -config_hash: 697560b514864f2b78206c694b73269b +config_hash: 12c91555f260c347a1f2199a96ba26bc From 66cf6d4d460f93c728aeee069af4f134b853b7d7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 14:23:44 +0000 Subject: [PATCH 081/105] chore(tests): improve enum examples --- tests/api-resources/beta/messages/batches.test.ts | 4 ++-- tests/api-resources/beta/messages/messages.test.ts | 4 ++-- tests/api-resources/messages/batches.test.ts | 4 ++-- tests/api-resources/messages/messages.test.ts | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/api-resources/beta/messages/batches.test.ts b/tests/api-resources/beta/messages/batches.test.ts index d7242749..3c1a1b4f 100644 --- a/tests/api-resources/beta/messages/batches.test.ts +++ b/tests/api-resources/beta/messages/batches.test.ts @@ -16,7 +16,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-7-sonnet-latest', + model: 'claude-3-7-sonnet-20250219', }, }, ], @@ -38,7 +38,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-7-sonnet-latest', + model: 'claude-3-7-sonnet-20250219', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, diff --git a/tests/api-resources/beta/messages/messages.test.ts b/tests/api-resources/beta/messages/messages.test.ts index bc4b9c32..c9abb472 100644 --- a/tests/api-resources/beta/messages/messages.test.ts +++ b/tests/api-resources/beta/messages/messages.test.ts @@ -12,7 +12,7 @@ describe('resource messages', () => { const responsePromise = client.beta.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-7-sonnet-latest', + model: 'claude-3-7-sonnet-20250219', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -27,7 +27,7 @@ describe('resource messages', () => { const response = await client.beta.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-7-sonnet-latest', + model: 'claude-3-7-sonnet-20250219', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, diff --git a/tests/api-resources/messages/batches.test.ts b/tests/api-resources/messages/batches.test.ts index ba6e9d57..a3ce329c 100644 --- a/tests/api-resources/messages/batches.test.ts +++ b/tests/api-resources/messages/batches.test.ts @@ -16,7 +16,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-7-sonnet-latest', + model: 'claude-3-7-sonnet-20250219', }, }, ], @@ -38,7 +38,7 @@ describe('resource batches', () => { params: { max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-7-sonnet-latest', + model: 'claude-3-7-sonnet-20250219', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], system: [ diff --git a/tests/api-resources/messages/messages.test.ts b/tests/api-resources/messages/messages.test.ts index 0b56715d..922963af 100644 --- a/tests/api-resources/messages/messages.test.ts +++ b/tests/api-resources/messages/messages.test.ts @@ -12,7 +12,7 @@ describe('resource messages', () => { const responsePromise = client.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-7-sonnet-latest', + model: 'claude-3-7-sonnet-20250219', }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -27,7 +27,7 @@ describe('resource messages', () => { const response = await client.messages.create({ max_tokens: 1024, messages: [{ content: 'Hello, world', role: 'user' }], - model: 'claude-3-7-sonnet-latest', + model: 'claude-3-7-sonnet-20250219', metadata: { user_id: '13803d75-b4b5-4c3e-b2a2-6f21399b021b' }, stop_sequences: ['string'], stream: false, From bbda5d3ccd5c10abbd0727c33c9d63bd366ef557 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 16:30:27 +0000 Subject: [PATCH 082/105] chore(internal): upload builds and expand CI branch coverage --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++---------- scripts/utils/upload-artifact.sh | 25 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 11 deletions(-) create mode 100755 scripts/utils/upload-artifact.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e81000b..21244059 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,20 +1,18 @@ name: CI on: push: - branches: - - main - - alpha - pull_request: - branches: - - main - - next - - alpha + branches-ignore: + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'preview-head/**' + - 'preview-base/**' + - 'preview/**' jobs: lint: name: lint runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 @@ -32,7 +30,9 @@ jobs: build: name: build runs-on: ubuntu-latest - + permissions: + contents: read + id-token: write steps: - uses: actions/checkout@v4 @@ -46,10 +46,24 @@ jobs: - name: Check build run: ./scripts/build + + - name: Get GitHub OIDC Token + if: github.repository == 'stainless-sdks/anthropic-typescript' + id: github-oidc + uses: actions/github-script@v6 + with: + script: core.setOutput('github_token', await core.getIDToken()); + + - name: Upload tarball + if: github.repository == 'stainless-sdks/anthropic-typescript' + env: + URL: https://pkg.stainless.com/s + AUTH: ${{ steps.github-oidc.outputs.github_token }} + SHA: ${{ github.sha }} + run: ./scripts/utils/upload-artifact.sh test: name: test runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh new file mode 100755 index 00000000..dff30294 --- /dev/null +++ b/scripts/utils/upload-artifact.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -exuo pipefail + +RESPONSE=$(curl -X POST "$URL" \ + -H "Authorization: Bearer $AUTH" \ + -H "Content-Type: application/json") + +SIGNED_URL=$(echo "$RESPONSE" | jq -r '.url') + +if [[ "$SIGNED_URL" == "null" ]]; then + echo -e "\033[31mFailed to get signed URL.\033[0m" + exit 1 +fi + +UPLOAD_RESPONSE=$(tar -cz dist | curl -v -X PUT \ + -H "Content-Type: application/gzip" \ + --data-binary @- "$SIGNED_URL" 2>&1) + +if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then + echo -e "\033[32mUploaded build to Stainless storage.\033[0m" + echo -e "\033[32mInstallation: npm install 'https://pkg.stainless.com/s/anthropic-typescript/$SHA'\033[0m" +else + echo -e "\033[31mFailed to upload artifact.\033[0m" + exit 1 +fi From 80d5daaff943536fbf300f5f19d7c9922294e837 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 17:04:20 +0000 Subject: [PATCH 083/105] feat(api): manual updates --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 18fa0ed7..30b9556d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 -config_hash: 12c91555f260c347a1f2199a96ba26bc +config_hash: 9d5b992847099d8fe5a5c09e66adbe5f From c6780ddc12282ae1e6796825c713bacf5a50812c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 17:59:45 +0000 Subject: [PATCH 084/105] chore(internal): improve node 18 shims --- package.json | 4 ++ scripts/build | 2 - src/internal/shims/crypto.node.d.mts | 1 - src/internal/shims/crypto.node.d.ts | 10 ---- src/internal/shims/crypto.node.js | 11 ---- src/internal/shims/crypto.node.mjs | 2 - src/internal/shims/crypto.ts | 18 ++++++ src/internal/shims/file.node.d.mts | 1 - src/internal/shims/file.node.d.ts | 20 ------- src/internal/shims/file.node.js | 11 ---- src/internal/shims/file.node.mjs | 2 - src/internal/shims/file.ts | 32 +++++++++++ src/internal/shims/getBuiltinModule.ts | 64 ++++++++++++++++++++++ src/internal/shims/nullGetBuiltinModule.ts | 1 + src/internal/to-file.ts | 4 +- src/internal/uploads.ts | 9 +-- src/internal/utils/uuid.ts | 16 ++++-- tests/uploads.test.ts | 2 +- 18 files changed, 136 insertions(+), 74 deletions(-) delete mode 100644 src/internal/shims/crypto.node.d.mts delete mode 100644 src/internal/shims/crypto.node.d.ts delete mode 100644 src/internal/shims/crypto.node.js delete mode 100644 src/internal/shims/crypto.node.mjs create mode 100644 src/internal/shims/crypto.ts delete mode 100644 src/internal/shims/file.node.d.mts delete mode 100644 src/internal/shims/file.node.d.ts delete mode 100644 src/internal/shims/file.node.js delete mode 100644 src/internal/shims/file.node.mjs create mode 100644 src/internal/shims/file.ts create mode 100644 src/internal/shims/getBuiltinModule.ts create mode 100644 src/internal/shims/nullGetBuiltinModule.ts diff --git a/package.json b/package.json index a2a186e3..fb6a52cb 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,10 @@ "resolutions": { "synckit": "0.8.8" }, + "browser": { + "./internal/shims/getBuiltinModule.mjs": "./internal/shims/nullGetBuiltinModule.mjs", + "./internal/shims/getBuiltinModule.js": "./internal/shims/nullGetBuiltinModule.js" + }, "imports": { "@anthropic-ai/sdk": ".", "@anthropic-ai/sdk/*": "./src/*" diff --git a/scripts/build b/scripts/build index 9572f803..bd9bd4eb 100755 --- a/scripts/build +++ b/scripts/build @@ -35,8 +35,6 @@ node scripts/utils/fix-index-exports.cjs cp tsconfig.dist-src.json dist/src/tsconfig.json cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts -mkdir -p dist/internal/shims -cp src/internal/shims/*.{mjs,js,d.ts,d.mts} dist/internal/shims node scripts/utils/postprocess-files.cjs diff --git a/src/internal/shims/crypto.node.d.mts b/src/internal/shims/crypto.node.d.mts deleted file mode 100644 index 5cc19630..00000000 --- a/src/internal/shims/crypto.node.d.mts +++ /dev/null @@ -1 +0,0 @@ -export { crypto } from './crypto.node.js'; diff --git a/src/internal/shims/crypto.node.d.ts b/src/internal/shims/crypto.node.d.ts deleted file mode 100644 index dc7caac8..00000000 --- a/src/internal/shims/crypto.node.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export declare const crypto: { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */ - getRandomValues(array: T): T; - /** - * Available only in secure contexts. - * - * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID) - */ - randomUUID?: () => string; -}; diff --git a/src/internal/shims/crypto.node.js b/src/internal/shims/crypto.node.js deleted file mode 100644 index 83062a3d..00000000 --- a/src/internal/shims/crypto.node.js +++ /dev/null @@ -1,11 +0,0 @@ -if (typeof require !== 'undefined') { - if (globalThis.crypto) { - exports.crypto = globalThis.crypto; - } else { - try { - // Use [require][0](...) and not require(...) so bundlers don't try to bundle the - // crypto module. - exports.crypto = [require][0]('node:crypto').webcrypto; - } catch (e) {} - } -} diff --git a/src/internal/shims/crypto.node.mjs b/src/internal/shims/crypto.node.mjs deleted file mode 100644 index 24c6f3b9..00000000 --- a/src/internal/shims/crypto.node.mjs +++ /dev/null @@ -1,2 +0,0 @@ -import * as mod from './crypto.node.js'; -export const crypto = globalThis.crypto || mod.crypto; diff --git a/src/internal/shims/crypto.ts b/src/internal/shims/crypto.ts new file mode 100644 index 00000000..905f81c6 --- /dev/null +++ b/src/internal/shims/crypto.ts @@ -0,0 +1,18 @@ +import { getBuiltinModule } from './getBuiltinModule'; + +type Crypto = { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */ + getRandomValues(array: T): T; + /** + * Available only in secure contexts. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID) + */ + randomUUID?: () => string; +}; +export let getCrypto: () => Crypto | undefined = function lazyGetCrypto() { + if (getCrypto !== lazyGetCrypto) return getCrypto(); + const crypto: Crypto = (globalThis as any).crypto || (getBuiltinModule?.('node:crypto') as any)?.webcrypto; + getCrypto = () => crypto; + return crypto; +}; diff --git a/src/internal/shims/file.node.d.mts b/src/internal/shims/file.node.d.mts deleted file mode 100644 index 38cc9ff7..00000000 --- a/src/internal/shims/file.node.d.mts +++ /dev/null @@ -1 +0,0 @@ -export { File } from './file.node.js'; diff --git a/src/internal/shims/file.node.d.ts b/src/internal/shims/file.node.d.ts deleted file mode 100644 index 9dc6b2fc..00000000 --- a/src/internal/shims/file.node.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -// The infer is to make TS show it as a nice union type, -// instead of literally `ConstructorParameters[0]` -type FallbackBlobSource = ConstructorParameters[0] extends infer T ? T : never; -/** - * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files. - */ -declare class FallbackFile extends Blob { - constructor(sources: FallbackBlobSource, fileName: string, options?: any); - /** - * The name of the `File`. - */ - readonly name: string; - /** - * The last modified date of the `File`. - */ - readonly lastModified: number; -} -export type File = InstanceType; -export const File: typeof globalThis extends { File: infer fileConstructor } ? fileConstructor -: typeof FallbackFile; diff --git a/src/internal/shims/file.node.js b/src/internal/shims/file.node.js deleted file mode 100644 index 3f8c2ed6..00000000 --- a/src/internal/shims/file.node.js +++ /dev/null @@ -1,11 +0,0 @@ -if (typeof require !== 'undefined') { - if (globalThis.File) { - exports.File = globalThis.File; - } else { - try { - // Use [require][0](...) and not require(...) so bundlers don't try to bundle the - // buffer module. - exports.File = [require][0]('node:buffer').File; - } catch (e) {} - } -} diff --git a/src/internal/shims/file.node.mjs b/src/internal/shims/file.node.mjs deleted file mode 100644 index 1f103f5d..00000000 --- a/src/internal/shims/file.node.mjs +++ /dev/null @@ -1,2 +0,0 @@ -import * as mod from './file.node.js'; -export const File = globalThis.File || mod.File; diff --git a/src/internal/shims/file.ts b/src/internal/shims/file.ts new file mode 100644 index 00000000..d5dc8209 --- /dev/null +++ b/src/internal/shims/file.ts @@ -0,0 +1,32 @@ +import { getBuiltinModule } from './getBuiltinModule'; + +export let getFile = function lazyGetFile(): FileConstructor { + if (getFile !== lazyGetFile) return getFile(); + // We can drop getBuiltinModule once we no longer support Node < 20.0.0 + const File = (globalThis as any).File ?? (getBuiltinModule?.('node:buffer') as any)?.File; + if (!File) throw new Error('`File` is not defined as a global, which is required for file uploads.'); + getFile = () => File; + return File; +}; + +type FileConstructor = + typeof globalThis extends { File: infer fileConstructor } ? fileConstructor : typeof FallbackFile; +export type File = InstanceType; + +// The infer is to make TS show it as a nice union type, +// instead of literally `ConstructorParameters[0]` +type FallbackBlobSource = ConstructorParameters[0] extends infer T ? T : never; +/** + * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files. + */ +declare class FallbackFile extends Blob { + constructor(sources: FallbackBlobSource, fileName: string, options?: any); + /** + * The name of the `File`. + */ + readonly name: string; + /** + * The last modified date of the `File`. + */ + readonly lastModified: number; +} diff --git a/src/internal/shims/getBuiltinModule.ts b/src/internal/shims/getBuiltinModule.ts new file mode 100644 index 00000000..a202f209 --- /dev/null +++ b/src/internal/shims/getBuiltinModule.ts @@ -0,0 +1,64 @@ +/** + * Load a Node built-in module. ID may or may not be prefixed by `node:` and + * will be normalized. If we used static imports then our bundle size would be bloated by + * injected polyfills, and if we used dynamic require then in addition to bundlers logging warnings, + * our code would not work when bundled to ESM and run in Node 18. + * @param {string} id ID of the built-in to be loaded. + * @returns {object|undefined} exports of the built-in. Undefined if the built-in + * does not exist. + */ +export let getBuiltinModule: null | ((id: string) => object | undefined) = function getBuiltinModuleLazy( + id: string, +): object | undefined { + try { + if (getBuiltinModule !== getBuiltinModuleLazy) return getBuiltinModule!(id); + if ((process as any).getBuiltinModule) { + getBuiltinModule = (process as any).getBuiltinModule; + } else { + /* Fallback implementation for Node 18 */ + function createFallbackGetBuiltinModule(BuiltinModule: any) { + return function getBuiltinModule(id: string): object | undefined { + id = BuiltinModule.normalizeRequirableId(String(id)); + if (!BuiltinModule.canBeRequiredByUsers(id)) { + return; + } + const mod = BuiltinModule.map.get(id); + mod.compileForPublicLoader(); + return mod.exports; + }; + } + const magicKey = Math.random() + ''; + let module: { BuiltinModule: any } | undefined; + try { + const kClone = Object.getOwnPropertySymbols(Blob.prototype).find( + (e) => e.description?.includes('clone'), + )!; + Object.defineProperty(Object.prototype, magicKey, { + get() { + module = this; + throw null; + }, + configurable: true, + }); + structuredClone( + new (class extends Blob { + [kClone]() { + return { + deserializeInfo: 'internal/bootstrap/realm:' + magicKey, + }; + } + })([]), + ); + } catch {} + delete (Object.prototype as any)[magicKey]; + if (module) { + getBuiltinModule = createFallbackGetBuiltinModule(module.BuiltinModule); + } else { + getBuiltinModule = () => undefined; + } + } + return getBuiltinModule!(id); + } catch { + return undefined; + } +}; diff --git a/src/internal/shims/nullGetBuiltinModule.ts b/src/internal/shims/nullGetBuiltinModule.ts new file mode 100644 index 00000000..8bd2280d --- /dev/null +++ b/src/internal/shims/nullGetBuiltinModule.ts @@ -0,0 +1 @@ +export const getBuiltinModule = null; diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts index 69b76d3a..e92ac694 100644 --- a/src/internal/to-file.ts +++ b/src/internal/to-file.ts @@ -1,4 +1,4 @@ -import { File } from './shims/file.node.js'; +import { type File, getFile } from './shims/file'; import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads'; import type { FilePropertyBag } from './builtin-types'; @@ -90,7 +90,7 @@ export async function toFile( // If we've been given a `File` we don't need to do anything if (isFileLike(value)) { - if (File && value instanceof File) { + if (value instanceof getFile()) { return value; } return makeFile([await value.arrayBuffer()], value.name); diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index 15e579e4..8bec6154 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -1,7 +1,7 @@ import { type RequestOptions } from './request-options'; import type { FilePropertyBag, Fetch } from './builtin-types'; import type { BaseAnthropic } from '../client'; -import { File } from './shims/file.node.js'; +import { type File, getFile } from './shims/file'; import { ReadableStreamFrom } from './shims'; export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; @@ -32,10 +32,7 @@ export function makeFile( fileName: string | undefined, options?: FilePropertyBag, ): File { - if (typeof File === 'undefined') { - throw new Error('`File` is not defined as a global which is required for file uploads'); - } - + const File = getFile(); return new File(fileBits as any, fileName ?? 'unknown_file', options); } @@ -129,7 +126,7 @@ export const createForm = async >( // We check for Blob not File because Bun.File doesn't inherit from File, // but they both inherit from Blob and have a `name` property at runtime. const isNamedBlob = (value: object) => - (File && value instanceof File) || (value instanceof Blob && 'name' in value); + value instanceof getFile() || (value instanceof Blob && 'name' in value); const isUploadable = (value: unknown) => typeof value === 'object' && diff --git a/src/internal/utils/uuid.ts b/src/internal/utils/uuid.ts index 1349c42c..5a262c6d 100644 --- a/src/internal/utils/uuid.ts +++ b/src/internal/utils/uuid.ts @@ -1,13 +1,19 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { crypto } from '../shims/crypto.node.js'; +import { getCrypto } from '../shims/crypto'; /** * https://stackoverflow.com/a/2117523 */ -export function uuid4() { - if (crypto.randomUUID) return crypto.randomUUID(); +export let uuid4 = function () { + const crypto = getCrypto(); + if (crypto?.randomUUID) { + uuid4 = crypto.randomUUID.bind(crypto); + return crypto.randomUUID(); + } + const u8 = new Uint8Array(1); + const randomByte = crypto ? () => crypto.getRandomValues(u8)[0]! : () => (Math.random() * 0xff) & 0xff; return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) => - (+c ^ (crypto.getRandomValues(new Uint8Array(1))[0]! & (15 >> (+c / 4)))).toString(16), + (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16), ); -} +}; diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 5246aac7..1da86a9b 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -101,7 +101,7 @@ describe('missing File error message', () => { await expect( uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })), ).rejects.toMatchInlineSnapshot( - `[Error: \`File\` is not defined as a global which is required for file uploads]`, + `[Error: \`File\` is not defined as a global, which is required for file uploads.]`, ); }); }); From 464431d1e57954812b10baa04d12795f4cba6b76 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 21:05:44 +0000 Subject: [PATCH 085/105] chore(internal): reduce CI branch coverage --- .github/workflows/ci.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21244059..7e606c32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,13 +1,12 @@ name: CI on: push: - branches-ignore: - - 'generated' - - 'codegen/**' - - 'integrated/**' - - 'preview-head/**' - - 'preview-base/**' - - 'preview/**' + branches: + - main + pull_request: + branches: + - main + - next jobs: lint: From 1071b342d56a81d375f2b373c649843f800a3ad5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 17:54:48 +0000 Subject: [PATCH 086/105] fix(internal): fix file uploads in node 18 jest --- src/internal/shims/getBuiltinModule.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/internal/shims/getBuiltinModule.ts b/src/internal/shims/getBuiltinModule.ts index a202f209..64daa2ce 100644 --- a/src/internal/shims/getBuiltinModule.ts +++ b/src/internal/shims/getBuiltinModule.ts @@ -29,11 +29,13 @@ export let getBuiltinModule: null | ((id: string) => object | undefined) = funct } const magicKey = Math.random() + ''; let module: { BuiltinModule: any } | undefined; + let ObjectPrototype: {} = Blob; + for (let next; (next = Reflect.getPrototypeOf(ObjectPrototype)); ObjectPrototype = next); try { const kClone = Object.getOwnPropertySymbols(Blob.prototype).find( (e) => e.description?.includes('clone'), )!; - Object.defineProperty(Object.prototype, magicKey, { + Object.defineProperty(ObjectPrototype, magicKey, { get() { module = this; throw null; @@ -50,7 +52,7 @@ export let getBuiltinModule: null | ((id: string) => object | undefined) = funct })([]), ); } catch {} - delete (Object.prototype as any)[magicKey]; + delete (ObjectPrototype as any)[magicKey]; if (module) { getBuiltinModule = createFallbackGetBuiltinModule(module.BuiltinModule); } else { From 595678f2b8588f20d7ca3d9219878a4d72c56c7d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 14:30:42 +0000 Subject: [PATCH 087/105] chore(client): minor internal fixes --- src/client.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client.ts b/src/client.ts index 27fa43d7..28afa6d4 100644 --- a/src/client.ts +++ b/src/client.ts @@ -738,17 +738,17 @@ export class BaseAnthropic { } buildRequest( - options: FinalRequestOptions, + inputOptions: FinalRequestOptions, { retryCount = 0 }: { retryCount?: number } = {}, ): { req: FinalizedRequestInit; url: string; timeout: number } { - options = { ...options }; + const options = { ...inputOptions }; const { method, path, query } = options; const url = this.buildURL(path!, query as Record); if ('timeout' in options) validatePositiveInteger('timeout', options.timeout); options.timeout = options.timeout ?? this.timeout; const { bodyHeaders, body } = this.buildBody({ options }); - const reqHeaders = this.buildHeaders({ options, method, bodyHeaders, retryCount }); + const reqHeaders = this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount }); const req: FinalizedRequestInit = { method, From 975795a61b3067396035621638feb631a7e44dbc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 17:01:06 +0000 Subject: [PATCH 088/105] chore(perf): faster base64 decoding --- src/internal/utils/base64.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/internal/utils/base64.ts b/src/internal/utils/base64.ts index f7288658..056c5ce8 100644 --- a/src/internal/utils/base64.ts +++ b/src/internal/utils/base64.ts @@ -22,15 +22,17 @@ export const toBase64 = (data: string | Uint8Array | null | undefined): string = export const fromBase64 = (str: string): Uint8Array => { if (typeof (globalThis as any).Buffer !== 'undefined') { - return new Uint8Array((globalThis as any).Buffer.from(str, 'base64')); + const buf = (globalThis as any).Buffer.from(str, 'base64'); + return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength); } if (typeof atob !== 'undefined') { - return new Uint8Array( - atob(str) - .split('') - .map((c) => c.charCodeAt(0)), - ); + const bstr = atob(str); + const buf = new Uint8Array(bstr.length); + for (let i = 0; i < bstr.length; i++) { + buf[i] = bstr.charCodeAt(i); + } + return buf; } throw new AnthropicError('Cannot decode base64 string; Expected `Buffer` or `atob` to be defined'); From 385f900ae36892a8c65e2568faf46ce7bb011206 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 20:13:59 +0000 Subject: [PATCH 089/105] chore(ci): add timeout thresholds for CI jobs --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e606c32..1b2d9d17 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,7 @@ on: jobs: lint: + timeout-minutes: 10 name: lint runs-on: ubuntu-latest steps: @@ -27,6 +28,7 @@ jobs: run: ./scripts/lint build: + timeout-minutes: 5 name: build runs-on: ubuntu-latest permissions: @@ -61,6 +63,7 @@ jobs: SHA: ${{ github.sha }} run: ./scripts/utils/upload-artifact.sh test: + timeout-minutes: 10 name: test runs-on: ubuntu-latest steps: From 7176150915334f06ac2ee3ed854ddf6752c1e113 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 17:56:29 +0000 Subject: [PATCH 090/105] chore(ci): run on more branches and use depot runners --- .github/workflows/ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b2d9d17..7c82227b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,18 @@ name: CI on: push: - branches: - - main - pull_request: - branches: - - main - - next + branches-ignore: + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'stl-preview-head/**' + - 'stl-preview-base/**' jobs: lint: timeout-minutes: 10 name: lint - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 @@ -30,7 +30,7 @@ jobs: build: timeout-minutes: 5 name: build - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 permissions: contents: read id-token: write @@ -65,7 +65,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 From 1f058806ccd549aa99194fc8b808ab21c7655bcf Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 19:58:43 +0000 Subject: [PATCH 091/105] chore(ci): only use depot for staging repos --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c82227b..123a3f11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/anthropic-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 @@ -30,7 +30,7 @@ jobs: build: timeout-minutes: 5 name: build - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/anthropic-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} permissions: contents: read id-token: write @@ -65,7 +65,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/anthropic-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 From b3dee573e69afe41d1c588e732780b5d370980dd Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 22:18:39 +0000 Subject: [PATCH 092/105] chore(internal): refactor utils --- src/client.ts | 10 +++--- src/core/streaming.ts | 8 ++--- src/internal/decoders/line.ts | 67 ++++++----------------------------- src/internal/headers.ts | 5 +-- src/internal/utils/base64.ts | 9 ++--- src/internal/utils/bytes.ts | 32 +++++++++++++++++ 6 files changed, 59 insertions(+), 72 deletions(-) create mode 100644 src/internal/utils/bytes.ts diff --git a/src/client.ts b/src/client.ts index 28afa6d4..20cd50f8 100644 --- a/src/client.ts +++ b/src/client.ts @@ -652,12 +652,12 @@ export class BaseAnthropic { fetchOptions.method = method.toUpperCase(); } - return ( + try { // use undefined this binding; fetch errors if bound to something else in browser/cloudflare - this.fetch.call(undefined, url, fetchOptions).finally(() => { - clearTimeout(timeout); - }) - ); + return await this.fetch.call(undefined, url, fetchOptions); + } finally { + clearTimeout(timeout); + } } private shouldRetry(response: Response): boolean { diff --git a/src/core/streaming.ts b/src/core/streaming.ts index daf54458..ae863756 100644 --- a/src/core/streaming.ts +++ b/src/core/streaming.ts @@ -5,6 +5,7 @@ import { findDoubleNewlineIndex, LineDecoder } from '../internal/decoders/line'; import { ReadableStreamToAsyncIterable } from '../internal/shims'; import { isAbortError } from '../internal/errors'; import { safeJSON } from '../internal/utils/values'; +import { encodeUTF8 } from '../internal/utils/bytes'; import { APIError } from './error'; @@ -173,9 +174,6 @@ export class Stream implements AsyncIterable { toReadableStream(): ReadableStream { const self = this; let iter: AsyncIterator; - const encoder: { - encode(str: string): Uint8Array; - } = new (globalThis as any).TextEncoder(); return makeReadableStream({ async start() { @@ -186,7 +184,7 @@ export class Stream implements AsyncIterable { const { value, done } = await iter.next(); if (done) return ctrl.close(); - const bytes = encoder.encode(JSON.stringify(value) + '\n'); + const bytes = encodeUTF8(JSON.stringify(value) + '\n'); ctrl.enqueue(bytes); } catch (err) { @@ -248,7 +246,7 @@ async function* iterSSEChunks(iterator: AsyncIterableIterator): AsyncGene const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) - : typeof chunk === 'string' ? new (globalThis as any).TextEncoder().encode(chunk) + : typeof chunk === 'string' ? encodeUTF8(chunk) : chunk; let newData = new Uint8Array(data.length + binaryChunk.length); diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts index 42559e22..b3bfa97c 100644 --- a/src/internal/decoders/line.ts +++ b/src/internal/decoders/line.ts @@ -1,4 +1,4 @@ -import { AnthropicError } from '../../core/error'; +import { concatBytes, decodeUTF8, encodeUTF8 } from '../utils/bytes'; export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; @@ -13,16 +13,11 @@ export class LineDecoder { static NEWLINE_CHARS = new Set(['\n', '\r']); static NEWLINE_REGEXP = /\r\n|[\n\r]/g; - buffer: Uint8Array; + #buffer: Uint8Array; #carriageReturnIndex: number | null; - textDecoder: - | undefined - | { - decode(buffer: Uint8Array | ArrayBuffer): string; - }; constructor() { - this.buffer = new Uint8Array(); + this.#buffer = new Uint8Array(); this.#carriageReturnIndex = null; } @@ -33,17 +28,14 @@ export class LineDecoder { const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) - : typeof chunk === 'string' ? new TextEncoder().encode(chunk) + : typeof chunk === 'string' ? encodeUTF8(chunk) : chunk; - let newData = new Uint8Array(this.buffer.length + binaryChunk.length); - newData.set(this.buffer); - newData.set(binaryChunk, this.buffer.length); - this.buffer = newData; + this.#buffer = concatBytes([this.#buffer, binaryChunk]); const lines: string[] = []; let patternIndex; - while ((patternIndex = findNewlineIndex(this.buffer, this.#carriageReturnIndex)) != null) { + while ((patternIndex = findNewlineIndex(this.#buffer, this.#carriageReturnIndex)) != null) { if (patternIndex.carriage && this.#carriageReturnIndex == null) { // skip until we either get a corresponding `\n`, a new `\r` or nothing this.#carriageReturnIndex = patternIndex.index; @@ -55,8 +47,8 @@ export class LineDecoder { this.#carriageReturnIndex != null && (patternIndex.index !== this.#carriageReturnIndex + 1 || patternIndex.carriage) ) { - lines.push(this.decodeText(this.buffer.slice(0, this.#carriageReturnIndex - 1))); - this.buffer = this.buffer.slice(this.#carriageReturnIndex); + lines.push(decodeUTF8(this.#buffer.subarray(0, this.#carriageReturnIndex - 1))); + this.#buffer = this.#buffer.subarray(this.#carriageReturnIndex); this.#carriageReturnIndex = null; continue; } @@ -64,55 +56,18 @@ export class LineDecoder { const endIndex = this.#carriageReturnIndex !== null ? patternIndex.preceding - 1 : patternIndex.preceding; - const line = this.decodeText(this.buffer.slice(0, endIndex)); + const line = decodeUTF8(this.#buffer.subarray(0, endIndex)); lines.push(line); - this.buffer = this.buffer.slice(patternIndex.index); + this.#buffer = this.#buffer.subarray(patternIndex.index); this.#carriageReturnIndex = null; } return lines; } - decodeText(bytes: Bytes): string { - if (bytes == null) return ''; - if (typeof bytes === 'string') return bytes; - - // Node: - if (typeof (globalThis as any).Buffer !== 'undefined') { - if (bytes instanceof (globalThis as any).Buffer) { - return bytes.toString(); - } - if (bytes instanceof Uint8Array) { - return (globalThis as any).Buffer.from(bytes).toString(); - } - - throw new AnthropicError( - `Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.`, - ); - } - - // Browser - if (typeof (globalThis as any).TextDecoder !== 'undefined') { - if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) { - this.textDecoder ??= new (globalThis as any).TextDecoder('utf8'); - return this.textDecoder!.decode(bytes); - } - - throw new AnthropicError( - `Unexpected: received non-Uint8Array/ArrayBuffer (${ - (bytes as any).constructor.name - }) in a web platform. Please report this error.`, - ); - } - - throw new AnthropicError( - `Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.`, - ); - } - flush(): string[] { - if (!this.buffer.length) { + if (!this.#buffer.length) { return []; } return this.decode('\n'); diff --git a/src/internal/headers.ts b/src/internal/headers.ts index a110a120..8659ddea 100644 --- a/src/internal/headers.ts +++ b/src/internal/headers.ts @@ -3,7 +3,7 @@ type HeaderValue = string | undefined | null; export type HeadersLike = | Headers - | readonly [string, HeaderValue][] + | readonly HeaderValue[][] | Record | undefined | null @@ -40,7 +40,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator; + let iter: Iterable; if (headers instanceof Headers) { iter = headers.entries(); } else if (isArray(headers)) { @@ -51,6 +51,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator { if (!data) return ''; - if (typeof data === 'string') { - data = new (globalThis as any).TextEncoder().encode(data); - } - if (typeof (globalThis as any).Buffer !== 'undefined') { return (globalThis as any).Buffer.from(data).toString('base64'); } + if (typeof data === 'string') { + data = encodeUTF8(data); + } + if (typeof btoa !== 'undefined') { return btoa(String.fromCharCode.apply(null, data as any)); } diff --git a/src/internal/utils/bytes.ts b/src/internal/utils/bytes.ts new file mode 100644 index 00000000..8da627ab --- /dev/null +++ b/src/internal/utils/bytes.ts @@ -0,0 +1,32 @@ +export function concatBytes(buffers: Uint8Array[]): Uint8Array { + let length = 0; + for (const buffer of buffers) { + length += buffer.length; + } + const output = new Uint8Array(length); + let index = 0; + for (const buffer of buffers) { + output.set(buffer, index); + index += buffer.length; + } + + return output; +} + +let encodeUTF8_: (str: string) => Uint8Array; +export function encodeUTF8(str: string) { + let encoder; + return ( + encodeUTF8_ ?? + ((encoder = new (globalThis as any).TextEncoder()), (encodeUTF8_ = encoder.encode.bind(encoder))) + )(str); +} + +let decodeUTF8_: (bytes: Uint8Array) => string; +export function decodeUTF8(bytes: Uint8Array) { + let decoder; + return ( + decodeUTF8_ ?? + ((decoder = new (globalThis as any).TextDecoder()), (decodeUTF8_ = decoder.decode.bind(decoder))) + )(bytes); +} From 6f8fce9cf7a921b0fc7a5cf0aada0ce130667082 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 30 Apr 2025 15:45:30 +0000 Subject: [PATCH 093/105] docs(readme): fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 62066377..29657aed 100644 --- a/README.md +++ b/README.md @@ -214,7 +214,7 @@ async function main() { main(); ``` -Error codes are as followed: +Error codes are as follows: | Status Code | Error Type | | ----------- | -------------------------- | From 9ce30ba225a37feb50c0089164bbec830ab18a1c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 14:40:20 +0000 Subject: [PATCH 094/105] chore(internal): fix format script --- .devcontainer/devcontainer.json | 4 +- MIGRATION.md | 175 ++++++++++++++++++-------------- bin/cli | 53 ++++++++++ bin/migration-config.json | 7 ++ package.json | 5 +- scripts/build | 6 +- scripts/format | 4 + tsconfig.build.json | 2 +- tsconfig.json | 2 +- 9 files changed, 173 insertions(+), 85 deletions(-) create mode 100755 bin/cli create mode 100644 bin/migration-config.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 763462fa..43fd5a73 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -9,9 +9,7 @@ "postCreateCommand": "yarn install", "customizations": { "vscode": { - "extensions": [ - "esbenp.prettier-vscode" - ] + "extensions": ["esbenp.prettier-vscode"] } } } diff --git a/MIGRATION.md b/MIGRATION.md index 573125c8..a3f2f7e2 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -4,95 +4,40 @@ This guide outlines the changes and steps needed to migrate your codebase to the The main changes are that the SDK now relies on the [builtin Web fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) instead of `node-fetch` and has zero dependencies. +## Migration CLI + +Most programs will only need minimal changes, but to assist there is a migration tool that will automatically update your code for the new version. +To use it, upgrade the `@anthropic-ai/sdk` package, then run `./node_modules/.bin/anthropic-ai-sdk migrate ./your/src/folders` to update your code. +To preview the changes without writing them to disk, run the tool with `--dry`. + ## Environment requirements The minimum supported runtime and tooling versions are now: -- Node.js 18.x last LTS (Required for built-in fetch support) +- Node.js 18.x last LTS (Required for builtin fetch support) - This was previously documented as the minimum supported Node.js version but Node.js 16.x mostly worked at runtime; now it will not. - TypeScript 4.9 - Jest 28 -## Minimum types requirements - -### DOM - -`tsconfig.json` - -```jsonc -{ - "target": "ES2015", // note: we recommend ES2020 or higher - "lib": ["DOM", "DOM.Iterable", "ES2018"] -} -``` - -### Node.js - -`tsconfig.json` - -```jsonc -{ - "target": "ES2015" // note: we recommend ES2020 or higher -} -``` - -`package.json` - -```json -{ - "devDependencies": { - "@types/node": ">= 18.18.7" - } -} -``` - -### Cloudflare Workers - -`tsconfig.json` - -```jsonc -{ - "target": "ES2015", // note: we recommend ES2020 or higher - "lib": ["ES2020"], // <- needed by @cloudflare/workers-types - "types": ["@cloudflare/workers-types"] -} -``` - -`package.json` - -```json -{ - "devDependencies": { - "@cloudflare/workers-types": ">= 0.20221111.0" - } -} -``` - -### Bun +## Breaking changes -`tsconfig.json` +### Web types for `withResponse`, `asResponse`, and `APIError.headers` -```jsonc -{ - "target": "ES2015" // note: we recommend ES2020 or higher -} -``` - -`package.json` +Because we now use the builtin Web fetch API on all platforms, if you wrote code that used `withResponse` or `asResponse` and then accessed `node-fetch`-specific properties on the result, you will need to switch to standardized alternatives. +For example, `body` is now a [Web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) rather than a [node `Readable`](https://nodejs.org/api/stream.html#readable-streams). -```json -{ - "devDependencies": { - "@types/bun": ">= 1.2.0" - } -} +```ts +// Before: +const res = await client.example.retrieve('string/with/slash').asResponse(); +res.body.pipe(process.stdout); + +// After: +import { Readable } from 'node:stream'; +const res = await client.example.retrieve('string/with/slash').asResponse(); +Readable.fromWeb(res.body).pipe(process.stdout); ``` -### Deno - -No config needed! - -## Breaking changes +Additionally, the `headers` property on `APIError` objects is now an instance of the Web [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) class. It was previously defined as `Record`. ### URI encoded path parameters @@ -322,6 +267,80 @@ import Anthropic from '@anthropic-ai/sdk/src'; import Anthropic from '@anthropic-ai/sdk'; ``` -### Headers +## TypeScript troubleshooting + +When referencing the library after updating, you may encounter new type errors related to JS features like private properties or fetch classes like Request, Response, and Headers. +To resolve these issues, configure your tsconfig.json and install the appropriate `@types` packages for your runtime environment using the guidelines below: + +### Browsers + +`tsconfig.json` + +```jsonc +{ + "target": "ES2018", // note: we recommend ES2020 or higher + "lib": ["DOM", "DOM.Iterable", "ES2018"] +} +``` + +### Node.js -The `headers` property on `APIError` objects is now an instance of the Web [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) class. It was previously just `Record`. +`tsconfig.json` + +```jsonc +{ + "target": "ES2018" // note: we recommend ES2020 or higher +} +``` + +`package.json` + +```json +{ + "devDependencies": { + "@types/node": ">= 18.18.7" + } +} +``` + +### Cloudflare Workers + +`tsconfig.json` + +```jsonc +{ + "target": "ES2018", // note: we recommend ES2020 or higher + "lib": ["ES2020"], // <- needed by @cloudflare/workers-types + "types": ["@cloudflare/workers-types"] +} +``` + +`package.json` + +```json +{ + "devDependencies": { + "@cloudflare/workers-types": ">= 0.20221111.0" + } +} +``` + +### Bun + +`tsconfig.json` + +```jsonc +{ + "target": "ES2018" // note: we recommend ES2020 or higher +} +``` + +`package.json` + +```json +{ + "devDependencies": { + "@types/bun": ">= 1.2.0" + } +} +``` diff --git a/bin/cli b/bin/cli new file mode 100755 index 00000000..a97538fe --- /dev/null +++ b/bin/cli @@ -0,0 +1,53 @@ +#!/usr/bin/env node + +const { spawnSync } = require('child_process'); + +const commands = { + migrate: { + description: + 'Run migrations to update your code using @anthropic-ai/sdk@0.39 to be compatible with @anthropic-ai/sdk@0.40', + fn: () => { + const result = spawnSync( + 'npx', + [ + '-y', + 'https://github.com/stainless-api/migrate-ts/releases/download/0.0.2/stainless-api-migrate-0.0.2-6.tgz', + '--migrationConfig', + require.resolve('./migration-config.json'), + ...process.argv.slice(3), + ], + { stdio: 'inherit' }, + ); + if (result.status !== 0) { + process.exit(result.status); + } + }, + }, +}; + +function exitWithHelp() { + console.log(`Usage: anthropic-ai-sdk `); + console.log(); + console.log('Subcommands:'); + + for (const [name, info] of Object.entries(commands)) { + console.log(` ${name} ${info.description}`); + } + + console.log(); + process.exit(1); +} + +if (process.argv.length < 3) { + exitWithHelp(); +} + +const commandName = process.argv[2]; + +const command = commands[commandName]; +if (!command) { + console.log(`Unknown subcommand ${commandName}.`); + exitWithHelp(); +} + +command.fn(); diff --git a/bin/migration-config.json b/bin/migration-config.json new file mode 100644 index 00000000..4f18169e --- /dev/null +++ b/bin/migration-config.json @@ -0,0 +1,7 @@ +{ + "pkg": "@anthropic-ai/sdk", + "githubRepo": "https://github.com/stainless-sdks/anthropic-typescript", + "clientClass": "Anthropic", + "baseClientClass": "BaseAnthropic", + "methods": [] +} diff --git a/package.json b/package.json index fb6a52cb..642918c1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "test": "./scripts/test", "build": "./scripts/build-all", "prepublishOnly": "echo 'to publish, run yarn build && (cd dist; yarn publish)' && exit 1", - "format": "prettier --write --cache --cache-strategy metadata . !dist", + "format": "./scripts/format", "prepare": "if ./scripts/utils/check-is-in-git-install.sh; then ./scripts/build && ./scripts/utils/git-swap.sh; fi", "tsn": "ts-node -r tsconfig-paths/register", "lint": "./scripts/lint", @@ -57,6 +57,9 @@ "@anthropic-ai/sdk": ".", "@anthropic-ai/sdk/*": "./src/*" }, + "bin": { + "anthropic-ai-sdk": "bin/cli" + }, "exports": { ".": { "import": "./dist/index.mjs", diff --git a/scripts/build b/scripts/build index bd9bd4eb..497a2391 100755 --- a/scripts/build +++ b/scripts/build @@ -19,9 +19,13 @@ for file in LICENSE CHANGELOG.md; do if [ -e "${file}" ]; then cp "${file}" dist; fi done if [ -e "bin/cli" ]; then - mkdir dist/bin + mkdir -p dist/bin cp -p "bin/cli" dist/bin/; fi +if [ -e "bin/migration-config.json" ]; then + mkdir -p dist/bin + cp -p "bin/migration-config.json" dist/bin/; +fi # this converts the export map paths for the dist directory # and does a few other minor things node scripts/utils/make-dist-package-json.cjs > dist/package.json diff --git a/scripts/format b/scripts/format index 903b1ef8..7a756401 100755 --- a/scripts/format +++ b/scripts/format @@ -6,3 +6,7 @@ cd "$(dirname "$0")/.." echo "==> Running eslint --fix" ./node_modules/.bin/eslint --fix . + +echo "==> Running prettier --write" +# format things eslint didn't +./node_modules/.bin/prettier --write --cache --cache-strategy metadata . '!**/dist' '!**/*.ts' '!**/*.mts' '!**/*.cts' '!**/*.js' '!**/*.mjs' '!**/*.cjs' diff --git a/tsconfig.build.json b/tsconfig.build.json index 0ad4e576..779a5cdb 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -6,7 +6,7 @@ "rootDir": "./dist/src", "paths": { "@anthropic-ai/sdk/*": ["dist/src/*"], - "@anthropic-ai/sdk": ["dist/src/index.ts"], + "@anthropic-ai/sdk": ["dist/src/index.ts"] }, "noEmit": false, "declaration": true, diff --git a/tsconfig.json b/tsconfig.json index c830a9da..9348bc95 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,7 +31,7 @@ "noUncheckedIndexedAccess": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, - "isolatedModules": false, + "isolatedModules": false, "skipLibCheck": true } From 74187dbc73585c68aa6ae0f05bcba6053d257434 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 18:37:48 +0000 Subject: [PATCH 095/105] chore(internal): share typescript helpers --- package.json | 10 ++-- tsc-multi.json | 4 +- yarn.lock | 128 ++++++++++++++++++++++++------------------------- 3 files changed, 71 insertions(+), 71 deletions(-) diff --git a/package.json b/package.json index 642918c1..99b295c0 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,9 @@ "@swc/jest": "^0.2.29", "@types/jest": "^29.4.0", "@types/node": "^20.17.6", - "typescript-eslint": "^8.24.0", - "@typescript-eslint/eslint-plugin": "^8.24.0", - "@typescript-eslint/parser": "^8.24.0", + "typescript-eslint": "8.31.1", + "@typescript-eslint/eslint-plugin": "8.31.1", + "@typescript-eslint/parser": "8.31.1", "eslint": "^9.20.1", "eslint-plugin-prettier": "^5.2.3", "eslint-plugin-unused-imports": "^4.1.4", @@ -42,9 +42,9 @@ "publint": "^0.2.12", "ts-jest": "^29.1.0", "ts-node": "^10.5.0", - "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz", "tsconfig-paths": "^4.0.0", - "typescript": "^4.8.2" + "typescript": "5.8.3" }, "resolutions": { "synckit": "0.8.8" diff --git a/tsc-multi.json b/tsc-multi.json index 4facad5a..170bac7a 100644 --- a/tsc-multi.json +++ b/tsc-multi.json @@ -1,7 +1,7 @@ { "targets": [ - { "extname": ".js", "module": "commonjs" }, - { "extname": ".mjs", "module": "esnext" } + { "extname": ".js", "module": "commonjs", "shareHelpers": "internal/tslib.js" }, + { "extname": ".mjs", "module": "esnext", "shareHelpers": "internal/tslib.mjs" } ], "projects": ["tsconfig.build.json"] } diff --git a/yarn.lock b/yarn.lock index b40f3dc3..43da555d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -961,62 +961,62 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@8.24.0", "@typescript-eslint/eslint-plugin@^8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz#574a95d67660a1e4544ae131d672867a5b40abb3" - integrity sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ== +"@typescript-eslint/eslint-plugin@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.1.tgz#62f1befe59647524994e89de4516d8dcba7a850a" + integrity sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.24.0" - "@typescript-eslint/type-utils" "8.24.0" - "@typescript-eslint/utils" "8.24.0" - "@typescript-eslint/visitor-keys" "8.24.0" + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/type-utils" "8.31.1" + "@typescript-eslint/utils" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" ts-api-utils "^2.0.1" -"@typescript-eslint/parser@8.24.0", "@typescript-eslint/parser@^8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.24.0.tgz#bba837f9ee125b78f459ad947ff9b61be8139085" - integrity sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA== +"@typescript-eslint/parser@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.31.1.tgz#e9b0ccf30d37dde724ee4d15f4dbc195995cce1b" + integrity sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q== dependencies: - "@typescript-eslint/scope-manager" "8.24.0" - "@typescript-eslint/types" "8.24.0" - "@typescript-eslint/typescript-estree" "8.24.0" - "@typescript-eslint/visitor-keys" "8.24.0" + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/typescript-estree" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz#2e34b3eb2ce768f2ffb109474174ced5417002b1" - integrity sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw== +"@typescript-eslint/scope-manager@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz#1eb52e76878f545e4add142e0d8e3e97e7aa443b" + integrity sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw== dependencies: - "@typescript-eslint/types" "8.24.0" - "@typescript-eslint/visitor-keys" "8.24.0" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" -"@typescript-eslint/type-utils@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz#6ee3ec4db06f9e5e7b01ca6c2b5dd5843a9fd1e8" - integrity sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA== +"@typescript-eslint/type-utils@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.31.1.tgz#be0f438fb24b03568e282a0aed85f776409f970c" + integrity sha512-fNaT/m9n0+dpSp8G/iOQ05GoHYXbxw81x+yvr7TArTuZuCA6VVKbqWYVZrV5dVagpDTtj/O8k5HBEE/p/HM5LA== dependencies: - "@typescript-eslint/typescript-estree" "8.24.0" - "@typescript-eslint/utils" "8.24.0" + "@typescript-eslint/typescript-estree" "8.31.1" + "@typescript-eslint/utils" "8.31.1" debug "^4.3.4" ts-api-utils "^2.0.1" -"@typescript-eslint/types@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.24.0.tgz#694e7fb18d70506c317b816de9521300b0f72c8e" - integrity sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw== +"@typescript-eslint/types@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.31.1.tgz#478ed6f7e8aee1be7b63a60212b6bffe1423b5d4" + integrity sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ== -"@typescript-eslint/typescript-estree@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz#0487349be174097bb329a58273100a9629e03c6c" - integrity sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ== +"@typescript-eslint/typescript-estree@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz#37792fe7ef4d3021c7580067c8f1ae66daabacdf" + integrity sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag== dependencies: - "@typescript-eslint/types" "8.24.0" - "@typescript-eslint/visitor-keys" "8.24.0" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/visitor-keys" "8.31.1" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -1024,22 +1024,22 @@ semver "^7.6.0" ts-api-utils "^2.0.1" -"@typescript-eslint/utils@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.24.0.tgz#21cb1195ae79230af825bfeed59574f5cb70a749" - integrity sha512-07rLuUBElvvEb1ICnafYWr4hk8/U7X9RDCOqd9JcAMtjh/9oRmcfN4yGzbPVirgMR0+HLVHehmu19CWeh7fsmQ== +"@typescript-eslint/utils@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.31.1.tgz#5628ea0393598a0b2f143d0fc6d019f0dee9dd14" + integrity sha512-2DSI4SNfF5T4oRveQ4nUrSjUqjMND0nLq9rEkz0gfGr3tg0S5KB6DhwR+WZPCjzkZl3cH+4x2ce3EsL50FubjQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "8.24.0" - "@typescript-eslint/types" "8.24.0" - "@typescript-eslint/typescript-estree" "8.24.0" + "@typescript-eslint/scope-manager" "8.31.1" + "@typescript-eslint/types" "8.31.1" + "@typescript-eslint/typescript-estree" "8.31.1" -"@typescript-eslint/visitor-keys@8.24.0": - version "8.24.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz#36ecf0b9b1d819ad88a3bd4157ab7d594cb797c9" - integrity sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg== +"@typescript-eslint/visitor-keys@8.31.1": + version "8.31.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz#6742b0e3ba1e0c1e35bdaf78c03e759eb8dd8e75" + integrity sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw== dependencies: - "@typescript-eslint/types" "8.24.0" + "@typescript-eslint/types" "8.31.1" eslint-visitor-keys "^4.2.0" acorn-jsx@^5.3.2: @@ -3284,9 +3284,9 @@ ts-node@^10.5.0: v8-compile-cache-lib "^3.0.0" yn "3.1.1" -"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz": - version "1.1.3" - resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz#8fc21fc95b247b86721b95fabfb10c6a436134c3" +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz": + version "1.1.4" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz#cbed459a9e902f5295ec3daaf1c7aa3b10427e55" dependencies: debug "^4.3.7" fast-glob "^3.3.2" @@ -3335,24 +3335,24 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typescript-eslint@^8.24.0: - version "8.24.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.24.0.tgz#cc655e71885ecb8280342b422ad839a2e2e46a96" - integrity sha512-/lmv4366en/qbB32Vz5+kCNZEMf6xYHwh1z48suBwZvAtnXKbP+YhGe8OLE2BqC67LMqKkCNLtjejdwsdW6uOQ== +typescript-eslint@8.31.1: + version "8.31.1" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.31.1.tgz#b77ab1e48ced2daab9225ff94bab54391a4af69b" + integrity sha512-j6DsEotD/fH39qKzXTQRwYYWlt7D+0HmfpOK+DVhwJOFLcdmn92hq3mBb7HlKJHbjjI/gTOqEcc9d6JfpFf/VA== dependencies: - "@typescript-eslint/eslint-plugin" "8.24.0" - "@typescript-eslint/parser" "8.24.0" - "@typescript-eslint/utils" "8.24.0" + "@typescript-eslint/eslint-plugin" "8.31.1" + "@typescript-eslint/parser" "8.31.1" + "@typescript-eslint/utils" "8.31.1" typescript@5.6.1-rc: version "5.6.1-rc" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.1-rc.tgz#d5e4d7d8170174fed607b74cc32aba3d77018e02" integrity sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ== -typescript@^4.8.2: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== undici-types@~5.26.4: version "5.26.5" From caab78382741526d50e0c6d3a3e2834ac889fbd7 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 18:11:02 +0000 Subject: [PATCH 096/105] feat(client): add withOptions helper --- src/client.ts | 18 +++++++++++ tests/index.test.ts | 76 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/src/client.ts b/src/client.ts index 20cd50f8..d2a0514a 100644 --- a/src/client.ts +++ b/src/client.ts @@ -283,6 +283,24 @@ export class BaseAnthropic { this.authToken = authToken; } + /** + * Create a new client instance re-using the same options given to the current client with optional overriding. + */ + withOptions(options: Partial): this { + return new (this.constructor as any as new (props: ClientOptions) => typeof this)({ + ...this._options, + baseURL: this.baseURL, + maxRetries: this.maxRetries, + timeout: this.timeout, + logger: this.logger, + logLevel: this.logLevel, + fetchOptions: this.fetchOptions, + apiKey: this.apiKey, + authToken: this.authToken, + ...options, + }); + } + protected defaultQuery(): Record | undefined { return this._options.defaultQuery; } diff --git a/tests/index.test.ts b/tests/index.test.ts index 39a605bf..81566271 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -331,6 +331,82 @@ describe('instantiate client', () => { expect(client2.maxRetries).toEqual(2); }); + describe('withOptions', () => { + test('creates a new client with overridden options', () => { + const client = new Anthropic({ + baseURL: 'http://localhost:5000/', + maxRetries: 3, + apiKey: 'my-anthropic-api-key', + }); + + const newClient = client.withOptions({ + maxRetries: 5, + baseURL: 'http://localhost:5001/', + }); + + // Verify the new client has updated options + expect(newClient.maxRetries).toEqual(5); + expect(newClient.baseURL).toEqual('http://localhost:5001/'); + + // Verify the original client is unchanged + expect(client.maxRetries).toEqual(3); + expect(client.baseURL).toEqual('http://localhost:5000/'); + + // Verify it's a different instance + expect(newClient).not.toBe(client); + expect(newClient.constructor).toBe(client.constructor); + }); + + test('inherits options from the parent client', () => { + const client = new Anthropic({ + baseURL: 'http://localhost:5000/', + defaultHeaders: { 'X-Test-Header': 'test-value' }, + defaultQuery: { 'test-param': 'test-value' }, + apiKey: 'my-anthropic-api-key', + }); + + const newClient = client.withOptions({ + baseURL: 'http://localhost:5001/', + }); + + // Test inherited options remain the same + expect(newClient.buildURL('/foo', null)).toEqual('http://localhost:5001/foo?test-param=test-value'); + + const { req } = newClient.buildRequest({ path: '/foo', method: 'get' }); + expect(req.headers.get('x-test-header')).toEqual('test-value'); + }); + + test('respects runtime property changes when creating new client', () => { + const client = new Anthropic({ + baseURL: 'http://localhost:5000/', + timeout: 1000, + apiKey: 'my-anthropic-api-key', + }); + + // Modify the client properties directly after creation + client.baseURL = 'http://localhost:6000/'; + client.timeout = 2000; + + // Create a new client with withOptions + const newClient = client.withOptions({ + maxRetries: 10, + }); + + // Verify the new client uses the updated properties, not the original ones + expect(newClient.baseURL).toEqual('http://localhost:6000/'); + expect(newClient.timeout).toEqual(2000); + expect(newClient.maxRetries).toEqual(10); + + // Original client should still have its modified properties + expect(client.baseURL).toEqual('http://localhost:6000/'); + expect(client.timeout).toEqual(2000); + expect(client.maxRetries).not.toEqual(10); + + // Verify URL building uses the updated baseURL + expect(newClient.buildURL('/bar', null)).toEqual('http://localhost:6000/bar'); + }); + }); + test('with environment variable arguments', () => { // set options via env var process.env['ANTHROPIC_API_KEY'] = 'my-anthropic-api-key'; From ffbb2dac2b9e3b82c57d043dfb279ab95948cbc0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 19:18:53 +0000 Subject: [PATCH 097/105] chore(client): drop support for EOL node versions --- .github/workflows/ci.yml | 6 +- MIGRATION.md | 5 +- README.md | 2 +- package.json | 7 +-- src/internal/shims/crypto.ts | 18 ------ src/internal/shims/file.ts | 32 ----------- src/internal/shims/getBuiltinModule.ts | 66 ---------------------- src/internal/shims/nullGetBuiltinModule.ts | 1 - src/internal/to-file.ts | 6 +- src/internal/uploads.ts | 20 +++++-- src/internal/utils/uuid.ts | 4 +- 11 files changed, 30 insertions(+), 137 deletions(-) delete mode 100644 src/internal/shims/crypto.ts delete mode 100644 src/internal/shims/file.ts delete mode 100644 src/internal/shims/getBuiltinModule.ts delete mode 100644 src/internal/shims/nullGetBuiltinModule.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 123a3f11..05510588 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Bootstrap run: ./scripts/bootstrap @@ -40,7 +40,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Bootstrap run: ./scripts/bootstrap @@ -72,7 +72,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' - name: Bootstrap run: ./scripts/bootstrap diff --git a/MIGRATION.md b/MIGRATION.md index a3f2f7e2..72fa9817 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -14,8 +14,7 @@ To preview the changes without writing them to disk, run the tool with `--dry`. The minimum supported runtime and tooling versions are now: -- Node.js 18.x last LTS (Required for builtin fetch support) - - This was previously documented as the minimum supported Node.js version but Node.js 16.x mostly worked at runtime; now it will not. +- Node.js 20 LTS (Most recent non-EOL Node version) - TypeScript 4.9 - Jest 28 @@ -298,7 +297,7 @@ To resolve these issues, configure your tsconfig.json and install the appropriat ```json { "devDependencies": { - "@types/node": ">= 18.18.7" + "@types/node": ">= 20" } } ``` diff --git a/README.md b/README.md index 29657aed..bd05be71 100644 --- a/README.md +++ b/README.md @@ -593,7 +593,7 @@ TypeScript >= 4.9 is supported. The following runtimes are supported: -- Node.js 18 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions. +- Node.js 20 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions. - Deno v1.28.0 or higher. - Bun 1.0 or later. - Cloudflare Workers. diff --git a/package.json b/package.json index 99b295c0..4bf4f488 100644 --- a/package.json +++ b/package.json @@ -49,10 +49,6 @@ "resolutions": { "synckit": "0.8.8" }, - "browser": { - "./internal/shims/getBuiltinModule.mjs": "./internal/shims/nullGetBuiltinModule.mjs", - "./internal/shims/getBuiltinModule.js": "./internal/shims/nullGetBuiltinModule.js" - }, "imports": { "@anthropic-ai/sdk": ".", "@anthropic-ai/sdk/*": "./src/*" @@ -75,5 +71,8 @@ "import": "./dist/*.mjs", "require": "./dist/*.js" } + }, + "engines": { + "node": ">= 20" } } diff --git a/src/internal/shims/crypto.ts b/src/internal/shims/crypto.ts deleted file mode 100644 index 905f81c6..00000000 --- a/src/internal/shims/crypto.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { getBuiltinModule } from './getBuiltinModule'; - -type Crypto = { - /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */ - getRandomValues(array: T): T; - /** - * Available only in secure contexts. - * - * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID) - */ - randomUUID?: () => string; -}; -export let getCrypto: () => Crypto | undefined = function lazyGetCrypto() { - if (getCrypto !== lazyGetCrypto) return getCrypto(); - const crypto: Crypto = (globalThis as any).crypto || (getBuiltinModule?.('node:crypto') as any)?.webcrypto; - getCrypto = () => crypto; - return crypto; -}; diff --git a/src/internal/shims/file.ts b/src/internal/shims/file.ts deleted file mode 100644 index d5dc8209..00000000 --- a/src/internal/shims/file.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { getBuiltinModule } from './getBuiltinModule'; - -export let getFile = function lazyGetFile(): FileConstructor { - if (getFile !== lazyGetFile) return getFile(); - // We can drop getBuiltinModule once we no longer support Node < 20.0.0 - const File = (globalThis as any).File ?? (getBuiltinModule?.('node:buffer') as any)?.File; - if (!File) throw new Error('`File` is not defined as a global, which is required for file uploads.'); - getFile = () => File; - return File; -}; - -type FileConstructor = - typeof globalThis extends { File: infer fileConstructor } ? fileConstructor : typeof FallbackFile; -export type File = InstanceType; - -// The infer is to make TS show it as a nice union type, -// instead of literally `ConstructorParameters[0]` -type FallbackBlobSource = ConstructorParameters[0] extends infer T ? T : never; -/** - * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files. - */ -declare class FallbackFile extends Blob { - constructor(sources: FallbackBlobSource, fileName: string, options?: any); - /** - * The name of the `File`. - */ - readonly name: string; - /** - * The last modified date of the `File`. - */ - readonly lastModified: number; -} diff --git a/src/internal/shims/getBuiltinModule.ts b/src/internal/shims/getBuiltinModule.ts deleted file mode 100644 index 64daa2ce..00000000 --- a/src/internal/shims/getBuiltinModule.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Load a Node built-in module. ID may or may not be prefixed by `node:` and - * will be normalized. If we used static imports then our bundle size would be bloated by - * injected polyfills, and if we used dynamic require then in addition to bundlers logging warnings, - * our code would not work when bundled to ESM and run in Node 18. - * @param {string} id ID of the built-in to be loaded. - * @returns {object|undefined} exports of the built-in. Undefined if the built-in - * does not exist. - */ -export let getBuiltinModule: null | ((id: string) => object | undefined) = function getBuiltinModuleLazy( - id: string, -): object | undefined { - try { - if (getBuiltinModule !== getBuiltinModuleLazy) return getBuiltinModule!(id); - if ((process as any).getBuiltinModule) { - getBuiltinModule = (process as any).getBuiltinModule; - } else { - /* Fallback implementation for Node 18 */ - function createFallbackGetBuiltinModule(BuiltinModule: any) { - return function getBuiltinModule(id: string): object | undefined { - id = BuiltinModule.normalizeRequirableId(String(id)); - if (!BuiltinModule.canBeRequiredByUsers(id)) { - return; - } - const mod = BuiltinModule.map.get(id); - mod.compileForPublicLoader(); - return mod.exports; - }; - } - const magicKey = Math.random() + ''; - let module: { BuiltinModule: any } | undefined; - let ObjectPrototype: {} = Blob; - for (let next; (next = Reflect.getPrototypeOf(ObjectPrototype)); ObjectPrototype = next); - try { - const kClone = Object.getOwnPropertySymbols(Blob.prototype).find( - (e) => e.description?.includes('clone'), - )!; - Object.defineProperty(ObjectPrototype, magicKey, { - get() { - module = this; - throw null; - }, - configurable: true, - }); - structuredClone( - new (class extends Blob { - [kClone]() { - return { - deserializeInfo: 'internal/bootstrap/realm:' + magicKey, - }; - } - })([]), - ); - } catch {} - delete (ObjectPrototype as any)[magicKey]; - if (module) { - getBuiltinModule = createFallbackGetBuiltinModule(module.BuiltinModule); - } else { - getBuiltinModule = () => undefined; - } - } - return getBuiltinModule!(id); - } catch { - return undefined; - } -}; diff --git a/src/internal/shims/nullGetBuiltinModule.ts b/src/internal/shims/nullGetBuiltinModule.ts deleted file mode 100644 index 8bd2280d..00000000 --- a/src/internal/shims/nullGetBuiltinModule.ts +++ /dev/null @@ -1 +0,0 @@ -export const getBuiltinModule = null; diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts index e92ac694..245e8493 100644 --- a/src/internal/to-file.ts +++ b/src/internal/to-file.ts @@ -1,6 +1,6 @@ -import { type File, getFile } from './shims/file'; import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads'; import type { FilePropertyBag } from './builtin-types'; +import { checkFileSupport } from './uploads'; type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView; @@ -85,12 +85,14 @@ export async function toFile( name?: string | null | undefined, options?: FilePropertyBag | undefined, ): Promise { + checkFileSupport(); + // If it's a promise, resolve it. value = await value; // If we've been given a `File` we don't need to do anything if (isFileLike(value)) { - if (value instanceof getFile()) { + if (value instanceof File) { return value; } return makeFile([await value.arrayBuffer()], value.name); diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts index 8bec6154..ece7e569 100644 --- a/src/internal/uploads.ts +++ b/src/internal/uploads.ts @@ -1,7 +1,6 @@ import { type RequestOptions } from './request-options'; import type { FilePropertyBag, Fetch } from './builtin-types'; import type { BaseAnthropic } from '../client'; -import { type File, getFile } from './shims/file'; import { ReadableStreamFrom } from './shims'; export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView; @@ -12,6 +11,20 @@ interface BunFile extends Blob { readonly name?: string | undefined; } +export const checkFileSupport = () => { + if (typeof File === 'undefined') { + const { process } = globalThis as any; + const isOldNode = + typeof process?.versions?.node === 'string' && parseInt(process.versions.node.split('.')) < 20; + throw new Error( + '`File` is not defined as a global, which is required for file uploads.' + + (isOldNode ? + " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`." + : ''), + ); + } +}; + /** * Typically, this is a native "File" class. * @@ -32,7 +45,7 @@ export function makeFile( fileName: string | undefined, options?: FilePropertyBag, ): File { - const File = getFile(); + checkFileSupport(); return new File(fileBits as any, fileName ?? 'unknown_file', options); } @@ -125,8 +138,7 @@ export const createForm = async >( // We check for Blob not File because Bun.File doesn't inherit from File, // but they both inherit from Blob and have a `name` property at runtime. -const isNamedBlob = (value: object) => - value instanceof getFile() || (value instanceof Blob && 'name' in value); +const isNamedBlob = (value: object) => value instanceof Blob && 'name' in value; const isUploadable = (value: unknown) => typeof value === 'object' && diff --git a/src/internal/utils/uuid.ts b/src/internal/utils/uuid.ts index 5a262c6d..b0e53aaf 100644 --- a/src/internal/utils/uuid.ts +++ b/src/internal/utils/uuid.ts @@ -1,12 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { getCrypto } from '../shims/crypto'; - /** * https://stackoverflow.com/a/2117523 */ export let uuid4 = function () { - const crypto = getCrypto(); + const { crypto } = globalThis as any; if (crypto?.randomUUID) { uuid4 = crypto.randomUUID.bind(crypto); return crypto.randomUUID(); From a6ae12953f6f841d4585a8cf8cf03fa24f17d57c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 00:40:28 +0000 Subject: [PATCH 098/105] chore(internal): codegen related update --- src/resources/beta/messages/batches.ts | 59 +++++++++++++++++++++++++ src/resources/beta/messages/messages.ts | 18 ++++++++ src/resources/beta/models.ts | 15 +++++++ src/resources/completions.ts | 9 ++++ src/resources/messages/batches.ts | 52 ++++++++++++++++++++++ src/resources/messages/messages.ts | 18 ++++++++ 6 files changed, 171 insertions(+) diff --git a/src/resources/beta/messages/batches.ts b/src/resources/beta/messages/batches.ts index bd279fc6..c55265d7 100644 --- a/src/resources/beta/messages/batches.ts +++ b/src/resources/beta/messages/batches.ts @@ -21,6 +21,25 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const betaMessageBatch = + * await client.beta.messages.batches.create({ + * requests: [ + * { + * custom_id: 'my-custom-id-1', + * params: { + * max_tokens: 1024, + * messages: [ + * { content: 'Hello, world', role: 'user' }, + * ], + * model: 'claude-3-7-sonnet-20250219', + * }, + * }, + * ], + * }); + * ``` */ create(params: BatchCreateParams, options?: RequestOptions): APIPromise { const { betas, ...body } = params; @@ -41,6 +60,14 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const betaMessageBatch = + * await client.beta.messages.batches.retrieve( + * 'message_batch_id', + * ); + * ``` */ retrieve( messageBatchID: string, @@ -63,6 +90,14 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const betaMessageBatch of client.beta.messages.batches.list()) { + * // ... + * } + * ``` */ list( params: BatchListParams | null | undefined = {}, @@ -87,6 +122,14 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const betaDeletedMessageBatch = + * await client.beta.messages.batches.delete( + * 'message_batch_id', + * ); + * ``` */ delete( messageBatchID: string, @@ -116,6 +159,14 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const betaMessageBatch = + * await client.beta.messages.batches.cancel( + * 'message_batch_id', + * ); + * ``` */ cancel( messageBatchID: string, @@ -141,6 +192,14 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const betaMessageBatchIndividualResponse = + * await client.beta.messages.batches.results( + * 'message_batch_id', + * ); + * ``` */ async results( messageBatchID: string, diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index fb1ad9ee..14154936 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -40,6 +40,15 @@ export class Messages extends APIResource { * conversations. * * Learn more about the Messages API in our [user guide](/en/docs/initial-setup) + * + * @example + * ```ts + * const betaMessage = await client.beta.messages.create({ + * max_tokens: 1024, + * messages: [{ content: 'Hello, world', role: 'user' }], + * model: 'claude-3-7-sonnet-20250219', + * }); + * ``` */ create(params: MessageCreateParamsNonStreaming, options?: RequestOptions): APIPromise; create( @@ -77,6 +86,15 @@ export class Messages extends APIResource { * * Learn more about token counting in our * [user guide](/en/docs/build-with-claude/token-counting) + * + * @example + * ```ts + * const betaMessageTokensCount = + * await client.beta.messages.countTokens({ + * messages: [{ content: 'string', role: 'user' }], + * model: 'claude-3-7-sonnet-latest', + * }); + * ``` */ countTokens( params: MessageCountTokensParams, diff --git a/src/resources/beta/models.ts b/src/resources/beta/models.ts index 8f7213f4..c5bfee58 100644 --- a/src/resources/beta/models.ts +++ b/src/resources/beta/models.ts @@ -12,6 +12,13 @@ export class Models extends APIResource { * * The Models API response can be used to determine information about a specific * model or resolve a model alias to a model ID. + * + * @example + * ```ts + * const betaModelInfo = await client.beta.models.retrieve( + * 'model_id', + * ); + * ``` */ retrieve(modelID: string, options?: RequestOptions): APIPromise { return this._client.get(path`/v1/models/${modelID}?beta=true`, options); @@ -22,6 +29,14 @@ export class Models extends APIResource { * * The Models API response can be used to determine which models are available for * use in the API. More recently released models are listed first. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const betaModelInfo of client.beta.models.list()) { + * // ... + * } + * ``` */ list( query: ModelListParams | null | undefined = {}, diff --git a/src/resources/completions.ts b/src/resources/completions.ts index 68f70344..154bed28 100644 --- a/src/resources/completions.ts +++ b/src/resources/completions.ts @@ -17,6 +17,15 @@ export class Completions extends APIResource { * Future models and features will not be compatible with Text Completions. See our * [migration guide](https://docs.anthropic.com/en/api/migrating-from-text-completions-to-messages) * for guidance in migrating from Text Completions to Messages. + * + * @example + * ```ts + * const completion = await client.completions.create({ + * max_tokens_to_sample: 256, + * model: 'claude-3-7-sonnet-latest', + * prompt: '\n\nHuman: Hello, world!\n\nAssistant:', + * }); + * ``` */ create(body: CompletionCreateParamsNonStreaming, options?: RequestOptions): APIPromise; create(body: CompletionCreateParamsStreaming, options?: RequestOptions): APIPromise>; diff --git a/src/resources/messages/batches.ts b/src/resources/messages/batches.ts index 5a7b2020..da5f49fe 100644 --- a/src/resources/messages/batches.ts +++ b/src/resources/messages/batches.ts @@ -21,6 +21,24 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const messageBatch = await client.messages.batches.create({ + * requests: [ + * { + * custom_id: 'my-custom-id-1', + * params: { + * max_tokens: 1024, + * messages: [ + * { content: 'Hello, world', role: 'user' }, + * ], + * model: 'claude-3-7-sonnet-20250219', + * }, + * }, + * ], + * }); + * ``` */ create(body: BatchCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/v1/messages/batches', { body, ...options }); @@ -33,6 +51,13 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const messageBatch = await client.messages.batches.retrieve( + * 'message_batch_id', + * ); + * ``` */ retrieve(messageBatchID: string, options?: RequestOptions): APIPromise { return this._client.get(path`/v1/messages/batches/${messageBatchID}`, options); @@ -44,6 +69,14 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const messageBatch of client.messages.batches.list()) { + * // ... + * } + * ``` */ list( query: BatchListParams | null | undefined = {}, @@ -60,6 +93,12 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const deletedMessageBatch = + * await client.messages.batches.delete('message_batch_id'); + * ``` */ delete(messageBatchID: string, options?: RequestOptions): APIPromise { return this._client.delete(path`/v1/messages/batches/${messageBatchID}`, options); @@ -78,6 +117,13 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const messageBatch = await client.messages.batches.cancel( + * 'message_batch_id', + * ); + * ``` */ cancel(messageBatchID: string, options?: RequestOptions): APIPromise { return this._client.post(path`/v1/messages/batches/${messageBatchID}/cancel`, options); @@ -92,6 +138,12 @@ export class Batches extends APIResource { * * Learn more about the Message Batches API in our * [user guide](/en/docs/build-with-claude/batch-processing) + * + * @example + * ```ts + * const messageBatchIndividualResponse = + * await client.messages.batches.results('message_batch_id'); + * ``` */ async results( messageBatchID: string, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index 613b9d7f..6cb42156 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -36,6 +36,15 @@ export class Messages extends APIResource { * conversations. * * Learn more about the Messages API in our [user guide](/en/docs/initial-setup) + * + * @example + * ```ts + * const message = await client.messages.create({ + * max_tokens: 1024, + * messages: [{ content: 'Hello, world', role: 'user' }], + * model: 'claude-3-7-sonnet-20250219', + * }); + * ``` */ create(body: MessageCreateParamsNonStreaming, options?: RequestOptions): APIPromise; create( @@ -82,6 +91,15 @@ export class Messages extends APIResource { * * Learn more about token counting in our * [user guide](/en/docs/build-with-claude/token-counting) + * + * @example + * ```ts + * const messageTokensCount = + * await client.messages.countTokens({ + * messages: [{ content: 'string', role: 'user' }], + * model: 'claude-3-7-sonnet-latest', + * }); + * ``` */ countTokens(body: MessageCountTokensParams, options?: RequestOptions): APIPromise { return this._client.post('/v1/messages/count_tokens', { body, ...options }); From b36623f33134e937ba8fc7585ab5fab3b31203ed Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 13:53:50 +0000 Subject: [PATCH 099/105] feat(api): adds web search capabilities to the Claude API --- .stats.yml | 6 +- MIGRATION.md | 2 + api.md | 32 ++- src/client.ts | 31 ++- src/resources/beta/beta.ts | 31 ++- src/resources/beta/index.ts | 22 +- src/resources/beta/messages/index.ts | 14 + src/resources/beta/messages/messages.ts | 333 +++++++++++++++++++++++- src/resources/beta/models.ts | 44 +++- src/resources/completions.ts | 47 ++-- src/resources/index.ts | 22 +- src/resources/messages/index.ts | 14 + src/resources/messages/messages.ts | 314 +++++++++++++++++++++- src/resources/models.ts | 44 +++- tests/api-resources/beta/models.test.ts | 9 +- tests/api-resources/completions.test.ts | 1 + tests/api-resources/models.test.ts | 9 +- 17 files changed, 913 insertions(+), 62 deletions(-) diff --git a/.stats.yml b/.stats.yml index 30b9556d..5aa47f53 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-ea0576fceb17a0976feca9aa03aa426984d6fe1390f2bcdbf9de0212a81c8334.yml -openapi_spec_hash: d2d7ec2a7a35a1ed2443c3b690c802c4 -config_hash: 9d5b992847099d8fe5a5c09e66adbe5f +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-7015ea2d98991d6c2e7931c521e36448778fe868cc1b8a21173898d67b14b819.yml +openapi_spec_hash: 2007ff815a3f39af8cebe1976d50f17d +config_hash: 4d0dcf47d77eae22d34624d2ac0f0b46 diff --git a/MIGRATION.md b/MIGRATION.md index 72fa9817..3d65662d 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -68,7 +68,9 @@ client.example.list(undefined, { headers: { ... } }); This affects the following methods: - `client.messages.batches.list()` +- `client.models.retrieve()` - `client.models.list()` +- `client.beta.models.retrieve()` - `client.beta.models.list()` - `client.beta.messages.batches.retrieve()` - `client.beta.messages.batches.list()` diff --git a/api.md b/api.md index 49ea4e12..a3eeb701 100644 --- a/api.md +++ b/api.md @@ -29,8 +29,10 @@ Types: - CitationContentBlockLocationParam - CitationPageLocation - CitationPageLocationParam +- CitationWebSearchResultLocationParam - CitationsConfigParam - CitationsDelta +- CitationsWebSearchResultLocation - ContentBlock - ContentBlockDeltaEvent - ContentBlockParam @@ -63,6 +65,9 @@ Types: - RawMessageStreamEvent - RedactedThinkingBlock - RedactedThinkingBlockParam +- ServerToolUsage +- ServerToolUseBlock +- ServerToolUseBlockParam - SignatureDelta - StopReason - TextBlock @@ -91,6 +96,15 @@ Types: - URLImageSource - URLPDFSource - Usage +- WebSearchResultBlock +- WebSearchResultBlockParam +- WebSearchTool20250305 +- WebSearchToolRequestError +- WebSearchToolResultBlock +- WebSearchToolResultBlockContent +- WebSearchToolResultBlockParam +- WebSearchToolResultBlockParamContent +- WebSearchToolResultError Methods: @@ -129,7 +143,7 @@ Types: Methods: -- client.models.retrieve(modelID) -> ModelInfo +- client.models.retrieve(modelID, { ...params }) -> ModelInfo - client.models.list({ ...params }) -> ModelInfosPage # Beta @@ -157,7 +171,7 @@ Types: Methods: -- client.beta.models.retrieve(modelID) -> BetaModelInfo +- client.beta.models.retrieve(modelID, { ...params }) -> BetaModelInfo - client.beta.models.list({ ...params }) -> BetaModelInfosPage ## Messages @@ -174,8 +188,10 @@ Types: - BetaCitationContentBlockLocationParam - BetaCitationPageLocation - BetaCitationPageLocationParam +- BetaCitationWebSearchResultLocationParam - BetaCitationsConfigParam - BetaCitationsDelta +- BetaCitationsWebSearchResultLocation - BetaContentBlock - BetaContentBlockParam - BetaContentBlockSource @@ -198,6 +214,9 @@ Types: - BetaRawMessageStreamEvent - BetaRedactedThinkingBlock - BetaRedactedThinkingBlockParam +- BetaServerToolUsage +- BetaServerToolUseBlock +- BetaServerToolUseBlockParam - BetaSignatureDelta - BetaStopReason - BetaTextBlock @@ -230,6 +249,15 @@ Types: - BetaURLImageSource - BetaURLPDFSource - BetaUsage +- BetaWebSearchResultBlock +- BetaWebSearchResultBlockParam +- BetaWebSearchTool20250305 +- BetaWebSearchToolRequestError +- BetaWebSearchToolResultBlock +- BetaWebSearchToolResultBlockContent +- BetaWebSearchToolResultBlockParam +- BetaWebSearchToolResultBlockParamContent +- BetaWebSearchToolResultError Methods: diff --git a/src/client.ts b/src/client.ts index d2a0514a..aaaf37e7 100644 --- a/src/client.ts +++ b/src/client.ts @@ -30,7 +30,7 @@ import { CompletionCreateParamsStreaming, Completions, } from './resources/completions'; -import { ModelInfo, ModelInfosPage, ModelListParams, Models } from './resources/models'; +import { ModelInfo, ModelInfosPage, ModelListParams, ModelRetrieveParams, Models } from './resources/models'; import { readEnv } from './internal/utils/env'; import { formatRequestDetails, loggerFor } from './internal/utils/log'; import { isEmptyObj } from './internal/utils/values'; @@ -59,8 +59,10 @@ import { CitationContentBlockLocationParam, CitationPageLocation, CitationPageLocationParam, + CitationWebSearchResultLocationParam, CitationsConfigParam, CitationsDelta, + CitationsWebSearchResultLocation, ContentBlock, ContentBlockDeltaEvent, ContentBlockParam, @@ -99,6 +101,9 @@ import { RawMessageStreamEvent, RedactedThinkingBlock, RedactedThinkingBlockParam, + ServerToolUsage, + ServerToolUseBlock, + ServerToolUseBlockParam, SignatureDelta, StopReason, TextBlock, @@ -127,6 +132,15 @@ import { URLImageSource, URLPDFSource, Usage, + WebSearchResultBlock, + WebSearchResultBlockParam, + WebSearchTool20250305, + WebSearchToolRequestError, + WebSearchToolResultBlock, + WebSearchToolResultBlockContent, + WebSearchToolResultBlockParam, + WebSearchToolResultBlockParamContent, + WebSearchToolResultError, } from './resources/messages/messages'; export interface ClientOptions { @@ -920,8 +934,10 @@ export declare namespace Anthropic { type CitationContentBlockLocationParam as CitationContentBlockLocationParam, type CitationPageLocation as CitationPageLocation, type CitationPageLocationParam as CitationPageLocationParam, + type CitationWebSearchResultLocationParam as CitationWebSearchResultLocationParam, type CitationsConfigParam as CitationsConfigParam, type CitationsDelta as CitationsDelta, + type CitationsWebSearchResultLocation as CitationsWebSearchResultLocation, type ContentBlock as ContentBlock, type ContentBlockDeltaEvent as ContentBlockDeltaEvent, type ContentBlockParam as ContentBlockParam, @@ -954,6 +970,9 @@ export declare namespace Anthropic { type RawMessageStreamEvent as RawMessageStreamEvent, type RedactedThinkingBlock as RedactedThinkingBlock, type RedactedThinkingBlockParam as RedactedThinkingBlockParam, + type ServerToolUsage as ServerToolUsage, + type ServerToolUseBlock as ServerToolUseBlock, + type ServerToolUseBlockParam as ServerToolUseBlockParam, type SignatureDelta as SignatureDelta, type StopReason as StopReason, type TextBlock as TextBlock, @@ -982,6 +1001,15 @@ export declare namespace Anthropic { type URLImageSource as URLImageSource, type URLPDFSource as URLPDFSource, type Usage as Usage, + type WebSearchResultBlock as WebSearchResultBlock, + type WebSearchResultBlockParam as WebSearchResultBlockParam, + type WebSearchTool20250305 as WebSearchTool20250305, + type WebSearchToolRequestError as WebSearchToolRequestError, + type WebSearchToolResultBlock as WebSearchToolResultBlock, + type WebSearchToolResultBlockContent as WebSearchToolResultBlockContent, + type WebSearchToolResultBlockParam as WebSearchToolResultBlockParam, + type WebSearchToolResultBlockParamContent as WebSearchToolResultBlockParamContent, + type WebSearchToolResultError as WebSearchToolResultError, type MessageCreateParams as MessageCreateParams, type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming, type MessageCreateParamsStreaming as MessageCreateParamsStreaming, @@ -993,6 +1021,7 @@ export declare namespace Anthropic { Models as Models, type ModelInfo as ModelInfo, type ModelInfosPage as ModelInfosPage, + type ModelRetrieveParams as ModelRetrieveParams, type ModelListParams as ModelListParams, }; diff --git a/src/resources/beta/beta.ts b/src/resources/beta/beta.ts index 64e330e1..df12f6be 100644 --- a/src/resources/beta/beta.ts +++ b/src/resources/beta/beta.ts @@ -2,7 +2,7 @@ import { APIResource } from '../../core/resource'; import * as ModelsAPI from './models'; -import { BetaModelInfo, BetaModelInfosPage, ModelListParams, Models } from './models'; +import { BetaModelInfo, BetaModelInfosPage, ModelListParams, ModelRetrieveParams, Models } from './models'; import * as MessagesAPI from './messages/messages'; import { BetaBase64ImageSource, @@ -15,8 +15,10 @@ import { BetaCitationContentBlockLocationParam, BetaCitationPageLocation, BetaCitationPageLocationParam, + BetaCitationWebSearchResultLocationParam, BetaCitationsConfigParam, BetaCitationsDelta, + BetaCitationsWebSearchResultLocation, BetaContentBlock, BetaContentBlockParam, BetaContentBlockSource, @@ -39,6 +41,9 @@ import { BetaRawMessageStreamEvent, BetaRedactedThinkingBlock, BetaRedactedThinkingBlockParam, + BetaServerToolUsage, + BetaServerToolUseBlock, + BetaServerToolUseBlockParam, BetaSignatureDelta, BetaStopReason, BetaTextBlock, @@ -71,6 +76,15 @@ import { BetaURLImageSource, BetaURLPDFSource, BetaUsage, + BetaWebSearchResultBlock, + BetaWebSearchResultBlockParam, + BetaWebSearchTool20250305, + BetaWebSearchToolRequestError, + BetaWebSearchToolResultBlock, + BetaWebSearchToolResultBlockContent, + BetaWebSearchToolResultBlockParam, + BetaWebSearchToolResultBlockParamContent, + BetaWebSearchToolResultError, MessageCountTokensParams, MessageCreateParams, MessageCreateParamsNonStreaming, @@ -188,6 +202,7 @@ export declare namespace Beta { Models as Models, type BetaModelInfo as BetaModelInfo, type BetaModelInfosPage as BetaModelInfosPage, + type ModelRetrieveParams as ModelRetrieveParams, type ModelListParams as ModelListParams, }; @@ -203,8 +218,10 @@ export declare namespace Beta { type BetaCitationContentBlockLocationParam as BetaCitationContentBlockLocationParam, type BetaCitationPageLocation as BetaCitationPageLocation, type BetaCitationPageLocationParam as BetaCitationPageLocationParam, + type BetaCitationWebSearchResultLocationParam as BetaCitationWebSearchResultLocationParam, type BetaCitationsConfigParam as BetaCitationsConfigParam, type BetaCitationsDelta as BetaCitationsDelta, + type BetaCitationsWebSearchResultLocation as BetaCitationsWebSearchResultLocation, type BetaContentBlock as BetaContentBlock, type BetaContentBlockParam as BetaContentBlockParam, type BetaContentBlockSource as BetaContentBlockSource, @@ -227,6 +244,9 @@ export declare namespace Beta { type BetaRawMessageStreamEvent as BetaRawMessageStreamEvent, type BetaRedactedThinkingBlock as BetaRedactedThinkingBlock, type BetaRedactedThinkingBlockParam as BetaRedactedThinkingBlockParam, + type BetaServerToolUsage as BetaServerToolUsage, + type BetaServerToolUseBlock as BetaServerToolUseBlock, + type BetaServerToolUseBlockParam as BetaServerToolUseBlockParam, type BetaSignatureDelta as BetaSignatureDelta, type BetaStopReason as BetaStopReason, type BetaTextBlock as BetaTextBlock, @@ -259,6 +279,15 @@ export declare namespace Beta { type BetaURLImageSource as BetaURLImageSource, type BetaURLPDFSource as BetaURLPDFSource, type BetaUsage as BetaUsage, + type BetaWebSearchResultBlock as BetaWebSearchResultBlock, + type BetaWebSearchResultBlockParam as BetaWebSearchResultBlockParam, + type BetaWebSearchTool20250305 as BetaWebSearchTool20250305, + type BetaWebSearchToolRequestError as BetaWebSearchToolRequestError, + type BetaWebSearchToolResultBlock as BetaWebSearchToolResultBlock, + type BetaWebSearchToolResultBlockContent as BetaWebSearchToolResultBlockContent, + type BetaWebSearchToolResultBlockParam as BetaWebSearchToolResultBlockParam, + type BetaWebSearchToolResultBlockParamContent as BetaWebSearchToolResultBlockParamContent, + type BetaWebSearchToolResultError as BetaWebSearchToolResultError, type MessageCreateParams as MessageCreateParams, type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming, type MessageCreateParamsStreaming as MessageCreateParamsStreaming, diff --git a/src/resources/beta/index.ts b/src/resources/beta/index.ts index 84dfd803..1bfa7e3c 100644 --- a/src/resources/beta/index.ts +++ b/src/resources/beta/index.ts @@ -27,8 +27,10 @@ export { type BetaCitationContentBlockLocationParam, type BetaCitationPageLocation, type BetaCitationPageLocationParam, + type BetaCitationWebSearchResultLocationParam, type BetaCitationsConfigParam, type BetaCitationsDelta, + type BetaCitationsWebSearchResultLocation, type BetaContentBlock, type BetaContentBlockParam, type BetaContentBlockSource, @@ -51,6 +53,9 @@ export { type BetaRawMessageStreamEvent, type BetaRedactedThinkingBlock, type BetaRedactedThinkingBlockParam, + type BetaServerToolUsage, + type BetaServerToolUseBlock, + type BetaServerToolUseBlockParam, type BetaSignatureDelta, type BetaStopReason, type BetaTextBlock, @@ -83,9 +88,24 @@ export { type BetaURLImageSource, type BetaURLPDFSource, type BetaUsage, + type BetaWebSearchResultBlock, + type BetaWebSearchResultBlockParam, + type BetaWebSearchTool20250305, + type BetaWebSearchToolRequestError, + type BetaWebSearchToolResultBlock, + type BetaWebSearchToolResultBlockContent, + type BetaWebSearchToolResultBlockParam, + type BetaWebSearchToolResultBlockParamContent, + type BetaWebSearchToolResultError, type MessageCreateParams, type MessageCreateParamsNonStreaming, type MessageCreateParamsStreaming, type MessageCountTokensParams, } from './messages/index'; -export { Models, type BetaModelInfo, type ModelListParams, type BetaModelInfosPage } from './models'; +export { + Models, + type BetaModelInfo, + type ModelRetrieveParams, + type ModelListParams, + type BetaModelInfosPage, +} from './models'; diff --git a/src/resources/beta/messages/index.ts b/src/resources/beta/messages/index.ts index 28442b78..5e04e017 100644 --- a/src/resources/beta/messages/index.ts +++ b/src/resources/beta/messages/index.ts @@ -31,8 +31,10 @@ export { type BetaCitationContentBlockLocationParam, type BetaCitationPageLocation, type BetaCitationPageLocationParam, + type BetaCitationWebSearchResultLocationParam, type BetaCitationsConfigParam, type BetaCitationsDelta, + type BetaCitationsWebSearchResultLocation, type BetaContentBlock, type BetaContentBlockParam, type BetaContentBlockSource, @@ -55,6 +57,9 @@ export { type BetaRawMessageStreamEvent, type BetaRedactedThinkingBlock, type BetaRedactedThinkingBlockParam, + type BetaServerToolUsage, + type BetaServerToolUseBlock, + type BetaServerToolUseBlockParam, type BetaSignatureDelta, type BetaStopReason, type BetaTextBlock, @@ -87,6 +92,15 @@ export { type BetaURLImageSource, type BetaURLPDFSource, type BetaUsage, + type BetaWebSearchResultBlock, + type BetaWebSearchResultBlockParam, + type BetaWebSearchTool20250305, + type BetaWebSearchToolRequestError, + type BetaWebSearchToolResultBlock, + type BetaWebSearchToolResultBlockContent, + type BetaWebSearchToolResultBlockParam, + type BetaWebSearchToolResultBlockParamContent, + type BetaWebSearchToolResultError, type MessageCreateParams, type MessageCreateParamsNonStreaming, type MessageCreateParamsStreaming, diff --git a/src/resources/beta/messages/messages.ts b/src/resources/beta/messages/messages.ts index 14154936..90200bf8 100644 --- a/src/resources/beta/messages/messages.ts +++ b/src/resources/beta/messages/messages.ts @@ -125,6 +125,9 @@ export interface BetaBase64PDFBlock { type: 'document'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; citations?: BetaCitationsConfigParam; @@ -230,19 +233,49 @@ export interface BetaCitationPageLocationParam { type: 'page_location'; } +export interface BetaCitationWebSearchResultLocationParam { + cited_text: string; + + encrypted_index: string; + + title: string | null; + + type: 'web_search_result_location'; + + url: string; +} + export interface BetaCitationsConfigParam { enabled?: boolean; } export interface BetaCitationsDelta { - citation: BetaCitationCharLocation | BetaCitationPageLocation | BetaCitationContentBlockLocation; + citation: + | BetaCitationCharLocation + | BetaCitationPageLocation + | BetaCitationContentBlockLocation + | BetaCitationsWebSearchResultLocation; type: 'citations_delta'; } +export interface BetaCitationsWebSearchResultLocation { + cited_text: string; + + encrypted_index: string; + + title: string | null; + + type: 'web_search_result_location'; + + url: string; +} + export type BetaContentBlock = | BetaTextBlock | BetaToolUseBlock + | BetaServerToolUseBlock + | BetaWebSearchToolResultBlock | BetaThinkingBlock | BetaRedactedThinkingBlock; @@ -250,6 +283,8 @@ export type BetaContentBlockParam = | BetaTextBlockParam | BetaImageBlockParam | BetaToolUseBlockParam + | BetaServerToolUseBlockParam + | BetaWebSearchToolResultBlockParam | BetaToolResultBlockParam | BetaBase64PDFBlock | BetaThinkingBlockParam @@ -268,6 +303,9 @@ export interface BetaImageBlockParam { type: 'image'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; } @@ -386,10 +424,30 @@ export interface BetaMessage { } export interface BetaMessageDeltaUsage { + /** + * The cumulative number of input tokens used to create the cache entry. + */ + cache_creation_input_tokens: number | null; + + /** + * The cumulative number of input tokens read from the cache. + */ + cache_read_input_tokens: number | null; + + /** + * The cumulative number of input tokens which were used. + */ + input_tokens: number | null; + /** * The cumulative number of output tokens which were used. */ output_tokens: number; + + /** + * The number of server tool requests. + */ + server_tool_use: BetaServerToolUsage | null; } export interface BetaMessageParam { @@ -441,7 +499,13 @@ export interface BetaRawContentBlockDeltaEvent { } export interface BetaRawContentBlockStartEvent { - content_block: BetaTextBlock | BetaToolUseBlock | BetaThinkingBlock | BetaRedactedThinkingBlock; + content_block: + | BetaTextBlock + | BetaToolUseBlock + | BetaServerToolUseBlock + | BetaWebSearchToolResultBlock + | BetaThinkingBlock + | BetaRedactedThinkingBlock; index: number; @@ -517,13 +581,51 @@ export interface BetaRedactedThinkingBlockParam { type: 'redacted_thinking'; } +export interface BetaServerToolUsage { + /** + * The number of web search tool requests. + */ + web_search_requests: number; +} + +export interface BetaServerToolUseBlock { + id: string; + + input: unknown; + + name: 'web_search'; + + type: 'server_tool_use'; +} + +export interface BetaServerToolUseBlockParam { + id: string; + + input: unknown; + + name: 'web_search'; + + type: 'server_tool_use'; + + /** + * Create a cache control breakpoint at this content block. + */ + cache_control?: BetaCacheControlEphemeral | null; +} + export interface BetaSignatureDelta { signature: string; type: 'signature_delta'; } -export type BetaStopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use'; +export type BetaStopReason = + | 'end_turn' + | 'max_tokens' + | 'stop_sequence' + | 'tool_use' + | 'pause_turn' + | 'refusal'; export interface BetaTextBlock { /** @@ -545,6 +647,9 @@ export interface BetaTextBlockParam { type: 'text'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; citations?: Array | null; @@ -553,12 +658,14 @@ export interface BetaTextBlockParam { export type BetaTextCitation = | BetaCitationCharLocation | BetaCitationPageLocation - | BetaCitationContentBlockLocation; + | BetaCitationContentBlockLocation + | BetaCitationsWebSearchResultLocation; export type BetaTextCitationParam = | BetaCitationCharLocationParam | BetaCitationPageLocationParam - | BetaCitationContentBlockLocationParam; + | BetaCitationContentBlockLocationParam + | BetaCitationWebSearchResultLocationParam; export interface BetaTextDelta { text: string; @@ -634,10 +741,13 @@ export interface BetaTool { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: string; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; /** @@ -673,12 +783,15 @@ export interface BetaToolBash20241022 { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: 'bash'; type: 'bash_20241022'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; } @@ -686,12 +799,15 @@ export interface BetaToolBash20250124 { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: 'bash'; type: 'bash_20250124'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; } @@ -772,12 +888,15 @@ export interface BetaToolComputerUse20241022 { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: 'computer'; type: 'computer_20241022'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; /** @@ -800,12 +919,15 @@ export interface BetaToolComputerUse20250124 { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: 'computer'; type: 'computer_20250124'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; /** @@ -819,6 +941,9 @@ export interface BetaToolResultBlockParam { type: 'tool_result'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; content?: string | Array; @@ -830,12 +955,15 @@ export interface BetaToolTextEditor20241022 { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: 'str_replace_editor'; type: 'text_editor_20241022'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; } @@ -843,23 +971,27 @@ export interface BetaToolTextEditor20250124 { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: 'str_replace_editor'; type: 'text_editor_20250124'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; } export type BetaToolUnion = + | BetaTool | BetaToolComputerUse20241022 | BetaToolBash20241022 | BetaToolTextEditor20241022 | BetaToolComputerUse20250124 | BetaToolBash20250124 | BetaToolTextEditor20250124 - | BetaTool; + | BetaWebSearchTool20250305; export interface BetaToolUseBlock { id: string; @@ -880,6 +1012,9 @@ export interface BetaToolUseBlockParam { type: 'tool_use'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: BetaCacheControlEphemeral | null; } @@ -915,6 +1050,157 @@ export interface BetaUsage { * The number of output tokens which were used. */ output_tokens: number; + + /** + * The number of server tool requests. + */ + server_tool_use: BetaServerToolUsage | null; +} + +export interface BetaWebSearchResultBlock { + encrypted_content: string; + + page_age: string | null; + + title: string; + + type: 'web_search_result'; + + url: string; +} + +export interface BetaWebSearchResultBlockParam { + encrypted_content: string; + + title: string; + + type: 'web_search_result'; + + url: string; + + page_age?: string | null; +} + +export interface BetaWebSearchTool20250305 { + /** + * Name of the tool. + * + * This is how the tool will be called by the model and in `tool_use` blocks. + */ + name: 'web_search'; + + type: 'web_search_20250305'; + + /** + * If provided, only these domains will be included in results. Cannot be used + * alongside `blocked_domains`. + */ + allowed_domains?: Array | null; + + /** + * If provided, these domains will never appear in results. Cannot be used + * alongside `allowed_domains`. + */ + blocked_domains?: Array | null; + + /** + * Create a cache control breakpoint at this content block. + */ + cache_control?: BetaCacheControlEphemeral | null; + + /** + * Maximum number of times the tool can be used in the API request. + */ + max_uses?: number | null; + + /** + * Parameters for the user's location. Used to provide more relevant search + * results. + */ + user_location?: BetaWebSearchTool20250305.UserLocation | null; +} + +export namespace BetaWebSearchTool20250305 { + /** + * Parameters for the user's location. Used to provide more relevant search + * results. + */ + export interface UserLocation { + type: 'approximate'; + + /** + * The city of the user. + */ + city?: string | null; + + /** + * The two letter + * [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the + * user. + */ + country?: string | null; + + /** + * The region of the user. + */ + region?: string | null; + + /** + * The [IANA timezone](https://nodatime.org/TimeZones) of the user. + */ + timezone?: string | null; + } +} + +export interface BetaWebSearchToolRequestError { + error_code: + | 'invalid_tool_input' + | 'unavailable' + | 'max_uses_exceeded' + | 'too_many_requests' + | 'query_too_long'; + + type: 'web_search_tool_result_error'; +} + +export interface BetaWebSearchToolResultBlock { + content: BetaWebSearchToolResultBlockContent; + + tool_use_id: string; + + type: 'web_search_tool_result'; +} + +export type BetaWebSearchToolResultBlockContent = + | BetaWebSearchToolResultError + | Array; + +export interface BetaWebSearchToolResultBlockParam { + content: BetaWebSearchToolResultBlockParamContent; + + tool_use_id: string; + + type: 'web_search_tool_result'; + + /** + * Create a cache control breakpoint at this content block. + */ + cache_control?: BetaCacheControlEphemeral | null; +} + +export type BetaWebSearchToolResultBlockParamContent = + | Array + | BetaWebSearchToolRequestError; + +export interface BetaWebSearchToolResultError { + error_code: + | 'invalid_tool_input' + | 'unavailable' + | 'max_uses_exceeded' + | 'too_many_requests' + | 'query_too_long'; + + type: 'web_search_tool_result_error'; } export type MessageCreateParams = MessageCreateParamsNonStreaming | MessageCreateParamsStreaming; @@ -1018,6 +1304,8 @@ export interface MessageCreateParamsBase { * [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use * the top-level `system` parameter — there is no `"system"` role for input * messages in the Messages API. + * + * There is a limit of 100000 messages in a single request. */ messages: Array; @@ -1313,6 +1601,8 @@ export interface MessageCountTokensParams { * [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use * the top-level `system` parameter — there is no `"system"` role for input * messages in the Messages API. + * + * There is a limit of 100000 messages in a single request. */ messages: Array; @@ -1423,13 +1713,14 @@ export interface MessageCountTokensParams { * See our [guide](https://docs.anthropic.com/en/docs/tool-use) for more details. */ tools?: Array< + | BetaTool | BetaToolComputerUse20241022 | BetaToolBash20241022 | BetaToolTextEditor20241022 | BetaToolComputerUse20250124 | BetaToolBash20250124 | BetaToolTextEditor20250124 - | BetaTool + | BetaWebSearchTool20250305 >; /** @@ -1452,8 +1743,10 @@ export declare namespace Messages { type BetaCitationContentBlockLocationParam as BetaCitationContentBlockLocationParam, type BetaCitationPageLocation as BetaCitationPageLocation, type BetaCitationPageLocationParam as BetaCitationPageLocationParam, + type BetaCitationWebSearchResultLocationParam as BetaCitationWebSearchResultLocationParam, type BetaCitationsConfigParam as BetaCitationsConfigParam, type BetaCitationsDelta as BetaCitationsDelta, + type BetaCitationsWebSearchResultLocation as BetaCitationsWebSearchResultLocation, type BetaContentBlock as BetaContentBlock, type BetaContentBlockParam as BetaContentBlockParam, type BetaContentBlockSource as BetaContentBlockSource, @@ -1476,6 +1769,9 @@ export declare namespace Messages { type BetaRawMessageStreamEvent as BetaRawMessageStreamEvent, type BetaRedactedThinkingBlock as BetaRedactedThinkingBlock, type BetaRedactedThinkingBlockParam as BetaRedactedThinkingBlockParam, + type BetaServerToolUsage as BetaServerToolUsage, + type BetaServerToolUseBlock as BetaServerToolUseBlock, + type BetaServerToolUseBlockParam as BetaServerToolUseBlockParam, type BetaSignatureDelta as BetaSignatureDelta, type BetaStopReason as BetaStopReason, type BetaTextBlock as BetaTextBlock, @@ -1508,6 +1804,15 @@ export declare namespace Messages { type BetaURLImageSource as BetaURLImageSource, type BetaURLPDFSource as BetaURLPDFSource, type BetaUsage as BetaUsage, + type BetaWebSearchResultBlock as BetaWebSearchResultBlock, + type BetaWebSearchResultBlockParam as BetaWebSearchResultBlockParam, + type BetaWebSearchTool20250305 as BetaWebSearchTool20250305, + type BetaWebSearchToolRequestError as BetaWebSearchToolRequestError, + type BetaWebSearchToolResultBlock as BetaWebSearchToolResultBlock, + type BetaWebSearchToolResultBlockContent as BetaWebSearchToolResultBlockContent, + type BetaWebSearchToolResultBlockParam as BetaWebSearchToolResultBlockParam, + type BetaWebSearchToolResultBlockParamContent as BetaWebSearchToolResultBlockParamContent, + type BetaWebSearchToolResultError as BetaWebSearchToolResultError, type MessageCreateParams as MessageCreateParams, type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming, type MessageCreateParamsStreaming as MessageCreateParamsStreaming, diff --git a/src/resources/beta/models.ts b/src/resources/beta/models.ts index c5bfee58..94473d38 100644 --- a/src/resources/beta/models.ts +++ b/src/resources/beta/models.ts @@ -1,8 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../../core/resource'; +import * as BetaAPI from './beta'; import { APIPromise } from '../../core/api-promise'; import { Page, type PageParams, PagePromise } from '../../core/pagination'; +import { buildHeaders } from '../../internal/headers'; import { RequestOptions } from '../../internal/request-options'; import { path } from '../../internal/utils/path'; @@ -20,8 +22,19 @@ export class Models extends APIResource { * ); * ``` */ - retrieve(modelID: string, options?: RequestOptions): APIPromise { - return this._client.get(path`/v1/models/${modelID}?beta=true`, options); + retrieve( + modelID: string, + params: ModelRetrieveParams | null | undefined = {}, + options?: RequestOptions, + ): APIPromise { + const { betas } = params ?? {}; + return this._client.get(path`/v1/models/${modelID}?beta=true`, { + ...options, + headers: buildHeaders([ + { ...(betas?.toString() != null ? { 'anthropic-beta': betas?.toString() } : undefined) }, + options?.headers, + ]), + }); } /** @@ -39,10 +52,18 @@ export class Models extends APIResource { * ``` */ list( - query: ModelListParams | null | undefined = {}, + params: ModelListParams | null | undefined = {}, options?: RequestOptions, ): PagePromise { - return this._client.getAPIList('/v1/models?beta=true', Page, { query, ...options }); + const { betas, ...query } = params ?? {}; + return this._client.getAPIList('/v1/models?beta=true', Page, { + query, + ...options, + headers: buildHeaders([ + { ...(betas?.toString() != null ? { 'anthropic-beta': betas?.toString() } : undefined) }, + options?.headers, + ]), + }); } } @@ -73,12 +94,25 @@ export interface BetaModelInfo { type: 'model'; } -export interface ModelListParams extends PageParams {} +export interface ModelRetrieveParams { + /** + * Optional header to specify the beta version(s) you want to use. + */ + betas?: Array; +} + +export interface ModelListParams extends PageParams { + /** + * Header param: Optional header to specify the beta version(s) you want to use. + */ + betas?: Array; +} export declare namespace Models { export { type BetaModelInfo as BetaModelInfo, type BetaModelInfosPage as BetaModelInfosPage, + type ModelRetrieveParams as ModelRetrieveParams, type ModelListParams as ModelListParams, }; } diff --git a/src/resources/completions.ts b/src/resources/completions.ts index 154bed28..fc52a9ff 100644 --- a/src/resources/completions.ts +++ b/src/resources/completions.ts @@ -2,9 +2,11 @@ import { APIResource } from '../core/resource'; import * as CompletionsAPI from './completions'; +import * as BetaAPI from './beta/beta'; import * as MessagesAPI from './messages/messages'; import { APIPromise } from '../core/api-promise'; import { Stream } from '../core/streaming'; +import { buildHeaders } from '../internal/headers'; import { RequestOptions } from '../internal/request-options'; export class Completions extends APIResource { @@ -27,21 +29,26 @@ export class Completions extends APIResource { * }); * ``` */ - create(body: CompletionCreateParamsNonStreaming, options?: RequestOptions): APIPromise; - create(body: CompletionCreateParamsStreaming, options?: RequestOptions): APIPromise>; + create(params: CompletionCreateParamsNonStreaming, options?: RequestOptions): APIPromise; + create(params: CompletionCreateParamsStreaming, options?: RequestOptions): APIPromise>; create( - body: CompletionCreateParamsBase, + params: CompletionCreateParamsBase, options?: RequestOptions, ): APIPromise | Completion>; create( - body: CompletionCreateParams, + params: CompletionCreateParams, options?: RequestOptions, ): APIPromise | APIPromise> { + const { betas, ...body } = params; return this._client.post('/v1/complete', { body, timeout: (this._client as any)._options.timeout ?? 600000, ...options, - stream: body.stream ?? false, + headers: buildHeaders([ + { ...(betas?.toString() != null ? { 'anthropic-beta': betas?.toString() } : undefined) }, + options?.headers, + ]), + stream: params.stream ?? false, }) as APIPromise | APIPromise>; } } @@ -89,7 +96,7 @@ export type CompletionCreateParams = CompletionCreateParamsNonStreaming | Comple export interface CompletionCreateParamsBase { /** - * The maximum number of tokens to generate before stopping. + * Body param: The maximum number of tokens to generate before stopping. * * Note that our models may stop _before_ reaching this maximum. This parameter * only specifies the absolute maximum number of tokens to generate. @@ -97,14 +104,14 @@ export interface CompletionCreateParamsBase { max_tokens_to_sample: number; /** - * The model that will complete your prompt.\n\nSee + * Body param: The model that will complete your prompt.\n\nSee * [models](https://docs.anthropic.com/en/docs/models-overview) for additional * details and options. */ model: MessagesAPI.Model; /** - * The prompt that you want Claude to complete. + * Body param: The prompt that you want Claude to complete. * * For proper response generation you will need to format your prompt using * alternating `\n\nHuman:` and `\n\nAssistant:` conversational turns. For example: @@ -121,12 +128,12 @@ export interface CompletionCreateParamsBase { prompt: string; /** - * An object describing metadata about the request. + * Body param: An object describing metadata about the request. */ metadata?: MessagesAPI.Metadata; /** - * Sequences that will cause the model to stop generating. + * Body param: Sequences that will cause the model to stop generating. * * Our models stop on `"\n\nHuman:"`, and may include additional built-in stop * sequences in the future. By providing the stop_sequences parameter, you may @@ -135,14 +142,15 @@ export interface CompletionCreateParamsBase { stop_sequences?: Array; /** - * Whether to incrementally stream the response using server-sent events. + * Body param: Whether to incrementally stream the response using server-sent + * events. * * See [streaming](https://docs.anthropic.com/en/api/streaming) for details. */ stream?: boolean; /** - * Amount of randomness injected into the response. + * Body param: Amount of randomness injected into the response. * * Defaults to `1.0`. Ranges from `0.0` to `1.0`. Use `temperature` closer to `0.0` * for analytical / multiple choice, and closer to `1.0` for creative and @@ -154,7 +162,7 @@ export interface CompletionCreateParamsBase { temperature?: number; /** - * Only sample from the top K options for each subsequent token. + * Body param: Only sample from the top K options for each subsequent token. * * Used to remove "long tail" low probability responses. * [Learn more technical details here](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277). @@ -165,7 +173,7 @@ export interface CompletionCreateParamsBase { top_k?: number; /** - * Use nucleus sampling. + * Body param: Use nucleus sampling. * * In nucleus sampling, we compute the cumulative distribution over all the options * for each subsequent token in decreasing probability order and cut it off once it @@ -176,6 +184,11 @@ export interface CompletionCreateParamsBase { * `temperature`. */ top_p?: number; + + /** + * Header param: Optional header to specify the beta version(s) you want to use. + */ + betas?: Array; } export namespace CompletionCreateParams { @@ -190,7 +203,8 @@ export namespace CompletionCreateParams { export interface CompletionCreateParamsNonStreaming extends CompletionCreateParamsBase { /** - * Whether to incrementally stream the response using server-sent events. + * Body param: Whether to incrementally stream the response using server-sent + * events. * * See [streaming](https://docs.anthropic.com/en/api/streaming) for details. */ @@ -199,7 +213,8 @@ export interface CompletionCreateParamsNonStreaming extends CompletionCreatePara export interface CompletionCreateParamsStreaming extends CompletionCreateParamsBase { /** - * Whether to incrementally stream the response using server-sent events. + * Body param: Whether to incrementally stream the response using server-sent + * events. * * See [streaming](https://docs.anthropic.com/en/api/streaming) for details. */ diff --git a/src/resources/index.ts b/src/resources/index.ts index 6a9c77f6..9f7f6fdb 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -34,8 +34,10 @@ export { type CitationContentBlockLocationParam, type CitationPageLocation, type CitationPageLocationParam, + type CitationWebSearchResultLocationParam, type CitationsConfigParam, type CitationsDelta, + type CitationsWebSearchResultLocation, type ContentBlock, type ContentBlockDeltaEvent, type ContentBlockParam, @@ -66,6 +68,9 @@ export { type RawMessageStreamEvent, type RedactedThinkingBlock, type RedactedThinkingBlockParam, + type ServerToolUsage, + type ServerToolUseBlock, + type ServerToolUseBlockParam, type SignatureDelta, type StopReason, type TextBlock, @@ -94,9 +99,24 @@ export { type URLImageSource, type URLPDFSource, type Usage, + type WebSearchResultBlock, + type WebSearchResultBlockParam, + type WebSearchTool20250305, + type WebSearchToolRequestError, + type WebSearchToolResultBlock, + type WebSearchToolResultBlockContent, + type WebSearchToolResultBlockParam, + type WebSearchToolResultBlockParamContent, + type WebSearchToolResultError, type MessageCreateParams, type MessageCreateParamsNonStreaming, type MessageCreateParamsStreaming, type MessageCountTokensParams, } from './messages/messages'; -export { Models, type ModelInfo, type ModelListParams, type ModelInfosPage } from './models'; +export { + Models, + type ModelInfo, + type ModelRetrieveParams, + type ModelListParams, + type ModelInfosPage, +} from './models'; diff --git a/src/resources/messages/index.ts b/src/resources/messages/index.ts index a02640e3..878c8b57 100644 --- a/src/resources/messages/index.ts +++ b/src/resources/messages/index.ts @@ -26,8 +26,10 @@ export { type CitationContentBlockLocationParam, type CitationPageLocation, type CitationPageLocationParam, + type CitationWebSearchResultLocationParam, type CitationsConfigParam, type CitationsDelta, + type CitationsWebSearchResultLocation, type ContentBlock, type ContentBlockDeltaEvent, type ContentBlockParam, @@ -60,6 +62,9 @@ export { type RawMessageStreamEvent, type RedactedThinkingBlock, type RedactedThinkingBlockParam, + type ServerToolUsage, + type ServerToolUseBlock, + type ServerToolUseBlockParam, type SignatureDelta, type StopReason, type TextBlock, @@ -88,6 +93,15 @@ export { type URLImageSource, type URLPDFSource, type Usage, + type WebSearchResultBlock, + type WebSearchResultBlockParam, + type WebSearchTool20250305, + type WebSearchToolRequestError, + type WebSearchToolResultBlock, + type WebSearchToolResultBlockContent, + type WebSearchToolResultBlockParam, + type WebSearchToolResultBlockParamContent, + type WebSearchToolResultError, type MessageCreateParams, type MessageCreateParamsBase, type MessageCreateParamsNonStreaming, diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts index 6cb42156..6d5b3f07 100644 --- a/src/resources/messages/messages.ts +++ b/src/resources/messages/messages.ts @@ -210,17 +210,51 @@ export interface CitationPageLocationParam { type: 'page_location'; } +export interface CitationWebSearchResultLocationParam { + cited_text: string; + + encrypted_index: string; + + title: string | null; + + type: 'web_search_result_location'; + + url: string; +} + export interface CitationsConfigParam { enabled?: boolean; } export interface CitationsDelta { - citation: CitationCharLocation | CitationPageLocation | CitationContentBlockLocation; + citation: + | CitationCharLocation + | CitationPageLocation + | CitationContentBlockLocation + | CitationsWebSearchResultLocation; type: 'citations_delta'; } -export type ContentBlock = TextBlock | ToolUseBlock | ThinkingBlock | RedactedThinkingBlock; +export interface CitationsWebSearchResultLocation { + cited_text: string; + + encrypted_index: string; + + title: string | null; + + type: 'web_search_result_location'; + + url: string; +} + +export type ContentBlock = + | TextBlock + | ToolUseBlock + | ServerToolUseBlock + | WebSearchToolResultBlock + | ThinkingBlock + | RedactedThinkingBlock; export type ContentBlockDeltaEvent = RawContentBlockDeltaEvent; @@ -228,6 +262,8 @@ export type ContentBlockParam = | TextBlockParam | ImageBlockParam | ToolUseBlockParam + | ServerToolUseBlockParam + | WebSearchToolResultBlockParam | ToolResultBlockParam | DocumentBlockParam | ThinkingBlockParam @@ -250,6 +286,9 @@ export interface DocumentBlockParam { type: 'document'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: CacheControlEphemeral | null; citations?: CitationsConfigParam; @@ -264,6 +303,9 @@ export interface ImageBlockParam { type: 'image'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: CacheControlEphemeral | null; } @@ -381,15 +423,35 @@ export interface Message { usage: Usage; } -export type MessageCountTokensTool = ToolBash20250124 | ToolTextEditor20250124 | Tool; +export type MessageCountTokensTool = Tool | ToolBash20250124 | ToolTextEditor20250124 | WebSearchTool20250305; export type MessageDeltaEvent = RawMessageDeltaEvent; export interface MessageDeltaUsage { + /** + * The cumulative number of input tokens used to create the cache entry. + */ + cache_creation_input_tokens: number | null; + + /** + * The cumulative number of input tokens read from the cache. + */ + cache_read_input_tokens: number | null; + + /** + * The cumulative number of input tokens which were used. + */ + input_tokens: number | null; + /** * The cumulative number of output tokens which were used. */ output_tokens: number; + + /** + * The number of server tool requests. + */ + server_tool_use: ServerToolUsage | null; } export interface MessageParam { @@ -480,7 +542,13 @@ export interface RawContentBlockDeltaEvent { } export interface RawContentBlockStartEvent { - content_block: TextBlock | ToolUseBlock | ThinkingBlock | RedactedThinkingBlock; + content_block: + | TextBlock + | ToolUseBlock + | ServerToolUseBlock + | WebSearchToolResultBlock + | ThinkingBlock + | RedactedThinkingBlock; index: number; @@ -556,13 +624,45 @@ export interface RedactedThinkingBlockParam { type: 'redacted_thinking'; } +export interface ServerToolUsage { + /** + * The number of web search tool requests. + */ + web_search_requests: number; +} + +export interface ServerToolUseBlock { + id: string; + + input: unknown; + + name: 'web_search'; + + type: 'server_tool_use'; +} + +export interface ServerToolUseBlockParam { + id: string; + + input: unknown; + + name: 'web_search'; + + type: 'server_tool_use'; + + /** + * Create a cache control breakpoint at this content block. + */ + cache_control?: CacheControlEphemeral | null; +} + export interface SignatureDelta { signature: string; type: 'signature_delta'; } -export type StopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use'; +export type StopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | 'pause_turn' | 'refusal'; export interface TextBlock { /** @@ -584,17 +684,25 @@ export interface TextBlockParam { type: 'text'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: CacheControlEphemeral | null; citations?: Array | null; } -export type TextCitation = CitationCharLocation | CitationPageLocation | CitationContentBlockLocation; +export type TextCitation = + | CitationCharLocation + | CitationPageLocation + | CitationContentBlockLocation + | CitationsWebSearchResultLocation; export type TextCitationParam = | CitationCharLocationParam | CitationPageLocationParam - | CitationContentBlockLocationParam; + | CitationContentBlockLocationParam + | CitationWebSearchResultLocationParam; export interface TextDelta { text: string; @@ -670,10 +778,13 @@ export interface Tool { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: string; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: CacheControlEphemeral | null; /** @@ -685,6 +796,8 @@ export interface Tool { * aspects of the tool input JSON schema. */ description?: string; + + type?: 'custom' | null; } export namespace Tool { @@ -707,12 +820,15 @@ export interface ToolBash20250124 { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: 'bash'; type: 'bash_20250124'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: CacheControlEphemeral | null; } @@ -784,6 +900,9 @@ export interface ToolResultBlockParam { type: 'tool_result'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: CacheControlEphemeral | null; content?: string | Array; @@ -795,16 +914,19 @@ export interface ToolTextEditor20250124 { /** * Name of the tool. * - * This is how the tool will be called by the model and in tool_use blocks. + * This is how the tool will be called by the model and in `tool_use` blocks. */ name: 'str_replace_editor'; type: 'text_editor_20250124'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: CacheControlEphemeral | null; } -export type ToolUnion = ToolBash20250124 | ToolTextEditor20250124 | Tool; +export type ToolUnion = Tool | ToolBash20250124 | ToolTextEditor20250124 | WebSearchTool20250305; export interface ToolUseBlock { id: string; @@ -825,6 +947,9 @@ export interface ToolUseBlockParam { type: 'tool_use'; + /** + * Create a cache control breakpoint at this content block. + */ cache_control?: CacheControlEphemeral | null; } @@ -860,6 +985,155 @@ export interface Usage { * The number of output tokens which were used. */ output_tokens: number; + + /** + * The number of server tool requests. + */ + server_tool_use: ServerToolUsage | null; +} + +export interface WebSearchResultBlock { + encrypted_content: string; + + page_age: string | null; + + title: string; + + type: 'web_search_result'; + + url: string; +} + +export interface WebSearchResultBlockParam { + encrypted_content: string; + + title: string; + + type: 'web_search_result'; + + url: string; + + page_age?: string | null; +} + +export interface WebSearchTool20250305 { + /** + * Name of the tool. + * + * This is how the tool will be called by the model and in `tool_use` blocks. + */ + name: 'web_search'; + + type: 'web_search_20250305'; + + /** + * If provided, only these domains will be included in results. Cannot be used + * alongside `blocked_domains`. + */ + allowed_domains?: Array | null; + + /** + * If provided, these domains will never appear in results. Cannot be used + * alongside `allowed_domains`. + */ + blocked_domains?: Array | null; + + /** + * Create a cache control breakpoint at this content block. + */ + cache_control?: CacheControlEphemeral | null; + + /** + * Maximum number of times the tool can be used in the API request. + */ + max_uses?: number | null; + + /** + * Parameters for the user's location. Used to provide more relevant search + * results. + */ + user_location?: WebSearchTool20250305.UserLocation | null; +} + +export namespace WebSearchTool20250305 { + /** + * Parameters for the user's location. Used to provide more relevant search + * results. + */ + export interface UserLocation { + type: 'approximate'; + + /** + * The city of the user. + */ + city?: string | null; + + /** + * The two letter + * [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of the + * user. + */ + country?: string | null; + + /** + * The region of the user. + */ + region?: string | null; + + /** + * The [IANA timezone](https://nodatime.org/TimeZones) of the user. + */ + timezone?: string | null; + } +} + +export interface WebSearchToolRequestError { + error_code: + | 'invalid_tool_input' + | 'unavailable' + | 'max_uses_exceeded' + | 'too_many_requests' + | 'query_too_long'; + + type: 'web_search_tool_result_error'; +} + +export interface WebSearchToolResultBlock { + content: WebSearchToolResultBlockContent; + + tool_use_id: string; + + type: 'web_search_tool_result'; +} + +export type WebSearchToolResultBlockContent = WebSearchToolResultError | Array; + +export interface WebSearchToolResultBlockParam { + content: WebSearchToolResultBlockParamContent; + + tool_use_id: string; + + type: 'web_search_tool_result'; + + /** + * Create a cache control breakpoint at this content block. + */ + cache_control?: CacheControlEphemeral | null; +} + +export type WebSearchToolResultBlockParamContent = + | Array + | WebSearchToolRequestError; + +export interface WebSearchToolResultError { + error_code: + | 'invalid_tool_input' + | 'unavailable' + | 'max_uses_exceeded' + | 'too_many_requests' + | 'query_too_long'; + + type: 'web_search_tool_result_error'; } export type MessageCreateParams = MessageCreateParamsNonStreaming | MessageCreateParamsStreaming; @@ -963,6 +1237,8 @@ export interface MessageCreateParamsBase { * [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use * the top-level `system` parameter — there is no `"system"` role for input * messages in the Messages API. + * + * There is a limit of 100000 messages in a single request. */ messages: Array; @@ -1272,6 +1548,8 @@ export interface MessageCountTokensParams { * [system prompt](https://docs.anthropic.com/en/docs/system-prompts), you can use * the top-level `system` parameter — there is no `"system"` role for input * messages in the Messages API. + * + * There is a limit of 100000 messages in a single request. */ messages: Array; @@ -1397,8 +1675,10 @@ export declare namespace Messages { type CitationContentBlockLocationParam as CitationContentBlockLocationParam, type CitationPageLocation as CitationPageLocation, type CitationPageLocationParam as CitationPageLocationParam, + type CitationWebSearchResultLocationParam as CitationWebSearchResultLocationParam, type CitationsConfigParam as CitationsConfigParam, type CitationsDelta as CitationsDelta, + type CitationsWebSearchResultLocation as CitationsWebSearchResultLocation, type ContentBlock as ContentBlock, type ContentBlockDeltaEvent as ContentBlockDeltaEvent, type ContentBlockParam as ContentBlockParam, @@ -1431,6 +1711,9 @@ export declare namespace Messages { type RawMessageStreamEvent as RawMessageStreamEvent, type RedactedThinkingBlock as RedactedThinkingBlock, type RedactedThinkingBlockParam as RedactedThinkingBlockParam, + type ServerToolUsage as ServerToolUsage, + type ServerToolUseBlock as ServerToolUseBlock, + type ServerToolUseBlockParam as ServerToolUseBlockParam, type SignatureDelta as SignatureDelta, type StopReason as StopReason, type TextBlock as TextBlock, @@ -1459,6 +1742,15 @@ export declare namespace Messages { type URLImageSource as URLImageSource, type URLPDFSource as URLPDFSource, type Usage as Usage, + type WebSearchResultBlock as WebSearchResultBlock, + type WebSearchResultBlockParam as WebSearchResultBlockParam, + type WebSearchTool20250305 as WebSearchTool20250305, + type WebSearchToolRequestError as WebSearchToolRequestError, + type WebSearchToolResultBlock as WebSearchToolResultBlock, + type WebSearchToolResultBlockContent as WebSearchToolResultBlockContent, + type WebSearchToolResultBlockParam as WebSearchToolResultBlockParam, + type WebSearchToolResultBlockParamContent as WebSearchToolResultBlockParamContent, + type WebSearchToolResultError as WebSearchToolResultError, type MessageCreateParams as MessageCreateParams, type MessageCreateParamsNonStreaming as MessageCreateParamsNonStreaming, type MessageCreateParamsStreaming as MessageCreateParamsStreaming, diff --git a/src/resources/models.ts b/src/resources/models.ts index df65f9b9..b42ae355 100644 --- a/src/resources/models.ts +++ b/src/resources/models.ts @@ -1,8 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../core/resource'; +import * as BetaAPI from './beta/beta'; import { APIPromise } from '../core/api-promise'; import { Page, type PageParams, PagePromise } from '../core/pagination'; +import { buildHeaders } from '../internal/headers'; import { RequestOptions } from '../internal/request-options'; import { path } from '../internal/utils/path'; @@ -13,8 +15,19 @@ export class Models extends APIResource { * The Models API response can be used to determine information about a specific * model or resolve a model alias to a model ID. */ - retrieve(modelID: string, options?: RequestOptions): APIPromise { - return this._client.get(path`/v1/models/${modelID}`, options); + retrieve( + modelID: string, + params: ModelRetrieveParams | null | undefined = {}, + options?: RequestOptions, + ): APIPromise { + const { betas } = params ?? {}; + return this._client.get(path`/v1/models/${modelID}`, { + ...options, + headers: buildHeaders([ + { ...(betas?.toString() != null ? { 'anthropic-beta': betas?.toString() } : undefined) }, + options?.headers, + ]), + }); } /** @@ -24,10 +37,18 @@ export class Models extends APIResource { * use in the API. More recently released models are listed first. */ list( - query: ModelListParams | null | undefined = {}, + params: ModelListParams | null | undefined = {}, options?: RequestOptions, ): PagePromise { - return this._client.getAPIList('/v1/models', Page, { query, ...options }); + const { betas, ...query } = params ?? {}; + return this._client.getAPIList('/v1/models', Page, { + query, + ...options, + headers: buildHeaders([ + { ...(betas?.toString() != null ? { 'anthropic-beta': betas?.toString() } : undefined) }, + options?.headers, + ]), + }); } } @@ -58,12 +79,25 @@ export interface ModelInfo { type: 'model'; } -export interface ModelListParams extends PageParams {} +export interface ModelRetrieveParams { + /** + * Optional header to specify the beta version(s) you want to use. + */ + betas?: Array; +} + +export interface ModelListParams extends PageParams { + /** + * Header param: Optional header to specify the beta version(s) you want to use. + */ + betas?: Array; +} export declare namespace Models { export { type ModelInfo as ModelInfo, type ModelInfosPage as ModelInfosPage, + type ModelRetrieveParams as ModelRetrieveParams, type ModelListParams as ModelListParams, }; } diff --git a/tests/api-resources/beta/models.test.ts b/tests/api-resources/beta/models.test.ts index 92df4bc3..805d1501 100644 --- a/tests/api-resources/beta/models.test.ts +++ b/tests/api-resources/beta/models.test.ts @@ -19,6 +19,13 @@ describe('resource models', () => { expect(dataAndResponse.response).toBe(rawResponse); }); + test('retrieve: request options and params are passed correctly', async () => { + // 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.retrieve('model_id', { betas: ['string'] }, { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(Anthropic.NotFoundError); + }); + test('list', async () => { const responsePromise = client.beta.models.list(); const rawResponse = await responsePromise.asResponse(); @@ -34,7 +41,7 @@ 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 }, + { 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/completions.test.ts b/tests/api-resources/completions.test.ts index c451afb9..1b1bfc3d 100644 --- a/tests/api-resources/completions.test.ts +++ b/tests/api-resources/completions.test.ts @@ -34,6 +34,7 @@ describe('resource completions', () => { temperature: 1, top_k: 5, top_p: 0.7, + betas: ['string'], }); }); }); diff --git a/tests/api-resources/models.test.ts b/tests/api-resources/models.test.ts index f1530064..6d7d61e9 100644 --- a/tests/api-resources/models.test.ts +++ b/tests/api-resources/models.test.ts @@ -19,6 +19,13 @@ describe('resource models', () => { expect(dataAndResponse.response).toBe(rawResponse); }); + test('retrieve: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.models.retrieve('model_id', { betas: ['string'] }, { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(Anthropic.NotFoundError); + }); + test('list', async () => { const responsePromise = client.models.list(); const rawResponse = await responsePromise.asResponse(); @@ -34,7 +41,7 @@ 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 }, + { after_id: 'after_id', before_id: 'before_id', limit: 1, betas: ['string'] }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Anthropic.NotFoundError); From 7bd45941a46703db869161fd0585cd209efc782c Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Wed, 7 May 2025 21:11:04 +0100 Subject: [PATCH 100/105] chore(internal): formatting fixes --- .github/workflows/create-releases.yml | 1 - .github/workflows/release-doctor.yml | 1 - README.md | 16 ++++++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/create-releases.yml b/.github/workflows/create-releases.yml index adb4c096..5cd26049 100644 --- a/.github/workflows/create-releases.yml +++ b/.github/workflows/create-releases.yml @@ -41,4 +41,3 @@ jobs: env: DATA: ${{ toJSON(steps.release.outputs) }} NPM_TOKEN: ${{ secrets.ANTHROPIC_NPM_TOKEN || secrets.NPM_TOKEN }} - diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 78458f5c..c80d8dba 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -21,4 +21,3 @@ jobs: env: STAINLESS_API_KEY: ${{ secrets.STAINLESS_API_KEY }} NPM_TOKEN: ${{ secrets.ANTHROPIC_NPM_TOKEN || secrets.NPM_TOKEN }} - diff --git a/README.md b/README.md index bd05be71..23cb04a1 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,6 @@ await anthropic.beta.messages.batches.create({ }); ``` - ### Getting results from a batch Once a Message Batch has been processed, indicated by `.processing_status === 'ended'`, you can access the results with `.batches.results()` @@ -172,7 +171,7 @@ Once a Message Batch has been processed, indicated by `.processing_status === 'e const results = await anthropic.beta.messages.batches.results(batch_id); for await (const entry of results) { if (entry.result.type === 'succeeded') { - console.log(entry.result.message.content) + console.log(entry.result.message.content); } } ``` @@ -234,11 +233,14 @@ Error codes are as follows: 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. ```ts -const message = await client.messages.create({ max_tokens: 1024, messages: [{ role: 'user', content: 'Hello, Claude' }], model: 'claude-3-5-sonnet-latest' }); -console.log(completion._request_id) // req_018EeWyXxfu5pfWkrYcMdjWG +const message = await client.messages.create({ + max_tokens: 1024, + messages: [{ role: 'user', content: 'Hello, Claude' }], + model: 'claude-3-5-sonnet-latest', +}); +console.log(completion._request_id); // req_018EeWyXxfu5pfWkrYcMdjWG ``` - ### Retries Certain errors will be automatically retried 2 times by default, with a short exponential backoff. @@ -263,12 +265,14 @@ await client.messages.create({ max_tokens: 1024, messages: [{ role: 'user', cont ### Timeouts By default requests time out after 10 minutes. However if you have specified a large `max_tokens` value and are -*not* streaming, the default timeout will be calculated dynamically using the formula: +_not_ streaming, the default timeout will be calculated dynamically using the formula: + ```typescript const minimum = 10 * 60; const calculated = (60 * 60 * maxTokens) / 128_000; return calculated < minimum ? minimum * 1000 : calculated * 1000; ``` + which will result in a timeout up to 60 minutes, scaled by the `max_tokens` parameter, unless overriden at the request or client level. You can configure this with a `timeout` option: From a718745e2574d3aa3e2d16a0e32ffc0f1fe53c0a Mon Sep 17 00:00:00 2001 From: Nathan McCandlish <39928272+nsmccandlish@users.noreply.github.com> Date: Mon, 5 May 2025 17:43:12 -0700 Subject: [PATCH 101/105] Update README - tool use is no longer beta --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 23cb04a1..3d54e6f6 100644 --- a/README.md +++ b/README.md @@ -176,9 +176,9 @@ for await (const entry of results) { } ``` -## Tool use beta +## Tool use -This SDK provides beta 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://docs.anthropic.com/claude/docs/tool-use). ## AWS Bedrock From 9f611d6ba8c6b3de02c3183e4f2f42d1540525f0 Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Fri, 25 Apr 2025 09:09:53 -0400 Subject: [PATCH 102/105] chore(bedrock): bump @aws-sdk/credential-providers --- packages/bedrock-sdk/yarn.lock | 1487 ++++++++++++++++++++++++-------- 1 file changed, 1116 insertions(+), 371 deletions(-) diff --git a/packages/bedrock-sdk/yarn.lock b/packages/bedrock-sdk/yarn.lock index 097d5605..093c0d77 100644 --- a/packages/bedrock-sdk/yarn.lock +++ b/packages/bedrock-sdk/yarn.lock @@ -59,6 +59,19 @@ "@aws-sdk/util-utf8-browser" "^3.0.0" tslib "^1.11.1" +"@aws-crypto/sha256-browser@5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz#153895ef1dba6f9fce38af550e0ef58988eb649e" + integrity sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw== + dependencies: + "@aws-crypto/sha256-js" "^5.2.0" + "@aws-crypto/supports-web-crypto" "^5.2.0" + "@aws-crypto/util" "^5.2.0" + "@aws-sdk/types" "^3.222.0" + "@aws-sdk/util-locate-window" "^3.0.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.6.2" + "@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz#f06b84d550d25521e60d2a0e2a90139341e007c2" @@ -68,6 +81,15 @@ "@aws-sdk/types" "^3.222.0" tslib "^1.11.1" +"@aws-crypto/sha256-js@5.2.0", "@aws-crypto/sha256-js@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz#c4fdb773fdbed9a664fc1a95724e206cf3860042" + integrity sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA== + dependencies: + "@aws-crypto/util" "^5.2.0" + "@aws-sdk/types" "^3.222.0" + tslib "^2.6.2" + "@aws-crypto/sha256-js@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-4.0.0.tgz#7feaad4d62cfaf6636a108763d0df0b01574ef0e" @@ -84,6 +106,13 @@ dependencies: tslib "^1.11.1" +"@aws-crypto/supports-web-crypto@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz#a1e399af29269be08e695109aa15da0a07b5b5fb" + integrity sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg== + dependencies: + tslib "^2.6.2" + "@aws-crypto/util@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-3.0.0.tgz#1c7ca90c29293f0883468ad48117937f0fe5bfb0" @@ -102,6 +131,15 @@ "@aws-sdk/util-utf8-browser" "^3.0.0" tslib "^1.11.1" +"@aws-crypto/util@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-5.2.0.tgz#71284c9cffe7927ddadac793c14f14886d3876da" + integrity sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ== + dependencies: + "@aws-sdk/types" "^3.222.0" + "@smithy/util-utf8" "^2.0.0" + tslib "^2.6.2" + "@aws-sdk/client-bedrock-runtime@^3.423.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.496.0.tgz#094e17ed2f559e9cc39f375ca9c340ecbd9ddbf8" @@ -152,51 +190,50 @@ "@smithy/util-utf8" "^2.1.1" tslib "^2.5.0" -"@aws-sdk/client-cognito-identity@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.496.0.tgz#fe7e3b56b2d1186c0164f2bbf591fb7371c5921f" - integrity sha512-rb0Pv8jzJ8XBNmhKl/Up8jnaLWPKuW622s9RR9JyVEu/uUR5tyhdEJvEsS88A9a0+BTRt4G7X1VnUXWAgi8hxQ== - dependencies: - "@aws-crypto/sha256-browser" "3.0.0" - "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/client-sts" "3.496.0" - "@aws-sdk/core" "3.496.0" - "@aws-sdk/credential-provider-node" "3.496.0" - "@aws-sdk/middleware-host-header" "3.496.0" - "@aws-sdk/middleware-logger" "3.496.0" - "@aws-sdk/middleware-recursion-detection" "3.496.0" - "@aws-sdk/middleware-signing" "3.496.0" - "@aws-sdk/middleware-user-agent" "3.496.0" - "@aws-sdk/region-config-resolver" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@aws-sdk/util-endpoints" "3.496.0" - "@aws-sdk/util-user-agent-browser" "3.496.0" - "@aws-sdk/util-user-agent-node" "3.496.0" - "@smithy/config-resolver" "^2.1.1" - "@smithy/core" "^1.3.1" - "@smithy/fetch-http-handler" "^2.4.1" - "@smithy/hash-node" "^2.1.1" - "@smithy/invalid-dependency" "^2.1.1" - "@smithy/middleware-content-length" "^2.1.1" - "@smithy/middleware-endpoint" "^2.4.1" - "@smithy/middleware-retry" "^2.1.1" - "@smithy/middleware-serde" "^2.1.1" - "@smithy/middleware-stack" "^2.1.1" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/node-http-handler" "^2.3.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/url-parser" "^2.1.1" - "@smithy/util-base64" "^2.1.1" - "@smithy/util-body-length-browser" "^2.1.1" - "@smithy/util-body-length-node" "^2.2.1" - "@smithy/util-defaults-mode-browser" "^2.1.1" - "@smithy/util-defaults-mode-node" "^2.1.1" - "@smithy/util-endpoints" "^1.1.1" - "@smithy/util-retry" "^2.1.1" - "@smithy/util-utf8" "^2.1.1" - tslib "^2.5.0" +"@aws-sdk/client-cognito-identity@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.796.0.tgz#8dcb4cb37789f887ed77e3fdcae8cfe1fff6cada" + integrity sha512-p8ZzHICnQaCL4oS16yHUCLH6/VkbmWP8p2P7vALncUYguHDE/oNcWNAARo56x3Qx0TbRCi0OD4KAwD6AhddMdg== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/core" "3.796.0" + "@aws-sdk/credential-provider-node" "3.796.0" + "@aws-sdk/middleware-host-header" "3.775.0" + "@aws-sdk/middleware-logger" "3.775.0" + "@aws-sdk/middleware-recursion-detection" "3.775.0" + "@aws-sdk/middleware-user-agent" "3.796.0" + "@aws-sdk/region-config-resolver" "3.775.0" + "@aws-sdk/types" "3.775.0" + "@aws-sdk/util-endpoints" "3.787.0" + "@aws-sdk/util-user-agent-browser" "3.775.0" + "@aws-sdk/util-user-agent-node" "3.796.0" + "@smithy/config-resolver" "^4.1.0" + "@smithy/core" "^3.2.0" + "@smithy/fetch-http-handler" "^5.0.2" + "@smithy/hash-node" "^4.0.2" + "@smithy/invalid-dependency" "^4.0.2" + "@smithy/middleware-content-length" "^4.0.2" + "@smithy/middleware-endpoint" "^4.1.0" + "@smithy/middleware-retry" "^4.1.0" + "@smithy/middleware-serde" "^4.0.3" + "@smithy/middleware-stack" "^4.0.2" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/node-http-handler" "^4.0.4" + "@smithy/protocol-http" "^5.1.0" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + "@smithy/url-parser" "^4.0.2" + "@smithy/util-base64" "^4.0.0" + "@smithy/util-body-length-browser" "^4.0.0" + "@smithy/util-body-length-node" "^4.0.0" + "@smithy/util-defaults-mode-browser" "^4.0.8" + "@smithy/util-defaults-mode-node" "^4.0.8" + "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-middleware" "^4.0.2" + "@smithy/util-retry" "^4.0.2" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" "@aws-sdk/client-sso@3.496.0": version "3.496.0" @@ -241,6 +278,50 @@ "@smithy/util-utf8" "^2.1.1" tslib "^2.5.0" +"@aws-sdk/client-sso@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.796.0.tgz#231fc98bd71c5e915e9060fba871a6d9d9ccb3d6" + integrity sha512-EJExg8mbwqP0VG+RNFV4ZPuUo7QsDsUfTnuFQY51V8iXrbOdV+PDLRr4psXj2fxvrLxc9AlGUMNqd/j4VZtQzA== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/core" "3.796.0" + "@aws-sdk/middleware-host-header" "3.775.0" + "@aws-sdk/middleware-logger" "3.775.0" + "@aws-sdk/middleware-recursion-detection" "3.775.0" + "@aws-sdk/middleware-user-agent" "3.796.0" + "@aws-sdk/region-config-resolver" "3.775.0" + "@aws-sdk/types" "3.775.0" + "@aws-sdk/util-endpoints" "3.787.0" + "@aws-sdk/util-user-agent-browser" "3.775.0" + "@aws-sdk/util-user-agent-node" "3.796.0" + "@smithy/config-resolver" "^4.1.0" + "@smithy/core" "^3.2.0" + "@smithy/fetch-http-handler" "^5.0.2" + "@smithy/hash-node" "^4.0.2" + "@smithy/invalid-dependency" "^4.0.2" + "@smithy/middleware-content-length" "^4.0.2" + "@smithy/middleware-endpoint" "^4.1.0" + "@smithy/middleware-retry" "^4.1.0" + "@smithy/middleware-serde" "^4.0.3" + "@smithy/middleware-stack" "^4.0.2" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/node-http-handler" "^4.0.4" + "@smithy/protocol-http" "^5.1.0" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + "@smithy/url-parser" "^4.0.2" + "@smithy/util-base64" "^4.0.0" + "@smithy/util-body-length-browser" "^4.0.0" + "@smithy/util-body-length-node" "^4.0.0" + "@smithy/util-defaults-mode-browser" "^4.0.8" + "@smithy/util-defaults-mode-node" "^4.0.8" + "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-middleware" "^4.0.2" + "@smithy/util-retry" "^4.0.2" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" + "@aws-sdk/client-sts@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.496.0.tgz#e0c142cf8bb1aec7a9c7b09dd9739f6773d94fd0" @@ -299,16 +380,33 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" -"@aws-sdk/credential-provider-cognito-identity@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.496.0.tgz#cb4105e9247bdee4b6cef4551f6d5939f9519bb4" - integrity sha512-LIB9hom5mqGxk+hdbpZnxIJ4F1c5ZuY5uu3aWy9luowci03Z5nzYYepzBwpoE5Lk102gqVKeia//mRr25blzWQ== +"@aws-sdk/core@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.796.0.tgz#6076b78772c1eb97ec6ea9064c85ce500e0aa889" + integrity sha512-tH8Sp7lCxISVoLnkyv4AouuXs2CDlMhTuesWa0lq2NX1f+DXsMwSBtN37ttZdpFMw3F8mWdsJt27X9h2Oq868A== + dependencies: + "@aws-sdk/types" "3.775.0" + "@smithy/core" "^3.2.0" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/property-provider" "^4.0.2" + "@smithy/protocol-http" "^5.1.0" + "@smithy/signature-v4" "^5.1.0" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + "@smithy/util-middleware" "^4.0.2" + fast-xml-parser "4.4.1" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-cognito-identity@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.796.0.tgz#c037d35d8a8284fc4cc658da9e7a2498f3703f1f" + integrity sha512-plvMsQNWW1Jq7YRs8S6xHEbdn+kO/F+vDjCBrPaT4LhcDMsXqO/jcDNRuYOnPRBQsqjp7n7MM3oMhyY4fupa6g== dependencies: - "@aws-sdk/client-cognito-identity" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@smithy/property-provider" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@aws-sdk/client-cognito-identity" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/property-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" "@aws-sdk/credential-provider-env@3.496.0": version "3.496.0" @@ -320,20 +418,32 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" -"@aws-sdk/credential-provider-http@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.496.0.tgz#7ff281bc0c80a041c69f0062e82b6def2e2a7de5" - integrity sha512-iphFlFX0qDFsE24XmFlcKmsR4uyNaqQrK+Y18mwSZMs1yWtL4Sck0rcTXU/cU2W3/xisjh7xFXK5L5aowjMZOg== +"@aws-sdk/credential-provider-env@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.796.0.tgz#4ed6903814868b0f9daa8c8db449b1f1adcda041" + integrity sha512-kQzGKm4IOYYO6vUrai2JocNwhJm4Aml2BsAV+tBhFhhkutE7khf9PUucoVjB78b0J48nF+kdSacqzY+gB81/Uw== dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/fetch-http-handler" "^2.4.1" - "@smithy/node-http-handler" "^2.3.1" - "@smithy/property-provider" "^2.1.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/util-stream" "^2.1.1" - tslib "^2.5.0" + "@aws-sdk/core" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/property-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@aws-sdk/credential-provider-http@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.796.0.tgz#7f36074021b2605dba4b758b4b0ca98fb5b965ad" + integrity sha512-wWOT6VAHIKOuHdKFGm1iyKvx7f6+Kc/YTzFWJPuT+l+CPlXR6ylP1UMIDsHHLKpMzsrh3CH77QDsjkhQrnKkfg== + dependencies: + "@aws-sdk/core" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/fetch-http-handler" "^5.0.2" + "@smithy/node-http-handler" "^4.0.4" + "@smithy/property-provider" "^4.0.2" + "@smithy/protocol-http" "^5.1.0" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + "@smithy/util-stream" "^4.2.0" + tslib "^2.6.2" "@aws-sdk/credential-provider-ini@3.496.0": version "3.496.0" @@ -351,6 +461,25 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/credential-provider-ini@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.796.0.tgz#6d5f260b93104b126e26919287a4e131d1cb8e75" + integrity sha512-qGWBDn9aO8avFfYU7daps7Sy6OglF1x0q0w48slt0KMXbHd2/LvKVIiYwyofYCXed0yzcEOF2IYm9FjXdcn+ug== + dependencies: + "@aws-sdk/core" "3.796.0" + "@aws-sdk/credential-provider-env" "3.796.0" + "@aws-sdk/credential-provider-http" "3.796.0" + "@aws-sdk/credential-provider-process" "3.796.0" + "@aws-sdk/credential-provider-sso" "3.796.0" + "@aws-sdk/credential-provider-web-identity" "3.796.0" + "@aws-sdk/nested-clients" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/credential-provider-imds" "^4.0.2" + "@smithy/property-provider" "^4.0.2" + "@smithy/shared-ini-file-loader" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/credential-provider-node@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.496.0.tgz#734fc5aa824c387c893ff5624b201c0243ea1c7c" @@ -368,6 +497,24 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/credential-provider-node@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.796.0.tgz#aa621e4f15d7317b351c1dbb896bfcabbc21db0c" + integrity sha512-WeNK7OWPrsOvhO3DAgpUO0FtmVghMaZ/IpPJHJ4Y0nBIsWOBXLrbZ2Y1mdT8N2bGGUaM91tJaV8Yf8COc3gvmA== + dependencies: + "@aws-sdk/credential-provider-env" "3.796.0" + "@aws-sdk/credential-provider-http" "3.796.0" + "@aws-sdk/credential-provider-ini" "3.796.0" + "@aws-sdk/credential-provider-process" "3.796.0" + "@aws-sdk/credential-provider-sso" "3.796.0" + "@aws-sdk/credential-provider-web-identity" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/credential-provider-imds" "^4.0.2" + "@smithy/property-provider" "^4.0.2" + "@smithy/shared-ini-file-loader" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/credential-provider-process@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.496.0.tgz#1d623bed61229767f389feab560e3a3117bf2d26" @@ -379,6 +526,18 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/credential-provider-process@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.796.0.tgz#d22d8adf73985fb218ff74365cd86b71bbd64513" + integrity sha512-r4e8/4AdKn/qQbRVocW7oXkpoiuXdTv0qty8AASNLnbQnT1vjD1bvmP6kp4fbHPWgwY8I9h0Dqjp49uy9Bqyuw== + dependencies: + "@aws-sdk/core" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/property-provider" "^4.0.2" + "@smithy/shared-ini-file-loader" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/credential-provider-sso@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.496.0.tgz#1c5f2d25b64936b79095f49cabbcd7832fb87087" @@ -392,6 +551,20 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/credential-provider-sso@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.796.0.tgz#db9081637747162ed8c5b29c61a98b898eea3e99" + integrity sha512-RUYsQ1t6UdzkpZ7pocUt1l/9l9GCYCaopIhv0DU6CipA8rkWtoweKsLHKdv+8wE4p6gqDfDIHGam1ivswiCIzg== + dependencies: + "@aws-sdk/client-sso" "3.796.0" + "@aws-sdk/core" "3.796.0" + "@aws-sdk/token-providers" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/property-provider" "^4.0.2" + "@smithy/shared-ini-file-loader" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/credential-provider-web-identity@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.496.0.tgz#7ad6d755445d1616a80dfa286a78c84dc1c3f14b" @@ -402,27 +575,42 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" -"@aws-sdk/credential-providers@^3.341.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-providers/-/credential-providers-3.496.0.tgz#ca41a6ee1a8de4b3a44c08624ebd0137cbfd5097" - integrity sha512-JqdSHFY3t+QMdS7Iok/ymvU3bZjVY7YuX9xroJJjMM/gkw+TxnJtVw/uIGsmoK1FT2KX+Dg4i/gmVyQAWubSJw== +"@aws-sdk/credential-provider-web-identity@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.796.0.tgz#8d19749fcf28f6603bb26a402f3f8e24797c35ba" + integrity sha512-dpmFJT4IyjT09vruvMu/rWQQjVreqdxAe8pLPpGhoeKyA1O6+PS73b+VNXKvD31rQT8e4g6dVpA6KMxNW63aag== dependencies: - "@aws-sdk/client-cognito-identity" "3.496.0" - "@aws-sdk/client-sso" "3.496.0" - "@aws-sdk/client-sts" "3.496.0" - "@aws-sdk/credential-provider-cognito-identity" "3.496.0" - "@aws-sdk/credential-provider-env" "3.496.0" - "@aws-sdk/credential-provider-http" "3.496.0" - "@aws-sdk/credential-provider-ini" "3.496.0" - "@aws-sdk/credential-provider-node" "3.496.0" - "@aws-sdk/credential-provider-process" "3.496.0" - "@aws-sdk/credential-provider-sso" "3.496.0" - "@aws-sdk/credential-provider-web-identity" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@smithy/credential-provider-imds" "^2.2.1" - "@smithy/property-provider" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@aws-sdk/core" "3.796.0" + "@aws-sdk/nested-clients" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/property-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@aws-sdk/credential-providers@^3.341.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-providers/-/credential-providers-3.796.0.tgz#60a9544366a08e6e6dc69625a668cfd12b6501d9" + integrity sha512-thZw44Bk3pS0PW81QmPfNSliX5XfXHDlWRjPYHBx+eTlPtidyD5klJkkfF5fkQlpHPeP2KNLuRnr6bRu+uMirg== + dependencies: + "@aws-sdk/client-cognito-identity" "3.796.0" + "@aws-sdk/core" "3.796.0" + "@aws-sdk/credential-provider-cognito-identity" "3.796.0" + "@aws-sdk/credential-provider-env" "3.796.0" + "@aws-sdk/credential-provider-http" "3.796.0" + "@aws-sdk/credential-provider-ini" "3.796.0" + "@aws-sdk/credential-provider-node" "3.796.0" + "@aws-sdk/credential-provider-process" "3.796.0" + "@aws-sdk/credential-provider-sso" "3.796.0" + "@aws-sdk/credential-provider-web-identity" "3.796.0" + "@aws-sdk/nested-clients" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/config-resolver" "^4.1.0" + "@smithy/core" "^3.2.0" + "@smithy/credential-provider-imds" "^4.0.2" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/property-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" "@aws-sdk/middleware-host-header@3.496.0": version "3.496.0" @@ -434,6 +622,16 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/middleware-host-header@3.775.0": + version "3.775.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.775.0.tgz#1bf8160b8f4f96ba30c19f9baa030a6c9bd5f94d" + integrity sha512-tkSegM0Z6WMXpLB8oPys/d+umYIocvO298mGvcMCncpRl77L9XkvSLJIFzaHes+o7djAgIduYw8wKIMStFss2w== + dependencies: + "@aws-sdk/types" "3.775.0" + "@smithy/protocol-http" "^5.1.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/middleware-logger@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.496.0.tgz#96f867ae50144eb6bae91a427e315a0f0eb783b0" @@ -443,6 +641,15 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/middleware-logger@3.775.0": + version "3.775.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.775.0.tgz#df1909d441cd4bade8d6c7d24c41532808db0e81" + integrity sha512-FaxO1xom4MAoUJsldmR92nT1G6uZxTdNYOFYtdHfd6N2wcNaTuxgjIvqzg5y7QIH9kn58XX/dzf1iTjgqUStZw== + dependencies: + "@aws-sdk/types" "3.775.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/middleware-recursion-detection@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.496.0.tgz#c14e1bbe609e4af3ec9037c2379e2b64d660e4dd" @@ -453,6 +660,16 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/middleware-recursion-detection@3.775.0": + version "3.775.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.775.0.tgz#36a40f467754d7c86424d12ef45c05e96ce3475b" + integrity sha512-GLCzC8D0A0YDG5u3F5U03Vb9j5tcOEFhr8oc6PDk0k0vm5VwtZOE6LvK7hcCSoAB4HXyOUM0sQuXrbaAh9OwXA== + dependencies: + "@aws-sdk/types" "3.775.0" + "@smithy/protocol-http" "^5.1.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/middleware-signing@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.496.0.tgz#265cb5a9d7825c111c53bb555e5cb2619f804dd1" @@ -477,6 +694,63 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/middleware-user-agent@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.796.0.tgz#80149d7f9034d41d35de88d96a6b73c1cb06413b" + integrity sha512-IeNg+3jNWT37J45opi5Jx89hGF0lOnZjiNwlMp3rKq7PlOqy8kWq5J1Gxk0W3tIkPpuf68CtBs/QFrRXWOjsZw== + dependencies: + "@aws-sdk/core" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@aws-sdk/util-endpoints" "3.787.0" + "@smithy/core" "^3.2.0" + "@smithy/protocol-http" "^5.1.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@aws-sdk/nested-clients@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.796.0.tgz#f13f3bd87b923561348394ac6a9010d74334cb7c" + integrity sha512-jJ8a0ldWtXh/ice7nldUjTqja7KYlSYk1pwfIIvJLIqEn2SvQHK/pyCINTmmOmFAWXMKBQBeWUMxo1pPYNytzQ== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/core" "3.796.0" + "@aws-sdk/middleware-host-header" "3.775.0" + "@aws-sdk/middleware-logger" "3.775.0" + "@aws-sdk/middleware-recursion-detection" "3.775.0" + "@aws-sdk/middleware-user-agent" "3.796.0" + "@aws-sdk/region-config-resolver" "3.775.0" + "@aws-sdk/types" "3.775.0" + "@aws-sdk/util-endpoints" "3.787.0" + "@aws-sdk/util-user-agent-browser" "3.775.0" + "@aws-sdk/util-user-agent-node" "3.796.0" + "@smithy/config-resolver" "^4.1.0" + "@smithy/core" "^3.2.0" + "@smithy/fetch-http-handler" "^5.0.2" + "@smithy/hash-node" "^4.0.2" + "@smithy/invalid-dependency" "^4.0.2" + "@smithy/middleware-content-length" "^4.0.2" + "@smithy/middleware-endpoint" "^4.1.0" + "@smithy/middleware-retry" "^4.1.0" + "@smithy/middleware-serde" "^4.0.3" + "@smithy/middleware-stack" "^4.0.2" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/node-http-handler" "^4.0.4" + "@smithy/protocol-http" "^5.1.0" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + "@smithy/url-parser" "^4.0.2" + "@smithy/util-base64" "^4.0.0" + "@smithy/util-body-length-browser" "^4.0.0" + "@smithy/util-body-length-node" "^4.0.0" + "@smithy/util-defaults-mode-browser" "^4.0.8" + "@smithy/util-defaults-mode-node" "^4.0.8" + "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-middleware" "^4.0.2" + "@smithy/util-retry" "^4.0.2" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" + "@aws-sdk/region-config-resolver@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.496.0.tgz#133c8a4a6d5e7672077ba124751f40b2d6efc3ed" @@ -489,6 +763,18 @@ "@smithy/util-middleware" "^2.1.1" tslib "^2.5.0" +"@aws-sdk/region-config-resolver@3.775.0": + version "3.775.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.775.0.tgz#592b52498e68501fe46480be3dfb185e949d1eab" + integrity sha512-40iH3LJjrQS3LKUJAl7Wj0bln7RFPEvUYKFxtP8a+oKFDO0F65F52xZxIJbPn6sHkxWDAnZlGgdjZXM3p2g5wQ== + dependencies: + "@aws-sdk/types" "3.775.0" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + "@smithy/util-config-provider" "^4.0.0" + "@smithy/util-middleware" "^4.0.2" + tslib "^2.6.2" + "@aws-sdk/token-providers@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.496.0.tgz#5b5baf0801fd591de4a28146afbdc8250197f9fa" @@ -532,7 +818,19 @@ "@smithy/util-utf8" "^2.1.1" tslib "^2.5.0" -"@aws-sdk/types@3.496.0", "@aws-sdk/types@^3.222.0": +"@aws-sdk/token-providers@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.796.0.tgz#c31f1d522a1df01ecf3780e72de67d2fc0c8787b" + integrity sha512-Sxr/EqJBxOwLsXHv8C91N/Aao8Rgjn5bcpzplrTZ7wrfDrzqQfSCvjh7apCxdLYMKPBV+an75blCAd7JD4/bAg== + dependencies: + "@aws-sdk/nested-clients" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/property-provider" "^4.0.2" + "@smithy/shared-ini-file-loader" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@aws-sdk/types@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.496.0.tgz#cdde44a94a57cf8f97cf05e4d0bdce2f56ce4eeb" integrity sha512-umkGadK4QuNQaMoDICMm7NKRI/mYSXiyPjcn3d53BhsuArYU/52CebGQKdt4At7SwwsiVJZw9RNBHyN5Mm0HVw== @@ -540,6 +838,14 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/types@3.775.0", "@aws-sdk/types@^3.222.0": + version "3.775.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.775.0.tgz#09863a9e68c080947db7c3d226d1c56b8f0f5150" + integrity sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA== + dependencies: + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/util-endpoints@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.496.0.tgz#5ce7d3efd7ab67db556e2c199e73826c44d22ecd" @@ -550,12 +856,22 @@ "@smithy/util-endpoints" "^1.1.1" tslib "^2.5.0" +"@aws-sdk/util-endpoints@3.787.0": + version "3.787.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.787.0.tgz#1398f0bd87f19e615ae920c73e16d9d5e5cb76d1" + integrity sha512-fd3zkiOkwnbdbN0Xp9TsP5SWrmv0SpT70YEdbb8wAj2DWQwiCmFszaSs+YCvhoCdmlR3Wl9Spu0pGpSAGKeYvQ== + dependencies: + "@aws-sdk/types" "3.775.0" + "@smithy/types" "^4.2.0" + "@smithy/util-endpoints" "^3.0.2" + tslib "^2.6.2" + "@aws-sdk/util-locate-window@^3.0.0": - version "3.495.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.495.0.tgz#9034fd8db77991b28ed20e067acdd53e8b8f824b" - integrity sha512-MfaPXT0kLX2tQaR90saBT9fWQq2DHqSSJRzW+MZWsmF+y5LGCOhO22ac/2o6TKSQm7h0HRc2GaADqYYYor62yg== + version "3.723.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.723.0.tgz#174551bfdd2eb36d3c16e7023fd7e7ee96ad0fa9" + integrity sha512-Yf2CS10BqK688DRsrKI/EO6B8ff5J86NXe4C+VCysK7UOgN0l1zOTeTukZ3H8Q9tYYX3oaF1961o8vRkFm7Nmw== dependencies: - tslib "^2.5.0" + tslib "^2.6.2" "@aws-sdk/util-user-agent-browser@3.496.0": version "3.496.0" @@ -567,6 +883,16 @@ bowser "^2.11.0" tslib "^2.5.0" +"@aws-sdk/util-user-agent-browser@3.775.0": + version "3.775.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.775.0.tgz#b69a1a5548ccc6db1acb3ec115967593ece927a1" + integrity sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A== + dependencies: + "@aws-sdk/types" "3.775.0" + "@smithy/types" "^4.2.0" + bowser "^2.11.0" + tslib "^2.6.2" + "@aws-sdk/util-user-agent-node@3.496.0": version "3.496.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.496.0.tgz#db14e02cf82af556c826570efc7db1e57de3262d" @@ -577,6 +903,17 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@aws-sdk/util-user-agent-node@3.796.0": + version "3.796.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.796.0.tgz#72c2ea1f32d2eb1200e111f48fd8a3c005f5202c" + integrity sha512-9fQpNcHgVFitf1tbTT8V1xGRoRHSmOAWjrhevo6Tc0WoINMAKz+4JNqfVGWRE5Tmtpq0oHKo1RmvxXQQtJYciA== + dependencies: + "@aws-sdk/middleware-user-agent" "3.796.0" + "@aws-sdk/types" "3.775.0" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@aws-sdk/util-utf8-browser@^3.0.0": version "3.259.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" @@ -1222,59 +1559,103 @@ dependencies: "@sinonjs/commons" "^3.0.0" -"@smithy/abort-controller@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.1.1.tgz#bb68596a7c8213c2ef259bc7fb0f0c118c67ea9d" - integrity sha512-1+qdrUqLhaALYL0iOcN43EP6yAXXQ2wWZ6taf4S2pNGowmOc5gx+iMQv+E42JizNJjB0+gEadOXeV1Bf7JWL1Q== +"@smithy/abort-controller@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.2.0.tgz#18983401a5e2154b5c94057730024a7d14cbcd35" + integrity sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -"@smithy/config-resolver@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-2.1.1.tgz#fc6b036084b98fd26a8ff01a5d7eb676e41749c7" - integrity sha512-lxfLDpZm+AWAHPFZps5JfDoO9Ux1764fOgvRUBpHIO8HWHcSN1dkgsago1qLRVgm1BZ8RCm8cgv99QvtaOWIhw== +"@smithy/abort-controller@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-4.0.2.tgz#36a23e8cc65fc03cacb6afa35dfbfd319c560c6b" + integrity sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw== dependencies: - "@smithy/node-config-provider" "^2.2.1" - "@smithy/types" "^2.9.1" - "@smithy/util-config-provider" "^2.2.1" - "@smithy/util-middleware" "^2.1.1" - tslib "^2.5.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@smithy/config-resolver@^2.1.1", "@smithy/config-resolver@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-2.2.0.tgz#54f40478bb61709b396960a3535866dba5422757" + integrity sha512-fsiMgd8toyUba6n1WRmr+qACzXltpdDkPTAaDqc8QqPBUzO+/JKwL6bUBseHVi8tu9l+3JOK+tSf7cay+4B3LA== + dependencies: + "@smithy/node-config-provider" "^2.3.0" + "@smithy/types" "^2.12.0" + "@smithy/util-config-provider" "^2.3.0" + "@smithy/util-middleware" "^2.2.0" + tslib "^2.6.2" + +"@smithy/config-resolver@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-4.1.0.tgz#de1043cbd75f05d99798b0fbcfdaf4b89b0f2f41" + integrity sha512-8smPlwhga22pwl23fM5ew4T9vfLUCeFXlcqNOCD5M5h8VmNPNUE9j6bQSuRXpDSV11L/E/SwEBQuW8hr6+nS1A== + dependencies: + "@smithy/node-config-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + "@smithy/util-config-provider" "^4.0.0" + "@smithy/util-middleware" "^4.0.2" + tslib "^2.6.2" "@smithy/core@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@smithy/core/-/core-1.3.1.tgz#ecedc564e68453b02c20db9e8435d59005c066d8" - integrity sha512-tf+NIu9FkOh312b6M9G4D68is4Xr7qptzaZGZUREELF8ysE1yLKphqt7nsomjKZVwW7WE5pDDex9idowNGRQ/Q== + version "1.4.2" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-1.4.2.tgz#1c3ed886d403041ce5bd2d816448420c57baa19c" + integrity sha512-2fek3I0KZHWJlRLvRTqxTEri+qV0GRHrJIoLFuBMZB4EMg4WgeBGfF0X6abnrNYpq55KJ6R4D6x4f0vLnhzinA== + dependencies: + "@smithy/middleware-endpoint" "^2.5.1" + "@smithy/middleware-retry" "^2.3.1" + "@smithy/middleware-serde" "^2.3.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/smithy-client" "^2.5.1" + "@smithy/types" "^2.12.0" + "@smithy/util-middleware" "^2.2.0" + tslib "^2.6.2" + +"@smithy/core@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.2.0.tgz#613b15f76eab9a6be396b1d5453b6bc8f22ba99c" + integrity sha512-k17bgQhVZ7YmUvA8at4af1TDpl0NDMBuBKJl8Yg0nrefwmValU+CnA5l/AriVdQNthU/33H3nK71HrLgqOPr1Q== + dependencies: + "@smithy/middleware-serde" "^4.0.3" + "@smithy/protocol-http" "^5.1.0" + "@smithy/types" "^4.2.0" + "@smithy/util-body-length-browser" "^4.0.0" + "@smithy/util-middleware" "^4.0.2" + "@smithy/util-stream" "^4.2.0" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" + +"@smithy/credential-provider-imds@^2.2.1", "@smithy/credential-provider-imds@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-2.3.0.tgz#326ce401b82e53f3c7ee4862a066136959a06166" + integrity sha512-BWB9mIukO1wjEOo1Ojgl6LrG4avcaC7T/ZP6ptmAaW4xluhSIPZhY+/PI5YKzlk+jsm+4sQZB45Bt1OfMeQa3w== dependencies: - "@smithy/middleware-endpoint" "^2.4.1" - "@smithy/middleware-retry" "^2.1.1" - "@smithy/middleware-serde" "^2.1.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/util-middleware" "^2.1.1" - tslib "^2.5.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/types" "^2.12.0" + "@smithy/url-parser" "^2.2.0" + tslib "^2.6.2" -"@smithy/credential-provider-imds@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-2.2.1.tgz#4805bf5e104718b959cf8699113fa9de6ddeeafa" - integrity sha512-7XHjZUxmZYnONheVQL7j5zvZXga+EWNgwEAP6OPZTi7l8J4JTeNh9aIOfE5fKHZ/ee2IeNOh54ZrSna+Vc6TFA== +"@smithy/credential-provider-imds@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.2.tgz#1ec34a04842fa69996b151a695b027f0486c69a8" + integrity sha512-32lVig6jCaWBHnY+OEQ6e6Vnt5vDHaLiydGrwYMW9tPqO688hPGTYRamYJ1EptxEC2rAwJrHWmPoKRBl4iTa8w== dependencies: - "@smithy/node-config-provider" "^2.2.1" - "@smithy/property-provider" "^2.1.1" - "@smithy/types" "^2.9.1" - "@smithy/url-parser" "^2.1.1" - tslib "^2.5.0" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/property-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + "@smithy/url-parser" "^4.0.2" + tslib "^2.6.2" "@smithy/eventstream-codec@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.1.1.tgz#4405ab0f9c77d439c575560c4886e59ee17d6d38" - integrity sha512-E8KYBxBIuU4c+zrpR22VsVrOPoEDzk35bQR3E+xm4k6Pa6JqzkDOdMyf9Atac5GPNKHJBdVaQ4JtjdWX2rl/nw== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.2.0.tgz#63d74fa817188995eb55e792a38060b0ede98dc4" + integrity sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw== dependencies: "@aws-crypto/crc32" "3.0.0" - "@smithy/types" "^2.9.1" - "@smithy/util-hex-encoding" "^2.1.1" - tslib "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/util-hex-encoding" "^2.2.0" + tslib "^2.6.2" "@smithy/eventstream-serde-browser@^2.1.1": version "2.1.1" @@ -1311,7 +1692,7 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" -"@smithy/fetch-http-handler@^2.2.1", "@smithy/fetch-http-handler@^2.4.1": +"@smithy/fetch-http-handler@^2.2.1": version "2.4.1" resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-2.4.1.tgz#b4d73bbc1449f61234077d58c705b843a8587bf0" integrity sha512-VYGLinPsFqH68lxfRhjQaSkjXM7JysUOJDTNjHBuN/ykyRb2f1gyavN9+VhhPTWCy32L4yZ2fdhpCs/nStEicg== @@ -1322,173 +1703,342 @@ "@smithy/util-base64" "^2.1.1" tslib "^2.5.0" +"@smithy/fetch-http-handler@^2.4.1", "@smithy/fetch-http-handler@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-2.5.0.tgz#0b8e1562807fdf91fe7dd5cde620d7a03ddc10ac" + integrity sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw== + dependencies: + "@smithy/protocol-http" "^3.3.0" + "@smithy/querystring-builder" "^2.2.0" + "@smithy/types" "^2.12.0" + "@smithy/util-base64" "^2.3.0" + tslib "^2.6.2" + +"@smithy/fetch-http-handler@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.2.tgz#9d3cacf044aa9573ab933f445ab95cddb284813d" + integrity sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ== + dependencies: + "@smithy/protocol-http" "^5.1.0" + "@smithy/querystring-builder" "^4.0.2" + "@smithy/types" "^4.2.0" + "@smithy/util-base64" "^4.0.0" + tslib "^2.6.2" + "@smithy/hash-node@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-2.1.1.tgz#0f8a22d97565ca948724f72267e4d3a2f33740a8" - integrity sha512-Qhoq0N8f2OtCnvUpCf+g1vSyhYQrZjhSwvJ9qvR8BUGOtTXiyv2x1OD2e6jVGmlpC4E4ax1USHoyGfV9JFsACg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-2.2.0.tgz#df29e1e64811be905cb3577703b0e2d0b07fc5cc" + integrity sha512-zLWaC/5aWpMrHKpoDF6nqpNtBhlAYKF/7+9yMN7GpdR8CzohnWfGtMznPybnwSS8saaXBMxIGwJqR4HmRp6b3g== dependencies: - "@smithy/types" "^2.9.1" - "@smithy/util-buffer-from" "^2.1.1" - "@smithy/util-utf8" "^2.1.1" - tslib "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/util-buffer-from" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@smithy/hash-node@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-4.0.2.tgz#a34fe5a33b067d754ca63302b9791778f003e437" + integrity sha512-VnTpYPnRUE7yVhWozFdlxcYknv9UN7CeOqSrMH+V877v4oqtVYuoqhIhtSjmGPvYrYnAkaM61sLMKHvxL138yg== + dependencies: + "@smithy/types" "^4.2.0" + "@smithy/util-buffer-from" "^4.0.0" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" "@smithy/invalid-dependency@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-2.1.1.tgz#bd69fa24dd35e9bc65a160bd86becdf1399e4463" - integrity sha512-7WTgnKw+VPg8fxu2v9AlNOQ5yaz6RA54zOVB4f6vQuR0xFKd+RzlCpt0WidYTsye7F+FYDIaS/RnJW4pxjNInw== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-2.2.0.tgz#ee3d8980022cb5edb514ac187d159b3e773640f0" + integrity sha512-nEDASdbKFKPXN2O6lOlTgrEEOO9NHIeO+HVvZnkqc8h5U9g3BIhWsvzFo+UcUbliMHvKNPD/zVxDrkP1Sbgp8Q== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/invalid-dependency@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-4.0.2.tgz#e9b1c5e407d795f10a03afba90e37bccdc3e38f7" + integrity sha512-GatB4+2DTpgWPday+mnUkoumP54u/MDM/5u44KF9hIu8jF0uafZtQLcdfIKkIcUNuF/fBojpLEHZS/56JqPeXQ== + dependencies: + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@smithy/is-array-buffer@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz#f84f0d9f9a36601a9ca9381688bd1b726fd39111" + integrity sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA== + dependencies: + tslib "^2.6.2" + +"@smithy/is-array-buffer@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz#9a95c2d46b8768946a9eec7f935feaddcffa5e7a" + integrity sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ== + dependencies: + tslib "^2.6.2" + +"@smithy/is-array-buffer@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz#55a939029321fec462bcc574890075cd63e94206" + integrity sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw== + dependencies: + tslib "^2.6.2" + +"@smithy/middleware-content-length@^2.1.1": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-2.2.0.tgz#a82e97bd83d8deab69e07fea4512563bedb9461a" + integrity sha512-5bl2LG1Ah/7E5cMSC+q+h3IpVHMeOkG0yLRyQT1p2aMJkSrZG7RlXHPuAgb7EyaFeidKEnnd/fNaLLaKlHGzDQ== + dependencies: + "@smithy/protocol-http" "^3.3.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/middleware-content-length@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-4.0.2.tgz#ff78658e8047ad7038f58478cf8713ee2f6ef647" + integrity sha512-hAfEXm1zU+ELvucxqQ7I8SszwQ4znWMbNv6PLMndN83JJN41EPuS93AIyh2N+gJ6x8QFhzSO6b7q2e6oClDI8A== + dependencies: + "@smithy/protocol-http" "^5.1.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@smithy/middleware-endpoint@^2.4.1", "@smithy/middleware-endpoint@^2.5.1": + version "2.5.1" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.5.1.tgz#1333c58304aff4d843e8ef4b85c8cb88975dd5ad" + integrity sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ== + dependencies: + "@smithy/middleware-serde" "^2.3.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + "@smithy/url-parser" "^2.2.0" + "@smithy/util-middleware" "^2.2.0" + tslib "^2.6.2" + +"@smithy/middleware-endpoint@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.0.tgz#cbfe47c5632942c960dbcf71fb02fd0d9985444d" + integrity sha512-xhLimgNCbCzsUppRTGXWkZywksuTThxaIB0HwbpsVLY5sceac4e1TZ/WKYqufQLaUy+gUSJGNdwD2jo3cXL0iA== + dependencies: + "@smithy/core" "^3.2.0" + "@smithy/middleware-serde" "^4.0.3" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/shared-ini-file-loader" "^4.0.2" + "@smithy/types" "^4.2.0" + "@smithy/url-parser" "^4.0.2" + "@smithy/util-middleware" "^4.0.2" + tslib "^2.6.2" + +"@smithy/middleware-retry@^2.1.1", "@smithy/middleware-retry@^2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.3.1.tgz#d6fdce94f2f826642c01b4448e97a509c4556ede" + integrity sha512-P2bGufFpFdYcWvqpyqqmalRtwFUNUA8vHjJR5iGqbfR6mp65qKOLcUd6lTr4S9Gn/enynSrSf3p3FVgVAf6bXA== + dependencies: + "@smithy/node-config-provider" "^2.3.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/service-error-classification" "^2.1.5" + "@smithy/smithy-client" "^2.5.1" + "@smithy/types" "^2.12.0" + "@smithy/util-middleware" "^2.2.0" + "@smithy/util-retry" "^2.2.0" + tslib "^2.6.2" + uuid "^9.0.1" + +"@smithy/middleware-retry@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.1.0.tgz#338ac1e025bbc6fd7b008152c4efa8bc0591acc9" + integrity sha512-2zAagd1s6hAaI/ap6SXi5T3dDwBOczOMCSkkYzktqN1+tzbk1GAsHNAdo/1uzxz3Ky02jvZQwbi/vmDA6z4Oyg== + dependencies: + "@smithy/node-config-provider" "^4.0.2" + "@smithy/protocol-http" "^5.1.0" + "@smithy/service-error-classification" "^4.0.2" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + "@smithy/util-middleware" "^4.0.2" + "@smithy/util-retry" "^4.0.2" + tslib "^2.6.2" + uuid "^9.0.1" + +"@smithy/middleware-serde@^2.1.1", "@smithy/middleware-serde@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-2.3.0.tgz#a7615ba646a88b6f695f2d55de13d8158181dd13" + integrity sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/middleware-serde@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-4.0.3.tgz#b90ef1065ad9dc0b54c561fae73c8a5792d145e3" + integrity sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A== + dependencies: + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@smithy/middleware-stack@^2.1.1", "@smithy/middleware-stack@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-2.2.0.tgz#3fb49eae6313f16f6f30fdaf28e11a7321f34d9f" + integrity sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/middleware-stack@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-4.0.2.tgz#ca7bc3eedc7c1349e2cf94e0dc92a68d681bef18" + integrity sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ== + dependencies: + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@smithy/node-config-provider@^2.2.1", "@smithy/node-config-provider@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-2.3.0.tgz#9fac0c94a14c5b5b8b8fa37f20c310a844ab9922" + integrity sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/shared-ini-file-loader" "^2.4.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -"@smithy/is-array-buffer@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-2.1.1.tgz#07b4c77ae67ed58a84400c76edd482271f9f957b" - integrity sha512-xozSQrcUinPpNPNPds4S7z/FakDTh1MZWtRP/2vQtYB/u3HYrX2UXuZs+VhaKBd6Vc7g2XPr2ZtwGBNDN6fNKQ== +"@smithy/node-config-provider@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-4.0.2.tgz#017ba626828bced0fa588e795246e5468632f3ef" + integrity sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw== dependencies: - tslib "^2.5.0" + "@smithy/property-provider" "^4.0.2" + "@smithy/shared-ini-file-loader" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" -"@smithy/is-array-buffer@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz#9a95c2d46b8768946a9eec7f935feaddcffa5e7a" - integrity sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ== +"@smithy/node-http-handler@^2.3.1", "@smithy/node-http-handler@^2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.5.0.tgz#7b5e0565dd23d340380489bd5fe4316d2bed32de" + integrity sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA== dependencies: + "@smithy/abort-controller" "^2.2.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/querystring-builder" "^2.2.0" + "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@smithy/middleware-content-length@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-2.1.1.tgz#df767de12d594bc5622009fb0fc8343522697d8c" - integrity sha512-rSr9ezUl9qMgiJR0UVtVOGEZElMdGFyl8FzWEF5iEKTlcWxGr2wTqGfDwtH3LAB7h+FPkxqv4ZU4cpuCN9Kf/g== +"@smithy/node-http-handler@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-4.0.4.tgz#aa583d201c1ee968170b65a07f06d633c214b7a1" + integrity sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g== dependencies: - "@smithy/protocol-http" "^3.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/abort-controller" "^4.0.2" + "@smithy/protocol-http" "^5.1.0" + "@smithy/querystring-builder" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" -"@smithy/middleware-endpoint@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.4.1.tgz#9e500df4d944741808e92018ccd2e948b598a49f" - integrity sha512-XPZTb1E2Oav60Ven3n2PFx+rX9EDsU/jSTA8VDamt7FXks67ekjPY/XrmmPDQaFJOTUHJNKjd8+kZxVO5Ael4Q== +"@smithy/property-provider@^2.1.1", "@smithy/property-provider@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-2.2.0.tgz#37e3525a3fa3e11749f86a4f89f0fd7765a6edb0" + integrity sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg== dependencies: - "@smithy/middleware-serde" "^2.1.1" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/shared-ini-file-loader" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/url-parser" "^2.1.1" - "@smithy/util-middleware" "^2.1.1" - tslib "^2.5.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -"@smithy/middleware-retry@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.1.1.tgz#ddc749dd927f136714f76ca5a52dcfb0993ee162" - integrity sha512-eMIHOBTXro6JZ+WWzZWd/8fS8ht5nS5KDQjzhNMHNRcG5FkNTqcKpYhw7TETMYzbLfhO5FYghHy1vqDWM4FLDA== +"@smithy/property-provider@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-4.0.2.tgz#4572c10415c9d4215f3df1530ba61b0319b17b55" + integrity sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A== dependencies: - "@smithy/node-config-provider" "^2.2.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/service-error-classification" "^2.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/util-middleware" "^2.1.1" - "@smithy/util-retry" "^2.1.1" - tslib "^2.5.0" - uuid "^8.3.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" -"@smithy/middleware-serde@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-2.1.1.tgz#2c5750f76e276a5249720f6c3c24fac29abbee16" - integrity sha512-D8Gq0aQBeE1pxf3cjWVkRr2W54t+cdM2zx78tNrVhqrDykRA7asq8yVJij1u5NDtKzKqzBSPYh7iW0svUKg76g== +"@smithy/protocol-http@^3.0.6", "@smithy/protocol-http@^3.1.1", "@smithy/protocol-http@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-3.3.0.tgz#a37df7b4bb4960cdda560ce49acfd64c455e4090" + integrity sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -"@smithy/middleware-stack@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-2.1.1.tgz#67f992dc36e8a6861f881f80a81c1c30956a0396" - integrity sha512-KPJhRlhsl8CjgGXK/DoDcrFGfAqoqvuwlbxy+uOO4g2Azn1dhH+GVfC3RAp+6PoL5PWPb+vt6Z23FP+Mr6qeCw== +"@smithy/protocol-http@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-5.1.0.tgz#ad34e336a95944785185234bebe2ec8dbe266936" + integrity sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" -"@smithy/node-config-provider@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-2.2.1.tgz#c440c7948d58d72f0e212aa1967aa12f0729defd" - integrity sha512-epzK3x1xNxA9oJgHQ5nz+2j6DsJKdHfieb+YgJ7ATWxzNcB7Hc+Uya2TUck5MicOPhDV8HZImND7ZOecVr+OWg== +"@smithy/querystring-builder@^2.1.1", "@smithy/querystring-builder@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-2.2.0.tgz#22937e19fcd0aaa1a3e614ef8cb6f8e86756a4ef" + integrity sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A== dependencies: - "@smithy/property-provider" "^2.1.1" - "@smithy/shared-ini-file-loader" "^2.3.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/util-uri-escape" "^2.2.0" + tslib "^2.6.2" -"@smithy/node-http-handler@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.3.1.tgz#77d23279ff0a12cbe7cde93c5e7c0e86ad56dd20" - integrity sha512-gLA8qK2nL9J0Rk/WEZSvgin4AppvuCYRYg61dcUo/uKxvMZsMInL5I5ZdJTogOvdfVug3N2dgI5ffcUfS4S9PA== +"@smithy/querystring-builder@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-4.0.2.tgz#834cea95bf413ab417bf9c166d60fd80d2cb3016" + integrity sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q== dependencies: - "@smithy/abort-controller" "^2.1.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/querystring-builder" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^4.2.0" + "@smithy/util-uri-escape" "^4.0.0" + tslib "^2.6.2" -"@smithy/property-provider@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-2.1.1.tgz#0f7ffc5e43829eaca5b2b5aae8554807a52b30f3" - integrity sha512-FX7JhhD/o5HwSwg6GLK9zxrMUrGnb3PzNBrcthqHKBc3dH0UfgEAU24xnJ8F0uow5mj17UeBEOI6o3CF2k7Mhw== +"@smithy/querystring-parser@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-2.2.0.tgz#24a5633f4b3806ff2888d4c2f4169e105fdffd79" + integrity sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -"@smithy/protocol-http@^3.0.6", "@smithy/protocol-http@^3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-3.1.1.tgz#eee522d0ed964a72b735d64925e07bcfb7a7806f" - integrity sha512-6ZRTSsaXuSL9++qEwH851hJjUA0OgXdQFCs+VDw4tGH256jQ3TjYY/i34N4vd24RV3nrjNsgd1yhb57uMoKbzQ== +"@smithy/querystring-parser@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-4.0.2.tgz#d80c5afb740e12ad8b4d4f58415e402c69712479" + integrity sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" -"@smithy/querystring-builder@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-2.1.1.tgz#b9693448ad3f8e0767d84cf5cae29f35514591fb" - integrity sha512-C/ko/CeEa8jdYE4gt6nHO5XDrlSJ3vdCG0ZAc6nD5ZIE7LBp0jCx4qoqp7eoutBu7VrGMXERSRoPqwi1WjCPbg== +"@smithy/service-error-classification@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-2.1.5.tgz#0568a977cc0db36299d8703a5d8609c1f600c005" + integrity sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ== dependencies: - "@smithy/types" "^2.9.1" - "@smithy/util-uri-escape" "^2.1.1" - tslib "^2.5.0" + "@smithy/types" "^2.12.0" -"@smithy/querystring-parser@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-2.1.1.tgz#a4282a66cc56844317dbff824e573f469bbfc032" - integrity sha512-H4+6jKGVhG1W4CIxfBaSsbm98lOO88tpDWmZLgkJpt8Zkk/+uG0FmmqMuCAc3HNM2ZDV+JbErxr0l5BcuIf/XQ== +"@smithy/service-error-classification@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-4.0.2.tgz#96740ed8be7ac5ad7d6f296d4ddf3f66444b8dcc" + integrity sha512-LA86xeFpTKn270Hbkixqs5n73S+LVM0/VZco8dqd+JT75Dyx3Lcw/MraL7ybjmz786+160K8rPOmhsq0SocoJQ== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^4.2.0" -"@smithy/service-error-classification@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-2.1.1.tgz#dd24e1ec529ae9ec8e87d8b15f0fc8f7e17f3d02" - integrity sha512-txEdZxPUgM1PwGvDvHzqhXisrc5LlRWYCf2yyHfvITWioAKat7srQvpjMAvgzf0t6t7j8yHrryXU9xt7RZqFpw== +"@smithy/shared-ini-file-loader@^2.3.1", "@smithy/shared-ini-file-loader@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.4.0.tgz#1636d6eb9bff41e36ac9c60364a37fd2ffcb9947" + integrity sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA== dependencies: - "@smithy/types" "^2.9.1" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -"@smithy/shared-ini-file-loader@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.3.1.tgz#a2e28b4d85f8a8262a84403fa2b74a086b3a7703" - integrity sha512-2E2kh24igmIznHLB6H05Na4OgIEilRu0oQpYXo3LCNRrawHAcfDKq9004zJs+sAMt2X5AbY87CUCJ7IpqpSgdw== +"@smithy/shared-ini-file-loader@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.2.tgz#15043f0516fe09ff4b22982bc5f644dc701ebae5" + integrity sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" "@smithy/signature-v4@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.1.1.tgz#6080171e3d694f40d3f553bbc236c5c433efd4d2" - integrity sha512-Hb7xub0NHuvvQD3YwDSdanBmYukoEkhqBjqoxo+bSdC0ryV9cTfgmNjuAQhTPYB6yeU7hTR+sPRiFMlxqv6kmg== - dependencies: - "@smithy/eventstream-codec" "^2.1.1" - "@smithy/is-array-buffer" "^2.1.1" - "@smithy/types" "^2.9.1" - "@smithy/util-hex-encoding" "^2.1.1" - "@smithy/util-middleware" "^2.1.1" - "@smithy/util-uri-escape" "^2.1.1" - "@smithy/util-utf8" "^2.1.1" - tslib "^2.5.0" + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.3.0.tgz#c30dd4028ae50c607db99459981cce8cdab7a3fd" + integrity sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q== + dependencies: + "@smithy/is-array-buffer" "^2.2.0" + "@smithy/types" "^2.12.0" + "@smithy/util-hex-encoding" "^2.2.0" + "@smithy/util-middleware" "^2.2.0" + "@smithy/util-uri-escape" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" "@smithy/signature-v4@^3.1.1": version "3.1.1" @@ -1503,7 +2053,21 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/smithy-client@^2.1.9", "@smithy/smithy-client@^2.3.1": +"@smithy/signature-v4@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-5.1.0.tgz#2c56e5b278482b04383d84ea2c07b7f0a8eb8f63" + integrity sha512-4t5WX60sL3zGJF/CtZsUQTs3UrZEDO2P7pEaElrekbLqkWPYkgqNW1oeiNYC6xXifBnT9dVBOnNQRvOE9riU9w== + dependencies: + "@smithy/is-array-buffer" "^4.0.0" + "@smithy/protocol-http" "^5.1.0" + "@smithy/types" "^4.2.0" + "@smithy/util-hex-encoding" "^4.0.0" + "@smithy/util-middleware" "^4.0.2" + "@smithy/util-uri-escape" "^4.0.0" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" + +"@smithy/smithy-client@^2.1.9": version "2.3.1" resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.3.1.tgz#0c3a4a0d3935c7ad2240cc23181f276705212b1f" integrity sha512-YsTdU8xVD64r2pLEwmltrNvZV6XIAC50LN6ivDopdt+YiF/jGH6PY9zUOu0CXD/d8GMB8gbhnpPsdrjAXHS9QA== @@ -1515,12 +2079,37 @@ "@smithy/util-stream" "^2.1.1" tslib "^2.5.0" -"@smithy/types@^2.3.4", "@smithy/types@^2.9.1": - version "2.9.1" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.9.1.tgz#ed04d4144eed3b8bd26d20fc85aae8d6e357ebb9" - integrity sha512-vjXlKNXyprDYDuJ7UW5iobdmyDm6g8dDG+BFUncAg/3XJaN45Gy5RWWWUVgrzIK7S4R1KWgIX5LeJcfvSI24bw== +"@smithy/smithy-client@^2.3.1", "@smithy/smithy-client@^2.5.1": + version "2.5.1" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.5.1.tgz#0fd2efff09dc65500d260e590f7541f8a387eae3" + integrity sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ== dependencies: - tslib "^2.5.0" + "@smithy/middleware-endpoint" "^2.5.1" + "@smithy/middleware-stack" "^2.2.0" + "@smithy/protocol-http" "^3.3.0" + "@smithy/types" "^2.12.0" + "@smithy/util-stream" "^2.2.0" + tslib "^2.6.2" + +"@smithy/smithy-client@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.2.0.tgz#0c64cae4fb5bb4f26386e9b2c33fc9a3c24c9df3" + integrity sha512-Qs65/w30pWV7LSFAez9DKy0Koaoh3iHhpcpCCJ4waj/iqwsuSzJna2+vYwq46yBaqO5ZbP9TjUsATUNxrKeBdw== + dependencies: + "@smithy/core" "^3.2.0" + "@smithy/middleware-endpoint" "^4.1.0" + "@smithy/middleware-stack" "^4.0.2" + "@smithy/protocol-http" "^5.1.0" + "@smithy/types" "^4.2.0" + "@smithy/util-stream" "^4.2.0" + tslib "^2.6.2" + +"@smithy/types@^2.12.0", "@smithy/types@^2.3.4", "@smithy/types@^2.9.1": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.12.0.tgz#c44845f8ba07e5e8c88eda5aed7e6a0c462da041" + integrity sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw== + dependencies: + tslib "^2.6.2" "@smithy/types@^3.2.0": version "3.2.0" @@ -1529,16 +2118,32 @@ dependencies: tslib "^2.6.2" -"@smithy/url-parser@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-2.1.1.tgz#a30de227b6734650d740b6dff74d488b874e85e3" - integrity sha512-qC9Bv8f/vvFIEkHsiNrUKYNl8uKQnn4BdhXl7VzQRP774AwIjiSMMwkbT+L7Fk8W8rzYVifzJNYxv1HwvfBo3Q== +"@smithy/types@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-4.2.0.tgz#e7998984cc54b1acbc32e6d4cf982c712e3d26b6" + integrity sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg== dependencies: - "@smithy/querystring-parser" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + tslib "^2.6.2" + +"@smithy/url-parser@^2.1.1", "@smithy/url-parser@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-2.2.0.tgz#6fcda6116391a4f61fef5580eb540e128359b3c0" + integrity sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ== + dependencies: + "@smithy/querystring-parser" "^2.2.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/url-parser@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-4.0.2.tgz#a316f7d8593ffab796348bc5df96237833880713" + integrity sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ== + dependencies: + "@smithy/querystring-parser" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" -"@smithy/util-base64@^2.0.0", "@smithy/util-base64@^2.1.1": +"@smithy/util-base64@^2.0.0": version "2.1.1" resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-2.1.1.tgz#af729085cc9d92ebd54a5d2c5d0aa5a0c31f83bf" integrity sha512-UfHVpY7qfF/MrgndI5PexSKVTxSZIdz9InghTFa49QOvuu9I52zLPLUHXvHpNuMb1iD2vmc6R+zbv/bdMipR/g== @@ -1546,27 +2151,59 @@ "@smithy/util-buffer-from" "^2.1.1" tslib "^2.5.0" +"@smithy/util-base64@^2.1.1", "@smithy/util-base64@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-2.3.0.tgz#312dbb4d73fb94249c7261aee52de4195c2dd8e2" + integrity sha512-s3+eVwNeJuXUwuMbusncZNViuhv2LjVJ1nMwTqSA0XAC7gjKhqqxRdJPhR8+YrkoZ9IiIbFk/yK6ACe/xlF+hw== + dependencies: + "@smithy/util-buffer-from" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@smithy/util-base64@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-base64/-/util-base64-4.0.0.tgz#8345f1b837e5f636e5f8470c4d1706ae0c6d0358" + integrity sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg== + dependencies: + "@smithy/util-buffer-from" "^4.0.0" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" + "@smithy/util-body-length-browser@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-2.1.1.tgz#1fc77072768013ae646415eedb9833cd252d055d" - integrity sha512-ekOGBLvs1VS2d1zM2ER4JEeBWAvIOUKeaFch29UjjJsxmZ/f0L3K3x0dEETgh3Q9bkZNHgT+rkdl/J/VUqSRag== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-2.2.0.tgz#25620645c6b62b42594ef4a93b66e6ab70e27d2c" + integrity sha512-dtpw9uQP7W+n3vOtx0CfBD5EWd7EPdIdsQnWTDoFf77e3VUf05uA7R7TGipIo8e4WL2kuPdnsr3hMQn9ziYj5w== dependencies: - tslib "^2.5.0" + tslib "^2.6.2" + +"@smithy/util-body-length-browser@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz#965d19109a4b1e5fe7a43f813522cce718036ded" + integrity sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA== + dependencies: + tslib "^2.6.2" "@smithy/util-body-length-node@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-2.2.1.tgz#a6f5c9911f1c3e23efb340d5ce7a590b62f2056e" - integrity sha512-/ggJG+ta3IDtpNVq4ktmEUtOkH1LW64RHB5B0hcr5ZaWBmo96UX2cIOVbjCqqDickTXqBWZ4ZO0APuaPrD7Abg== + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-2.3.0.tgz#d065a9b5e305ff899536777bbfe075cdc980136f" + integrity sha512-ITWT1Wqjubf2CJthb0BuT9+bpzBfXeMokH/AAa5EJQgbv9aPMVfnM76iFIZVFf50hYXGbtiV71BHAthNWd6+dw== dependencies: - tslib "^2.5.0" + tslib "^2.6.2" -"@smithy/util-buffer-from@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-2.1.1.tgz#f9346bf8b23c5ba6f6bdb61dd9db779441ba8d08" - integrity sha512-clhNjbyfqIv9Md2Mg6FffGVrJxw7bgK7s3Iax36xnfVj6cg0fUG7I4RH0XgXJF8bxi+saY5HR21g2UPKSxVCXg== +"@smithy/util-body-length-node@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz#3db245f6844a9b1e218e30c93305bfe2ffa473b3" + integrity sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg== dependencies: - "@smithy/is-array-buffer" "^2.1.1" - tslib "^2.5.0" + tslib "^2.6.2" + +"@smithy/util-buffer-from@^2.1.1", "@smithy/util-buffer-from@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz#6fc88585165ec73f8681d426d96de5d402021e4b" + integrity sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA== + dependencies: + "@smithy/is-array-buffer" "^2.2.0" + tslib "^2.6.2" "@smithy/util-buffer-from@^3.0.0": version "3.0.0" @@ -1576,52 +2213,100 @@ "@smithy/is-array-buffer" "^3.0.0" tslib "^2.6.2" -"@smithy/util-config-provider@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-2.2.1.tgz#aea0a80236d6cedaee60473802899cff4a8cc0ba" - integrity sha512-50VL/tx9oYYcjJn/qKqNy7sCtpD0+s8XEBamIFo4mFFTclKMNp+rsnymD796uybjiIquB7VCB/DeafduL0y2kw== +"@smithy/util-buffer-from@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz#b23b7deb4f3923e84ef50c8b2c5863d0dbf6c0b9" + integrity sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug== dependencies: - tslib "^2.5.0" + "@smithy/is-array-buffer" "^4.0.0" + tslib "^2.6.2" + +"@smithy/util-config-provider@^2.2.1", "@smithy/util-config-provider@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-2.3.0.tgz#bc79f99562d12a1f8423100ca662a6fb07cde943" + integrity sha512-HZkzrRcuFN1k70RLqlNK4FnPXKOpkik1+4JaBoHNJn+RnJGYqaa3c5/+XtLOXhlKzlRgNvyaLieHTW2VwGN0VQ== + dependencies: + tslib "^2.6.2" + +"@smithy/util-config-provider@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz#e0c7c8124c7fba0b696f78f0bd0ccb060997d45e" + integrity sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w== + dependencies: + tslib "^2.6.2" "@smithy/util-defaults-mode-browser@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.1.1.tgz#be9ac82acee6ec4821b610e7187b0e147f0ba8ff" - integrity sha512-lqLz/9aWRO6mosnXkArtRuQqqZBhNpgI65YDpww4rVQBuUT7qzKbDLG5AmnQTCiU4rOquaZO/Kt0J7q9Uic7MA== + version "2.2.1" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.2.1.tgz#9db31416daf575d2963c502e0528cfe8055f0c4e" + integrity sha512-RtKW+8j8skk17SYowucwRUjeh4mCtnm5odCL0Lm2NtHQBsYKrNW0od9Rhopu9wF1gHMfHeWF7i90NwBz/U22Kw== dependencies: - "@smithy/property-provider" "^2.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" + "@smithy/property-provider" "^2.2.0" + "@smithy/smithy-client" "^2.5.1" + "@smithy/types" "^2.12.0" bowser "^2.11.0" - tslib "^2.5.0" + tslib "^2.6.2" -"@smithy/util-defaults-mode-node@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.1.1.tgz#0910ee00aac3e8a08aac3e6ae8794e52f3efef02" - integrity sha512-tYVrc+w+jSBfBd267KDnvSGOh4NMz+wVH7v4CClDbkdPfnjvImBZsOURncT5jsFwR9KCuDyPoSZq4Pa6+eCUrA== +"@smithy/util-defaults-mode-browser@^4.0.8": + version "4.0.8" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.8.tgz#77bc4590cdc928901b80f3482e79607a2cbcb150" + integrity sha512-ZTypzBra+lI/LfTYZeop9UjoJhhGRTg3pxrNpfSTQLd3AJ37r2z4AXTKpq1rFXiiUIJsYyFgNJdjWRGP/cbBaQ== dependencies: - "@smithy/config-resolver" "^2.1.1" - "@smithy/credential-provider-imds" "^2.2.1" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/property-provider" "^2.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/property-provider" "^4.0.2" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + bowser "^2.11.0" + tslib "^2.6.2" + +"@smithy/util-defaults-mode-node@^2.1.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.3.1.tgz#4613210a3d107aadb3f85bd80cb71c796dd8bf0a" + integrity sha512-vkMXHQ0BcLFysBMWgSBLSk3+leMpFSyyFj8zQtv5ZyUBx8/owVh1/pPEkzmW/DR/Gy/5c8vjLDD9gZjXNKbrpA== + dependencies: + "@smithy/config-resolver" "^2.2.0" + "@smithy/credential-provider-imds" "^2.3.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/smithy-client" "^2.5.1" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/util-defaults-mode-node@^4.0.8": + version "4.0.8" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.8.tgz#123b517efe6434977139b341d1f64b5f1e743aac" + integrity sha512-Rgk0Jc/UDfRTzVthye/k2dDsz5Xxs9LZaKCNPgJTRyoyBoeiNCnHsYGOyu1PKN+sDyPnJzMOz22JbwxzBp9NNA== + dependencies: + "@smithy/config-resolver" "^4.1.0" + "@smithy/credential-provider-imds" "^4.0.2" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/property-provider" "^4.0.2" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" "@smithy/util-endpoints@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-1.1.1.tgz#45426dba6fb42282a0ad955600b2b3ba050d118f" - integrity sha512-sI4d9rjoaekSGEtq3xSb2nMjHMx8QXcz2cexnVyRWsy4yQ9z3kbDpX+7fN0jnbdOp0b3KSTZJZ2Yb92JWSanLw== + version "1.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-1.2.0.tgz#b8b805f47e8044c158372f69b88337703117665d" + integrity sha512-BuDHv8zRjsE5zXd3PxFXFknzBG3owCpjq8G3FcsXW3CykYXuEqM3nTSsmLzw5q+T12ZYuDlVUZKBdpNbhVtlrQ== dependencies: - "@smithy/node-config-provider" "^2.2.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/node-config-provider" "^2.3.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -"@smithy/util-hex-encoding@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.1.1.tgz#978252b9fb242e0a59bae4ead491210688e0d15f" - integrity sha512-3UNdP2pkYUUBGEXzQI9ODTDK+Tcu1BlCyDBaRHwyxhA+8xLP8agEKQq4MGmpjqb4VQAjq9TwlCQX0kP6XDKYLg== +"@smithy/util-endpoints@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-3.0.2.tgz#6933a0d6d4a349523ef71ca9540c9c0b222b559e" + integrity sha512-6QSutU5ZyrpNbnd51zRTL7goojlcnuOB55+F9VBD+j8JpRY50IGamsjlycrmpn8PQkmJucFW8A0LSfXj7jjtLQ== dependencies: - tslib "^2.5.0" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@smithy/util-hex-encoding@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz#87edb7c88c2f422cfca4bb21f1394ae9602c5085" + integrity sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ== + dependencies: + tslib "^2.6.2" "@smithy/util-hex-encoding@^3.0.0": version "3.0.0" @@ -1630,13 +2315,20 @@ dependencies: tslib "^2.6.2" -"@smithy/util-middleware@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-2.1.1.tgz#903ba19bb17704f4b476fb9ade9bf9eb0174bc3d" - integrity sha512-mKNrk8oz5zqkNcbcgAAepeJbmfUW6ogrT2Z2gDbIUzVzNAHKJQTYmH9jcy0jbWb+m7ubrvXKb6uMjkSgAqqsFA== +"@smithy/util-hex-encoding@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz#dd449a6452cffb37c5b1807ec2525bb4be551e8d" + integrity sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + tslib "^2.6.2" + +"@smithy/util-middleware@^2.1.1", "@smithy/util-middleware@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-2.2.0.tgz#80cfad40f6cca9ffe42a5899b5cb6abd53a50006" + integrity sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw== + dependencies: + "@smithy/types" "^2.12.0" + tslib "^2.6.2" "@smithy/util-middleware@^3.0.2": version "3.0.2" @@ -1646,35 +2338,66 @@ "@smithy/types" "^3.2.0" tslib "^2.6.2" -"@smithy/util-retry@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-2.1.1.tgz#f2d3566b6e5b841028c7240c852007d4037e49b2" - integrity sha512-Mg+xxWPTeSPrthpC5WAamJ6PW4Kbo01Fm7lWM1jmGRvmrRdsd3192Gz2fBXAMURyXpaNxyZf6Hr/nQ4q70oVEA== +"@smithy/util-middleware@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-4.0.2.tgz#272f1249664e27068ef0d5f967a233bf7b77962c" + integrity sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ== dependencies: - "@smithy/service-error-classification" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" -"@smithy/util-stream@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-2.1.1.tgz#3ae0e88c3a1a45899e29c1655d2e5a3865b6c0a6" - integrity sha512-J7SMIpUYvU4DQN55KmBtvaMc7NM3CZ2iWICdcgaovtLzseVhAqFRYqloT3mh0esrFw+3VEK6nQFteFsTqZSECQ== +"@smithy/util-retry@^2.1.1", "@smithy/util-retry@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-2.2.0.tgz#e8e019537ab47ba6b2e87e723ec51ee223422d85" + integrity sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g== dependencies: - "@smithy/fetch-http-handler" "^2.4.1" - "@smithy/node-http-handler" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/util-base64" "^2.1.1" - "@smithy/util-buffer-from" "^2.1.1" - "@smithy/util-hex-encoding" "^2.1.1" - "@smithy/util-utf8" "^2.1.1" - tslib "^2.5.0" + "@smithy/service-error-classification" "^2.1.5" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" -"@smithy/util-uri-escape@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-2.1.1.tgz#7eedc93b73ecda68f12fb9cf92e9fa0fbbed4d83" - integrity sha512-saVzI1h6iRBUVSqtnlOnc9ssU09ypo7n+shdQ8hBTZno/9rZ3AuRYvoHInV57VF7Qn7B+pFJG7qTzFiHxWlWBw== +"@smithy/util-retry@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-4.0.2.tgz#9b64cf460d63555884e641721d19e3c0abff8ee6" + integrity sha512-Qryc+QG+7BCpvjloFLQrmlSd0RsVRHejRXd78jNO3+oREueCjwG1CCEH1vduw/ZkM1U9TztwIKVIi3+8MJScGg== dependencies: - tslib "^2.5.0" + "@smithy/service-error-classification" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@smithy/util-stream@^2.1.1", "@smithy/util-stream@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-2.2.0.tgz#b1279e417992a0f74afa78d7501658f174ed7370" + integrity sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA== + dependencies: + "@smithy/fetch-http-handler" "^2.5.0" + "@smithy/node-http-handler" "^2.5.0" + "@smithy/types" "^2.12.0" + "@smithy/util-base64" "^2.3.0" + "@smithy/util-buffer-from" "^2.2.0" + "@smithy/util-hex-encoding" "^2.2.0" + "@smithy/util-utf8" "^2.3.0" + tslib "^2.6.2" + +"@smithy/util-stream@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-4.2.0.tgz#85f85516b0042726162bf619caa3358332195652" + integrity sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ== + dependencies: + "@smithy/fetch-http-handler" "^5.0.2" + "@smithy/node-http-handler" "^4.0.4" + "@smithy/types" "^4.2.0" + "@smithy/util-base64" "^4.0.0" + "@smithy/util-buffer-from" "^4.0.0" + "@smithy/util-hex-encoding" "^4.0.0" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" + +"@smithy/util-uri-escape@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz#56f5764051a33b67bc93fdd2a869f971b0635406" + integrity sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA== + dependencies: + tslib "^2.6.2" "@smithy/util-uri-escape@^3.0.0": version "3.0.0" @@ -1683,13 +2406,20 @@ dependencies: tslib "^2.6.2" -"@smithy/util-utf8@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.1.1.tgz#690018dd28f47f014114497735e51417ea5900a6" - integrity sha512-BqTpzYEcUMDwAKr7/mVRUtHDhs6ZoXDi9NypMvMfOr/+u1NW7JgqodPDECiiLboEm6bobcPcECxzjtQh865e9A== +"@smithy/util-uri-escape@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz#a96c160c76f3552458a44d8081fade519d214737" + integrity sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg== dependencies: - "@smithy/util-buffer-from" "^2.1.1" - tslib "^2.5.0" + tslib "^2.6.2" + +"@smithy/util-utf8@^2.0.0", "@smithy/util-utf8@^2.1.1", "@smithy/util-utf8@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.3.0.tgz#dd96d7640363259924a214313c3cf16e7dd329c5" + integrity sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A== + dependencies: + "@smithy/util-buffer-from" "^2.2.0" + tslib "^2.6.2" "@smithy/util-utf8@^3.0.0": version "3.0.0" @@ -1699,6 +2429,14 @@ "@smithy/util-buffer-from" "^3.0.0" tslib "^2.6.2" +"@smithy/util-utf8@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-4.0.0.tgz#09ca2d9965e5849e72e347c130f2a29d5c0c863c" + integrity sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow== + dependencies: + "@smithy/util-buffer-from" "^4.0.0" + tslib "^2.6.2" + "@ts-morph/common@~0.20.0": version "0.20.0" resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.20.0.tgz#3f161996b085ba4519731e4d24c35f6cba5b80af" @@ -2606,6 +3344,13 @@ fast-xml-parser@4.2.5: dependencies: strnum "^1.0.5" +fast-xml-parser@4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz#86dbf3f18edf8739326447bcaac31b4ae7f6514f" + integrity sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw== + dependencies: + strnum "^1.0.5" + fastq@^1.6.0: version "1.16.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.16.0.tgz#83b9a9375692db77a822df081edb6a9cf6839320" @@ -3969,9 +4714,9 @@ strip-json-comments@^3.1.1: integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== strnum@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" - integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + version "1.1.2" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.1.2.tgz#57bca4fbaa6f271081715dbc9ed7cee5493e28e4" + integrity sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA== superstruct@^1.0.3: version "1.0.3" @@ -4125,9 +4870,9 @@ tslib@^1.11.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.3.1, tslib@^2.5.0, tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -4181,10 +4926,10 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== v8-compile-cache-lib@^3.0.1: version "3.0.1" From ff925db987a66950c997ec50b9c55e67152d1945 Mon Sep 17 00:00:00 2001 From: Robert Craigie Date: Mon, 28 Apr 2025 13:23:50 -0400 Subject: [PATCH 103/105] chore(bedrock): bump @aws-sdk dependencies --- packages/bedrock-sdk/package.json | 4 +- packages/bedrock-sdk/yarn.lock | 876 +++++++----------------------- 2 files changed, 202 insertions(+), 678 deletions(-) diff --git a/packages/bedrock-sdk/package.json b/packages/bedrock-sdk/package.json index 352931a5..8526e3d5 100644 --- a/packages/bedrock-sdk/package.json +++ b/packages/bedrock-sdk/package.json @@ -24,8 +24,8 @@ "dependencies": { "@anthropic-ai/sdk": "file:../../dist/", "@aws-crypto/sha256-js": "^4.0.0", - "@aws-sdk/client-bedrock-runtime": "^3.423.0", - "@aws-sdk/credential-providers": "^3.341.0", + "@aws-sdk/client-bedrock-runtime": "^3.797.0", + "@aws-sdk/credential-providers": "^3.796.0", "@smithy/eventstream-serde-node": "^2.0.10", "@smithy/fetch-http-handler": "^2.2.1", "@smithy/protocol-http": "^3.0.6", diff --git a/packages/bedrock-sdk/yarn.lock b/packages/bedrock-sdk/yarn.lock index 093c0d77..ffc8fbb8 100644 --- a/packages/bedrock-sdk/yarn.lock +++ b/packages/bedrock-sdk/yarn.lock @@ -38,26 +38,14 @@ "@aws-sdk/types" "^3.222.0" tslib "^1.11.1" -"@aws-crypto/ie11-detection@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz#640ae66b4ec3395cee6a8e94ebcd9f80c24cd688" - integrity sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q== - dependencies: - tslib "^1.11.1" - -"@aws-crypto/sha256-browser@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz#05f160138ab893f1c6ba5be57cfd108f05827766" - integrity sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ== +"@aws-crypto/crc32@5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-5.2.0.tgz#cfcc22570949c98c6689cfcbd2d693d36cdae2e1" + integrity sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg== dependencies: - "@aws-crypto/ie11-detection" "^3.0.0" - "@aws-crypto/sha256-js" "^3.0.0" - "@aws-crypto/supports-web-crypto" "^3.0.0" - "@aws-crypto/util" "^3.0.0" + "@aws-crypto/util" "^5.2.0" "@aws-sdk/types" "^3.222.0" - "@aws-sdk/util-locate-window" "^3.0.0" - "@aws-sdk/util-utf8-browser" "^3.0.0" - tslib "^1.11.1" + tslib "^2.6.2" "@aws-crypto/sha256-browser@5.2.0": version "5.2.0" @@ -72,15 +60,6 @@ "@smithy/util-utf8" "^2.0.0" tslib "^2.6.2" -"@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz#f06b84d550d25521e60d2a0e2a90139341e007c2" - integrity sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ== - dependencies: - "@aws-crypto/util" "^3.0.0" - "@aws-sdk/types" "^3.222.0" - tslib "^1.11.1" - "@aws-crypto/sha256-js@5.2.0", "@aws-crypto/sha256-js@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz#c4fdb773fdbed9a664fc1a95724e206cf3860042" @@ -99,13 +78,6 @@ "@aws-sdk/types" "^3.222.0" tslib "^1.11.1" -"@aws-crypto/supports-web-crypto@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz#5d1bf825afa8072af2717c3e455f35cda0103ec2" - integrity sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg== - dependencies: - tslib "^1.11.1" - "@aws-crypto/supports-web-crypto@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz#a1e399af29269be08e695109aa15da0a07b5b5fb" @@ -140,65 +112,17 @@ "@smithy/util-utf8" "^2.0.0" tslib "^2.6.2" -"@aws-sdk/client-bedrock-runtime@^3.423.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.496.0.tgz#094e17ed2f559e9cc39f375ca9c340ecbd9ddbf8" - integrity sha512-aG9BRKTh9x5ZGgBUYUunWZsL5EGmNmDfDN6dCXdzSpQjP/O5aRWn0EpdIuGHhYfQeY3MkqfdlamewBkInYRhGQ== - dependencies: - "@aws-crypto/sha256-browser" "3.0.0" - "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/client-sts" "3.496.0" - "@aws-sdk/core" "3.496.0" - "@aws-sdk/credential-provider-node" "3.496.0" - "@aws-sdk/middleware-host-header" "3.496.0" - "@aws-sdk/middleware-logger" "3.496.0" - "@aws-sdk/middleware-recursion-detection" "3.496.0" - "@aws-sdk/middleware-signing" "3.496.0" - "@aws-sdk/middleware-user-agent" "3.496.0" - "@aws-sdk/region-config-resolver" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@aws-sdk/util-endpoints" "3.496.0" - "@aws-sdk/util-user-agent-browser" "3.496.0" - "@aws-sdk/util-user-agent-node" "3.496.0" - "@smithy/config-resolver" "^2.1.1" - "@smithy/core" "^1.3.1" - "@smithy/eventstream-serde-browser" "^2.1.1" - "@smithy/eventstream-serde-config-resolver" "^2.1.1" - "@smithy/eventstream-serde-node" "^2.1.1" - "@smithy/fetch-http-handler" "^2.4.1" - "@smithy/hash-node" "^2.1.1" - "@smithy/invalid-dependency" "^2.1.1" - "@smithy/middleware-content-length" "^2.1.1" - "@smithy/middleware-endpoint" "^2.4.1" - "@smithy/middleware-retry" "^2.1.1" - "@smithy/middleware-serde" "^2.1.1" - "@smithy/middleware-stack" "^2.1.1" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/node-http-handler" "^2.3.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/url-parser" "^2.1.1" - "@smithy/util-base64" "^2.1.1" - "@smithy/util-body-length-browser" "^2.1.1" - "@smithy/util-body-length-node" "^2.2.1" - "@smithy/util-defaults-mode-browser" "^2.1.1" - "@smithy/util-defaults-mode-node" "^2.1.1" - "@smithy/util-endpoints" "^1.1.1" - "@smithy/util-retry" "^2.1.1" - "@smithy/util-stream" "^2.1.1" - "@smithy/util-utf8" "^2.1.1" - tslib "^2.5.0" - -"@aws-sdk/client-cognito-identity@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.796.0.tgz#8dcb4cb37789f887ed77e3fdcae8cfe1fff6cada" - integrity sha512-p8ZzHICnQaCL4oS16yHUCLH6/VkbmWP8p2P7vALncUYguHDE/oNcWNAARo56x3Qx0TbRCi0OD4KAwD6AhddMdg== +"@aws-sdk/client-bedrock-runtime@^3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.797.0.tgz#80dba98b5479858ebf294ed8329d981acb68d037" + integrity sha512-cyg0LtT/bWOo+vfCT73JsP4MbM566nblS7uEF1XS9OkiRzDcnIaCZFBX9KL6cxZ8T+N4Yi40BRY+c3O6qR4SGA== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" "@aws-sdk/core" "3.796.0" - "@aws-sdk/credential-provider-node" "3.796.0" + "@aws-sdk/credential-provider-node" "3.797.0" + "@aws-sdk/eventstream-handler-node" "3.775.0" + "@aws-sdk/middleware-eventstream" "3.775.0" "@aws-sdk/middleware-host-header" "3.775.0" "@aws-sdk/middleware-logger" "3.775.0" "@aws-sdk/middleware-recursion-detection" "3.775.0" @@ -210,6 +134,9 @@ "@aws-sdk/util-user-agent-node" "3.796.0" "@smithy/config-resolver" "^4.1.0" "@smithy/core" "^3.2.0" + "@smithy/eventstream-serde-browser" "^4.0.2" + "@smithy/eventstream-serde-config-resolver" "^4.1.0" + "@smithy/eventstream-serde-node" "^4.0.2" "@smithy/fetch-http-handler" "^5.0.2" "@smithy/hash-node" "^4.0.2" "@smithy/invalid-dependency" "^4.0.2" @@ -232,60 +159,21 @@ "@smithy/util-endpoints" "^3.0.2" "@smithy/util-middleware" "^4.0.2" "@smithy/util-retry" "^4.0.2" + "@smithy/util-stream" "^4.2.0" "@smithy/util-utf8" "^4.0.0" + "@types/uuid" "^9.0.1" tslib "^2.6.2" + uuid "^9.0.1" -"@aws-sdk/client-sso@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.496.0.tgz#765cbfb3afcbe7bc8f2430e40afd4d542a0d58fb" - integrity sha512-fuaMuxKg7CMUsP9l3kxYWCOxFsBjdA0xj5nlikaDm1661/gB4KkAiGqRY8LsQkpNXvXU8Nj+f7oCFADFyGYzyw== - dependencies: - "@aws-crypto/sha256-browser" "3.0.0" - "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/core" "3.496.0" - "@aws-sdk/middleware-host-header" "3.496.0" - "@aws-sdk/middleware-logger" "3.496.0" - "@aws-sdk/middleware-recursion-detection" "3.496.0" - "@aws-sdk/middleware-user-agent" "3.496.0" - "@aws-sdk/region-config-resolver" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@aws-sdk/util-endpoints" "3.496.0" - "@aws-sdk/util-user-agent-browser" "3.496.0" - "@aws-sdk/util-user-agent-node" "3.496.0" - "@smithy/config-resolver" "^2.1.1" - "@smithy/core" "^1.3.1" - "@smithy/fetch-http-handler" "^2.4.1" - "@smithy/hash-node" "^2.1.1" - "@smithy/invalid-dependency" "^2.1.1" - "@smithy/middleware-content-length" "^2.1.1" - "@smithy/middleware-endpoint" "^2.4.1" - "@smithy/middleware-retry" "^2.1.1" - "@smithy/middleware-serde" "^2.1.1" - "@smithy/middleware-stack" "^2.1.1" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/node-http-handler" "^2.3.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/url-parser" "^2.1.1" - "@smithy/util-base64" "^2.1.1" - "@smithy/util-body-length-browser" "^2.1.1" - "@smithy/util-body-length-node" "^2.2.1" - "@smithy/util-defaults-mode-browser" "^2.1.1" - "@smithy/util-defaults-mode-node" "^2.1.1" - "@smithy/util-endpoints" "^1.1.1" - "@smithy/util-retry" "^2.1.1" - "@smithy/util-utf8" "^2.1.1" - tslib "^2.5.0" - -"@aws-sdk/client-sso@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.796.0.tgz#231fc98bd71c5e915e9060fba871a6d9d9ccb3d6" - integrity sha512-EJExg8mbwqP0VG+RNFV4ZPuUo7QsDsUfTnuFQY51V8iXrbOdV+PDLRr4psXj2fxvrLxc9AlGUMNqd/j4VZtQzA== +"@aws-sdk/client-cognito-identity@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.797.0.tgz#e26c9922d08178f726aa30dc2fbd8d088eb0ec08" + integrity sha512-IzpwVFYpLOV7Anm2CvihMb+qx/2OFjd47BWVOtMtMBDeYbygYKmTWQ2XdqWMlTwKub/gwzn0yRoXSeGuKl/yEQ== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" "@aws-sdk/core" "3.796.0" + "@aws-sdk/credential-provider-node" "3.797.0" "@aws-sdk/middleware-host-header" "3.775.0" "@aws-sdk/middleware-logger" "3.775.0" "@aws-sdk/middleware-recursion-detection" "3.775.0" @@ -322,63 +210,49 @@ "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@aws-sdk/client-sts@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.496.0.tgz#e0c142cf8bb1aec7a9c7b09dd9739f6773d94fd0" - integrity sha512-3pSdqgegdwbK3CT1WvGHhA+Bf91R9cr8G1Ynp+iU2wZvy8ueJfMUk0NYfjo3EEv0YhSbMLKuduzZfvQHFHXYhw== - dependencies: - "@aws-crypto/sha256-browser" "3.0.0" - "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/core" "3.496.0" - "@aws-sdk/credential-provider-node" "3.496.0" - "@aws-sdk/middleware-host-header" "3.496.0" - "@aws-sdk/middleware-logger" "3.496.0" - "@aws-sdk/middleware-recursion-detection" "3.496.0" - "@aws-sdk/middleware-user-agent" "3.496.0" - "@aws-sdk/region-config-resolver" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@aws-sdk/util-endpoints" "3.496.0" - "@aws-sdk/util-user-agent-browser" "3.496.0" - "@aws-sdk/util-user-agent-node" "3.496.0" - "@smithy/config-resolver" "^2.1.1" - "@smithy/core" "^1.3.1" - "@smithy/fetch-http-handler" "^2.4.1" - "@smithy/hash-node" "^2.1.1" - "@smithy/invalid-dependency" "^2.1.1" - "@smithy/middleware-content-length" "^2.1.1" - "@smithy/middleware-endpoint" "^2.4.1" - "@smithy/middleware-retry" "^2.1.1" - "@smithy/middleware-serde" "^2.1.1" - "@smithy/middleware-stack" "^2.1.1" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/node-http-handler" "^2.3.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/url-parser" "^2.1.1" - "@smithy/util-base64" "^2.1.1" - "@smithy/util-body-length-browser" "^2.1.1" - "@smithy/util-body-length-node" "^2.2.1" - "@smithy/util-defaults-mode-browser" "^2.1.1" - "@smithy/util-defaults-mode-node" "^2.1.1" - "@smithy/util-endpoints" "^1.1.1" - "@smithy/util-middleware" "^2.1.1" - "@smithy/util-retry" "^2.1.1" - "@smithy/util-utf8" "^2.1.1" - fast-xml-parser "4.2.5" - tslib "^2.5.0" - -"@aws-sdk/core@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.496.0.tgz#ec1394753b6b2f6e38aea593e30b2db5c7390969" - integrity sha512-yT+ug7Cw/3eJi7x2es0+46x12+cIJm5Xv+GPWsrTFD1TKgqO/VPEgfDtHFagDNbFmjNQA65Ygc/kEdIX9ICX/A== +"@aws-sdk/client-sso@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.797.0.tgz#94d123568830788980cc8712a94d3b20de735e4c" + integrity sha512-9xuR918p7tShR67ZL+AOSbydpJxSHAOdXcQswxxWR/hKCF7tULX7tyL3gNo3l/ETp0CDcStvorOdH/nCbzEOjw== dependencies: - "@smithy/core" "^1.3.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/signature-v4" "^2.1.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/core" "3.796.0" + "@aws-sdk/middleware-host-header" "3.775.0" + "@aws-sdk/middleware-logger" "3.775.0" + "@aws-sdk/middleware-recursion-detection" "3.775.0" + "@aws-sdk/middleware-user-agent" "3.796.0" + "@aws-sdk/region-config-resolver" "3.775.0" + "@aws-sdk/types" "3.775.0" + "@aws-sdk/util-endpoints" "3.787.0" + "@aws-sdk/util-user-agent-browser" "3.775.0" + "@aws-sdk/util-user-agent-node" "3.796.0" + "@smithy/config-resolver" "^4.1.0" + "@smithy/core" "^3.2.0" + "@smithy/fetch-http-handler" "^5.0.2" + "@smithy/hash-node" "^4.0.2" + "@smithy/invalid-dependency" "^4.0.2" + "@smithy/middleware-content-length" "^4.0.2" + "@smithy/middleware-endpoint" "^4.1.0" + "@smithy/middleware-retry" "^4.1.0" + "@smithy/middleware-serde" "^4.0.3" + "@smithy/middleware-stack" "^4.0.2" + "@smithy/node-config-provider" "^4.0.2" + "@smithy/node-http-handler" "^4.0.4" + "@smithy/protocol-http" "^5.1.0" + "@smithy/smithy-client" "^4.2.0" + "@smithy/types" "^4.2.0" + "@smithy/url-parser" "^4.0.2" + "@smithy/util-base64" "^4.0.0" + "@smithy/util-body-length-browser" "^4.0.0" + "@smithy/util-body-length-node" "^4.0.0" + "@smithy/util-defaults-mode-browser" "^4.0.8" + "@smithy/util-defaults-mode-node" "^4.0.8" + "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-middleware" "^4.0.2" + "@smithy/util-retry" "^4.0.2" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" "@aws-sdk/core@3.796.0": version "3.796.0" @@ -397,27 +271,17 @@ fast-xml-parser "4.4.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-cognito-identity@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.796.0.tgz#c037d35d8a8284fc4cc658da9e7a2498f3703f1f" - integrity sha512-plvMsQNWW1Jq7YRs8S6xHEbdn+kO/F+vDjCBrPaT4LhcDMsXqO/jcDNRuYOnPRBQsqjp7n7MM3oMhyY4fupa6g== +"@aws-sdk/credential-provider-cognito-identity@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.797.0.tgz#fb223c90670b50c14dcc427999904f2bb3add40b" + integrity sha512-hE/fOgFIToJKuMz8hxUZ9PqqyG9xkjig4my6JxE+dcKxefoK3gT2ELrDjw/MOnjqeUorzJ8O5PjJxa1zzIzchw== dependencies: - "@aws-sdk/client-cognito-identity" "3.796.0" + "@aws-sdk/client-cognito-identity" "3.797.0" "@aws-sdk/types" "3.775.0" "@smithy/property-provider" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-env@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.496.0.tgz#5055bd2e3a169e5c10b37c40e0f356046947e707" - integrity sha512-lukQMJ8SWWP5RqkRNOHi/H+WMhRvSWa3Fc5Jf/VP6xHiPLfF1XafcvthtV91e0VwPCiseI+HqChrcGq8pvnxHw== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/property-provider" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - "@aws-sdk/credential-provider-env@3.796.0": version "3.796.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.796.0.tgz#4ed6903814868b0f9daa8c8db449b1f1adcda041" @@ -445,34 +309,18 @@ "@smithy/util-stream" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-ini@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.496.0.tgz#4de82fc173ba1581af4bf6fcad610f2fc0fd8ca1" - integrity sha512-2nD1jp1sIwcQaWK1y/9ruQOkW16RUxZpzgjbW/gnK3iiUXwx+/FNQWxshud+GTSx3Q4x6eIhqsbjtP4VVPPuUA== - dependencies: - "@aws-sdk/credential-provider-env" "3.496.0" - "@aws-sdk/credential-provider-process" "3.496.0" - "@aws-sdk/credential-provider-sso" "3.496.0" - "@aws-sdk/credential-provider-web-identity" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@smithy/credential-provider-imds" "^2.2.1" - "@smithy/property-provider" "^2.1.1" - "@smithy/shared-ini-file-loader" "^2.3.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - -"@aws-sdk/credential-provider-ini@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.796.0.tgz#6d5f260b93104b126e26919287a4e131d1cb8e75" - integrity sha512-qGWBDn9aO8avFfYU7daps7Sy6OglF1x0q0w48slt0KMXbHd2/LvKVIiYwyofYCXed0yzcEOF2IYm9FjXdcn+ug== +"@aws-sdk/credential-provider-ini@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.797.0.tgz#e617edac6dbd761e13826d49092b85a337bf29a2" + integrity sha512-Zpj6pJ2hnebrhLDr+x61ArMUkjHG6mfJRfamHxeVTgZkhLcwHjC5aM4u9pWTVugIaPY+VBtgkKPbi3TRbHlt2g== dependencies: "@aws-sdk/core" "3.796.0" "@aws-sdk/credential-provider-env" "3.796.0" "@aws-sdk/credential-provider-http" "3.796.0" "@aws-sdk/credential-provider-process" "3.796.0" - "@aws-sdk/credential-provider-sso" "3.796.0" - "@aws-sdk/credential-provider-web-identity" "3.796.0" - "@aws-sdk/nested-clients" "3.796.0" + "@aws-sdk/credential-provider-sso" "3.797.0" + "@aws-sdk/credential-provider-web-identity" "3.797.0" + "@aws-sdk/nested-clients" "3.797.0" "@aws-sdk/types" "3.775.0" "@smithy/credential-provider-imds" "^4.0.2" "@smithy/property-provider" "^4.0.2" @@ -480,34 +328,17 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-node@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.496.0.tgz#734fc5aa824c387c893ff5624b201c0243ea1c7c" - integrity sha512-IVF9RvLePfRa5S5/eBIRChJCWOzQkGwM8P/L79Gl84u/cH2oSG4NtUI/YTDlrtmnYn7YsGhINSV0WnzfF2twfQ== - dependencies: - "@aws-sdk/credential-provider-env" "3.496.0" - "@aws-sdk/credential-provider-ini" "3.496.0" - "@aws-sdk/credential-provider-process" "3.496.0" - "@aws-sdk/credential-provider-sso" "3.496.0" - "@aws-sdk/credential-provider-web-identity" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@smithy/credential-provider-imds" "^2.2.1" - "@smithy/property-provider" "^2.1.1" - "@smithy/shared-ini-file-loader" "^2.3.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - -"@aws-sdk/credential-provider-node@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.796.0.tgz#aa621e4f15d7317b351c1dbb896bfcabbc21db0c" - integrity sha512-WeNK7OWPrsOvhO3DAgpUO0FtmVghMaZ/IpPJHJ4Y0nBIsWOBXLrbZ2Y1mdT8N2bGGUaM91tJaV8Yf8COc3gvmA== +"@aws-sdk/credential-provider-node@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.797.0.tgz#bf82e239b14c8fcc7da660c2bc1ec042123638d9" + integrity sha512-xJSWvvnmzEfHbqbpN4F3E3mI9+zJ/VWLGiKOjzX1Inbspa5WqNn2GoMamolZR2TvvZS4F3Hp73TD1WoBzkIjuw== dependencies: "@aws-sdk/credential-provider-env" "3.796.0" "@aws-sdk/credential-provider-http" "3.796.0" - "@aws-sdk/credential-provider-ini" "3.796.0" + "@aws-sdk/credential-provider-ini" "3.797.0" "@aws-sdk/credential-provider-process" "3.796.0" - "@aws-sdk/credential-provider-sso" "3.796.0" - "@aws-sdk/credential-provider-web-identity" "3.796.0" + "@aws-sdk/credential-provider-sso" "3.797.0" + "@aws-sdk/credential-provider-web-identity" "3.797.0" "@aws-sdk/types" "3.775.0" "@smithy/credential-provider-imds" "^4.0.2" "@smithy/property-provider" "^4.0.2" @@ -515,17 +346,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-process@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.496.0.tgz#1d623bed61229767f389feab560e3a3117bf2d26" - integrity sha512-/YZscCTGOKVmGr916Th4XF8Sz6JDtZ/n2loHG9exok9iy/qIbACsTRNLP9zexPxhPoue/oZqecY5xbVljfY34A== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/property-provider" "^2.1.1" - "@smithy/shared-ini-file-loader" "^2.3.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - "@aws-sdk/credential-provider-process@3.796.0": version "3.796.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.796.0.tgz#d22d8adf73985fb218ff74365cd86b71bbd64513" @@ -538,71 +358,48 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-sso@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.496.0.tgz#1c5f2d25b64936b79095f49cabbcd7832fb87087" - integrity sha512-eP7GxpT2QYubSDG7uk1GJW4eNymZCq65IxDyEFCXOP/kfqkxriCY+iVEFG6/Mo3LxvgrgHXU4jxrCAXMAWN43g== - dependencies: - "@aws-sdk/client-sso" "3.496.0" - "@aws-sdk/token-providers" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@smithy/property-provider" "^2.1.1" - "@smithy/shared-ini-file-loader" "^2.3.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - -"@aws-sdk/credential-provider-sso@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.796.0.tgz#db9081637747162ed8c5b29c61a98b898eea3e99" - integrity sha512-RUYsQ1t6UdzkpZ7pocUt1l/9l9GCYCaopIhv0DU6CipA8rkWtoweKsLHKdv+8wE4p6gqDfDIHGam1ivswiCIzg== +"@aws-sdk/credential-provider-sso@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.797.0.tgz#ea22714498157c937acd3170660b10ae0348366a" + integrity sha512-VlyWnjTsTnBXqXcEW0nw3S7nj00n9fYwF6uU6HPO9t860yIySG01lNPAWTvAt3DfVL5SRS0GANriCZF6ohcMcQ== dependencies: - "@aws-sdk/client-sso" "3.796.0" + "@aws-sdk/client-sso" "3.797.0" "@aws-sdk/core" "3.796.0" - "@aws-sdk/token-providers" "3.796.0" + "@aws-sdk/token-providers" "3.797.0" "@aws-sdk/types" "3.775.0" "@smithy/property-provider" "^4.0.2" "@smithy/shared-ini-file-loader" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-web-identity@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.496.0.tgz#7ad6d755445d1616a80dfa286a78c84dc1c3f14b" - integrity sha512-IbP+qLlvJSpNPj+zW6TtFuLRTK5Tf0hW+2pom4vFyi5YSH4pn8UOC136UdewX8vhXGS9BJQ5zBDMasIyl5VeGQ== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/property-provider" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - -"@aws-sdk/credential-provider-web-identity@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.796.0.tgz#8d19749fcf28f6603bb26a402f3f8e24797c35ba" - integrity sha512-dpmFJT4IyjT09vruvMu/rWQQjVreqdxAe8pLPpGhoeKyA1O6+PS73b+VNXKvD31rQT8e4g6dVpA6KMxNW63aag== +"@aws-sdk/credential-provider-web-identity@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.797.0.tgz#e52b5a054a71f83ffafe3461b41851d5008d84de" + integrity sha512-DIb05FEmdOX7bNsqSVEAB3UkaDgrYHonQ2+gcBLqZ7LoDNnovHIlvC5jii93usgEStxITZstnzw+49keNEgVWw== dependencies: "@aws-sdk/core" "3.796.0" - "@aws-sdk/nested-clients" "3.796.0" + "@aws-sdk/nested-clients" "3.797.0" "@aws-sdk/types" "3.775.0" "@smithy/property-provider" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-providers@^3.341.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-providers/-/credential-providers-3.796.0.tgz#60a9544366a08e6e6dc69625a668cfd12b6501d9" - integrity sha512-thZw44Bk3pS0PW81QmPfNSliX5XfXHDlWRjPYHBx+eTlPtidyD5klJkkfF5fkQlpHPeP2KNLuRnr6bRu+uMirg== +"@aws-sdk/credential-providers@^3.796.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-providers/-/credential-providers-3.797.0.tgz#d34fc066ef0a03ba3d108ad09340490f13f9c567" + integrity sha512-UBsPtUql1q22kMNKcUKhpRKlZXHW1ESbcrv0Z/BekwHEu8fuxgS8aRsfminUcLaBLPjBJjEy6AhY/rXUpX6lsg== dependencies: - "@aws-sdk/client-cognito-identity" "3.796.0" + "@aws-sdk/client-cognito-identity" "3.797.0" "@aws-sdk/core" "3.796.0" - "@aws-sdk/credential-provider-cognito-identity" "3.796.0" + "@aws-sdk/credential-provider-cognito-identity" "3.797.0" "@aws-sdk/credential-provider-env" "3.796.0" "@aws-sdk/credential-provider-http" "3.796.0" - "@aws-sdk/credential-provider-ini" "3.796.0" - "@aws-sdk/credential-provider-node" "3.796.0" + "@aws-sdk/credential-provider-ini" "3.797.0" + "@aws-sdk/credential-provider-node" "3.797.0" "@aws-sdk/credential-provider-process" "3.796.0" - "@aws-sdk/credential-provider-sso" "3.796.0" - "@aws-sdk/credential-provider-web-identity" "3.796.0" - "@aws-sdk/nested-clients" "3.796.0" + "@aws-sdk/credential-provider-sso" "3.797.0" + "@aws-sdk/credential-provider-web-identity" "3.797.0" + "@aws-sdk/nested-clients" "3.797.0" "@aws-sdk/types" "3.775.0" "@smithy/config-resolver" "^4.1.0" "@smithy/core" "^3.2.0" @@ -612,15 +409,25 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-host-header@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.496.0.tgz#e17de11d553548872566c72669c5ea2e7164722b" - integrity sha512-jUdPpSJeqCYXf6hSjfwsfHway7peIV8Vz51w/BN91bF4vB/bYwAC5o9/iJiK/EoByp5asxA8fg9wFOyGjzdbLg== +"@aws-sdk/eventstream-handler-node@3.775.0": + version "3.775.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.775.0.tgz#4f1b8baa29d1c46d5f94908f695d0ccf4363c8f5" + integrity sha512-NAGVlICJW5dTQwfHj0HB4OUtFIVjMrUOacIq8EapJpJJG5rOZFaaG3BbhC1dpbraRmD/+dClnRZOKikK0eatrg== dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/protocol-http" "^3.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@aws-sdk/types" "3.775.0" + "@smithy/eventstream-codec" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@aws-sdk/middleware-eventstream@3.775.0": + version "3.775.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.775.0.tgz#a751ccb2d9ab6f345d17ef81848322896d7defd3" + integrity sha512-B5/ZUTBSOhMbSrvrTlnogrwG3SLHRuwTnXAwoRyUGJfH2iblBgVPwyzOEmjpm53iaaGMa7SsBJ+xSNBXJZGuIw== + dependencies: + "@aws-sdk/types" "3.775.0" + "@smithy/protocol-http" "^5.1.0" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" "@aws-sdk/middleware-host-header@3.775.0": version "3.775.0" @@ -632,15 +439,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-logger@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.496.0.tgz#96f867ae50144eb6bae91a427e315a0f0eb783b0" - integrity sha512-EwMVSY6iBMeGbVnvwdaFl/ClMS/YWtxCAo+bcEtgk8ltRuo7qgbJem8Km/fvWC1vdWvIbe4ArdJ8iGzq62ffAw== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - "@aws-sdk/middleware-logger@3.775.0": version "3.775.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.775.0.tgz#df1909d441cd4bade8d6c7d24c41532808db0e81" @@ -650,16 +448,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-recursion-detection@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.496.0.tgz#c14e1bbe609e4af3ec9037c2379e2b64d660e4dd" - integrity sha512-+IuOcFsfqg2WAnaEzH6KhVbicqCxtOq9w3DH2jwTpddRlCx2Kqf6wCzg8luhHRGyjBZdsbIS+OXwyMevoppawA== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/protocol-http" "^3.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - "@aws-sdk/middleware-recursion-detection@3.775.0": version "3.775.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.775.0.tgz#36a40f467754d7c86424d12ef45c05e96ce3475b" @@ -670,30 +458,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-signing@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.496.0.tgz#265cb5a9d7825c111c53bb555e5cb2619f804dd1" - integrity sha512-Oq73Brs4IConvWnRlh8jM1V7LHoTw9SVQklu/QW2FPlNrB3B8fuTdWHHYIWv7ybw1bykXoCY99v865Mmq/Or/g== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/property-provider" "^2.1.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/signature-v4" "^2.1.1" - "@smithy/types" "^2.9.1" - "@smithy/util-middleware" "^2.1.1" - tslib "^2.5.0" - -"@aws-sdk/middleware-user-agent@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.496.0.tgz#82b49fd8613ae5a9ceafc9117c34271615d0f002" - integrity sha512-+iMtRxFk0GmFWNUF4ilxylOQd9PZdR4ZC9jkcPIh1PZlvKtpCyFywKlk5RRZKklSoJ/CttcqwhMvOXTNbWm/0w== - dependencies: - "@aws-sdk/types" "3.496.0" - "@aws-sdk/util-endpoints" "3.496.0" - "@smithy/protocol-http" "^3.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - "@aws-sdk/middleware-user-agent@3.796.0": version "3.796.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.796.0.tgz#80149d7f9034d41d35de88d96a6b73c1cb06413b" @@ -707,10 +471,10 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/nested-clients@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.796.0.tgz#f13f3bd87b923561348394ac6a9010d74334cb7c" - integrity sha512-jJ8a0ldWtXh/ice7nldUjTqja7KYlSYk1pwfIIvJLIqEn2SvQHK/pyCINTmmOmFAWXMKBQBeWUMxo1pPYNytzQ== +"@aws-sdk/nested-clients@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.797.0.tgz#59699196a9b3fa43b021bdf1715e531d74885f75" + integrity sha512-xCsRKdsv0GAg9E28fvYBdC3JR2xdtZ2o41MVknOs+pSFtMsZm3SsgxObN35p1OTMk/o/V0LORGVLnFQMlc5QiA== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" @@ -751,18 +515,6 @@ "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@aws-sdk/region-config-resolver@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.496.0.tgz#133c8a4a6d5e7672077ba124751f40b2d6efc3ed" - integrity sha512-URrNVOPHPgEDm6QFu6lDC2cUFs+Jx23mA3jEwCvoKlXiEY/ZoWjH8wlX3OMUlLrF1qoUTuD03jjrJzF6zoCgug== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/types" "^2.9.1" - "@smithy/util-config-provider" "^2.2.1" - "@smithy/util-middleware" "^2.1.1" - tslib "^2.5.0" - "@aws-sdk/region-config-resolver@3.775.0": version "3.775.0" resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.775.0.tgz#592b52498e68501fe46480be3dfb185e949d1eab" @@ -775,69 +527,18 @@ "@smithy/util-middleware" "^4.0.2" tslib "^2.6.2" -"@aws-sdk/token-providers@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.496.0.tgz#5b5baf0801fd591de4a28146afbdc8250197f9fa" - integrity sha512-fyi8RcObEa1jNETJdc2H6q9VHrrdKCj/b6+fbLvymb7mUVRd0aWUn+24SNUImnSOnrwYnwaMfyyEC388X4MbFQ== - dependencies: - "@aws-crypto/sha256-browser" "3.0.0" - "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/middleware-host-header" "3.496.0" - "@aws-sdk/middleware-logger" "3.496.0" - "@aws-sdk/middleware-recursion-detection" "3.496.0" - "@aws-sdk/middleware-user-agent" "3.496.0" - "@aws-sdk/region-config-resolver" "3.496.0" - "@aws-sdk/types" "3.496.0" - "@aws-sdk/util-endpoints" "3.496.0" - "@aws-sdk/util-user-agent-browser" "3.496.0" - "@aws-sdk/util-user-agent-node" "3.496.0" - "@smithy/config-resolver" "^2.1.1" - "@smithy/fetch-http-handler" "^2.4.1" - "@smithy/hash-node" "^2.1.1" - "@smithy/invalid-dependency" "^2.1.1" - "@smithy/middleware-content-length" "^2.1.1" - "@smithy/middleware-endpoint" "^2.4.1" - "@smithy/middleware-retry" "^2.1.1" - "@smithy/middleware-serde" "^2.1.1" - "@smithy/middleware-stack" "^2.1.1" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/node-http-handler" "^2.3.1" - "@smithy/property-provider" "^2.1.1" - "@smithy/protocol-http" "^3.1.1" - "@smithy/shared-ini-file-loader" "^2.3.1" - "@smithy/smithy-client" "^2.3.1" - "@smithy/types" "^2.9.1" - "@smithy/url-parser" "^2.1.1" - "@smithy/util-base64" "^2.1.1" - "@smithy/util-body-length-browser" "^2.1.1" - "@smithy/util-body-length-node" "^2.2.1" - "@smithy/util-defaults-mode-browser" "^2.1.1" - "@smithy/util-defaults-mode-node" "^2.1.1" - "@smithy/util-endpoints" "^1.1.1" - "@smithy/util-retry" "^2.1.1" - "@smithy/util-utf8" "^2.1.1" - tslib "^2.5.0" - -"@aws-sdk/token-providers@3.796.0": - version "3.796.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.796.0.tgz#c31f1d522a1df01ecf3780e72de67d2fc0c8787b" - integrity sha512-Sxr/EqJBxOwLsXHv8C91N/Aao8Rgjn5bcpzplrTZ7wrfDrzqQfSCvjh7apCxdLYMKPBV+an75blCAd7JD4/bAg== +"@aws-sdk/token-providers@3.797.0": + version "3.797.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.797.0.tgz#9f8c316f1adfda592c8dc6e69082879896720696" + integrity sha512-TLFkP4BBdkH2zCXhG3JjaYrRft25MMZ+6/YDz1C/ikq2Zk8krUbVoSmhtYMVz10JtxAPiQ++w0vI/qbz2JSDXg== dependencies: - "@aws-sdk/nested-clients" "3.796.0" + "@aws-sdk/nested-clients" "3.797.0" "@aws-sdk/types" "3.775.0" "@smithy/property-provider" "^4.0.2" "@smithy/shared-ini-file-loader" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/types@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.496.0.tgz#cdde44a94a57cf8f97cf05e4d0bdce2f56ce4eeb" - integrity sha512-umkGadK4QuNQaMoDICMm7NKRI/mYSXiyPjcn3d53BhsuArYU/52CebGQKdt4At7SwwsiVJZw9RNBHyN5Mm0HVw== - dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - "@aws-sdk/types@3.775.0", "@aws-sdk/types@^3.222.0": version "3.775.0" resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.775.0.tgz#09863a9e68c080947db7c3d226d1c56b8f0f5150" @@ -846,16 +547,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/util-endpoints@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.496.0.tgz#5ce7d3efd7ab67db556e2c199e73826c44d22ecd" - integrity sha512-1QzOiWHi383ZwqSi/R2KgKCd7M+6DxkxI5acqLPm8mvDRDP2jRjrnVaC0g9/tlttWousGEemDUWStwrD2mVYSw== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/types" "^2.9.1" - "@smithy/util-endpoints" "^1.1.1" - tslib "^2.5.0" - "@aws-sdk/util-endpoints@3.787.0": version "3.787.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.787.0.tgz#1398f0bd87f19e615ae920c73e16d9d5e5cb76d1" @@ -873,16 +564,6 @@ dependencies: tslib "^2.6.2" -"@aws-sdk/util-user-agent-browser@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.496.0.tgz#494b086dd8b07acdd6be65034c51545e5bcee37b" - integrity sha512-4j2spN+h0I0qfSMsGvJXTfQBu1e18rPdekKvzsGJxhaAE1tNgUfUT4nbvc5uVn0sNjZmirskmJ3kfbzVOrqIFg== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/types" "^2.9.1" - bowser "^2.11.0" - tslib "^2.5.0" - "@aws-sdk/util-user-agent-browser@3.775.0": version "3.775.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.775.0.tgz#b69a1a5548ccc6db1acb3ec115967593ece927a1" @@ -893,16 +574,6 @@ bowser "^2.11.0" tslib "^2.6.2" -"@aws-sdk/util-user-agent-node@3.496.0": - version "3.496.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.496.0.tgz#db14e02cf82af556c826570efc7db1e57de3262d" - integrity sha512-h0Ax0jlDc7UIo3KoSI4C4tVLBFoiAdx3+DhTVfgLS7x93d41dMlziPoBX2RgdcFn37qnzw6AQKTVTMwDbRCGpg== - dependencies: - "@aws-sdk/types" "3.496.0" - "@smithy/node-config-provider" "^2.2.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" - "@aws-sdk/util-user-agent-node@3.796.0": version "3.796.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.796.0.tgz#72c2ea1f32d2eb1200e111f48fd8a3c005f5202c" @@ -1575,17 +1246,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/config-resolver@^2.1.1", "@smithy/config-resolver@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-2.2.0.tgz#54f40478bb61709b396960a3535866dba5422757" - integrity sha512-fsiMgd8toyUba6n1WRmr+qACzXltpdDkPTAaDqc8QqPBUzO+/JKwL6bUBseHVi8tu9l+3JOK+tSf7cay+4B3LA== - dependencies: - "@smithy/node-config-provider" "^2.3.0" - "@smithy/types" "^2.12.0" - "@smithy/util-config-provider" "^2.3.0" - "@smithy/util-middleware" "^2.2.0" - tslib "^2.6.2" - "@smithy/config-resolver@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-4.1.0.tgz#de1043cbd75f05d99798b0fbcfdaf4b89b0f2f41" @@ -1597,20 +1257,6 @@ "@smithy/util-middleware" "^4.0.2" tslib "^2.6.2" -"@smithy/core@^1.3.1": - version "1.4.2" - resolved "https://registry.yarnpkg.com/@smithy/core/-/core-1.4.2.tgz#1c3ed886d403041ce5bd2d816448420c57baa19c" - integrity sha512-2fek3I0KZHWJlRLvRTqxTEri+qV0GRHrJIoLFuBMZB4EMg4WgeBGfF0X6abnrNYpq55KJ6R4D6x4f0vLnhzinA== - dependencies: - "@smithy/middleware-endpoint" "^2.5.1" - "@smithy/middleware-retry" "^2.3.1" - "@smithy/middleware-serde" "^2.3.0" - "@smithy/protocol-http" "^3.3.0" - "@smithy/smithy-client" "^2.5.1" - "@smithy/types" "^2.12.0" - "@smithy/util-middleware" "^2.2.0" - tslib "^2.6.2" - "@smithy/core@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.2.0.tgz#613b15f76eab9a6be396b1d5453b6bc8f22ba99c" @@ -1625,17 +1271,6 @@ "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@smithy/credential-provider-imds@^2.2.1", "@smithy/credential-provider-imds@^2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-2.3.0.tgz#326ce401b82e53f3c7ee4862a066136959a06166" - integrity sha512-BWB9mIukO1wjEOo1Ojgl6LrG4avcaC7T/ZP6ptmAaW4xluhSIPZhY+/PI5YKzlk+jsm+4sQZB45Bt1OfMeQa3w== - dependencies: - "@smithy/node-config-provider" "^2.3.0" - "@smithy/property-provider" "^2.2.0" - "@smithy/types" "^2.12.0" - "@smithy/url-parser" "^2.2.0" - tslib "^2.6.2" - "@smithy/credential-provider-imds@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.2.tgz#1ec34a04842fa69996b151a695b027f0486c69a8" @@ -1647,7 +1282,7 @@ "@smithy/url-parser" "^4.0.2" tslib "^2.6.2" -"@smithy/eventstream-codec@^2.1.1": +"@smithy/eventstream-codec@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-2.2.0.tgz#63d74fa817188995eb55e792a38060b0ede98dc4" integrity sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw== @@ -1657,24 +1292,34 @@ "@smithy/util-hex-encoding" "^2.2.0" tslib "^2.6.2" -"@smithy/eventstream-serde-browser@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.1.1.tgz#743a374639e9e2dd858b6fda1fd814eb6c604946" - integrity sha512-JvEdCmGlZUay5VtlT8/kdR6FlvqTDUiJecMjXsBb0+k1H/qc9ME5n2XKPo8q/MZwEIA1GmGgYMokKGjVvMiDow== +"@smithy/eventstream-codec@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-4.0.2.tgz#d4d77699308a3dfeea1b2e87683845f5d8440bdb" + integrity sha512-p+f2kLSK7ZrXVfskU/f5dzksKTewZk8pJLPvER3aFHPt76C2MxD9vNatSfLzzQSQB4FNO96RK4PSXfhD1TTeMQ== dependencies: - "@smithy/eventstream-serde-universal" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@aws-crypto/crc32" "5.2.0" + "@smithy/types" "^4.2.0" + "@smithy/util-hex-encoding" "^4.0.0" + tslib "^2.6.2" -"@smithy/eventstream-serde-config-resolver@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.1.1.tgz#0b84d6f8be0836af7b92455c69f7427e4f01e7a2" - integrity sha512-EqNqXYp3+dk//NmW3NAgQr9bEQ7fsu/CcxQmTiq07JlaIcne/CBWpMZETyXm9w5LXkhduBsdXdlMscfDUDn2fA== +"@smithy/eventstream-serde-browser@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.2.tgz#876f05491373ab217801c47b802601b8c09388d4" + integrity sha512-CepZCDs2xgVUtH7ZZ7oDdZFH8e6Y2zOv8iiX6RhndH69nlojCALSKK+OXwZUgOtUZEUaZ5e1hULVCHYbCn7pug== dependencies: - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/eventstream-serde-universal" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + +"@smithy/eventstream-serde-config-resolver@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.0.tgz#4ab7a2575e9041a2df2179bce64619a4e632e4d3" + integrity sha512-1PI+WPZ5TWXrfj3CIoKyUycYynYJgZjuQo8U+sphneOtjsgrttYybdqESFReQrdWJ+LKt6NEdbYzmmfDBmjX2A== + dependencies: + "@smithy/types" "^4.2.0" + tslib "^2.6.2" -"@smithy/eventstream-serde-node@^2.0.10", "@smithy/eventstream-serde-node@^2.1.1": +"@smithy/eventstream-serde-node@^2.0.10": version "2.1.1" resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.1.1.tgz#2e1afa27f9c7eb524c1c53621049c5e4e3cea6a5" integrity sha512-LF882q/aFidFNDX7uROAGxq3H0B7rjyPkV6QDn6/KDQ+CG7AFkRccjxRf1xqajq/Pe4bMGGr+VKAaoF6lELIQw== @@ -1683,14 +1328,32 @@ "@smithy/types" "^2.9.1" tslib "^2.5.0" +"@smithy/eventstream-serde-node@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.2.tgz#390306ff79edb0c607705f639d8c5a76caad4bf7" + integrity sha512-C5bJ/C6x9ENPMx2cFOirspnF9ZsBVnBMtP6BdPl/qYSuUawdGQ34Lq0dMcf42QTjUZgWGbUIZnz6+zLxJlb9aw== + dependencies: + "@smithy/eventstream-serde-universal" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" + "@smithy/eventstream-serde-universal@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.1.1.tgz#0f5eec9ad033017973a67bafb5549782499488d2" - integrity sha512-LR0mMT+XIYTxk4k2fIxEA1BPtW3685QlqufUEUAX1AJcfFfxNDKEvuCRZbO8ntJb10DrIFVJR9vb0MhDCi0sAQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.2.0.tgz#a75e330040d5e2ca2ac0d8bccde3e390ac5afd38" + integrity sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA== dependencies: - "@smithy/eventstream-codec" "^2.1.1" - "@smithy/types" "^2.9.1" - tslib "^2.5.0" + "@smithy/eventstream-codec" "^2.2.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + +"@smithy/eventstream-serde-universal@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.2.tgz#9f45472fc4fe5fe5f7c22c33d90ec6fc0230d0ae" + integrity sha512-St8h9JqzvnbB52FtckiHPN4U/cnXcarMniXRXTKn0r4b4XesZOGiAyUdj1aXbqqn1icSqBlzzUsCl6nPB018ng== + dependencies: + "@smithy/eventstream-codec" "^4.0.2" + "@smithy/types" "^4.2.0" + tslib "^2.6.2" "@smithy/fetch-http-handler@^2.2.1": version "2.4.1" @@ -1703,7 +1366,7 @@ "@smithy/util-base64" "^2.1.1" tslib "^2.5.0" -"@smithy/fetch-http-handler@^2.4.1", "@smithy/fetch-http-handler@^2.5.0": +"@smithy/fetch-http-handler@^2.5.0": version "2.5.0" resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-2.5.0.tgz#0b8e1562807fdf91fe7dd5cde620d7a03ddc10ac" integrity sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw== @@ -1725,16 +1388,6 @@ "@smithy/util-base64" "^4.0.0" tslib "^2.6.2" -"@smithy/hash-node@^2.1.1": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-2.2.0.tgz#df29e1e64811be905cb3577703b0e2d0b07fc5cc" - integrity sha512-zLWaC/5aWpMrHKpoDF6nqpNtBhlAYKF/7+9yMN7GpdR8CzohnWfGtMznPybnwSS8saaXBMxIGwJqR4HmRp6b3g== - dependencies: - "@smithy/types" "^2.12.0" - "@smithy/util-buffer-from" "^2.2.0" - "@smithy/util-utf8" "^2.3.0" - tslib "^2.6.2" - "@smithy/hash-node@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-4.0.2.tgz#a34fe5a33b067d754ca63302b9791778f003e437" @@ -1745,14 +1398,6 @@ "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@smithy/invalid-dependency@^2.1.1": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-2.2.0.tgz#ee3d8980022cb5edb514ac187d159b3e773640f0" - integrity sha512-nEDASdbKFKPXN2O6lOlTgrEEOO9NHIeO+HVvZnkqc8h5U9g3BIhWsvzFo+UcUbliMHvKNPD/zVxDrkP1Sbgp8Q== - dependencies: - "@smithy/types" "^2.12.0" - tslib "^2.6.2" - "@smithy/invalid-dependency@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-4.0.2.tgz#e9b1c5e407d795f10a03afba90e37bccdc3e38f7" @@ -1782,15 +1427,6 @@ dependencies: tslib "^2.6.2" -"@smithy/middleware-content-length@^2.1.1": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-2.2.0.tgz#a82e97bd83d8deab69e07fea4512563bedb9461a" - integrity sha512-5bl2LG1Ah/7E5cMSC+q+h3IpVHMeOkG0yLRyQT1p2aMJkSrZG7RlXHPuAgb7EyaFeidKEnnd/fNaLLaKlHGzDQ== - dependencies: - "@smithy/protocol-http" "^3.3.0" - "@smithy/types" "^2.12.0" - tslib "^2.6.2" - "@smithy/middleware-content-length@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-4.0.2.tgz#ff78658e8047ad7038f58478cf8713ee2f6ef647" @@ -1800,7 +1436,7 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/middleware-endpoint@^2.4.1", "@smithy/middleware-endpoint@^2.5.1": +"@smithy/middleware-endpoint@^2.4.1": version "2.5.1" resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.5.1.tgz#1333c58304aff4d843e8ef4b85c8cb88975dd5ad" integrity sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ== @@ -1827,21 +1463,6 @@ "@smithy/util-middleware" "^4.0.2" tslib "^2.6.2" -"@smithy/middleware-retry@^2.1.1", "@smithy/middleware-retry@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.3.1.tgz#d6fdce94f2f826642c01b4448e97a509c4556ede" - integrity sha512-P2bGufFpFdYcWvqpyqqmalRtwFUNUA8vHjJR5iGqbfR6mp65qKOLcUd6lTr4S9Gn/enynSrSf3p3FVgVAf6bXA== - dependencies: - "@smithy/node-config-provider" "^2.3.0" - "@smithy/protocol-http" "^3.3.0" - "@smithy/service-error-classification" "^2.1.5" - "@smithy/smithy-client" "^2.5.1" - "@smithy/types" "^2.12.0" - "@smithy/util-middleware" "^2.2.0" - "@smithy/util-retry" "^2.2.0" - tslib "^2.6.2" - uuid "^9.0.1" - "@smithy/middleware-retry@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.1.0.tgz#338ac1e025bbc6fd7b008152c4efa8bc0591acc9" @@ -1857,7 +1478,7 @@ tslib "^2.6.2" uuid "^9.0.1" -"@smithy/middleware-serde@^2.1.1", "@smithy/middleware-serde@^2.3.0": +"@smithy/middleware-serde@^2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-2.3.0.tgz#a7615ba646a88b6f695f2d55de13d8158181dd13" integrity sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q== @@ -1873,7 +1494,7 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/middleware-stack@^2.1.1", "@smithy/middleware-stack@^2.2.0": +"@smithy/middleware-stack@^2.1.1": version "2.2.0" resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-2.2.0.tgz#3fb49eae6313f16f6f30fdaf28e11a7321f34d9f" integrity sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA== @@ -1889,7 +1510,7 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/node-config-provider@^2.2.1", "@smithy/node-config-provider@^2.3.0": +"@smithy/node-config-provider@^2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-2.3.0.tgz#9fac0c94a14c5b5b8b8fa37f20c310a844ab9922" integrity sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg== @@ -1909,7 +1530,7 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/node-http-handler@^2.3.1", "@smithy/node-http-handler@^2.5.0": +"@smithy/node-http-handler@^2.5.0": version "2.5.0" resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-2.5.0.tgz#7b5e0565dd23d340380489bd5fe4316d2bed32de" integrity sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA== @@ -1931,7 +1552,7 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/property-provider@^2.1.1", "@smithy/property-provider@^2.2.0": +"@smithy/property-provider@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-2.2.0.tgz#37e3525a3fa3e11749f86a4f89f0fd7765a6edb0" integrity sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg== @@ -1997,13 +1618,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/service-error-classification@^2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-2.1.5.tgz#0568a977cc0db36299d8703a5d8609c1f600c005" - integrity sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ== - dependencies: - "@smithy/types" "^2.12.0" - "@smithy/service-error-classification@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-4.0.2.tgz#96740ed8be7ac5ad7d6f296d4ddf3f66444b8dcc" @@ -2011,7 +1625,7 @@ dependencies: "@smithy/types" "^4.2.0" -"@smithy/shared-ini-file-loader@^2.3.1", "@smithy/shared-ini-file-loader@^2.4.0": +"@smithy/shared-ini-file-loader@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.4.0.tgz#1636d6eb9bff41e36ac9c60364a37fd2ffcb9947" integrity sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA== @@ -2027,19 +1641,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/signature-v4@^2.1.1": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.3.0.tgz#c30dd4028ae50c607db99459981cce8cdab7a3fd" - integrity sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q== - dependencies: - "@smithy/is-array-buffer" "^2.2.0" - "@smithy/types" "^2.12.0" - "@smithy/util-hex-encoding" "^2.2.0" - "@smithy/util-middleware" "^2.2.0" - "@smithy/util-uri-escape" "^2.2.0" - "@smithy/util-utf8" "^2.3.0" - tslib "^2.6.2" - "@smithy/signature-v4@^3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-3.1.1.tgz#4882aacb3260a47b8279b2ffc6a135e03e225260" @@ -2079,18 +1680,6 @@ "@smithy/util-stream" "^2.1.1" tslib "^2.5.0" -"@smithy/smithy-client@^2.3.1", "@smithy/smithy-client@^2.5.1": - version "2.5.1" - resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.5.1.tgz#0fd2efff09dc65500d260e590f7541f8a387eae3" - integrity sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ== - dependencies: - "@smithy/middleware-endpoint" "^2.5.1" - "@smithy/middleware-stack" "^2.2.0" - "@smithy/protocol-http" "^3.3.0" - "@smithy/types" "^2.12.0" - "@smithy/util-stream" "^2.2.0" - tslib "^2.6.2" - "@smithy/smithy-client@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.2.0.tgz#0c64cae4fb5bb4f26386e9b2c33fc9a3c24c9df3" @@ -2125,7 +1714,7 @@ dependencies: tslib "^2.6.2" -"@smithy/url-parser@^2.1.1", "@smithy/url-parser@^2.2.0": +"@smithy/url-parser@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-2.2.0.tgz#6fcda6116391a4f61fef5580eb540e128359b3c0" integrity sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ== @@ -2169,13 +1758,6 @@ "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@smithy/util-body-length-browser@^2.1.1": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-2.2.0.tgz#25620645c6b62b42594ef4a93b66e6ab70e27d2c" - integrity sha512-dtpw9uQP7W+n3vOtx0CfBD5EWd7EPdIdsQnWTDoFf77e3VUf05uA7R7TGipIo8e4WL2kuPdnsr3hMQn9ziYj5w== - dependencies: - tslib "^2.6.2" - "@smithy/util-body-length-browser@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz#965d19109a4b1e5fe7a43f813522cce718036ded" @@ -2183,13 +1765,6 @@ dependencies: tslib "^2.6.2" -"@smithy/util-body-length-node@^2.2.1": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-2.3.0.tgz#d065a9b5e305ff899536777bbfe075cdc980136f" - integrity sha512-ITWT1Wqjubf2CJthb0BuT9+bpzBfXeMokH/AAa5EJQgbv9aPMVfnM76iFIZVFf50hYXGbtiV71BHAthNWd6+dw== - dependencies: - tslib "^2.6.2" - "@smithy/util-body-length-node@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz#3db245f6844a9b1e218e30c93305bfe2ffa473b3" @@ -2221,13 +1796,6 @@ "@smithy/is-array-buffer" "^4.0.0" tslib "^2.6.2" -"@smithy/util-config-provider@^2.2.1", "@smithy/util-config-provider@^2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-2.3.0.tgz#bc79f99562d12a1f8423100ca662a6fb07cde943" - integrity sha512-HZkzrRcuFN1k70RLqlNK4FnPXKOpkik1+4JaBoHNJn+RnJGYqaa3c5/+XtLOXhlKzlRgNvyaLieHTW2VwGN0VQ== - dependencies: - tslib "^2.6.2" - "@smithy/util-config-provider@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz#e0c7c8124c7fba0b696f78f0bd0ccb060997d45e" @@ -2235,17 +1803,6 @@ dependencies: tslib "^2.6.2" -"@smithy/util-defaults-mode-browser@^2.1.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.2.1.tgz#9db31416daf575d2963c502e0528cfe8055f0c4e" - integrity sha512-RtKW+8j8skk17SYowucwRUjeh4mCtnm5odCL0Lm2NtHQBsYKrNW0od9Rhopu9wF1gHMfHeWF7i90NwBz/U22Kw== - dependencies: - "@smithy/property-provider" "^2.2.0" - "@smithy/smithy-client" "^2.5.1" - "@smithy/types" "^2.12.0" - bowser "^2.11.0" - tslib "^2.6.2" - "@smithy/util-defaults-mode-browser@^4.0.8": version "4.0.8" resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.8.tgz#77bc4590cdc928901b80f3482e79607a2cbcb150" @@ -2257,19 +1814,6 @@ bowser "^2.11.0" tslib "^2.6.2" -"@smithy/util-defaults-mode-node@^2.1.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.3.1.tgz#4613210a3d107aadb3f85bd80cb71c796dd8bf0a" - integrity sha512-vkMXHQ0BcLFysBMWgSBLSk3+leMpFSyyFj8zQtv5ZyUBx8/owVh1/pPEkzmW/DR/Gy/5c8vjLDD9gZjXNKbrpA== - dependencies: - "@smithy/config-resolver" "^2.2.0" - "@smithy/credential-provider-imds" "^2.3.0" - "@smithy/node-config-provider" "^2.3.0" - "@smithy/property-provider" "^2.2.0" - "@smithy/smithy-client" "^2.5.1" - "@smithy/types" "^2.12.0" - tslib "^2.6.2" - "@smithy/util-defaults-mode-node@^4.0.8": version "4.0.8" resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.8.tgz#123b517efe6434977139b341d1f64b5f1e743aac" @@ -2283,15 +1827,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/util-endpoints@^1.1.1": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-1.2.0.tgz#b8b805f47e8044c158372f69b88337703117665d" - integrity sha512-BuDHv8zRjsE5zXd3PxFXFknzBG3owCpjq8G3FcsXW3CykYXuEqM3nTSsmLzw5q+T12ZYuDlVUZKBdpNbhVtlrQ== - dependencies: - "@smithy/node-config-provider" "^2.3.0" - "@smithy/types" "^2.12.0" - tslib "^2.6.2" - "@smithy/util-endpoints@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-3.0.2.tgz#6933a0d6d4a349523ef71ca9540c9c0b222b559e" @@ -2322,7 +1857,7 @@ dependencies: tslib "^2.6.2" -"@smithy/util-middleware@^2.1.1", "@smithy/util-middleware@^2.2.0": +"@smithy/util-middleware@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-2.2.0.tgz#80cfad40f6cca9ffe42a5899b5cb6abd53a50006" integrity sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw== @@ -2346,15 +1881,6 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/util-retry@^2.1.1", "@smithy/util-retry@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-2.2.0.tgz#e8e019537ab47ba6b2e87e723ec51ee223422d85" - integrity sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g== - dependencies: - "@smithy/service-error-classification" "^2.1.5" - "@smithy/types" "^2.12.0" - tslib "^2.6.2" - "@smithy/util-retry@^4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-4.0.2.tgz#9b64cf460d63555884e641721d19e3c0abff8ee6" @@ -2364,7 +1890,7 @@ "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@smithy/util-stream@^2.1.1", "@smithy/util-stream@^2.2.0": +"@smithy/util-stream@^2.1.1": version "2.2.0" resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-2.2.0.tgz#b1279e417992a0f74afa78d7501658f174ed7370" integrity sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA== @@ -2413,7 +1939,7 @@ dependencies: tslib "^2.6.2" -"@smithy/util-utf8@^2.0.0", "@smithy/util-utf8@^2.1.1", "@smithy/util-utf8@^2.3.0": +"@smithy/util-utf8@^2.0.0", "@smithy/util-utf8@^2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@smithy/util-utf8/-/util-utf8-2.3.0.tgz#dd96d7640363259924a214313c3cf16e7dd329c5" integrity sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A== @@ -2571,6 +2097,11 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== +"@types/uuid@^9.0.1": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + "@types/yargs-parser@*": version "21.0.3" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" @@ -3337,13 +2868,6 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== -fast-xml-parser@4.2.5: - version "4.2.5" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz#a6747a09296a6cb34f2ae634019bf1738f3b421f" - integrity sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g== - dependencies: - strnum "^1.0.5" - fast-xml-parser@4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz#86dbf3f18edf8739326447bcaac31b4ae7f6514f" From cb620bbb60e64f27168f74db7a48ad8c2d5f953e Mon Sep 17 00:00:00 2001 From: Em Date: Thu, 20 Mar 2025 15:50:14 -0400 Subject: [PATCH 104/105] fix(bedrock,vertex): update to new SDK version --- .prettierignore | 1 + packages/bedrock-sdk/build | 13 +- packages/bedrock-sdk/package.json | 3 +- packages/bedrock-sdk/src/client.ts | 79 +++--- packages/bedrock-sdk/src/{ => core}/auth.ts | 1 - packages/bedrock-sdk/src/core/error.ts | 1 + packages/bedrock-sdk/src/core/pagination.ts | 1 + .../bedrock-sdk/src/{ => core}/streaming.ts | 15 +- packages/bedrock-sdk/src/index.ts | 6 +- packages/bedrock-sdk/src/internal | 1 + packages/bedrock-sdk/tsconfig.build.json | 2 +- packages/bedrock-sdk/tsconfig.dist-src.json | 4 +- packages/bedrock-sdk/tsconfig.json | 2 +- packages/bedrock-sdk/yarn.lock | 230 ++++++------------ packages/vertex-sdk/build | 13 +- packages/vertex-sdk/package.json | 3 +- packages/vertex-sdk/src/client.ts | 73 +++--- packages/vertex-sdk/src/core/error.ts | 1 + packages/vertex-sdk/src/core/pagination.ts | 1 + packages/vertex-sdk/src/core/streaming.ts | 1 + packages/vertex-sdk/src/index.ts | 3 +- packages/vertex-sdk/src/internal | 1 + packages/vertex-sdk/tsconfig.build.json | 2 +- packages/vertex-sdk/tsconfig.json | 2 +- packages/vertex-sdk/yarn.lock | 203 ++++++---------- src/internal/headers.ts | 8 +- src/internal/parse.ts | 2 +- 27 files changed, 259 insertions(+), 413 deletions(-) mode change 100644 => 100755 packages/bedrock-sdk/build rename packages/bedrock-sdk/src/{ => core}/auth.ts (97%) create mode 100644 packages/bedrock-sdk/src/core/error.ts create mode 100644 packages/bedrock-sdk/src/core/pagination.ts rename packages/bedrock-sdk/src/{ => core}/streaming.ts (91%) create mode 120000 packages/bedrock-sdk/src/internal mode change 100644 => 100755 packages/vertex-sdk/build create mode 100644 packages/vertex-sdk/src/core/error.ts create mode 100644 packages/vertex-sdk/src/core/pagination.ts create mode 100644 packages/vertex-sdk/src/core/streaming.ts create mode 120000 packages/vertex-sdk/src/internal diff --git a/.prettierignore b/.prettierignore index 3548c5af..f108fb45 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,3 +5,4 @@ CHANGELOG.md # don't format tsc output, will break source maps /dist +/packages/*/dist diff --git a/packages/bedrock-sdk/build b/packages/bedrock-sdk/build old mode 100644 new mode 100755 index 4f14ea52..4477865f --- a/packages/bedrock-sdk/build +++ b/packages/bedrock-sdk/build @@ -24,17 +24,16 @@ node scripts/postprocess-dist-package-json.cjs # build to .js/.mjs/.d.ts files npm exec tsc-multi -# we need to add exports = module.exports = Anthropic TypeScript to index.js; -# No way to get that from index.ts because it would cause compile errors +# we need to patch index.js so that `new module.exports()` works for cjs backwards +# compat. No way to get that from index.ts because it would cause compile errors # when building .mjs DIST_PATH=./dist node ../../scripts/utils/fix-index-exports.cjs -# with "moduleResolution": "nodenext", if ESM resolves to index.d.ts, -# it'll have TS errors on the default import. But if it resolves to -# index.d.mts the default import will work (even though both files have -# the same export default statement) -cp dist/index.d.ts dist/index.d.mts cp tsconfig.dist-src.json dist/src/tsconfig.json +cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts +cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts +mkdir -p dist/internal/shims +cp src/internal/shims/*.{mjs,js,d.ts,d.mts} dist/internal/shims DIST_PATH=./dist PKG_IMPORT_PATH=@anthropic-ai/bedrock-sdk/ node ../../scripts/utils/postprocess-files.cjs diff --git a/packages/bedrock-sdk/package.json b/packages/bedrock-sdk/package.json index 8526e3d5..5f1563b5 100644 --- a/packages/bedrock-sdk/package.json +++ b/packages/bedrock-sdk/package.json @@ -35,6 +35,7 @@ "@smithy/util-base64": "^2.0.0" }, "devDependencies": { + "@types/node": "^20.17.6", "@types/jest": "^29.4.0", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", @@ -46,7 +47,7 @@ "ts-jest": "^29.1.0", "ts-morph": "^19.0.0", "ts-node": "^10.5.0", - "tsc-multi": "^1.1.0", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz", "tsconfig-paths": "^4.0.0", "typescript": "^4.8.2" }, diff --git a/packages/bedrock-sdk/src/client.ts b/packages/bedrock-sdk/src/client.ts index 86bd17ef..7d47d816 100644 --- a/packages/bedrock-sdk/src/client.ts +++ b/packages/bedrock-sdk/src/client.ts @@ -1,13 +1,19 @@ -import * as Core from '@anthropic-ai/sdk/core'; +import { BaseAnthropic, ClientOptions as CoreClientOptions } from '@anthropic-ai/sdk/client'; import * as Resources from '@anthropic-ai/sdk/resources/index'; -import * as API from '@anthropic-ai/sdk/index'; -import { getAuthHeaders } from './auth'; -import { Stream } from './streaming'; +import { getAuthHeaders } from './core/auth'; +import { Stream } from './core/streaming'; +import { readEnv } from './internal/utils/env'; +import { FinalRequestOptions } from './internal/request-options'; +import { isObj } from './internal/utils/values'; +import { buildHeaders } from './internal/headers'; +import { FinalizedRequestInit } from './internal/types'; + +export { BaseAnthropic } from '@anthropic-ai/sdk/client'; const DEFAULT_VERSION = 'bedrock-2023-05-31'; const MODEL_ENDPOINTS = new Set(['/v1/complete', '/v1/messages', '/v1/messages?beta=true']); -export type ClientOptions = Omit & { +export type ClientOptions = Omit & { awsSecretKey?: string | null | undefined; awsAccessKey?: string | null | undefined; @@ -19,14 +25,12 @@ export type ClientOptions = Omit & { }; /** API Client for interfacing with the Anthropic Bedrock API. */ -export class AnthropicBedrock extends Core.APIClient { +export class AnthropicBedrock extends BaseAnthropic { awsSecretKey: string | null; awsAccessKey: string | null; awsRegion: string; awsSessionToken: string | null; - private _options: ClientOptions; - /** * API Client for interfacing with the Anthropic Bedrock API. * @@ -36,37 +40,25 @@ export class AnthropicBedrock extends Core.APIClient { * @param {string | null | undefined} [opts.awsSessionToken] * @param {string} [opts.baseURL=process.env['ANTHROPIC_BEDROCK_BASE_URL'] ?? https://bedrock-runtime.${this.awsRegion}.amazonaws.com] - Override the default base URL for the API. * @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out. - * @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections. - * @param {Core.Fetch} [opts.fetch] - Specify a custom `fetch` function implementation. + * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls. + * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation. * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request. - * @param {Core.Headers} opts.defaultHeaders - Default headers to include with every request to the API. - * @param {Core.DefaultQuery} opts.defaultQuery - Default query parameters to include with every request to the API. + * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API. + * @param {Record} opts.defaultQuery - Default query parameters to include with every request to the API. + * @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers. */ constructor({ - baseURL = Core.readEnv('ANTHROPIC_BEDROCK_BASE_URL'), + awsRegion = readEnv('AWS_REGION') ?? 'us-east-1', + baseURL = readEnv('ANTHROPIC_BEDROCK_BASE_URL') ?? `https://bedrock-runtime.${awsRegion}.amazonaws.com`, awsSecretKey = null, awsAccessKey = null, - awsRegion = Core.readEnv('AWS_REGION') ?? 'us-east-1', awsSessionToken = null, ...opts }: ClientOptions = {}) { - const options: ClientOptions = { - awsSecretKey, - awsAccessKey, - awsRegion, - awsSessionToken, - ...opts, - baseURL: baseURL || `https://bedrock-runtime.${awsRegion}.amazonaws.com`, - }; - super({ - baseURL: options.baseURL!, - timeout: options.timeout ?? 600000 /* 10 minutes */, - httpAgent: options.httpAgent, - maxRetries: options.maxRetries, - fetch: options.fetch, + baseURL, + ...opts, }); - this._options = options; this.awsSecretKey = awsSecretKey; this.awsAccessKey = awsAccessKey; @@ -78,20 +70,13 @@ export class AnthropicBedrock extends Core.APIClient { completions: Resources.Completions = new Resources.Completions(this); beta: BetaResource = makeBetaResource(this); - protected override defaultQuery(): Core.DefaultQuery | undefined { - return this._options.defaultQuery; - } - - protected override defaultHeaders(opts: Core.FinalRequestOptions): Core.Headers { - return { - ...super.defaultHeaders(opts), - ...this._options.defaultHeaders, - }; + protected override validateHeaders() { + // auth validation is handled in prepareRequest since it needs to be async } protected override async prepareRequest( - request: RequestInit, - { url, options }: { url: string; options: Core.FinalRequestOptions }, + request: FinalizedRequestInit, + { url, options }: { url: string; options: FinalRequestOptions }, ): Promise { const regionName = this.awsRegion; if (!regionName) { @@ -107,29 +92,29 @@ export class AnthropicBedrock extends Core.APIClient { awsSecretKey: this.awsSecretKey, awsSessionToken: this.awsSessionToken, }); - request.headers = { ...request.headers, ...headers }; + request.headers = buildHeaders([headers, request.headers]).values; } - override buildRequest(options: Core.FinalRequestOptions): { - req: RequestInit; + override buildRequest(options: FinalRequestOptions): { + req: FinalizedRequestInit; url: string; timeout: number; } { options.__streamClass = Stream; - if (Core.isObj(options.body)) { + if (isObj(options.body)) { // create a shallow copy of the request body so that code that mutates it later // doesn't mutate the original user-provided object options.body = { ...options.body }; } - if (Core.isObj(options.body)) { + if (isObj(options.body)) { if (!options.body['anthropic_version']) { options.body['anthropic_version'] = DEFAULT_VERSION; } if (options.headers && !options.body['anthropic_beta']) { - const betas = Core.getHeader(options.headers, 'anthropic-beta'); + const betas = buildHeaders([options.headers]).values.get('anthropic-beta'); if (betas != null) { options.body['anthropic_beta'] = betas.split(','); } @@ -137,7 +122,7 @@ export class AnthropicBedrock extends Core.APIClient { } if (MODEL_ENDPOINTS.has(options.path) && options.method === 'post') { - if (!Core.isObj(options.body)) { + if (!isObj(options.body)) { throw new Error('Expected request body to be an object for post /v1/messages'); } diff --git a/packages/bedrock-sdk/src/auth.ts b/packages/bedrock-sdk/src/core/auth.ts similarity index 97% rename from packages/bedrock-sdk/src/auth.ts rename to packages/bedrock-sdk/src/core/auth.ts index 357f6e50..45242287 100644 --- a/packages/bedrock-sdk/src/auth.ts +++ b/packages/bedrock-sdk/src/core/auth.ts @@ -3,7 +3,6 @@ import { SignatureV4 } from '@smithy/signature-v4'; import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; import { HttpRequest } from '@smithy/protocol-http'; import { Sha256 } from '@aws-crypto/sha256-js'; -import type { RequestInit } from '@anthropic-ai/sdk/_shims/index'; type AuthProps = { url: string; diff --git a/packages/bedrock-sdk/src/core/error.ts b/packages/bedrock-sdk/src/core/error.ts new file mode 100644 index 00000000..9104880f --- /dev/null +++ b/packages/bedrock-sdk/src/core/error.ts @@ -0,0 +1 @@ +export * from '@anthropic-ai/sdk/core/error'; diff --git a/packages/bedrock-sdk/src/core/pagination.ts b/packages/bedrock-sdk/src/core/pagination.ts new file mode 100644 index 00000000..6e3b4728 --- /dev/null +++ b/packages/bedrock-sdk/src/core/pagination.ts @@ -0,0 +1 @@ +export * from '@anthropic-ai/sdk/core/pagination'; diff --git a/packages/bedrock-sdk/src/streaming.ts b/packages/bedrock-sdk/src/core/streaming.ts similarity index 91% rename from packages/bedrock-sdk/src/streaming.ts rename to packages/bedrock-sdk/src/core/streaming.ts index 7f054c39..f797428c 100644 --- a/packages/bedrock-sdk/src/streaming.ts +++ b/packages/bedrock-sdk/src/core/streaming.ts @@ -2,15 +2,12 @@ import { EventStreamMarshaller } from '@smithy/eventstream-serde-node'; import { fromBase64, toBase64 } from '@smithy/util-base64'; import { streamCollector } from '@smithy/fetch-http-handler'; import { EventStreamSerdeContext, SerdeContext } from '@smithy/types'; -import { - Stream as CoreStream, - readableStreamAsyncIterable, - ServerSentEvent, -} from '@anthropic-ai/sdk/streaming'; +import { Stream as CoreStream, ServerSentEvent } from '@anthropic-ai/sdk/streaming'; import { AnthropicError } from '@anthropic-ai/sdk/error'; import { APIError } from '@anthropic-ai/sdk'; -import { createResponseHeaders, safeJSON } from '@anthropic-ai/sdk/core'; -import { de_ResponseStream } from './AWS_restJson1'; +import { de_ResponseStream } from '../AWS_restJson1'; +import { ReadableStreamToAsyncIterable } from '../internal/shims'; +import { safeJSON } from '../internal/utils/values'; type Bytes = string | ArrayBuffer | Uint8Array | Buffer | null | undefined; @@ -42,7 +39,7 @@ export class Stream extends CoreStream { throw new AnthropicError(`Attempted to iterate over a response with no body`); } - const responseBodyIter = readableStreamAsyncIterable(response.body); + const responseBodyIter = ReadableStreamToAsyncIterable(response.body); const eventStream = de_ResponseStream(responseBodyIter, getMinimalSerdeContext()); for await (const event of eventStream) { if (event.chunk && event.chunk.bytes) { @@ -84,7 +81,7 @@ export class Stream extends CoreStream { const errJSON = safeJSON(errText); const errMessage = errJSON ? undefined : errText; - throw APIError.generate(undefined, errJSON, errMessage, createResponseHeaders(response.headers)); + throw APIError.generate(undefined, errJSON, errMessage, response.headers); } } done = true; diff --git a/packages/bedrock-sdk/src/index.ts b/packages/bedrock-sdk/src/index.ts index 585aaf4a..02628aed 100644 --- a/packages/bedrock-sdk/src/index.ts +++ b/packages/bedrock-sdk/src/index.ts @@ -1,4 +1,2 @@ -import { AnthropicBedrock } from './client'; - -export default AnthropicBedrock; -export { AnthropicBedrock }; +export * from './client'; +export { AnthropicBedrock as default } from './client'; diff --git a/packages/bedrock-sdk/src/internal b/packages/bedrock-sdk/src/internal new file mode 120000 index 00000000..9466b9ff --- /dev/null +++ b/packages/bedrock-sdk/src/internal @@ -0,0 +1 @@ +../../../src/internal/ \ No newline at end of file diff --git a/packages/bedrock-sdk/tsconfig.build.json b/packages/bedrock-sdk/tsconfig.build.json index 3ed3bf89..d7cba722 100644 --- a/packages/bedrock-sdk/tsconfig.build.json +++ b/packages/bedrock-sdk/tsconfig.build.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "include": ["dist/src"], - "exclude": [], + "exclude": ["dist/src/internal/detect-platform.ts"], "compilerOptions": { "rootDir": "./dist/src", "paths": { diff --git a/packages/bedrock-sdk/tsconfig.dist-src.json b/packages/bedrock-sdk/tsconfig.dist-src.json index e9f2d70b..c550e299 100644 --- a/packages/bedrock-sdk/tsconfig.dist-src.json +++ b/packages/bedrock-sdk/tsconfig.dist-src.json @@ -4,8 +4,8 @@ // via declaration maps "include": ["index.ts"], "compilerOptions": { - "target": "es2015", - "lib": ["DOM"], + "target": "ES2015", + "lib": ["DOM", "DOM.Iterable", "ES2018"], "moduleResolution": "node" } } diff --git a/packages/bedrock-sdk/tsconfig.json b/packages/bedrock-sdk/tsconfig.json index f7918bc9..d6dbe3c2 100644 --- a/packages/bedrock-sdk/tsconfig.json +++ b/packages/bedrock-sdk/tsconfig.json @@ -1,6 +1,6 @@ { "include": ["src", "tests", "examples"], - "exclude": [], + "exclude": ["dist/src/internal/detect-platform.ts"], "compilerOptions": { "target": "es2020", "lib": ["es2020"], diff --git a/packages/bedrock-sdk/yarn.lock b/packages/bedrock-sdk/yarn.lock index ffc8fbb8..6831cf50 100644 --- a/packages/bedrock-sdk/yarn.lock +++ b/packages/bedrock-sdk/yarn.lock @@ -16,18 +16,7 @@ "@jridgewell/trace-mapping" "^0.3.9" "@anthropic-ai/sdk@file:../../dist": - # x-release-please-start-version - version "0.33.1" - # x-release-please-end-version - dependencies: - "@types/node" "^18.11.18" - "@types/node-fetch" "^2.6.4" - abort-controller "^3.0.0" - agentkeepalive "^4.2.1" - form-data-encoder "1.7.2" - formdata-node "^4.3.2" - node-fetch "^2.6.7" - web-streams-polyfill "^3.2.1" + version "0.40.0-beta.0" "@aws-crypto/crc32@3.0.0": version "3.0.0" @@ -2065,14 +2054,6 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/node-fetch@^2.6.4": - version "2.6.11" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" - integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== - dependencies: - "@types/node" "*" - form-data "^4.0.0" - "@types/node@*": version "20.11.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.5.tgz#be10c622ca7fcaa3cf226cf80166abc31389d86e" @@ -2080,12 +2061,12 @@ dependencies: undici-types "~5.26.4" -"@types/node@^18.11.18": - version "18.19.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.8.tgz#c1e42b165e5a526caf1f010747e0522cb2c9c36a" - integrity sha512-g1pZtPhsvGVTwmeVoexWZLTQaOvXwoSq//pTL0DHeNzUDrFnir4fgETdhjhIxjVnN+hKOuh98+E1eMLnUXstFg== +"@types/node@^20.17.6": + version "20.17.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.24.tgz#2325476954e6fc8c2f11b9c61e26ba6eb7d3f5b6" + integrity sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA== dependencies: - undici-types "~5.26.4" + undici-types "~6.19.2" "@types/semver@^7.5.0": version "7.5.6" @@ -2205,13 +2186,6 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -2227,13 +2201,6 @@ acorn@^8.4.1, acorn@^8.9.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== -agentkeepalive@^4.2.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== - dependencies: - humanize-ms "^1.2.1" - aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -2313,11 +2280,6 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -2410,6 +2372,13 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + browserslist@^4.22.2: version "4.22.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" @@ -2544,13 +2513,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -2595,6 +2557,13 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" +debug@^4.3.7: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + dedent@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" @@ -2610,11 +2579,6 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -2801,11 +2765,6 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -2858,6 +2817,17 @@ fast-glob@^3.2.12, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" + integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.8" + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -2903,6 +2873,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -2933,28 +2910,6 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== -form-data-encoder@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040" - integrity sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A== - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -formdata-node@^4.3.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.4.1.tgz#23f6a5cb9cb55315912cbec4ff7b0f59bbd191e2" - integrity sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ== - dependencies: - node-domexception "1.0.0" - web-streams-polyfill "4.0.0-beta.3" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -3082,13 +3037,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - ignore@^5.2.0, ignore@^5.2.4: version "5.3.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" @@ -3753,17 +3701,13 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== +micromatch@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - mime-db "1.52.0" + braces "^3.0.3" + picomatch "^2.3.1" mimic-fn@^2.1.0: version "2.1.0" @@ -3806,7 +3750,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0: +ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3816,18 +3760,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -node-domexception@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" - integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== - -node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -3975,6 +3907,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -4242,10 +4179,10 @@ strnum@^1.0.5: resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.1.2.tgz#57bca4fbaa6f271081715dbc9ed7cee5493e28e4" integrity sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA== -superstruct@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.3.tgz#de626a5b49c6641ff4d37da3c7598e7a87697046" - integrity sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg== +superstruct@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.4.tgz#0adb99a7578bd2f1c526220da6571b2d485d91ca" + integrity sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ== supports-color@^5.3.0: version "5.5.0" @@ -4312,11 +4249,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - ts-api-utils@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" @@ -4363,21 +4295,20 @@ ts-node@^10.5.0: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tsc-multi@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tsc-multi/-/tsc-multi-1.1.0.tgz#0e2b03c0ed0ac58ecb556f11709441102d202680" - integrity sha512-THE6X+sse7EZ2qMhqXvBhd2HMTvXyWwYnx+2T/ijqdp/6Rf7rUc2uPRzPdrrljZCNcYDeL0qP2P7tqm2IwayTg== +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz": + version "1.1.3" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz#8fc21fc95b247b86721b95fabfb10c6a436134c3" dependencies: - debug "^4.3.4" - fast-glob "^3.2.12" + debug "^4.3.7" + fast-glob "^3.3.2" get-stdin "^8.0.0" p-all "^3.0.0" - picocolors "^1.0.0" + picocolors "^1.1.1" signal-exit "^3.0.7" string-to-stream "^3.0.1" - superstruct "^1.0.3" - tslib "^2.5.0" - yargs "^17.7.1" + superstruct "^1.0.4" + tslib "^2.8.1" + yargs "^17.7.2" tsconfig-paths@^4.0.0: version "4.2.0" @@ -4398,6 +4329,11 @@ tslib@^2.3.1, tslib@^2.5.0, tslib@^2.6.2: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== +tslib@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -4430,6 +4366,11 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" @@ -4476,29 +4417,6 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" -web-streams-polyfill@4.0.0-beta.3: - version "4.0.0-beta.3" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38" - integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug== - -web-streams-polyfill@^3.2.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz#32e26522e05128203a7de59519be3c648004343b" - integrity sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -4548,7 +4466,7 @@ yargs-parser@^21.0.1, yargs-parser@^21.1.1: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^17.3.1, yargs@^17.7.1: +yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== diff --git a/packages/vertex-sdk/build b/packages/vertex-sdk/build old mode 100644 new mode 100755 index 3bb0ece2..c1cef81f --- a/packages/vertex-sdk/build +++ b/packages/vertex-sdk/build @@ -24,17 +24,16 @@ node scripts/postprocess-dist-package-json.cjs # build to .js/.mjs/.d.ts files npm exec tsc-multi -# we need to add exports = module.exports = Anthropic TypeScript to index.js; -# No way to get that from index.ts because it would cause compile errors +# we need to patch index.js so that `new module.exports()` works for cjs backwards +# compat. No way to get that from index.ts because it would cause compile errors # when building .mjs DIST_PATH=./dist node ../../scripts/utils/fix-index-exports.cjs -# with "moduleResolution": "nodenext", if ESM resolves to index.d.ts, -# it'll have TS errors on the default import. But if it resolves to -# index.d.mts the default import will work (even though both files have -# the same export default statement) -cp dist/index.d.ts dist/index.d.mts cp tsconfig.dist-src.json dist/src/tsconfig.json +cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts +cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts +mkdir -p dist/internal/shims +cp src/internal/shims/*.{mjs,js,d.ts,d.mts} dist/internal/shims DIST_PATH=./dist PKG_IMPORT_PATH=@anthropic-ai/vertex-sdk/ node ../../scripts/utils/postprocess-files.cjs diff --git a/packages/vertex-sdk/package.json b/packages/vertex-sdk/package.json index 43fc356d..b2593c4d 100644 --- a/packages/vertex-sdk/package.json +++ b/packages/vertex-sdk/package.json @@ -26,6 +26,7 @@ "google-auth-library": "^9.4.2" }, "devDependencies": { + "@types/node": "^20.17.6", "@types/jest": "^29.4.0", "@typescript-eslint/eslint-plugin": "^6.7.0", "@typescript-eslint/parser": "^6.7.0", @@ -37,7 +38,7 @@ "ts-jest": "^29.1.0", "ts-morph": "^19.0.0", "ts-node": "^10.5.0", - "tsc-multi": "^1.1.0", + "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz", "tsconfig-paths": "^4.0.0", "typescript": "^4.8.2" }, diff --git a/packages/vertex-sdk/src/client.ts b/packages/vertex-sdk/src/client.ts index f1046455..4f3566eb 100644 --- a/packages/vertex-sdk/src/client.ts +++ b/packages/vertex-sdk/src/client.ts @@ -1,13 +1,18 @@ -import * as Core from '@anthropic-ai/sdk/core'; +import { BaseAnthropic, ClientOptions as CoreClientOptions } from '@anthropic-ai/sdk/client'; import * as Resources from '@anthropic-ai/sdk/resources/index'; -import * as API from '@anthropic-ai/sdk/index'; -import { type RequestInit } from '@anthropic-ai/sdk/_shims/index'; import { GoogleAuth } from 'google-auth-library'; +import { readEnv } from './internal/utils/env'; +import { FinalRequestOptions } from './internal/request-options'; +import { FinalizedRequestInit } from './internal/types'; +import { isObj } from './internal/utils/values'; +import { buildHeaders } from './internal/headers'; + +export { BaseAnthropic } from '@anthropic-ai/sdk/client'; const DEFAULT_VERSION = 'vertex-2023-10-16'; const MODEL_ENDPOINTS = new Set(['/v1/messages', '/v1/messages?beta=true']); -export type ClientOptions = Omit & { +export type ClientOptions = Omit & { region?: string | null | undefined; projectId?: string | null | undefined; accessToken?: string | null | undefined; @@ -24,12 +29,11 @@ export type ClientOptions = Omit & { googleAuth?: GoogleAuth | null | undefined; }; -export class AnthropicVertex extends Core.APIClient { +export class AnthropicVertex extends BaseAnthropic { region: string; projectId: string | null; accessToken: string | null; - private _options: ClientOptions; private _auth: GoogleAuth; private _authClientPromise: ReturnType; @@ -42,16 +46,17 @@ export class AnthropicVertex extends Core.APIClient { * @param {string | null} [opts.region=process.env['CLOUD_ML_REGION']] * @param {string} [opts.baseURL=process.env['ANTHROPIC_VERTEX__BASE_URL'] ?? https://${region}-aiplatform.googleapis.com/v1] - Override the default base URL for the API. * @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out. - * @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections. - * @param {Core.Fetch} [opts.fetch] - Specify a custom `fetch` function implementation. + * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls. + * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation. * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request. - * @param {Core.Headers} opts.defaultHeaders - Default headers to include with every request to the API. - * @param {Core.DefaultQuery} opts.defaultQuery - Default query parameters to include with every request to the API. + * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API. + * @param {Record} opts.defaultQuery - Default query parameters to include with every request to the API. + * @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers. */ constructor({ - baseURL = Core.readEnv('ANTHROPIC_VERTEX_BASE_URL'), - region = Core.readEnv('CLOUD_ML_REGION') ?? null, - projectId = Core.readEnv('ANTHROPIC_VERTEX_PROJECT_ID') ?? null, + baseURL = readEnv('ANTHROPIC_VERTEX_BASE_URL'), + region = readEnv('CLOUD_ML_REGION') ?? null, + projectId = readEnv('ANTHROPIC_VERTEX_PROJECT_ID') ?? null, ...opts }: ClientOptions = {}) { if (!region) { @@ -60,44 +65,28 @@ export class AnthropicVertex extends Core.APIClient { ); } - const options: ClientOptions = { - ...opts, - baseURL: baseURL || `https://${region}-aiplatform.googleapis.com/v1`, - }; - super({ - baseURL: options.baseURL!, - timeout: options.timeout ?? 600000 /* 10 minutes */, - httpAgent: options.httpAgent, - maxRetries: options.maxRetries, - fetch: options.fetch, + baseURL: baseURL || `https://${region}-aiplatform.googleapis.com/v1`, + ...opts, }); - this._options = options; this.region = region; this.projectId = projectId; - this.accessToken = options.accessToken ?? null; + this.accessToken = opts.accessToken ?? null; this._auth = - options.googleAuth ?? new GoogleAuth({ scopes: 'https://www.googleapis.com/auth/cloud-platform' }); + opts.googleAuth ?? new GoogleAuth({ scopes: 'https://www.googleapis.com/auth/cloud-platform' }); this._authClientPromise = this._auth.getClient(); } messages: MessagesResource = makeMessagesResource(this); beta: BetaResource = makeBetaResource(this); - protected override defaultQuery(): Core.DefaultQuery | undefined { - return this._options.defaultQuery; - } - - protected override defaultHeaders(opts: Core.FinalRequestOptions): Core.Headers { - return { - ...super.defaultHeaders(opts), - ...this._options.defaultHeaders, - }; + protected override validateHeaders() { + // auth validation is handled in prepareOptions since it needs to be async } - protected override async prepareOptions(options: Core.FinalRequestOptions): Promise { + protected override async prepareOptions(options: FinalRequestOptions): Promise { const authClient = await this._authClientPromise; const authHeaders = await authClient.getRequestHeaders(); @@ -106,21 +95,21 @@ export class AnthropicVertex extends Core.APIClient { this.projectId = projectId; } - options.headers = { ...authHeaders, ...options.headers }; + options.headers = buildHeaders([authHeaders, options.headers]); } - override buildRequest(options: Core.FinalRequestOptions): { - req: RequestInit; + override buildRequest(options: FinalRequestOptions): { + req: FinalizedRequestInit; url: string; timeout: number; } { - if (Core.isObj(options.body)) { + if (isObj(options.body)) { // create a shallow copy of the request body so that code that mutates it later // doesn't mutate the original user-provided object options.body = { ...options.body }; } - if (Core.isObj(options.body)) { + if (isObj(options.body)) { if (!options.body['anthropic_version']) { options.body['anthropic_version'] = DEFAULT_VERSION; } @@ -133,7 +122,7 @@ export class AnthropicVertex extends Core.APIClient { ); } - if (!Core.isObj(options.body)) { + if (!isObj(options.body)) { throw new Error('Expected request body to be an object for post /v1/messages'); } diff --git a/packages/vertex-sdk/src/core/error.ts b/packages/vertex-sdk/src/core/error.ts new file mode 100644 index 00000000..9104880f --- /dev/null +++ b/packages/vertex-sdk/src/core/error.ts @@ -0,0 +1 @@ +export * from '@anthropic-ai/sdk/core/error'; diff --git a/packages/vertex-sdk/src/core/pagination.ts b/packages/vertex-sdk/src/core/pagination.ts new file mode 100644 index 00000000..6e3b4728 --- /dev/null +++ b/packages/vertex-sdk/src/core/pagination.ts @@ -0,0 +1 @@ +export * from '@anthropic-ai/sdk/core/pagination'; diff --git a/packages/vertex-sdk/src/core/streaming.ts b/packages/vertex-sdk/src/core/streaming.ts new file mode 100644 index 00000000..a1ef0845 --- /dev/null +++ b/packages/vertex-sdk/src/core/streaming.ts @@ -0,0 +1 @@ +export * from '@anthropic-ai/sdk/core/streaming'; diff --git a/packages/vertex-sdk/src/index.ts b/packages/vertex-sdk/src/index.ts index 2853ecec..4727335b 100644 --- a/packages/vertex-sdk/src/index.ts +++ b/packages/vertex-sdk/src/index.ts @@ -1 +1,2 @@ -export { AnthropicVertex } from './client'; +export * from './client'; +export { AnthropicVertex as default } from './client'; diff --git a/packages/vertex-sdk/src/internal b/packages/vertex-sdk/src/internal new file mode 120000 index 00000000..9466b9ff --- /dev/null +++ b/packages/vertex-sdk/src/internal @@ -0,0 +1 @@ +../../../src/internal/ \ No newline at end of file diff --git a/packages/vertex-sdk/tsconfig.build.json b/packages/vertex-sdk/tsconfig.build.json index 6a34fb8f..16fb081f 100644 --- a/packages/vertex-sdk/tsconfig.build.json +++ b/packages/vertex-sdk/tsconfig.build.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "include": ["dist/src"], - "exclude": [], + "exclude": ["dist/src/internal/detect-platform.ts"], "compilerOptions": { "rootDir": "./dist/src", "paths": { diff --git a/packages/vertex-sdk/tsconfig.json b/packages/vertex-sdk/tsconfig.json index 102b727e..c3fb982d 100644 --- a/packages/vertex-sdk/tsconfig.json +++ b/packages/vertex-sdk/tsconfig.json @@ -1,6 +1,6 @@ { "include": ["src", "tests", "examples"], - "exclude": [], + "exclude": ["dist/src/internal/detect-platform.ts"], "compilerOptions": { "target": "es2020", "lib": ["es2020"], diff --git a/packages/vertex-sdk/yarn.lock b/packages/vertex-sdk/yarn.lock index efc703d6..870bb78c 100644 --- a/packages/vertex-sdk/yarn.lock +++ b/packages/vertex-sdk/yarn.lock @@ -16,17 +16,7 @@ "@jridgewell/trace-mapping" "^0.3.9" "@anthropic-ai/sdk@file:../../dist": - # x-release-please-start-version - version "0.33.1" - # x-release-please-end-version - dependencies: - "@types/node" "^18.11.18" - "@types/node-fetch" "^2.6.4" - abort-controller "^3.0.0" - agentkeepalive "^4.2.1" - form-data-encoder "1.7.2" - formdata-node "^4.3.2" - node-fetch "^2.6.7" + version "0.40.0-beta.0" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": version "7.23.5" @@ -768,14 +758,6 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/node-fetch@^2.6.4": - version "2.6.11" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" - integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== - dependencies: - "@types/node" "*" - form-data "^4.0.0" - "@types/node@*": version "20.11.5" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.5.tgz#be10c622ca7fcaa3cf226cf80166abc31389d86e" @@ -783,12 +765,12 @@ dependencies: undici-types "~5.26.4" -"@types/node@^18.11.18": - version "18.19.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.8.tgz#c1e42b165e5a526caf1f010747e0522cb2c9c36a" - integrity sha512-g1pZtPhsvGVTwmeVoexWZLTQaOvXwoSq//pTL0DHeNzUDrFnir4fgETdhjhIxjVnN+hKOuh98+E1eMLnUXstFg== +"@types/node@^20.17.6": + version "20.17.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.24.tgz#2325476954e6fc8c2f11b9c61e26ba6eb7d3f5b6" + integrity sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA== dependencies: - undici-types "~5.26.4" + undici-types "~6.19.2" "@types/semver@^7.5.0": version "7.5.6" @@ -903,13 +885,6 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -932,13 +907,6 @@ agent-base@^7.0.2: dependencies: debug "^4.3.4" -agentkeepalive@^4.2.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== - dependencies: - humanize-ms "^1.2.1" - aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -1018,11 +986,6 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -1120,6 +1083,13 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + browserslist@^4.22.2: version "4.22.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" @@ -1259,13 +1229,6 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -1310,6 +1273,13 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" +debug@^4.3.7: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + dedent@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" @@ -1325,11 +1295,6 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -1523,11 +1488,6 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -1585,6 +1545,17 @@ fast-glob@^3.2.12, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" + integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.8" + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -1623,6 +1594,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -1653,28 +1631,6 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== -form-data-encoder@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040" - integrity sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A== - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -formdata-node@^4.3.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.4.1.tgz#23f6a5cb9cb55315912cbec4ff7b0f59bbd191e2" - integrity sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ== - dependencies: - node-domexception "1.0.0" - web-streams-polyfill "4.0.0-beta.3" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1848,13 +1804,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - ignore@^5.2.0, ignore@^5.2.4: version "5.3.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" @@ -2543,17 +2492,13 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== +micromatch@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - mime-db "1.52.0" + braces "^3.0.3" + picomatch "^2.3.1" mimic-fn@^2.1.0: version "2.1.0" @@ -2596,7 +2541,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0: +ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -2606,12 +2551,7 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -node-domexception@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" - integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== - -node-fetch@^2.6.7, node-fetch@^2.6.9: +node-fetch@^2.6.9: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -2765,6 +2705,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -3027,10 +2972,10 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -superstruct@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.3.tgz#de626a5b49c6641ff4d37da3c7598e7a87697046" - integrity sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg== +superstruct@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.4.tgz#0adb99a7578bd2f1c526220da6571b2d485d91ca" + integrity sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ== supports-color@^5.3.0: version "5.5.0" @@ -3148,21 +3093,20 @@ ts-node@^10.5.0: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tsc-multi@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tsc-multi/-/tsc-multi-1.1.0.tgz#0e2b03c0ed0ac58ecb556f11709441102d202680" - integrity sha512-THE6X+sse7EZ2qMhqXvBhd2HMTvXyWwYnx+2T/ijqdp/6Rf7rUc2uPRzPdrrljZCNcYDeL0qP2P7tqm2IwayTg== +"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz": + version "1.1.3" + resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz#8fc21fc95b247b86721b95fabfb10c6a436134c3" dependencies: - debug "^4.3.4" - fast-glob "^3.2.12" + debug "^4.3.7" + fast-glob "^3.3.2" get-stdin "^8.0.0" p-all "^3.0.0" - picocolors "^1.0.0" + picocolors "^1.1.1" signal-exit "^3.0.7" string-to-stream "^3.0.1" - superstruct "^1.0.3" - tslib "^2.5.0" - yargs "^17.7.1" + superstruct "^1.0.4" + tslib "^2.8.1" + yargs "^17.7.2" tsconfig-paths@^4.0.0: version "4.2.0" @@ -3173,11 +3117,16 @@ tsconfig-paths@^4.0.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.5.0, tslib@^2.6.2: +tslib@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -3210,6 +3159,11 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" @@ -3251,11 +3205,6 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" -web-streams-polyfill@4.0.0-beta.3: - version "4.0.0-beta.3" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38" - integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug== - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -3318,7 +3267,7 @@ yargs-parser@^21.0.1, yargs-parser@^21.1.1: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^17.3.1, yargs@^17.7.1: +yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== diff --git a/src/internal/headers.ts b/src/internal/headers.ts index 8659ddea..13e417d3 100644 --- a/src/internal/headers.ts +++ b/src/internal/headers.ts @@ -9,7 +9,9 @@ export type HeadersLike = | null | NullableHeaders; -const brand_privateNullableHeaders = Symbol('brand.privateNullableHeaders'); +const brand_privateNullableHeaders = Symbol.for('brand.privateNullableHeaders') as symbol & { + description: 'brand.privateNullableHeaders'; +}; /** * @internal @@ -18,7 +20,7 @@ const brand_privateNullableHeaders = Symbol('brand.privateNullableHeaders'); */ export type NullableHeaders = { /** Brand check, prevent users from creating a NullableHeaders. */ - [brand_privateNullableHeaders]: true; + [_: typeof brand_privateNullableHeaders]: true; /** Parsed headers. */ values: Headers; /** Set of lowercase header names explicitly set to null. */ @@ -31,7 +33,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator Date: Wed, 7 May 2025 21:27:14 +0100 Subject: [PATCH 105/105] fix(messages): updates for server tools --- examples/tools.ts | 2 +- examples/web-search-stream.ts | 64 +++++++++++++++++++++++ examples/web-search.ts | 52 ++++++++++++++++++ src/lib/BetaMessageStream.ts | 9 ++++ src/lib/MessageStream.ts | 9 ++++ tests/api-resources/MessageStream.test.ts | 56 ++++++++++++++------ 6 files changed, 176 insertions(+), 16 deletions(-) create mode 100755 examples/web-search-stream.ts create mode 100755 examples/web-search.ts diff --git a/examples/tools.ts b/examples/tools.ts index 1a696bc0..8928efb0 100644 --- a/examples/tools.ts +++ b/examples/tools.ts @@ -49,7 +49,7 @@ async function main() { { type: 'tool_result', tool_use_id: tool.id, - content: [{ type: 'text', text: 'The weather is 73f' }], + content: 'The weather is 73f', }, ], }, diff --git a/examples/web-search-stream.ts b/examples/web-search-stream.ts new file mode 100755 index 00000000..38d08d46 --- /dev/null +++ b/examples/web-search-stream.ts @@ -0,0 +1,64 @@ +#!/usr/bin/env -S npm run tsn -T + +import Anthropic from '@anthropic-ai/sdk'; + +const client = new Anthropic(); + +async function main() { + console.log('Claude with Web Search (Streaming)'); + console.log('=================================='); + + // Create a stream with web search enabled + const stream = client.messages + .stream({ + model: 'claude-3-5-sonnet-latest', + max_tokens: 1024, + messages: [ + { + role: 'user', + content: "What's the weather in New York?", + }, + ], + tools: [ + { + name: 'web_search', + type: 'web_search_20250305', + }, + ], + }) + .on('text', (text) => { + // Print text as it arrives + process.stdout.write(text); + }) + .on('streamEvent', (event) => { + // Track when web search is being used + if (event.type === 'content_block_start' && event.content_block.type === 'web_search_tool_result') { + process.stdout.write('\n[Web search started...]'); + } + }); + + // Wait for the stream to complete + const message = await stream.finalMessage(); + + console.log('\n\nFinal usage statistics:'); + console.log(`Input tokens: ${message.usage.input_tokens}`); + console.log(`Output tokens: ${message.usage.output_tokens}`); + + if (message.usage.server_tool_use) { + console.log(`Web search requests: ${message.usage.server_tool_use.web_search_requests}`); + } else { + console.log('No web search requests recorded in usage'); + } + + // Display message content types for debugging + console.log('\nMessage Content Types:'); + message.content.forEach((block, i) => { + console.log(`Content Block ${i + 1}: Type = ${block.type}`); + }); + + // Show full message for debugging + console.log('\nComplete message structure:'); + console.dir(message, { depth: 4 }); +} + +main().catch(console.error); diff --git a/examples/web-search.ts b/examples/web-search.ts new file mode 100755 index 00000000..e5c528ac --- /dev/null +++ b/examples/web-search.ts @@ -0,0 +1,52 @@ +#!/usr/bin/env -S npm run tsn -T + +import Anthropic from '@anthropic-ai/sdk'; + +const client = new Anthropic(); + +async function main() { + console.log('Web Search Example'); + console.log('================='); + + // Create a message with web search enabled + const message = await client.messages.create({ + model: 'claude-3-5-sonnet-latest', + max_tokens: 1024, + messages: [ + { + role: 'user', + content: + "What's the current weather in San Francisco? Please search the web for up-to-date information.", + }, + ], + tools: [ + { + name: 'web_search', + type: 'web_search_20250305', + }, + ], + }); + + // Print the full response + console.log('\nFull response:'); + console.dir(message, { depth: 4 }); + + // Extract and print the content + console.log('\nResponse content:'); + for (const contentBlock of message.content) { + if (contentBlock.type === 'text') { + console.log(contentBlock.text); + } + } + + // Print usage information + console.log('\nUsage statistics:'); + console.log(`Input tokens: ${message.usage.input_tokens}`); + console.log(`Output tokens: ${message.usage.output_tokens}`); + + if (message.usage.server_tool_use) { + console.log(`Web search requests: ${message.usage.server_tool_use.web_search_requests}`); + } +} + +main().catch(console.error); diff --git a/src/lib/BetaMessageStream.ts b/src/lib/BetaMessageStream.ts index 06ba3dd3..6a57ba49 100644 --- a/src/lib/BetaMessageStream.ts +++ b/src/lib/BetaMessageStream.ts @@ -531,6 +531,15 @@ export class BetaMessageStream implements AsyncIterable snapshot.stop_reason = event.delta.stop_reason; snapshot.stop_sequence = event.delta.stop_sequence; snapshot.usage.output_tokens = event.usage.output_tokens; + + // Update other usage fields if they exist in the event + if (event.usage.input_tokens) { + snapshot.usage.input_tokens = event.usage.input_tokens; + } + snapshot.usage.cache_creation_input_tokens = event.usage.cache_creation_input_tokens; + snapshot.usage.cache_read_input_tokens = event.usage.cache_read_input_tokens; + snapshot.usage.server_tool_use = event.usage.server_tool_use; + return snapshot; case 'content_block_start': snapshot.content.push(event.content_block); diff --git a/src/lib/MessageStream.ts b/src/lib/MessageStream.ts index 5d1e8096..afb91af1 100644 --- a/src/lib/MessageStream.ts +++ b/src/lib/MessageStream.ts @@ -531,6 +531,15 @@ export class MessageStream implements AsyncIterable { snapshot.stop_reason = event.delta.stop_reason; snapshot.stop_sequence = event.delta.stop_sequence; snapshot.usage.output_tokens = event.usage.output_tokens; + + // Update other usage fields if they exist in the event + if (event.usage.input_tokens) { + snapshot.usage.input_tokens = event.usage.input_tokens; + } + snapshot.usage.cache_creation_input_tokens = event.usage.cache_creation_input_tokens; + snapshot.usage.cache_read_input_tokens = event.usage.cache_read_input_tokens; + snapshot.usage.server_tool_use = event.usage.server_tool_use; + return snapshot; case 'content_block_start': snapshot.content.push(event.content_block); diff --git a/tests/api-resources/MessageStream.test.ts b/tests/api-resources/MessageStream.test.ts index 5b21615f..b01d0708 100644 --- a/tests/api-resources/MessageStream.test.ts +++ b/tests/api-resources/MessageStream.test.ts @@ -34,6 +34,19 @@ async function* messageIterable(message: Message): AsyncGenerator { input_tokens: 10, cache_creation_input_tokens: null, cache_read_input_tokens: null, + server_tool_use: null, }, }), ); @@ -226,22 +250,22 @@ describe('MessageStream class', () => { }, { "args": [ - "{"type":"message_start","message":{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message_start","message":{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "streamEvent", }, { "args": [ "{"type":"content_block_start","content_block":{"type":"text","text":"","citations":null},"index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "streamEvent", }, { "args": [ "{"type":"content_block_delta","delta":{"type":"text_delta","text":"Hello"},"index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "streamEvent", }, @@ -255,7 +279,7 @@ describe('MessageStream class', () => { { "args": [ "{"type":"content_block_delta","delta":{"type":"text_delta","text":" ther"},"index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello ther","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello ther","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "streamEvent", }, @@ -269,7 +293,7 @@ describe('MessageStream class', () => { { "args": [ "{"type":"content_block_delta","delta":{"type":"text_delta","text":"e!"},"index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "streamEvent", }, @@ -283,7 +307,7 @@ describe('MessageStream class', () => { { "args": [ "{"type":"content_block_stop","index":0}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":null,"stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "streamEvent", }, @@ -295,27 +319,27 @@ describe('MessageStream class', () => { }, { "args": [ - "{"type":"message_delta","usage":{"output_tokens":6},"delta":{"stop_reason":"end_turn","stop_sequence":null}}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message_delta","usage":{"output_tokens":6,"input_tokens":null,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null},"delta":{"stop_reason":"end_turn","stop_sequence":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "streamEvent", }, { "args": [ "{"type":"message_stop"}", - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "streamEvent", }, { "args": [ - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "message", }, { "args": [ - "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null}}", + "{"type":"message","id":"msg_01hhptzfxdaeehfxfv070yb6b8","role":"assistant","content":[{"type":"text","text":"Hello there!","citations":null}],"model":"claude-3-opus-20240229","stop_reason":"end_turn","stop_sequence":null,"usage":{"output_tokens":6,"input_tokens":10,"cache_creation_input_tokens":null,"cache_read_input_tokens":null,"server_tool_use":null}}", ], "type": "finalMessage", }, @@ -348,6 +372,7 @@ describe('MessageStream class', () => { "cache_read_input_tokens": null, "input_tokens": 10, "output_tokens": 6, + "server_tool_use": null, }, } `); @@ -378,6 +403,7 @@ describe('MessageStream class', () => { input_tokens: 10, cache_creation_input_tokens: null, cache_read_input_tokens: null, + server_tool_use: null, }, }), ); @@ -405,7 +431,7 @@ describe('MessageStream class', () => { const stream = anthropic.messages.stream( { max_tokens: 1024, - model: 'claude-2.1', + model: 'claude-3-7-sonnet-20250219', messages: [{ role: 'user', content: 'Say hello there!' }], }, { maxRetries: 0 }, @@ -430,7 +456,7 @@ describe('MessageStream class', () => { const stream = anthropic.messages.stream( { max_tokens: 1024, - model: 'claude-2.1', + model: 'claude-3-7-sonnet-20250219', messages: [{ role: 'user', content: 'Say hello there!' }], }, { maxRetries: 0 },