Update test framework: fix run_tests.py to support all test files, add auto-import-check for test files

This commit is contained in:
qiaoxinjiu
2026-05-09 15:11:30 +08:00
parent eb053a347f
commit eaba8328da
21739 changed files with 2236758 additions and 719 deletions

View File

@@ -0,0 +1,9 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
export class MultipartBody {
constructor(public body: any) {}
get [Symbol.toStringTag](): string {
return 'MultipartBody';
}
}

46
node_modules/@anthropic-ai/sdk/src/_shims/README.md generated vendored Normal file
View File

@@ -0,0 +1,46 @@
# 👋 Wondering what everything in here does?
`@anthropic-ai/sdk` supports a wide variety of runtime environments like Node.js, Deno, Bun, browsers, and various
edge runtimes, as well as both CommonJS (CJS) and EcmaScript Modules (ESM).
To do this, `@anthropic-ai/sdk` provides shims for either using `node-fetch` when in Node (because `fetch` is still experimental there) or the global `fetch` API built into the environment when not in Node.
It uses [conditional exports](https://nodejs.org/api/packages.html#conditional-exports) to
automatically select the correct shims for each environment. However, conditional exports are a fairly new
feature and not supported everywhere. For instance, the TypeScript `"moduleResolution": "node"`
setting doesn't consult the `exports` map, compared to `"moduleResolution": "nodeNext"`, which does.
Unfortunately that's still the default setting, and it can result in errors like
getting the wrong raw `Response` type from `.asResponse()`, for example.
The user can work around these issues by manually importing one of:
- `import '@anthropic-ai/sdk/shims/node'`
- `import '@anthropic-ai/sdk/shims/web'`
All of the code here in `_shims` handles selecting the automatic default shims or manual overrides.
### How it works - Runtime
Runtime shims get installed by calling `setShims` exported by `@anthropic-ai/sdk/_shims/registry`.
Manually importing `@anthropic-ai/sdk/shims/node` or `@anthropic-ai/sdk/shims/web`, calls `setShims` with the respective runtime shims.
All client code imports shims from `@anthropic-ai/sdk/_shims/index`, which:
- checks if shims have been set manually
- if not, calls `setShims` with the shims from `@anthropic-ai/sdk/_shims/auto/runtime`
- re-exports the installed shims from `@anthropic-ai/sdk/_shims/registry`.
`@anthropic-ai/sdk/_shims/auto/runtime` exports web runtime shims.
If the `node` export condition is set, the export map replaces it with `@anthropic-ai/sdk/_shims/auto/runtime-node`.
### How it works - Type time
All client code imports shim types from `@anthropic-ai/sdk/_shims/index`, which selects the manual types from `@anthropic-ai/sdk/_shims/manual-types` if they have been declared, otherwise it exports the auto types from `@anthropic-ai/sdk/_shims/auto/types`.
`@anthropic-ai/sdk/_shims/manual-types` exports an empty namespace.
Manually importing `@anthropic-ai/sdk/shims/node` or `@anthropic-ai/sdk/shims/web` merges declarations into this empty namespace, so they get picked up by `@anthropic-ai/sdk/_shims/index`.
`@anthropic-ai/sdk/_shims/auto/types` exports web type definitions.
If the `node` export condition is set, the export map replaces it with `@anthropic-ai/sdk/_shims/auto/types-node`, though TS only picks this up if `"moduleResolution": "nodenext"` or `"moduleResolution": "bundler"`.

View File

@@ -0,0 +1,4 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
export * from '../bun-runtime';

View File

@@ -0,0 +1,4 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
export * from '../node-runtime';

View File

@@ -0,0 +1,4 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
export * from '../web-runtime';

View File

@@ -0,0 +1,4 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
export * from '../node-types';

View File

@@ -0,0 +1,101 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
export type Agent = any;
// @ts-ignore
declare const _fetch: typeof fetch;
export { _fetch as fetch };
// @ts-ignore
type _Request = Request;
export { _Request as Request };
// @ts-ignore
type _RequestInfo = RequestInfo;
export { type _RequestInfo as RequestInfo };
// @ts-ignore
type _RequestInit = RequestInit;
export { type _RequestInit as RequestInit };
// @ts-ignore
type _Response = Response;
export { _Response as Response };
// @ts-ignore
type _ResponseInit = ResponseInit;
export { type _ResponseInit as ResponseInit };
// @ts-ignore
type _ResponseType = ResponseType;
export { type _ResponseType as ResponseType };
// @ts-ignore
type _BodyInit = BodyInit;
export { type _BodyInit as BodyInit };
// @ts-ignore
type _Headers = Headers;
export { _Headers as Headers };
// @ts-ignore
type _HeadersInit = HeadersInit;
export { type _HeadersInit as HeadersInit };
type EndingType = 'native' | 'transparent';
export interface BlobPropertyBag {
endings?: EndingType;
type?: string;
}
export interface FilePropertyBag extends BlobPropertyBag {
lastModified?: number;
}
export type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;
// @ts-ignore
type _FormData = FormData;
// @ts-ignore
declare const _FormData: typeof FormData;
export { _FormData as FormData };
// @ts-ignore
type _File = File;
// @ts-ignore
declare const _File: typeof File;
export { _File as File };
// @ts-ignore
type _Blob = Blob;
// @ts-ignore
declare const _Blob: typeof Blob;
export { _Blob as Blob };
export declare class Readable {
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<any>;
}
export declare class FsReadStream extends Readable {
path: {}; // node type is string | Buffer
}
// @ts-ignore
type _ReadableStream<R = any> = ReadableStream<R>;
// @ts-ignore
declare const _ReadableStream: typeof ReadableStream;
export { _ReadableStream as ReadableStream };

View File

@@ -0,0 +1,3 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/

View File

@@ -0,0 +1,3 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/

View File

@@ -0,0 +1,14 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
import { type Shims } from './registry';
import { getRuntime as getWebRuntime } from './web-runtime';
import { ReadStream as FsReadStream } from 'node:fs';
export function getRuntime(): Shims {
const runtime = getWebRuntime();
function isFsReadStream(value: any): value is FsReadStream {
return value instanceof FsReadStream;
}
return { ...runtime, isFsReadStream };
}

81
node_modules/@anthropic-ai/sdk/src/_shims/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,81 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
import { manual } from './manual-types';
import * as auto from "./auto/types";
import { type RequestOptions } from '../core';
type SelectType<Manual, Auto> = unknown extends Manual ? Auto : Manual;
export const kind: string;
// @ts-ignore
export type Agent = SelectType<manual.Agent, auto.Agent>;
// @ts-ignore
export const fetch: SelectType<typeof manual.fetch, typeof auto.fetch>;
// @ts-ignore
export type Request = SelectType<manual.Request, auto.Request>;
// @ts-ignore
export type RequestInfo = SelectType<manual.RequestInfo, auto.RequestInfo>;
// @ts-ignore
export type RequestInit = SelectType<manual.RequestInit, auto.RequestInit>;
// @ts-ignore
export type Response = SelectType<manual.Response, auto.Response>;
// @ts-ignore
export type ResponseInit = SelectType<manual.ResponseInit, auto.ResponseInit>;
// @ts-ignore
export type ResponseType = SelectType<manual.ResponseType, auto.ResponseType>;
// @ts-ignore
export type BodyInit = SelectType<manual.BodyInit, auto.BodyInit>;
// @ts-ignore
export type Headers = SelectType<manual.Headers, auto.Headers>;
// @ts-ignore
export const Headers: SelectType<typeof manual.Headers, typeof auto.Headers>;
// @ts-ignore
export type HeadersInit = SelectType<manual.HeadersInit, auto.HeadersInit>;
// @ts-ignore
export type BlobPropertyBag = SelectType<manual.BlobPropertyBag, auto.BlobPropertyBag>;
// @ts-ignore
export type FilePropertyBag = SelectType<manual.FilePropertyBag, auto.FilePropertyBag>;
// @ts-ignore
export type FileFromPathOptions = SelectType<manual.FileFromPathOptions, auto.FileFromPathOptions>;
// @ts-ignore
export type FormData = SelectType<manual.FormData, auto.FormData>;
// @ts-ignore
export const FormData: SelectType<typeof manual.FormData, typeof auto.FormData>;
// @ts-ignore
export type File = SelectType<manual.File, auto.File>;
// @ts-ignore
export const File: SelectType<typeof manual.File, typeof auto.File>;
// @ts-ignore
export type Blob = SelectType<manual.Blob, auto.Blob>;
// @ts-ignore
export const Blob: SelectType<typeof manual.Blob, typeof auto.Blob>;
// @ts-ignore
export type Readable = SelectType<manual.Readable, auto.Readable>;
// @ts-ignore
export type FsReadStream = SelectType<manual.FsReadStream, auto.FsReadStream>;
// @ts-ignore
export type ReadableStream = SelectType<manual.ReadableStream, auto.ReadableStream>;
// @ts-ignore
export const ReadableStream: SelectType<typeof manual.ReadableStream, typeof auto.ReadableStream>;
export function getMultipartRequestOptions<T extends {} = Record<string, unknown>>(
form: FormData,
opts: RequestOptions<T>,
): Promise<RequestOptions<T>>;
export function getDefaultAgent(url: string): any;
// @ts-ignore
export type FileFromPathOptions = SelectType<manual.FileFromPathOptions, auto.FileFromPathOptions>;
export function fileFromPath(path: string, options?: FileFromPathOptions): Promise<File>;
export function fileFromPath(path: string, filename?: string, options?: FileFromPathOptions): Promise<File>;
export function isFsReadStream(value: any): value is FsReadStream;

13
node_modules/@anthropic-ai/sdk/src/_shims/index.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
const shims = require('./registry');
const auto = require('@anthropic-ai/sdk/_shims/auto/runtime');
if (!shims.kind) shims.setShims(auto.getRuntime(), { auto: true });
for (const property of Object.keys(shims)) {
Object.defineProperty(exports, property, {
get() {
return shims[property];
},
});
}

7
node_modules/@anthropic-ai/sdk/src/_shims/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
import * as shims from './registry.mjs';
import * as auto from "./auto/runtime";
if (!shims.kind) shims.setShims(auto.getRuntime(), { auto: true });
export * from './registry.mjs';

View File

@@ -0,0 +1,12 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
/**
* Types will get added to this namespace when you import one of the following:
*
* import '@anthropic-ai/sdk/shims/node'
* import '@anthropic-ai/sdk/shims/web'
*
* Importing more than one will cause type and runtime errors.
*/
export namespace manual {}

View File

@@ -0,0 +1,3 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/

View File

@@ -0,0 +1,3 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/

View File

@@ -0,0 +1,83 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
import * as nf from 'node-fetch';
import * as fd from 'formdata-node';
import { type File, type FilePropertyBag } from 'formdata-node';
import KeepAliveAgent from 'agentkeepalive';
import { AbortController as AbortControllerPolyfill } from 'abort-controller';
import { ReadStream as FsReadStream } from 'node:fs';
import { type Agent } from 'node:http';
import { FormDataEncoder } from 'form-data-encoder';
import { Readable } from 'node:stream';
import { type RequestOptions } from '../core';
import { MultipartBody } from './MultipartBody';
import { type Shims } from './registry';
// @ts-ignore (this package does not have proper export maps for this export)
import { ReadableStream } from 'web-streams-polyfill/dist/ponyfill.es2018.js';
type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;
let fileFromPathWarned = false;
/**
* @deprecated use fs.createReadStream('./my/file.txt') instead
*/
async function fileFromPath(path: string): Promise<File>;
async function fileFromPath(path: string, filename?: string): Promise<File>;
async function fileFromPath(path: string, options?: FileFromPathOptions): Promise<File>;
async function fileFromPath(path: string, filename?: string, options?: FileFromPathOptions): Promise<File>;
async function fileFromPath(path: string, ...args: any[]): Promise<File> {
// this import fails in environments that don't handle export maps correctly, like old versions of Jest
const { fileFromPath: _fileFromPath } = await import('formdata-node/file-from-path');
if (!fileFromPathWarned) {
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path)}) instead`);
fileFromPathWarned = true;
}
// @ts-ignore
return await _fileFromPath(path, ...args);
}
const defaultHttpAgent: Agent = new KeepAliveAgent({ keepAlive: true, timeout: 5 * 60 * 1000 });
const defaultHttpsAgent: Agent = new KeepAliveAgent.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1000 });
async function getMultipartRequestOptions<T extends {} = Record<string, unknown>>(
form: fd.FormData,
opts: RequestOptions<T>,
): Promise<RequestOptions<T>> {
const encoder = new FormDataEncoder(form);
const readable = Readable.from(encoder);
const body = new MultipartBody(readable);
const headers = {
...opts.headers,
...encoder.headers,
'Content-Length': encoder.contentLength,
};
return { ...opts, body: body as any, headers };
}
export function getRuntime(): Shims {
// Polyfill global object if needed.
if (typeof AbortController === 'undefined') {
// @ts-expect-error (the types are subtly different, but compatible in practice)
globalThis.AbortController = AbortControllerPolyfill;
}
return {
kind: 'node',
fetch: nf.default,
Request: nf.Request,
Response: nf.Response,
Headers: nf.Headers,
FormData: fd.FormData,
Blob: fd.Blob,
File: fd.File,
ReadableStream,
getMultipartRequestOptions,
getDefaultAgent: (url: string): Agent => (url.startsWith('https') ? defaultHttpsAgent : defaultHttpAgent),
fileFromPath,
isFsReadStream: (value: any): value is FsReadStream => value instanceof FsReadStream,
};
}

View File

@@ -0,0 +1,42 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
import * as nf from 'node-fetch';
import * as fd from 'formdata-node';
export { type Agent } from 'node:http';
export { type Readable } from 'node:stream';
export { type ReadStream as FsReadStream } from 'node:fs';
export { ReadableStream } from 'web-streams-polyfill';
export const fetch: typeof nf.default;
export type Request = nf.Request;
export type RequestInfo = nf.RequestInfo;
export type RequestInit = nf.RequestInit;
export type Response = nf.Response;
export type ResponseInit = nf.ResponseInit;
export type ResponseType = nf.ResponseType;
export type BodyInit = nf.BodyInit;
export type Headers = nf.Headers;
export type HeadersInit = nf.HeadersInit;
type EndingType = 'native' | 'transparent';
export interface BlobPropertyBag {
endings?: EndingType;
type?: string;
}
export interface FilePropertyBag extends BlobPropertyBag {
lastModified?: number;
}
export type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;
export type FormData = fd.FormData;
export const FormData: typeof fd.FormData;
export type File = fd.File;
export const File: typeof fd.File;
export type Blob = fd.Blob;
export const Blob: typeof fd.Blob;

View File

@@ -0,0 +1,3 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/

View File

@@ -0,0 +1,3 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/

67
node_modules/@anthropic-ai/sdk/src/_shims/registry.ts generated vendored Normal file
View File

@@ -0,0 +1,67 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
import { type RequestOptions } from '../core';
export interface Shims {
kind: string;
fetch: any;
Request: any;
Response: any;
Headers: any;
FormData: any;
Blob: any;
File: any;
ReadableStream: any;
getMultipartRequestOptions: <T extends {} = Record<string, unknown>>(
form: Shims['FormData'],
opts: RequestOptions<T>,
) => Promise<RequestOptions<T>>;
getDefaultAgent: (url: string) => any;
fileFromPath:
| ((path: string, filename?: string, options?: {}) => Promise<Shims['File']>)
| ((path: string, options?: {}) => Promise<Shims['File']>);
isFsReadStream: (value: any) => boolean;
}
export let auto = false;
export let kind: Shims['kind'] | undefined = undefined;
export let fetch: Shims['fetch'] | undefined = undefined;
export let Request: Shims['Request'] | undefined = undefined;
export let Response: Shims['Response'] | undefined = undefined;
export let Headers: Shims['Headers'] | undefined = undefined;
export let FormData: Shims['FormData'] | undefined = undefined;
export let Blob: Shims['Blob'] | undefined = undefined;
export let File: Shims['File'] | undefined = undefined;
export let ReadableStream: Shims['ReadableStream'] | undefined = undefined;
export let getMultipartRequestOptions: Shims['getMultipartRequestOptions'] | undefined = undefined;
export let getDefaultAgent: Shims['getDefaultAgent'] | undefined = undefined;
export let fileFromPath: Shims['fileFromPath'] | undefined = undefined;
export let isFsReadStream: Shims['isFsReadStream'] | undefined = undefined;
export function setShims(shims: Shims, options: { auto: boolean } = { auto: false }) {
if (auto) {
throw new Error(
`you must \`import '@anthropic-ai/sdk/shims/${shims.kind}'\` before importing anything else from @anthropic-ai/sdk`,
);
}
if (kind) {
throw new Error(
`can't \`import '@anthropic-ai/sdk/shims/${shims.kind}'\` after \`import '@anthropic-ai/sdk/shims/${kind}'\``,
);
}
auto = options.auto;
kind = shims.kind;
fetch = shims.fetch;
Request = shims.Request;
Response = shims.Response;
Headers = shims.Headers;
FormData = shims.FormData;
Blob = shims.Blob;
File = shims.File;
ReadableStream = shims.ReadableStream;
getMultipartRequestOptions = shims.getMultipartRequestOptions;
getDefaultAgent = shims.getDefaultAgent;
fileFromPath = shims.fileFromPath;
isFsReadStream = shims.isFsReadStream;
}

View File

@@ -0,0 +1,103 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
import { MultipartBody } from './MultipartBody';
import { type RequestOptions } from '../core';
import { type Shims } from './registry';
export function getRuntime({ manuallyImported }: { manuallyImported?: boolean } = {}): Shims {
const recommendation =
manuallyImported ?
`You may need to use polyfills`
: `Add one of these imports before your first \`import … from '@anthropic-ai/sdk'\`:
- \`import '@anthropic-ai/sdk/shims/node'\` (if you're running on Node)
- \`import '@anthropic-ai/sdk/shims/web'\` (otherwise)
`;
let _fetch, _Request, _Response, _Headers;
try {
// @ts-ignore
_fetch = fetch;
// @ts-ignore
_Request = Request;
// @ts-ignore
_Response = Response;
// @ts-ignore
_Headers = Headers;
} catch (error) {
throw new Error(
`this environment is missing the following Web Fetch API type: ${
(error as any).message
}. ${recommendation}`,
);
}
return {
kind: 'web',
fetch: _fetch,
Request: _Request,
Response: _Response,
Headers: _Headers,
FormData:
// @ts-ignore
typeof FormData !== 'undefined' ? FormData : (
class FormData {
// @ts-ignore
constructor() {
throw new Error(
`file uploads aren't supported in this environment yet as 'FormData' is undefined. ${recommendation}`,
);
}
}
),
Blob:
typeof Blob !== 'undefined' ? Blob : (
class Blob {
constructor() {
throw new Error(
`file uploads aren't supported in this environment yet as 'Blob' is undefined. ${recommendation}`,
);
}
}
),
File:
// @ts-ignore
typeof File !== 'undefined' ? File : (
class File {
// @ts-ignore
constructor() {
throw new Error(
`file uploads aren't supported in this environment yet as 'File' is undefined. ${recommendation}`,
);
}
}
),
ReadableStream:
// @ts-ignore
typeof ReadableStream !== 'undefined' ? ReadableStream : (
class ReadableStream {
// @ts-ignore
constructor() {
throw new Error(
`streaming isn't supported in this environment yet as 'ReadableStream' is undefined. ${recommendation}`,
);
}
}
),
getMultipartRequestOptions: async <T extends {} = Record<string, unknown>>(
// @ts-ignore
form: FormData,
opts: RequestOptions<T>,
): Promise<RequestOptions<T>> => ({
...opts,
body: new MultipartBody(form) as any,
}),
getDefaultAgent: (url: string) => undefined,
fileFromPath: () => {
throw new Error(
'The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/anthropics/anthropic-sdk-typescript#file-uploads',
);
},
isFsReadStream: (value: any) => false,
};
}

View File

@@ -0,0 +1,83 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/
export type Agent = any;
declare const _fetch: typeof fetch;
export { _fetch as fetch };
type _Request = Request;
export { _Request as Request };
type _RequestInfo = RequestInfo;
export { type _RequestInfo as RequestInfo };
type _RequestInit = RequestInit;
export { type _RequestInit as RequestInit };
type _Response = Response;
export { _Response as Response };
type _ResponseInit = ResponseInit;
export { type _ResponseInit as ResponseInit };
type _ResponseType = ResponseType;
export { type _ResponseType as ResponseType };
type _BodyInit = BodyInit;
export { type _BodyInit as BodyInit };
type _Headers = Headers;
export { _Headers as Headers };
type _HeadersInit = HeadersInit;
export { type _HeadersInit as HeadersInit };
type EndingType = 'native' | 'transparent';
export interface BlobPropertyBag {
endings?: EndingType;
type?: string;
}
export interface FilePropertyBag extends BlobPropertyBag {
lastModified?: number;
}
export type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;
type _FormData = FormData;
declare const _FormData: typeof FormData;
export { _FormData as FormData };
type _File = File;
declare const _File: typeof File;
export { _File as File };
type _Blob = Blob;
declare const _Blob: typeof Blob;
export { _Blob as Blob };
export declare class Readable {
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<any>;
}
export declare class FsReadStream extends Readable {
path: {}; // node type is string | Buffer
}
type _ReadableStream<R = any> = ReadableStream<R>;
declare const _ReadableStream: typeof ReadableStream;
export { _ReadableStream as ReadableStream };

View File

@@ -0,0 +1,3 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/

View File

@@ -0,0 +1,3 @@
/**
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
*/

1108
node_modules/@anthropic-ai/sdk/src/core.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

145
node_modules/@anthropic-ai/sdk/src/error.ts generated vendored Normal file
View File

@@ -0,0 +1,145 @@
// File generated from our OpenAPI spec by Stainless.
import { castToError, Headers } from './core';
export class AnthropicError extends Error {}
export class APIError extends AnthropicError {
readonly status: number | undefined;
readonly headers: Headers | undefined;
readonly error: Object | undefined;
constructor(
status: number | undefined,
error: Object | undefined,
message: string | undefined,
headers: Headers | undefined,
) {
super(`${APIError.makeMessage(status, error, message)}`);
this.status = status;
this.headers = headers;
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,
) {
if (!status) {
return new APIConnectionError({ cause: castToError(errorResponse) });
}
const error = errorResponse as Record<string, any>;
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 {
override readonly status: undefined = undefined;
constructor({ message }: { message?: string } = {}) {
super(undefined, undefined, message || 'Request was aborted.', undefined);
}
}
export class APIConnectionError extends APIError {
override readonly status: undefined = undefined;
constructor({ message, cause }: { message?: string; 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 {
override readonly status: 400 = 400;
}
export class AuthenticationError extends APIError {
override readonly status: 401 = 401;
}
export class PermissionDeniedError extends APIError {
override readonly status: 403 = 403;
}
export class NotFoundError extends APIError {
override readonly status: 404 = 404;
}
export class ConflictError extends APIError {
override readonly status: 409 = 409;
}
export class UnprocessableEntityError extends APIError {
override readonly status: 422 = 422;
}
export class RateLimitError extends APIError {
override readonly status: 429 = 429;
}
export class InternalServerError extends APIError {}

236
node_modules/@anthropic-ai/sdk/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,236 @@
// File generated from our OpenAPI spec by Stainless.
import * as Core from './core';
import * as Errors from './error';
import { type Agent } from './_shims/index';
import * as Uploads from './uploads';
import * as API from "./resources/index";
export interface ClientOptions {
/**
* Defaults to process.env['ANTHROPIC_API_KEY'].
*/
apiKey?: string | null;
/**
* Defaults to process.env['ANTHROPIC_AUTH_TOKEN'].
*/
authToken?: string | null;
/**
* Override the default base URL for the API, e.g., "https://api.example.com/v2/"
*/
baseURL?: string;
/**
* The maximum amount of time (in milliseconds) that the client should wait for a response
* from the server before timing out a single request.
*
* 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;
/**
* 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.
*/
httpAgent?: Agent;
/**
* Specify a custom `fetch` function implementation.
*
* If not provided, we use `node-fetch` on Node.js and otherwise expect that `fetch` is
* defined globally.
*/
fetch?: Core.Fetch | undefined;
/**
* The maximum number of times that the client will retry a request in case of a
* temporary failure, like a network error or a 5XX error from the server.
*
* @default 2
*/
maxRetries?: number;
/**
* Default headers to include with every request to the API.
*
* These can be removed in individual requests by explicitly setting the
* header to `undefined` or `null` in request options.
*/
defaultHeaders?: Core.Headers;
/**
* Default query parameters to include with every request to the API.
*
* These can be removed in individual requests by explicitly setting the
* param to `undefined` in request options.
*/
defaultQuery?: Core.DefaultQuery;
}
/** API Client for interfacing with the Anthropic API. */
export class Anthropic extends Core.APIClient {
apiKey: string | null;
authToken: string | null;
private _options: ClientOptions;
/**
* API Client for interfacing with the Anthropic API.
*
* @param {string | null} [opts.apiKey==process.env['ANTHROPIC_API_KEY'] ?? null]
* @param {string | null} [opts.authToken==process.env['ANTHROPIC_AUTH_TOKEN'] ?? null]
* @param {string} [opts.baseURL] - 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 {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.
*/
constructor({
apiKey = Core.readEnv('ANTHROPIC_API_KEY') ?? null,
authToken = Core.readEnv('ANTHROPIC_AUTH_TOKEN') ?? null,
...opts
}: ClientOptions = {}) {
const options: ClientOptions = {
apiKey,
authToken,
...opts,
baseURL: opts.baseURL ?? `https://api.anthropic.com`,
};
super({
baseURL: options.baseURL!,
timeout: options.timeout ?? 600000 /* 10 minutes */,
httpAgent: options.httpAgent,
maxRetries: options.maxRetries,
fetch: options.fetch,
});
this._options = options;
this.apiKey = apiKey;
this.authToken = authToken;
}
completions: API.Completions = new API.Completions(this);
protected override defaultQuery(): Core.DefaultQuery | undefined {
return this._options.defaultQuery;
}
protected override defaultHeaders(opts: Core.FinalRequestOptions): Core.Headers {
return {
...super.defaultHeaders(opts),
'anthropic-version': '2023-06-01',
...this._options.defaultHeaders,
};
}
protected override validateHeaders(headers: Core.Headers, customHeaders: Core.Headers) {
if (this.apiKey && headers['X-Api-Key']) {
return;
}
if (customHeaders['X-Api-Key'] === null) {
return;
}
if (this.authToken && headers['Authorization']) {
return;
}
if (customHeaders['Authorization'] === null) {
return;
}
throw new Error(
'Could not resolve authentication method. Expected either apiKey or authToken to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted',
);
}
protected override authHeaders(opts: Core.FinalRequestOptions): Core.Headers {
const apiKeyAuth = this.apiKeyAuth(opts);
const bearerAuth = this.bearerAuth(opts);
if (apiKeyAuth != null && !Core.isEmptyObj(apiKeyAuth)) {
return apiKeyAuth;
}
if (bearerAuth != null && !Core.isEmptyObj(bearerAuth)) {
return bearerAuth;
}
return {};
}
protected apiKeyAuth(opts: Core.FinalRequestOptions): Core.Headers {
if (this.apiKey == null) {
return {};
}
return { 'X-Api-Key': this.apiKey };
}
protected bearerAuth(opts: Core.FinalRequestOptions): Core.Headers {
if (this.authToken == null) {
return {};
}
return { Authorization: `Bearer ${this.authToken}` };
}
static Anthropic = this;
static HUMAN_PROMPT = '\n\nHuman:';
static AI_PROMPT = '\n\nAssistant:';
static AnthropicError = Errors.AnthropicError;
static APIError = Errors.APIError;
static APIConnectionError = Errors.APIConnectionError;
static APIConnectionTimeoutError = Errors.APIConnectionTimeoutError;
static APIUserAbortError = Errors.APIUserAbortError;
static NotFoundError = Errors.NotFoundError;
static ConflictError = Errors.ConflictError;
static RateLimitError = Errors.RateLimitError;
static BadRequestError = Errors.BadRequestError;
static AuthenticationError = Errors.AuthenticationError;
static InternalServerError = Errors.InternalServerError;
static PermissionDeniedError = Errors.PermissionDeniedError;
static UnprocessableEntityError = Errors.UnprocessableEntityError;
}
export const { HUMAN_PROMPT, AI_PROMPT } = Anthropic;
export const {
AnthropicError,
APIError,
APIConnectionError,
APIConnectionTimeoutError,
APIUserAbortError,
NotFoundError,
ConflictError,
RateLimitError,
BadRequestError,
AuthenticationError,
InternalServerError,
PermissionDeniedError,
UnprocessableEntityError,
} = Errors;
export import toFile = Uploads.toFile;
export import fileFromPath = Uploads.fileFromPath;
export namespace Anthropic {
// Helper functions
export import toFile = Uploads.toFile;
export import fileFromPath = Uploads.fileFromPath;
export import RequestOptions = Core.RequestOptions;
export import Completions = API.Completions;
export import Completion = API.Completion;
export import CompletionCreateParams = API.CompletionCreateParams;
export import CompletionCreateParamsNonStreaming = API.CompletionCreateParamsNonStreaming;
export import CompletionCreateParamsStreaming = API.CompletionCreateParamsStreaming;
}
export default Anthropic;

24
node_modules/@anthropic-ai/sdk/src/resource.ts generated vendored Normal file
View File

@@ -0,0 +1,24 @@
// File generated from our OpenAPI spec by Stainless.
import type { Anthropic } from './index';
export class APIResource {
protected client: Anthropic;
constructor(client: Anthropic) {
this.client = client;
this.get = client.get.bind(client);
this.post = client.post.bind(client);
this.patch = client.patch.bind(client);
this.put = client.put.bind(client);
this.delete = client.delete.bind(client);
this.getAPIList = client.getAPIList.bind(client);
}
protected get: Anthropic['get'];
protected post: Anthropic['post'];
protected patch: Anthropic['patch'];
protected put: Anthropic['put'];
protected delete: Anthropic['delete'];
protected getAPIList: Anthropic['getAPIList'];
}

View File

@@ -0,0 +1,190 @@
// File generated from our OpenAPI spec by Stainless.
import * as Core from "../core";
import { APIPromise } from "../core";
import { APIResource } from "../resource";
import * as CompletionsAPI from "./completions";
import { Stream } from "../streaming";
export class Completions extends APIResource {
/**
* Create a completion
*/
create(body: CompletionCreateParamsNonStreaming, options?: Core.RequestOptions): APIPromise<Completion>;
create(
body: CompletionCreateParamsStreaming,
options?: Core.RequestOptions,
): APIPromise<Stream<Completion>>;
create(
body: CompletionCreateParamsBase,
options?: Core.RequestOptions,
): APIPromise<Stream<Completion> | Completion>;
create(
body: CompletionCreateParams,
options?: Core.RequestOptions,
): APIPromise<Completion> | APIPromise<Stream<Completion>> {
return this.post('/v1/complete', { body, timeout: 600000, ...options, stream: body.stream ?? false }) as
| APIPromise<Completion>
| APIPromise<Stream<Completion>>;
}
}
export interface Completion {
/**
* The resulting completion up to and excluding the stop sequences.
*/
completion: string;
/**
* The model that performed the completion.
*/
model: string;
/**
* The reason that we stopped sampling.
*
* This may be one the following values:
*
* - `"stop_sequence"`: we reached a stop sequence — either provided by you via the
* `stop_sequences` parameter, or a stop sequence built into the model
* - `"max_tokens"`: we exceeded `max_tokens_to_sample` or the model's maximum
*/
stop_reason: string;
}
export type CompletionCreateParams = CompletionCreateParamsNonStreaming | CompletionCreateParamsStreaming;
export interface CompletionCreateParamsBase {
/**
* 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.
*/
max_tokens_to_sample: number;
/**
* The model that will complete your prompt.
*
* As we improve Claude, we develop new versions of it that you can query. This
* parameter controls which version of Claude answers your request. Right now we
* are offering two model families: Claude, and Claude Instant. You can use them by
* setting `model` to `"claude-2"` or `"claude-instant-1"`, respectively. See
* [models](https://docs.anthropic.com/claude/reference/selecting-a-model) for
* additional details.
*/
model: (string & {}) | 'claude-2' | 'claude-instant-1';
/**
* The prompt that you want Claude to complete.
*
* For proper response generation you will need to format your prompt as follows:
*
* ```javascript
* const userQuestion = r"Why is the sky blue?";
* const prompt = `\n\nHuman: ${userQuestion}\n\nAssistant:`;
* ```
*
* See our
* [comments on prompts](https://docs.anthropic.com/claude/docs/introduction-to-prompt-design)
* for more context.
*/
prompt: string;
/**
* An object describing metadata about the request.
*/
metadata?: CompletionCreateParams.Metadata;
/**
* Sequences that will cause the model to stop generating completion text.
*
* Our models stop on `"\n\nHuman:"`, and may include additional built-in stop
* sequences in the future. By providing the stop_sequences parameter, you may
* include additional strings that will cause the model to stop generating.
*/
stop_sequences?: Array<string>;
/**
* Whether to incrementally stream the response using server-sent events.
*
* See
* [this guide to SSE events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
* for details.
*/
stream?: boolean;
/**
* Amount of randomness injected into the response.
*
* Defaults to 1. Ranges from 0 to 1. Use temp closer to 0 for analytical /
* multiple choice, and closer to 1 for creative and generative tasks.
*/
temperature?: number;
/**
* 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).
*/
top_k?: number;
/**
* Use nucleus sampling.
*
* In nucleus sampling, we compute the cumulative distribution over all the options
* for each subsequent token in decreasing probability order and cut it off once it
* reaches a particular probability specified by `top_p`. You should either alter
* `temperature` or `top_p`, but not both.
*/
top_p?: number;
}
export namespace CompletionCreateParams {
/**
* An object describing metadata about the request.
*/
export interface Metadata {
/**
* An external identifier for the user who is associated with the request.
*
* This should be a uuid, hash value, or other opaque identifier. Anthropic may use
* this id to help detect abuse. Do not include any identifying information such as
* name, email address, or phone number.
*/
user_id?: string;
}
export type CompletionCreateParamsNonStreaming = CompletionsAPI.CompletionCreateParamsNonStreaming;
export type CompletionCreateParamsStreaming = CompletionsAPI.CompletionCreateParamsStreaming;
}
export interface CompletionCreateParamsNonStreaming extends CompletionCreateParamsBase {
/**
* Whether to incrementally stream the response using server-sent events.
*
* See
* [this guide to SSE events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
* for details.
*/
stream?: false;
}
export interface CompletionCreateParamsStreaming extends CompletionCreateParamsBase {
/**
* Whether to incrementally stream the response using server-sent events.
*
* See
* [this guide to SSE events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
* for details.
*/
stream: true;
}
export namespace Completions {
export import Completion = CompletionsAPI.Completion;
export import CompletionCreateParams = CompletionsAPI.CompletionCreateParams;
export import CompletionCreateParamsNonStreaming = CompletionsAPI.CompletionCreateParamsNonStreaming;
export import CompletionCreateParamsStreaming = CompletionsAPI.CompletionCreateParamsStreaming;
}

View File

@@ -0,0 +1,9 @@
// File generated from our OpenAPI spec by Stainless.
export {
Completion,
CompletionCreateParams,
CompletionCreateParamsNonStreaming,
CompletionCreateParamsStreaming,
Completions,
} from './completions';

View File

@@ -0,0 +1,3 @@
// File generated from our OpenAPI spec by Stainless.
export {};

50
node_modules/@anthropic-ai/sdk/src/shims/node.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
// @ts-ignore
import * as types from '../_shims/node-types';
import { setShims } from '../_shims/registry';
import { getRuntime } from '../_shims/node-runtime';
setShims(getRuntime());
declare module '../_shims/manual-types' {
export namespace manual {
// @ts-ignore
export type Agent = types.Agent;
// @ts-ignore
export import fetch = types.fetch;
// @ts-ignore
export type Request = types.Request;
// @ts-ignore
export type RequestInfo = types.RequestInfo;
// @ts-ignore
export type RequestInit = types.RequestInit;
// @ts-ignore
export type Response = types.Response;
// @ts-ignore
export type ResponseInit = types.ResponseInit;
// @ts-ignore
export type ResponseType = types.ResponseType;
// @ts-ignore
export type BodyInit = types.BodyInit;
// @ts-ignore
export type Headers = types.Headers;
// @ts-ignore
export type HeadersInit = types.HeadersInit;
// @ts-ignore
export type BlobPropertyBag = types.BlobPropertyBag;
// @ts-ignore
export type FilePropertyBag = types.FilePropertyBag;
// @ts-ignore
export type FileFromPathOptions = types.FileFromPathOptions;
// @ts-ignore
export import FormData = types.FormData;
// @ts-ignore
export import File = types.File;
// @ts-ignore
export import Blob = types.Blob;
// @ts-ignore
export type Readable = types.Readable;
// @ts-ignore
export type FsReadStream = types.FsReadStream;
// @ts-ignore
export import ReadableStream = types.ReadableStream;
}
}

50
node_modules/@anthropic-ai/sdk/src/shims/web.ts generated vendored Normal file
View File

@@ -0,0 +1,50 @@
// @ts-ignore
import * as types from '../_shims/web-types';
import { setShims } from '../_shims/registry';
import { getRuntime } from '../_shims/web-runtime';
setShims(getRuntime({ manuallyImported: true }));
declare module '../_shims/manual-types' {
export namespace manual {
// @ts-ignore
export type Agent = types.Agent;
// @ts-ignore
export import fetch = types.fetch;
// @ts-ignore
export type Request = types.Request;
// @ts-ignore
export type RequestInfo = types.RequestInfo;
// @ts-ignore
export type RequestInit = types.RequestInit;
// @ts-ignore
export type Response = types.Response;
// @ts-ignore
export type ResponseInit = types.ResponseInit;
// @ts-ignore
export type ResponseType = types.ResponseType;
// @ts-ignore
export type BodyInit = types.BodyInit;
// @ts-ignore
export type Headers = types.Headers;
// @ts-ignore
export type HeadersInit = types.HeadersInit;
// @ts-ignore
export type BlobPropertyBag = types.BlobPropertyBag;
// @ts-ignore
export type FilePropertyBag = types.FilePropertyBag;
// @ts-ignore
export type FileFromPathOptions = types.FileFromPathOptions;
// @ts-ignore
export import FormData = types.FormData;
// @ts-ignore
export import File = types.File;
// @ts-ignore
export import Blob = types.Blob;
// @ts-ignore
export type Readable = types.Readable;
// @ts-ignore
export type FsReadStream = types.FsReadStream;
// @ts-ignore
export import ReadableStream = types.ReadableStream;
}
}

395
node_modules/@anthropic-ai/sdk/src/streaming.ts generated vendored Normal file
View File

@@ -0,0 +1,395 @@
import { ReadableStream, type Response } from './_shims/index';
import { AnthropicError } from './error';
import { safeJSON, createResponseHeaders } from "./core";
import { APIError } from "./error";
type Bytes = string | ArrayBuffer | Uint8Array | Buffer | null | undefined;
type ServerSentEvent = {
event: string | null;
data: string;
raw: string[];
};
export class Stream<Item> implements AsyncIterable<Item> {
controller: AbortController;
constructor(private iterator: () => AsyncIterator<Item>, controller: AbortController) {
this.controller = controller;
}
static fromSSEResponse<Item>(response: Response, controller: AbortController) {
let consumed = false;
const decoder = new SSEDecoder();
async function* iterMessages(): AsyncGenerator<ServerSentEvent, void, unknown> {
if (!response.body) {
controller.abort();
throw new AnthropicError(`Attempted to iterate over a response with no body`);
}
const lineDecoder = new LineDecoder();
const iter = readableStreamAsyncIterable<Bytes>(response.body);
for await (const chunk of iter) {
for (const line of lineDecoder.decode(chunk)) {
const sse = decoder.decode(line);
if (sse) yield sse;
}
}
for (const line of lineDecoder.flush()) {
const sse = decoder.decode(line);
if (sse) yield sse;
}
}
async function* iterator(): AsyncIterator<Item, any, undefined> {
if (consumed) {
throw new Error('Cannot iterate over a consumed stream, use `.tee()` to split the stream.');
}
consumed = true;
let done = false;
try {
for await (const sse of iterMessages()) {
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 === 'ping') {
continue;
}
if (sse.event === 'error') {
const errText = sse.data;
const errJSON = safeJSON(errText);
const errMessage = errJSON ? undefined : errText;
throw APIError.generate(undefined, errJSON, errMessage, createResponseHeaders(response.headers));
}
}
done = true;
} catch (e) {
// If the user calls `stream.controller.abort()`, we should exit without throwing.
if (e instanceof Error && e.name === 'AbortError') 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<Item>(readableStream: ReadableStream, controller: AbortController) {
let consumed = false;
async function* iterLines(): AsyncGenerator<string, void, unknown> {
const lineDecoder = new LineDecoder();
const iter = readableStreamAsyncIterable<Bytes>(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<Item, any, undefined> {
if (consumed) {
throw new Error('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 (e instanceof Error && e.name === 'AbortError') 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<Item> {
return this.iterator();
}
tee(): [Stream<Item>, Stream<Item>] {
const left: Array<Promise<IteratorResult<Item>>> = [];
const right: Array<Promise<IteratorResult<Item>>> = [];
const iterator = this.iterator();
const teeIterator = (queue: Array<Promise<IteratorResult<Item>>>): AsyncIterator<Item> => {
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<Item>;
const encoder = new TextEncoder();
return new ReadableStream({
async start() {
iter = self[Symbol.asyncIterator]();
},
async pull(ctrl) {
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?.();
},
});
}
}
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;
}
}
/**
* A re-implementation of httpx's `LineDecoder` in Python that handles incrementally
* reading lines from text.
*
* https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258
*/
class LineDecoder {
// prettier-ignore
static NEWLINE_CHARS = new Set(['\n', '\r', '\x0b', '\x0c', '\x1c', '\x1d', '\x1e', '\x85', '\u2028', '\u2029']);
static NEWLINE_REGEXP = /\r\n|[\n\r\x0b\x0c\x1c\x1d\x1e\x85\u2028\u2029]/g;
buffer: string[];
trailingCR: boolean;
textDecoder: any; // TextDecoder found in browsers; not typed to avoid pulling in either "dom" or "node" types.
constructor() {
this.buffer = [];
this.trailingCR = false;
}
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) {
return [];
}
const trailingNewline = LineDecoder.NEWLINE_CHARS.has(text[text.length - 1] || '');
let lines = text.split(LineDecoder.NEWLINE_REGEXP);
if (lines.length === 1 && !trailingNewline) {
this.buffer.push(lines[0]!);
return [];
}
if (this.buffer.length > 0) {
lines = [this.buffer.join('') + lines[0], ...lines.slice(1)];
this.buffer = [];
}
if (!trailingNewline) {
this.buffer = [lines.pop() || ''];
}
return lines;
}
decodeText(bytes: Bytes): string {
if (bytes == null) return '';
if (typeof bytes === 'string') return bytes;
// Node:
if (typeof Buffer !== 'undefined') {
if (bytes instanceof Buffer) {
return bytes.toString();
}
if (bytes instanceof Uint8Array) {
return 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 TextDecoder !== 'undefined') {
if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) {
this.textDecoder ??= new 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 && !this.trailingCR) {
return [];
}
const lines = [this.buffer.join('')];
this.buffer = [];
this.trailingCR = false;
return lines;
}
}
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, '', ''];
}
/**
* 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
*/
function readableStreamAsyncIterable<T>(stream: any): AsyncIterableIterator<T> {
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;
},
};
}

11
node_modules/@anthropic-ai/sdk/src/tsconfig.json generated vendored Normal file
View File

@@ -0,0 +1,11 @@
{
// this config is included in the published src directory to prevent TS errors
// from appearing when users go to source, and VSCode opens the source .ts file
// via declaration maps
"include": ["index.ts"],
"compilerOptions": {
"target": "es2015",
"lib": ["DOM"],
"moduleResolution": "node"
}
}

246
node_modules/@anthropic-ai/sdk/src/uploads.ts generated vendored Normal file
View File

@@ -0,0 +1,246 @@
import { type RequestOptions } from './core';
import {
FormData,
File,
type Blob,
type FilePropertyBag,
getMultipartRequestOptions,
type FsReadStream,
isFsReadStream,
} from './_shims/index';
import { MultipartBody } from './_shims/MultipartBody';
export { fileFromPath } from './_shims/index';
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 | FsReadStream;
/**
* Intended to match web.Blob, node.Blob, node-fetch.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<string>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */
slice(start?: number, end?: number): BlobLike;
// unfortunately @types/node-fetch@^2.6.4 doesn't type the arrayBuffer method
}
/**
* Intended to match web.File, node.File, node-fetch.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;
}
/**
* Intended to match web.Response, node.Response, node-fetch.Response, etc.
*/
export interface ResponseLike {
url: string;
blob(): Promise<BlobLike>;
}
export const isResponseLike = (value: any): value is ResponseLike =>
value != null &&
typeof value === 'object' &&
typeof value.url === 'string' &&
typeof value.blob === 'function';
export const isFileLike = (value: any): value is FileLike =>
value != null &&
typeof value === 'object' &&
typeof value.name === 'string' &&
typeof value.lastModified === 'number' &&
isBlobLike(value);
/**
* The BlobLike type omits arrayBuffer() because @types/node-fetch@^2.6.4 lacks it; but 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<ArrayBuffer> } =>
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';
export const isUploadable = (value: any): value is Uploadable => {
return isFileLike(value) || isResponseLike(value) || isFsReadStream(value);
};
export type ToFileInput = Uploadable | Exclude<BlobLikePart, string> | AsyncIterable<BlobLikePart>;
/**
* 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<ToFileInput>,
name?: string | null | undefined,
options: FilePropertyBag | undefined = {},
): Promise<FileLike> {
// If it's a promise, resolve it.
value = await value;
if (isResponseLike(value)) {
const blob = await value.blob();
name ||= new URL(value.url).pathname.split(/[\\/]/).pop() ?? 'unknown_file';
return new File([blob as any], 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 new File(bits, name, options);
}
async function getBytes(value: ToFileInput): Promise<Array<BlobPart>> {
let parts: Array<BlobPart> = [];
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<unknown> =>
value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function';
export const isMultipartBody = (body: any): body is MultipartBody =>
body && typeof body === 'object' && body.body && body[Symbol.toStringTag] === 'MultipartBody';
/**
* 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 <T extends {} = Record<string, unknown>>(
opts: RequestOptions<T>,
): Promise<RequestOptions<T | MultipartBody>> => {
if (!hasUploadableValue(opts.body)) return opts;
const form = await createForm(opts.body);
return getMultipartRequestOptions(form, opts);
};
export const multipartFormRequestOptions = async <T extends {} = Record<string, unknown>>(
opts: RequestOptions<T>,
): Promise<RequestOptions<T | MultipartBody>> => {
const form = await createForm(opts.body);
return getMultipartRequestOptions(form, opts);
};
export const createForm = async <T = Record<string, unknown>>(body: T | undefined): Promise<FormData> => {
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<void> => {
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 File);
} 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`,
);
}
};

1
node_modules/@anthropic-ai/sdk/src/version.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export const VERSION = '0.8.1'; // x-release-please-version