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
JavaScript
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