UNPKG

simple-ai-provider

Version:

A simple and extensible AI provider package for easy integration of multiple AI services

1,472 lines (1,431 loc) 418 kB
var __defProp = Object.defineProperty; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __hasOwnProp = Object.prototype.hasOwnProperty; var __moduleCache = /* @__PURE__ */ new WeakMap; var __toCommonJS = (from) => { var entry = __moduleCache.get(from), desc; if (entry) return entry; entry = __defProp({}, "__esModule", { value: true }); if (from && typeof from === "object" || typeof from === "function") __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable })); __moduleCache.set(from, entry); return entry; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true, configurable: true, set: (newValue) => all[name] = () => newValue }); }; // src/index.ts var exports_src = {}; __export(exports_src, { createProvider: () => createProvider, createOpenWebUIProvider: () => createOpenWebUIProvider, createOpenAIProvider: () => createOpenAIProvider, createGeminiProvider: () => createGeminiProvider, createClaudeProvider: () => createClaudeProvider, VERSION: () => VERSION3, SUPPORTED_PROVIDERS: () => SUPPORTED_PROVIDERS, PROVIDER_REGISTRY: () => PROVIDER_REGISTRY, OpenWebUIProvider: () => OpenWebUIProvider, OpenAIProvider: () => OpenAIProvider, GeminiProvider: () => GeminiProvider, ClaudeProvider: () => ClaudeProvider, BaseAIProvider: () => BaseAIProvider, AIProviderError: () => AIProviderError, AIErrorType: () => AIErrorType }); module.exports = __toCommonJS(exports_src); // src/types/index.ts var AIErrorType; ((AIErrorType2) => { AIErrorType2["AUTHENTICATION"] = "authentication"; AIErrorType2["RATE_LIMIT"] = "rate_limit"; AIErrorType2["INVALID_REQUEST"] = "invalid_request"; AIErrorType2["MODEL_NOT_FOUND"] = "model_not_found"; AIErrorType2["NETWORK"] = "network"; AIErrorType2["TIMEOUT"] = "timeout"; AIErrorType2["UNKNOWN"] = "unknown"; })(AIErrorType ||= {}); class AIProviderError extends Error { type; statusCode; originalError; constructor(message, type, statusCode, originalError) { super(message); this.type = type; this.statusCode = statusCode; this.originalError = originalError; this.name = "AIProviderError"; } } // src/providers/base.ts class BaseAIProvider { config; initialized = false; constructor(config) { this.config = this.validateAndNormalizeConfig(config); } async initialize() { try { await this.doInitialize(); this.initialized = true; } catch (error) { throw this.normalizeError(error); } } isInitialized() { return this.initialized; } async complete(params) { this.ensureInitialized(); this.validateCompletionParams(params); try { return await this.doComplete(params); } catch (error) { throw this.normalizeError(error); } } async* stream(params) { this.ensureInitialized(); this.validateCompletionParams(params); try { yield* this.doStream(params); } catch (error) { throw this.normalizeError(error); } } validateAndNormalizeConfig(config) { if (!config) { throw new AIProviderError("Configuration object is required", "invalid_request" /* INVALID_REQUEST */); } if (!config.apiKey || typeof config.apiKey !== "string" || config.apiKey.trim() === "") { throw new AIProviderError("API key is required and must be a non-empty string", "invalid_request" /* INVALID_REQUEST */); } return { ...config, timeout: this.validateTimeout(config.timeout), maxRetries: this.validateMaxRetries(config.maxRetries) }; } validateTimeout(timeout) { const defaultTimeout = 30000; if (timeout === undefined) { return defaultTimeout; } if (typeof timeout !== "number" || timeout < 1000 || timeout > 300000) { throw new AIProviderError("Timeout must be a number between 1000ms (1s) and 300000ms (5min)", "invalid_request" /* INVALID_REQUEST */); } return timeout; } validateMaxRetries(maxRetries) { const defaultMaxRetries = 3; if (maxRetries === undefined) { return defaultMaxRetries; } if (typeof maxRetries !== "number" || maxRetries < 0 || maxRetries > 10) { throw new AIProviderError("Max retries must be a number between 0 and 10", "invalid_request" /* INVALID_REQUEST */); } return maxRetries; } ensureInitialized() { if (!this.initialized) { throw new AIProviderError("Provider must be initialized before use. Call initialize() first.", "invalid_request" /* INVALID_REQUEST */); } } validateCompletionParams(params) { if (!params || typeof params !== "object") { throw new AIProviderError("Completion parameters object is required", "invalid_request" /* INVALID_REQUEST */); } this.validateMessages(params.messages); this.validateTemperature(params.temperature); this.validateTopP(params.topP); this.validateMaxTokens(params.maxTokens); this.validateStopSequences(params.stopSequences); } validateMessages(messages) { if (!Array.isArray(messages) || messages.length === 0) { throw new AIProviderError("Messages must be a non-empty array", "invalid_request" /* INVALID_REQUEST */); } const validRoles = ["system", "user", "assistant"]; for (let i = 0;i < messages.length; i++) { const message = messages[i]; if (!message || typeof message !== "object") { throw new AIProviderError(`Message at index ${i} must be an object`, "invalid_request" /* INVALID_REQUEST */); } if (!validRoles.includes(message.role)) { throw new AIProviderError(`Message at index ${i} has invalid role '${message.role}'. Must be: ${validRoles.join(", ")}`, "invalid_request" /* INVALID_REQUEST */); } if (typeof message.content !== "string" || message.content.trim() === "") { throw new AIProviderError(`Message at index ${i} must have non-empty string content`, "invalid_request" /* INVALID_REQUEST */); } } } validateTemperature(temperature) { if (temperature !== undefined) { if (typeof temperature !== "number" || temperature < 0 || temperature > 1) { throw new AIProviderError("Temperature must be a number between 0.0 and 1.0", "invalid_request" /* INVALID_REQUEST */); } } } validateTopP(topP) { if (topP !== undefined) { if (typeof topP !== "number" || topP <= 0 || topP > 1) { throw new AIProviderError("Top-p must be a number between 0.0 (exclusive) and 1.0 (inclusive)", "invalid_request" /* INVALID_REQUEST */); } } } validateMaxTokens(maxTokens) { if (maxTokens !== undefined) { if (typeof maxTokens !== "number" || !Number.isInteger(maxTokens) || maxTokens < 1) { throw new AIProviderError("Max tokens must be a positive integer", "invalid_request" /* INVALID_REQUEST */); } } } validateStopSequences(stopSequences) { if (stopSequences !== undefined) { if (!Array.isArray(stopSequences)) { throw new AIProviderError("Stop sequences must be an array of strings", "invalid_request" /* INVALID_REQUEST */); } for (let i = 0;i < stopSequences.length; i++) { if (typeof stopSequences[i] !== "string") { throw new AIProviderError(`Stop sequence at index ${i} must be a string`, "invalid_request" /* INVALID_REQUEST */); } } } } normalizeError(error) { if (error instanceof AIProviderError) { return error; } const status = error.status || error.statusCode; const message = error.message || "Unknown error occurred"; if (status) { switch (status) { case 400: return new AIProviderError(`Bad request: ${message}`, "invalid_request" /* INVALID_REQUEST */, status, error); case 401: case 403: return new AIProviderError("Authentication failed. Please verify your API key is correct and has the necessary permissions.", "authentication" /* AUTHENTICATION */, status, error); case 404: return new AIProviderError("The specified model or endpoint was not found. Please check the model name and availability.", "model_not_found" /* MODEL_NOT_FOUND */, status, error); case 429: return new AIProviderError("Rate limit exceeded. Please reduce your request frequency and try again later.", "rate_limit" /* RATE_LIMIT */, status, error); case 500: case 502: case 503: case 504: return new AIProviderError("Service temporarily unavailable. Please try again in a few moments.", "network" /* NETWORK */, status, error); } } if (message.includes("timeout") || message.includes("ETIMEDOUT")) { return new AIProviderError("Request timed out. The operation took longer than expected.", "timeout" /* TIMEOUT */, undefined, error); } if (message.includes("network") || message.includes("ENOTFOUND") || message.includes("ECONNREFUSED")) { return new AIProviderError("Network error occurred. Please check your internet connection and try again.", "network" /* NETWORK */, undefined, error); } return new AIProviderError(`Provider error: ${message}`, "unknown" /* UNKNOWN */, status, error); } } // node_modules/@anthropic-ai/sdk/internal/tslib.mjs function __classPrivateFieldSet(receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; } function __classPrivateFieldGet(receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } // node_modules/@anthropic-ai/sdk/internal/utils/uuid.mjs var uuid4 = function() { const { crypto } = globalThis; 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() * 255 & 255; return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => (+c ^ randomByte() & 15 >> +c / 4).toString(16)); }; // node_modules/@anthropic-ai/sdk/internal/errors.mjs function isAbortError(err) { return typeof err === "object" && err !== null && (("name" in err) && err.name === "AbortError" || ("message" in err) && String(err.message).includes("FetchRequestCanceledException")); } var castToError = (err) => { if (err instanceof Error) return err; if (typeof err === "object" && err !== null) { try { if (Object.prototype.toString.call(err) === "[object Error]") { const error = new Error(err.message, err.cause ? { cause: err.cause } : {}); if (err.stack) error.stack = err.stack; if (err.cause && !error.cause) error.cause = err.cause; if (err.name) error.name = err.name; return error; } } catch {} try { return new Error(JSON.stringify(err)); } catch {} } return new Error(err); }; // node_modules/@anthropic-ai/sdk/core/error.mjs class AnthropicError extends Error { } class APIError extends AnthropicError { constructor(status, error, message, headers) { super(`${APIError.makeMessage(status, error, message)}`); this.status = status; this.headers = headers; this.requestID = headers?.get("request-id"); this.error = error; } static makeMessage(status, error, message) { 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, errorResponse, message, headers) { if (!status || !headers) { return new APIConnectionError({ message, cause: castToError(errorResponse) }); } const error = errorResponse; 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); } } class APIUserAbortError extends APIError { constructor({ message } = {}) { super(undefined, undefined, message || "Request was aborted.", undefined); } } class APIConnectionError extends APIError { constructor({ message, cause }) { super(undefined, undefined, message || "Connection error.", undefined); if (cause) this.cause = cause; } } class APIConnectionTimeoutError extends APIConnectionError { constructor({ message } = {}) { super({ message: message ?? "Request timed out." }); } } class BadRequestError extends APIError { } class AuthenticationError extends APIError { } class PermissionDeniedError extends APIError { } class NotFoundError extends APIError { } class ConflictError extends APIError { } class UnprocessableEntityError extends APIError { } class RateLimitError extends APIError { } class InternalServerError extends APIError { } // node_modules/@anthropic-ai/sdk/internal/utils/values.mjs var startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i; var isAbsoluteURL = (url) => { return startsWithSchemeRegexp.test(url); }; function maybeObj(x) { if (typeof x !== "object") { return {}; } return x ?? {}; } function isEmptyObj(obj) { if (!obj) return true; for (const _k in obj) return false; return true; } function hasOwn(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } var validatePositiveInteger = (name, n) => { if (typeof n !== "number" || !Number.isInteger(n)) { throw new AnthropicError(`${name} must be an integer`); } if (n < 0) { throw new AnthropicError(`${name} must be a positive integer`); } return n; }; var safeJSON = (text) => { try { return JSON.parse(text); } catch (err) { return; } }; // node_modules/@anthropic-ai/sdk/internal/utils/sleep.mjs var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // node_modules/@anthropic-ai/sdk/internal/utils/log.mjs var levelNumbers = { off: 0, error: 200, warn: 300, info: 400, debug: 500 }; var parseLogLevel = (maybeLevel, sourceName, client) => { if (!maybeLevel) { return; } 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; }; function noop() {} function makeLogFn(fnLevel, logger, logLevel) { if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) { return noop; } else { return logger[fnLevel].bind(logger); } } var noopLogger = { error: noop, warn: noop, info: noop, debug: noop }; var cachedLoggers = new WeakMap; function loggerFor(client) { const logger = client.logger; const logLevel = client.logLevel ?? "off"; if (!logger) { return noopLogger; } const cachedLogger = cachedLoggers.get(logger); if (cachedLogger && cachedLogger[0] === logLevel) { return cachedLogger[1]; } const levelLogger = { error: makeLogFn("error", logger, logLevel), warn: makeLogFn("warn", logger, logLevel), info: makeLogFn("info", logger, logLevel), debug: makeLogFn("debug", logger, logLevel) }; cachedLoggers.set(logger, [logLevel, levelLogger]); return levelLogger; } var formatRequestDetails = (details) => { if (details.options) { details.options = { ...details.options }; delete details.options["headers"]; } 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; }; // node_modules/@anthropic-ai/sdk/version.mjs var VERSION = "0.52.0"; // node_modules/@anthropic-ai/sdk/internal/detect-platform.mjs var isRunningInBrowser = () => { return typeof window !== "undefined" && typeof window.document !== "undefined" && typeof navigator !== "undefined"; }; function getDetectedPlatform() { if (typeof Deno !== "undefined" && Deno.build != null) { return "deno"; } if (typeof EdgeRuntime !== "undefined") { return "edge"; } if (Object.prototype.toString.call(typeof globalThis.process !== "undefined" ? globalThis.process : 0) === "[object process]") { return "node"; } return "unknown"; } var getPlatformProperties = () => { const detectedPlatform = getDetectedPlatform(); if (detectedPlatform === "deno") { return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": normalizePlatform(Deno.build.os), "X-Stainless-Arch": normalizeArch(Deno.build.arch), "X-Stainless-Runtime": "deno", "X-Stainless-Runtime-Version": typeof Deno.version === "string" ? Deno.version : Deno.version?.deno ?? "unknown" }; } if (typeof EdgeRuntime !== "undefined") { return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": "Unknown", "X-Stainless-Arch": `other:${EdgeRuntime}`, "X-Stainless-Runtime": "edge", "X-Stainless-Runtime-Version": globalThis.process.version }; } if (detectedPlatform === "node") { return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": normalizePlatform(globalThis.process.platform), "X-Stainless-Arch": normalizeArch(globalThis.process.arch), "X-Stainless-Runtime": "node", "X-Stainless-Runtime-Version": globalThis.process.version }; } const browserInfo = getBrowserInfo(); if (browserInfo) { return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": "Unknown", "X-Stainless-Arch": "unknown", "X-Stainless-Runtime": `browser:${browserInfo.browser}`, "X-Stainless-Runtime-Version": browserInfo.version }; } return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": "Unknown", "X-Stainless-Arch": "unknown", "X-Stainless-Runtime": "unknown", "X-Stainless-Runtime-Version": "unknown" }; }; function getBrowserInfo() { if (typeof navigator === "undefined" || !navigator) { return null; } const browserPatterns = [ { key: "edge", pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "ie", pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "ie", pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "chrome", pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "firefox", pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "safari", pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ } ]; for (const { key, pattern } of browserPatterns) { const match = pattern.exec(navigator.userAgent); if (match) { const major = match[1] || 0; const minor = match[2] || 0; const patch = match[3] || 0; return { browser: key, version: `${major}.${minor}.${patch}` }; } } return null; } var normalizeArch = (arch) => { if (arch === "x32") return "x32"; if (arch === "x86_64" || arch === "x64") return "x64"; if (arch === "arm") return "arm"; if (arch === "aarch64" || arch === "arm64") return "arm64"; if (arch) return `other:${arch}`; return "unknown"; }; var normalizePlatform = (platform) => { platform = platform.toLowerCase(); if (platform.includes("ios")) return "iOS"; if (platform === "android") return "Android"; if (platform === "darwin") return "MacOS"; if (platform === "win32") return "Windows"; if (platform === "freebsd") return "FreeBSD"; if (platform === "openbsd") return "OpenBSD"; if (platform === "linux") return "Linux"; if (platform) return `Other:${platform}`; return "Unknown"; }; var _platformHeaders; var getPlatformHeaders = () => { return _platformHeaders ?? (_platformHeaders = getPlatformProperties()); }; // node_modules/@anthropic-ai/sdk/internal/shims.mjs function getDefaultFetch() { if (typeof fetch !== "undefined") { return fetch; } throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new Anthropic({ fetch })` or polyfill the global, `globalThis.fetch = fetch`"); } function makeReadableStream(...args) { const ReadableStream2 = globalThis.ReadableStream; if (typeof ReadableStream2 === "undefined") { throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`"); } return new ReadableStream2(...args); } function ReadableStreamFrom(iterable) { let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator](); return makeReadableStream({ start() {}, async pull(controller) { const { done, value } = await iter.next(); if (done) { controller.close(); } else { controller.enqueue(value); } }, async cancel() { await iter.return?.(); } }); } function ReadableStreamToAsyncIterable(stream) { if (stream[Symbol.asyncIterator]) return stream; const reader = stream.getReader(); return { async next() { try { const result = await reader.read(); if (result?.done) reader.releaseLock(); return result; } catch (e) { reader.releaseLock(); throw e; } }, async return() { const cancelPromise = reader.cancel(); reader.releaseLock(); await cancelPromise; return { done: true, value: undefined }; }, [Symbol.asyncIterator]() { return this; } }; } async function CancelReadableStream(stream) { 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; } // node_modules/@anthropic-ai/sdk/internal/request-options.mjs var FallbackEncoder = ({ headers, body }) => { return { bodyHeaders: { "content-type": "application/json" }, body: JSON.stringify(body) }; }; // node_modules/@anthropic-ai/sdk/internal/utils/bytes.mjs function concatBytes(buffers) { 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; } var encodeUTF8_; function encodeUTF8(str) { let encoder; return (encodeUTF8_ ?? (encoder = new globalThis.TextEncoder, encodeUTF8_ = encoder.encode.bind(encoder)))(str); } var decodeUTF8_; function decodeUTF8(bytes) { let decoder; return (decodeUTF8_ ?? (decoder = new globalThis.TextDecoder, decodeUTF8_ = decoder.decode.bind(decoder)))(bytes); } // node_modules/@anthropic-ai/sdk/internal/decoders/line.mjs var _LineDecoder_buffer; var _LineDecoder_carriageReturnIndex; class LineDecoder { constructor() { _LineDecoder_buffer.set(this, undefined); _LineDecoder_carriageReturnIndex.set(this, undefined); __classPrivateFieldSet(this, _LineDecoder_buffer, new Uint8Array, "f"); __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f"); } decode(chunk) { if (chunk == null) { return []; } const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) : typeof chunk === "string" ? encodeUTF8(chunk) : chunk; __classPrivateFieldSet(this, _LineDecoder_buffer, concatBytes([__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), binaryChunk]), "f"); const lines = []; let patternIndex; while ((patternIndex = findNewlineIndex(__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"))) != null) { if (patternIndex.carriage && __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") == null) { __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, patternIndex.index, "f"); continue; } if (__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") != null && (patternIndex.index !== __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") + 1 || patternIndex.carriage)) { lines.push(decodeUTF8(__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") - 1))); __classPrivateFieldSet(this, _LineDecoder_buffer, __classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f")), "f"); __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f"); continue; } const endIndex = __classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") !== null ? patternIndex.preceding - 1 : patternIndex.preceding; const line = decodeUTF8(__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, endIndex)); lines.push(line); __classPrivateFieldSet(this, _LineDecoder_buffer, __classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(patternIndex.index), "f"); __classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f"); } return lines; } flush() { if (!__classPrivateFieldGet(this, _LineDecoder_buffer, "f").length) { return []; } return this.decode(` `); } } _LineDecoder_buffer = new WeakMap, _LineDecoder_carriageReturnIndex = new WeakMap; LineDecoder.NEWLINE_CHARS = new Set([` `, "\r"]); LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g; function findNewlineIndex(buffer, startIndex) { const newline = 10; const carriage = 13; 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; } function findDoubleNewlineIndex(buffer) { const newline = 10; const carriage = 13; for (let i = 0;i < buffer.length - 1; i++) { if (buffer[i] === newline && buffer[i + 1] === newline) { return i + 2; } if (buffer[i] === carriage && buffer[i + 1] === carriage) { return i + 2; } if (buffer[i] === carriage && buffer[i + 1] === newline && i + 3 < buffer.length && buffer[i + 2] === carriage && buffer[i + 3] === newline) { return i + 4; } } return -1; } // node_modules/@anthropic-ai/sdk/core/streaming.mjs class Stream { constructor(iterator, controller) { this.iterator = iterator; this.controller = controller; } static fromSSEResponse(response, controller) { let consumed = false; async function* iterator() { 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 (isAbortError(e)) return; throw e; } finally { if (!done) controller.abort(); } } return new Stream(iterator, controller); } static fromReadableStream(readableStream, controller) { let consumed = false; async function* iterLines() { 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() { 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 (isAbortError(e)) return; throw e; } finally { if (!done) controller.abort(); } } return new Stream(iterator, controller); } [Symbol.asyncIterator]() { return this.iterator(); } tee() { const left = []; const right = []; const iterator = this.iterator(); const teeIterator = (queue) => { 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) ]; } toReadableStream() { const self = this; let iter; return makeReadableStream({ async start() { iter = self[Symbol.asyncIterator](); }, async pull(ctrl) { try { const { value, done } = await iter.next(); if (done) return ctrl.close(); const bytes = encodeUTF8(JSON.stringify(value) + ` `); ctrl.enqueue(bytes); } catch (err) { ctrl.error(err); } }, async cancel() { await iter.return?.(); } }); } } async function* _iterSSEMessages(response, controller) { if (!response.body) { controller.abort(); if (typeof globalThis.navigator !== "undefined" && globalThis.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; } } async function* iterSSEChunks(iterator) { 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" ? encodeUTF8(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 { constructor() { this.event = null; this.data = []; this.chunks = []; } decode(line) { if (line.endsWith("\r")) { line = line.substring(0, line.length - 1); } if (!line) { if (!this.event && !this.data.length) return null; const sse = { event: this.event, data: this.data.join(` `), 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, delimiter) { const index = str.indexOf(delimiter); if (index !== -1) { return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)]; } return [str, "", ""]; } // node_modules/@anthropic-ai/sdk/internal/parse.mjs async function defaultParseResponse(client, props) { 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); } return Stream.fromSSEResponse(response, props.controller); } if (response.status === 204) { return null; } if (props.options.__binaryResponse) { return response; } const contentType = response.headers.get("content-type"); 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, response); } const text = await response.text(); return text; })(); loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({ retryOfRequestLogID, url: response.url, status: response.status, body, durationMs: Date.now() - startTime })); return body; } function addRequestID(value, response) { if (!value || typeof value !== "object" || Array.isArray(value)) { return value; } return Object.defineProperty(value, "_request_id", { value: response.headers.get("request-id"), enumerable: false }); } // node_modules/@anthropic-ai/sdk/core/api-promise.mjs var _APIPromise_client; class APIPromise extends Promise { constructor(client, responsePromise, parseResponse = defaultParseResponse) { super((resolve) => { resolve(null); }); this.responsePromise = responsePromise; this.parseResponse = parseResponse; _APIPromise_client.set(this, undefined); __classPrivateFieldSet(this, _APIPromise_client, client, "f"); } _thenUnwrap(transform) { return new APIPromise(__classPrivateFieldGet(this, _APIPromise_client, "f"), this.responsePromise, async (client, props) => addRequestID(transform(await this.parseResponse(client, props), props), props.response)); } asResponse() { return this.responsePromise.then((p) => p.response); } async withResponse() { const [data, response] = await Promise.all([this.parse(), this.asResponse()]); return { data, response, request_id: response.headers.get("request-id") }; } parse() { if (!this.parsedPromise) { this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(__classPrivateFieldGet(this, _APIPromise_client, "f"), data)); } return this.parsedPromise; } then(onfulfilled, onrejected) { return this.parse().then(onfulfilled, onrejected); } catch(onrejected) { return this.parse().catch(onrejected); } finally(onfinally) { return this.parse().finally(onfinally); } } _APIPromise_client = new WeakMap; // node_modules/@anthropic-ai/sdk/core/pagination.mjs var _AbstractPage_client; class AbstractPage { constructor(client, response, body, options) { _AbstractPage_client.set(this, undefined); __classPrivateFieldSet(this, _AbstractPage_client, client, "f"); this.options = options; this.response = response; this.body = body; } hasNextPage() { const items = this.getPaginatedItems(); if (!items.length) return false; return this.nextPageRequestOptions() != null; } async getNextPage() { const nextOptions = this.nextPageRequestOptions(); if (!nextOptions) { throw new AnthropicError("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`."); } return await __classPrivateFieldGet(this, _AbstractPage_client, "f").requestAPIList(this.constructor, nextOptions); } async* iterPages() { let page = this; yield page; while (page.hasNextPage()) { page = await page.getNextPage(); yield page; } } async* [(_AbstractPage_client = new WeakMap, Symbol.asyncIterator)]() { for await (const page of this.iterPages()) { for (const item of page.getPaginatedItems()) { yield item; } } } } class PagePromise extends APIPromise { constructor(client, request, Page) { super(client, request, async (client2, props) => new Page(client2, props.response, await defaultParseResponse(client2, props), props.options)); } async* [Symbol.asyncIterator]() { const page = await this; for await (const item of page) { yield item; } } } class Page extends AbstractPage { constructor(client, response, body, options) { 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() { return this.data ?? []; } hasNextPage() { if (this.has_more === false) { return false; } return super.hasNextPage(); } nextPageRequestOptions() { if (this.options.query?.["before_id"]) { 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 } }; } } // node_modules/@anthropic-ai/sdk/internal/uploads.mjs var checkFileSupport = () => { if (typeof File === "undefined") { const { process: process2 } = globalThis; const isOldNode = typeof process2?.versions?.node === "string" && parseInt(process2.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`." : "")); } }; function makeFile(fileBits, fileName, options) { checkFileSupport(); return new File(fileBits, fileName ?? "unknown_file", options); } function getName(value) { return (typeof value === "object" && value !== null && (("name" in value) && value.name && String(value.name) || ("url" in value) && value.url && String(value.url) || ("filename" in value) && value.filename && String(value.filename) || ("path" in value) && value.path && String(value.path)) || "").split(/[\\/]/).pop() || undefined; } var isAsyncIterable = (value) => value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function"; var multipartFormRequestOptions = async (opts, fetch2) => { return { ...opts, body: await createForm(opts.body, fetch2) }; }; var supportsFormDataMap = new WeakMap; function supportsFormData(fetchObject) { const fetch2 = typeof fetchObject === "function" ? fetchObject : fetchObject.fetch; const cached = supportsFormDataMap.get(fetch2); if (cached) return cached; const promise = (async () => { try { const FetchResponse = "Response" in fetch2 ? fetch2.Response : (await fetch2("data:,")).constructor; const data = new FormData; if (data.toString() === await new FetchResponse(data).text()) { return false; } return true; } catch { return true; } })(); supportsFormDataMap.set(fetch2, promise); return promise; } var createForm = async (body, fetch2) => { if (!await supportsFormData(fetch2)) { 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; }; var isNamedBlob = (value) => value instanceof Blob && ("name" in value); var addFormValue = async (form, key, value) => { 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'`); } if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { form.append(key, String(value)); } else if (value instanceof Response) { let options = {}; const contentType = value.headers.get("Content-Type"); if (contentType) { options = { type: contentType }; } form.append(key, makeFile([await value.blob()], getName(value), options)); } else if (isAsyncIterable(value)) { form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value))); } else if (isNamedBlob(value)) { form.append(key, makeFile([value], getName(value), { type: value.type })); } 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`); } }; // node_modules/@anthropic-ai/sdk/internal/to-file.mjs var isBlobLike = (value) => 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"; var isFileLike = (value) => value != null && typeof value === "object" && typeof value.name === "string" && typeof value.lastModified === "number" && isBlobLike(value); var isResponseLike = (value) => value != null && typeof value === "object" && typeof value.url === "string" && typeof value.blob === "function"; async function toFile(value, name, options) { checkFileSupport(); value = await value; name || (name = getName(value)); if (isFileLike(value)) { if (value instanceof File && name == null && options == null) { return value; } return makeFile([await value.arrayBuffer()], name ?? value.name, { type: value.type, lastModified: value.lastModified, ...options }); } if (isResponseLike(value)) { const blob = await value.blob(); name || (name = new URL(value.url).pathname.split(/[\\/]/).pop()); return makeFile(await getBytes(blob), name, options); } const parts = await getBytes(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) { let parts = []; if (typeof value === "string" || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) { parts.push(value); } else if (isBlobLike(value)) { parts.push(value instanceof Blob ? value : await value.arrayBuffer()); } else if (isAsyncIterable(value)) { for await (const chunk of value) { parts.push(...await getBytes(chunk)); } } else { const constructor = value?.constructor?.name; throw new Error(`Unexpected data type: ${typeof value}${constructor ? `; constructor: ${constructor}` : ""}${propsForError(value)}`); } return parts; } function propsForError(value) { if (typeof value !== "object" || value === null) return ""; const props = Object.getOwnPropertyNames(value); return `; props: [${props.map((p) => `"${p}"`).join(", ")}]`; } // node_modules/@anthropic-ai/sdk/core/resource.mjs class APIResource { constructor(client) { this._client = client; } } // node_modules/@anthropic-ai/sdk/internal/headers.mjs var brand_privateNullableHeaders = Symbol.for("brand.privateNullableHeaders"); var isArray = Array.isArray; function* iterateHeaders(headers) { if (!headers) return; if (brand_privateNullableHeaders in headers) { const { values, nulls } = headers; yield* values.entries(); for (const name of nulls) { yield [name, null]; } return; } let shouldClear = false; let iter; if (headers instanceof Headers) { iter = headers.entries(); } else if (isArray(headers)) { iter = headers; } else { shouldClear = true; iter = Object.entries(headers ?? {}); } for (let row of iter) { const name = row[0]; if (typeof name !== "string") throw new TypeError("expected header name to be a string"); const values = isArray(row[1]) ? row[1] : [row[1]]; let didClear = false; for (const value of values) { if (value === undefined) continue; if (shouldClear && !didClear) { didClear = true; yield [name, null]; } yield [name, value]; } } } var buildHeaders = (newHeaders) => { const targetHeaders = new Headers; const nullHeaders = new Set; for (const headers of newHeaders) { const seenHeaders = new Set; for (const [name, value] of iterateHeaders(headers)) { const lowerName = name.toLowerCase(); if (!seenHeaders.has(lowerName)) { targetHeaders.delete(name); seenHeaders.add(lowerName); } if (value === null) { targetHeaders.delete(name); nullHeaders.add(lowerName); } else { targetHeaders.append(name, value); nullHeaders.delete(lowerName); } } } return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders }; }; // node_modules/@anthropic-ai/sdk/internal/utils/path.mjs function encodeURIPath(str) { return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent); } var createPathTagFunction = (pathEncoder = encodeURIPath) => function path(statics, ...params) { 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; while ((match = invalidSegmentPattern.ex