@providerprotocol/ai 0.0.29 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/anthropic/index.d.ts +12 -1
  2. package/dist/anthropic/index.js +15 -10
  3. package/dist/anthropic/index.js.map +1 -1
  4. package/dist/{chunk-Z6DKC37J.js → chunk-3C7O2RNO.js} +2 -2
  5. package/dist/{chunk-55X3W2MN.js → chunk-3D6XGGVG.js} +9 -2
  6. package/dist/{chunk-55X3W2MN.js.map → chunk-3D6XGGVG.js.map} +1 -1
  7. package/dist/{chunk-QNJO7DSD.js → chunk-4J6OFUKX.js} +10 -1
  8. package/dist/chunk-4J6OFUKX.js.map +1 -0
  9. package/dist/{chunk-73IIE3QT.js → chunk-6S222DHN.js} +11 -1
  10. package/dist/chunk-6S222DHN.js.map +1 -0
  11. package/dist/{chunk-SBCATNHA.js → chunk-KUPF5KHT.js} +2 -2
  12. package/dist/{embedding-DtyOFIsS.d.ts → embedding-D2BYIehX.d.ts} +22 -2
  13. package/dist/google/index.d.ts +5 -1
  14. package/dist/google/index.js +22 -13
  15. package/dist/google/index.js.map +1 -1
  16. package/dist/http/index.d.ts +8 -3
  17. package/dist/http/index.js +9 -5
  18. package/dist/index.d.ts +118 -6
  19. package/dist/index.js +641 -86
  20. package/dist/index.js.map +1 -1
  21. package/dist/{llm-DgDEy9il.d.ts → llm-BQJZj3cD.d.ts} +277 -10
  22. package/dist/ollama/index.d.ts +1 -1
  23. package/dist/ollama/index.js +32 -21
  24. package/dist/ollama/index.js.map +1 -1
  25. package/dist/openai/index.d.ts +1 -1
  26. package/dist/openai/index.js +21 -15
  27. package/dist/openai/index.js.map +1 -1
  28. package/dist/openrouter/index.d.ts +2 -2
  29. package/dist/openrouter/index.js +19 -8
  30. package/dist/openrouter/index.js.map +1 -1
  31. package/dist/proxy/index.d.ts +2 -2
  32. package/dist/proxy/index.js +9 -6
  33. package/dist/proxy/index.js.map +1 -1
  34. package/dist/{retry-DXLQnTuU.d.ts → retry-8Ch-WWgX.d.ts} +16 -2
  35. package/dist/xai/index.d.ts +16 -36
  36. package/dist/xai/index.js +29 -19
  37. package/dist/xai/index.js.map +1 -1
  38. package/package.json +1 -1
  39. package/dist/chunk-73IIE3QT.js.map +0 -1
  40. package/dist/chunk-QNJO7DSD.js.map +0 -1
  41. /package/dist/{chunk-Z6DKC37J.js.map → chunk-3C7O2RNO.js.map} +0 -0
  42. /package/dist/{chunk-SBCATNHA.js.map → chunk-KUPF5KHT.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@providerprotocol/ai",
3
- "version": "0.0.29",
3
+ "version": "0.0.32",
4
4
  "description": "UPP: Unified Provider Protocol for AI inference",
5
5
  "license": "MIT",
6
6
  "homepage": "https://providerprotocol.org",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types/stream.ts"],"sourcesContent":["/**\n * @fileoverview Streaming types for real-time LLM responses.\n *\n * Defines the event types and interfaces for streaming LLM inference,\n * including text deltas, tool call deltas, and control events.\n *\n * @module types/stream\n */\n\nimport type { Turn } from './turn.ts';\n\n/**\n * Stream event type constants.\n *\n * Use these constants instead of raw strings for type-safe event handling:\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n * ```\n */\nexport const StreamEventType = {\n /** Incremental text output */\n TextDelta: 'text_delta',\n /** Incremental reasoning/thinking output */\n ReasoningDelta: 'reasoning_delta',\n /** Incremental image data */\n ImageDelta: 'image_delta',\n /** Incremental audio data */\n AudioDelta: 'audio_delta',\n /** Incremental video data */\n VideoDelta: 'video_delta',\n /** Incremental tool call data (arguments being streamed) */\n ToolCallDelta: 'tool_call_delta',\n /** Tool execution has started (may be emitted after completion in some implementations) */\n ToolExecutionStart: 'tool_execution_start',\n /** Tool execution has completed */\n ToolExecutionEnd: 'tool_execution_end',\n /** Beginning of a message */\n MessageStart: 'message_start',\n /** End of a message */\n MessageStop: 'message_stop',\n /** Beginning of a content block */\n ContentBlockStart: 'content_block_start',\n /** End of a content block */\n ContentBlockStop: 'content_block_stop',\n} as const;\n\n/**\n * Stream event type discriminator union.\n *\n * This type is derived from {@link StreamEventType} constants. Use `StreamEventType.TextDelta`\n * for constants or `type MyType = StreamEventType` for type annotations.\n */\nexport type StreamEventType = (typeof StreamEventType)[keyof typeof StreamEventType];\n\n/**\n * Event delta data payload.\n *\n * Contains the type-specific data for a streaming event.\n * Different fields are populated depending on the event type.\n */\nexport interface EventDelta {\n /** Incremental text content (for text_delta, reasoning_delta) */\n text?: string;\n\n /** Incremental binary data (for image_delta, audio_delta, video_delta) */\n data?: Uint8Array;\n\n /** Tool call identifier (for tool_call_delta, tool_execution_start/end) */\n toolCallId?: string;\n\n /** Tool name (for tool_call_delta, tool_execution_start/end) */\n toolName?: string;\n\n /** Incremental JSON arguments string (for tool_call_delta) */\n argumentsJson?: string;\n\n /** Tool execution result (for tool_execution_end) */\n result?: unknown;\n\n /** Whether tool execution resulted in an error (for tool_execution_end) */\n isError?: boolean;\n\n /** Timestamp in milliseconds (for tool_execution_start/end) */\n timestamp?: number;\n}\n\n/**\n * A single streaming event from the LLM.\n *\n * Events are emitted in order as the model generates output,\n * allowing for real-time display of responses.\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * } else if (event.type === StreamEventType.ToolCallDelta) {\n * console.log('Tool:', event.delta.toolName);\n * }\n * }\n * ```\n */\nexport interface StreamEvent {\n /** Event type discriminator */\n type: StreamEventType;\n\n /** Index of the content block this event belongs to */\n index: number;\n\n /** Event-specific data payload */\n delta: EventDelta;\n}\n\n/**\n * Stream result - an async iterable that also provides the final turn.\n *\n * Allows consuming streaming events while also awaiting the complete\n * Turn result after streaming finishes.\n *\n * @typeParam TData - Type of the structured output data\n *\n * @example\n * ```typescript\n * import { StreamEventType } from 'upp';\n *\n * const stream = instance.stream('Tell me a story');\n *\n * // Consume streaming events\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n *\n * // Get the complete turn after streaming\n * const turn = await stream.turn;\n * console.log('\\n\\nTokens used:', turn.usage.totalTokens);\n * ```\n */\nexport interface StreamResult<TData = unknown>\n extends AsyncIterable<StreamEvent> {\n /**\n * Promise that resolves to the complete Turn after streaming finishes.\n * Rejects if the stream is aborted or terminated early.\n */\n readonly turn: Promise<Turn<TData>>;\n\n /**\n * Aborts the stream, stopping further events and cancelling the request.\n * This will cause {@link StreamResult.turn} to reject.\n */\n abort(): void;\n}\n\n/**\n * Creates a StreamResult from an async generator and completion promise.\n *\n * @typeParam TData - Type of the structured output data\n * @param generator - Async generator that yields stream events\n * @param turnPromiseOrFactory - Promise or factory that resolves to the complete Turn\n * @param abortController - Controller for aborting the stream\n * @returns A StreamResult that can be iterated and awaited\n *\n * @example\n * ```typescript\n * const abortController = new AbortController();\n * const stream = createStreamResult(\n * eventGenerator(),\n * turnPromise,\n * abortController\n * );\n * ```\n */\nexport function createStreamResult<TData = unknown>(\n generator: AsyncGenerator<StreamEvent, void, unknown>,\n turnPromiseOrFactory: Promise<Turn<TData>> | (() => Promise<Turn<TData>>),\n abortController: AbortController\n): StreamResult<TData> {\n let cachedTurn: Promise<Turn<TData>> | null = null;\n\n const getTurn = (): Promise<Turn<TData>> => {\n // Lazily build the turn promise to avoid work (or rejections) when unused.\n if (typeof turnPromiseOrFactory === 'function') {\n if (!cachedTurn) {\n cachedTurn = turnPromiseOrFactory();\n }\n return cachedTurn;\n }\n\n return turnPromiseOrFactory;\n };\n\n return {\n [Symbol.asyncIterator]() {\n return generator;\n },\n get turn() {\n return getTurn();\n },\n abort() {\n abortController.abort();\n },\n };\n}\n\n/**\n * Creates a text delta stream event.\n *\n * @param text - The incremental text content\n * @param index - Content block index (default: 0)\n * @returns A text_delta StreamEvent\n */\nexport function textDelta(text: string, index = 0): StreamEvent {\n return {\n type: StreamEventType.TextDelta,\n index,\n delta: { text },\n };\n}\n\n/**\n * Creates a tool call delta stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being called\n * @param argumentsJson - Incremental JSON arguments string\n * @param index - Content block index (default: 0)\n * @returns A tool_call_delta StreamEvent\n */\nexport function toolCallDelta(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolCallDelta,\n index,\n delta: { toolCallId, toolName, argumentsJson },\n };\n}\n\n/**\n * Creates a message start stream event.\n *\n * @returns A message_start StreamEvent\n */\nexport function messageStart(): StreamEvent {\n return {\n type: StreamEventType.MessageStart,\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a message stop stream event.\n *\n * @returns A message_stop StreamEvent\n */\nexport function messageStop(): StreamEvent {\n return {\n type: StreamEventType.MessageStop,\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a content block start stream event.\n *\n * @param index - The content block index starting\n * @returns A content_block_start StreamEvent\n */\nexport function contentBlockStart(index: number): StreamEvent {\n return {\n type: StreamEventType.ContentBlockStart,\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a content block stop stream event.\n *\n * @param index - The content block index stopping\n * @returns A content_block_stop StreamEvent\n */\nexport function contentBlockStop(index: number): StreamEvent {\n return {\n type: StreamEventType.ContentBlockStop,\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a tool execution start stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being executed\n * @param timestamp - Start timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_start StreamEvent\n */\nexport function toolExecutionStart(\n toolCallId: string,\n toolName: string,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolExecutionStart,\n index,\n delta: { toolCallId, toolName, timestamp },\n };\n}\n\n/**\n * Creates a tool execution end stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool that was executed\n * @param result - The result from the tool execution\n * @param isError - Whether the execution resulted in an error\n * @param timestamp - End timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_end StreamEvent\n */\nexport function toolExecutionEnd(\n toolCallId: string,\n toolName: string,\n result: unknown,\n isError: boolean,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: StreamEventType.ToolExecutionEnd,\n index,\n delta: { toolCallId, toolName, result, isError, timestamp },\n };\n}\n"],"mappings":";AA2BO,IAAM,kBAAkB;AAAA;AAAA,EAE7B,WAAW;AAAA;AAAA,EAEX,gBAAgB;AAAA;AAAA,EAEhB,YAAY;AAAA;AAAA,EAEZ,YAAY;AAAA;AAAA,EAEZ,YAAY;AAAA;AAAA,EAEZ,eAAe;AAAA;AAAA,EAEf,oBAAoB;AAAA;AAAA,EAEpB,kBAAkB;AAAA;AAAA,EAElB,cAAc;AAAA;AAAA,EAEd,aAAa;AAAA;AAAA,EAEb,mBAAmB;AAAA;AAAA,EAEnB,kBAAkB;AACpB;AAoIO,SAAS,mBACd,WACA,sBACA,iBACqB;AACrB,MAAI,aAA0C;AAE9C,QAAM,UAAU,MAA4B;AAE1C,QAAI,OAAO,yBAAyB,YAAY;AAC9C,UAAI,CAAC,YAAY;AACf,qBAAa,qBAAqB;AAAA,MACpC;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,CAAC,OAAO,aAAa,IAAI;AACvB,aAAO;AAAA,IACT;AAAA,IACA,IAAI,OAAO;AACT,aAAO,QAAQ;AAAA,IACjB;AAAA,IACA,QAAQ;AACN,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF;AACF;AASO,SAAS,UAAU,MAAc,QAAQ,GAAgB;AAC9D,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,KAAK;AAAA,EAChB;AACF;AAWO,SAAS,cACd,YACA,UACA,eACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,cAAc;AAAA,EAC/C;AACF;AAOO,SAAS,eAA4B;AAC1C,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB,OAAO;AAAA,IACP,OAAO,CAAC;AAAA,EACV;AACF;AAOO,SAAS,cAA2B;AACzC,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB,OAAO;AAAA,IACP,OAAO,CAAC;AAAA,EACV;AACF;AAQO,SAAS,kBAAkB,OAA4B;AAC5D,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,CAAC;AAAA,EACV;AACF;AAQO,SAAS,iBAAiB,OAA4B;AAC3D,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,CAAC;AAAA,EACV;AACF;AAWO,SAAS,mBACd,YACA,UACA,WACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,UAAU;AAAA,EAC3C;AACF;AAaO,SAAS,iBACd,YACA,UACA,QACA,SACA,WACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM,gBAAgB;AAAA,IACtB;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,QAAQ,SAAS,UAAU;AAAA,EAC5D;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types/errors.ts","../src/utils/error.ts","../src/http/errors.ts","../src/http/fetch.ts"],"sourcesContent":["/**\n * @fileoverview Error types for the Unified Provider Protocol.\n *\n * Provides normalized error codes and a unified error class for handling\n * errors across different AI providers in a consistent manner.\n *\n * @module types/errors\n */\n\n/**\n * Error code constants for cross-provider error handling.\n *\n * Use these constants instead of raw strings for type-safe error handling:\n *\n * @example\n * ```typescript\n * import { ErrorCode } from 'upp';\n *\n * try {\n * await llm.generate('Hello');\n * } catch (error) {\n * if (error instanceof UPPError) {\n * switch (error.code) {\n * case ErrorCode.RateLimited:\n * await delay(error.retryAfter);\n * break;\n * case ErrorCode.AuthenticationFailed:\n * throw new Error('Invalid API key');\n * }\n * }\n * }\n * ```\n */\nexport const ErrorCode = {\n /** API key is invalid or expired */\n AuthenticationFailed: 'AUTHENTICATION_FAILED',\n /** Rate limit exceeded, retry after delay */\n RateLimited: 'RATE_LIMITED',\n /** Input exceeds model's context window */\n ContextLengthExceeded: 'CONTEXT_LENGTH_EXCEEDED',\n /** Requested model does not exist */\n ModelNotFound: 'MODEL_NOT_FOUND',\n /** Request parameters are malformed */\n InvalidRequest: 'INVALID_REQUEST',\n /** Provider returned an unexpected response format */\n InvalidResponse: 'INVALID_RESPONSE',\n /** Content was blocked by safety filters */\n ContentFiltered: 'CONTENT_FILTERED',\n /** Account quota or credits exhausted */\n QuotaExceeded: 'QUOTA_EXCEEDED',\n /** Provider-specific error not covered by other codes */\n ProviderError: 'PROVIDER_ERROR',\n /** Network connectivity issue */\n NetworkError: 'NETWORK_ERROR',\n /** Request exceeded timeout limit */\n Timeout: 'TIMEOUT',\n /** Request was cancelled via AbortSignal */\n Cancelled: 'CANCELLED',\n} as const;\n\n/**\n * Error code discriminator union.\n *\n * This type is derived from {@link ErrorCode} constants. Use `ErrorCode.RateLimited`\n * for constants or `type MyCode = ErrorCode` for type annotations.\n */\nexport type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\n/**\n * Modality type constants.\n *\n * Use these constants for type-safe modality handling:\n *\n * @example\n * ```typescript\n * import { ModalityType } from 'upp';\n *\n * if (provider.modality === ModalityType.LLM) {\n * // Handle LLM provider\n * }\n * ```\n */\nexport const ModalityType = {\n /** Large language model for text generation */\n LLM: 'llm',\n /** Text/image embedding model */\n Embedding: 'embedding',\n /** Image generation model */\n Image: 'image',\n /** Audio processing/generation model */\n Audio: 'audio',\n /** Video processing/generation model */\n Video: 'video',\n} as const;\n\n/**\n * Modality type discriminator union.\n *\n * This type is derived from {@link ModalityType} constants. The name `Modality`\n * is kept for backward compatibility; `ModalityType` works as both the const\n * object and this type.\n */\nexport type Modality = (typeof ModalityType)[keyof typeof ModalityType];\n\n/**\n * Type alias for Modality, allowing `ModalityType` to work as both const and type.\n */\nexport type ModalityType = Modality;\n\n/**\n * Unified Provider Protocol Error.\n *\n * All provider-specific errors are normalized to this type, providing\n * a consistent interface for error handling across different AI providers.\n *\n * @example\n * ```typescript\n * import { ErrorCode, ModalityType } from 'upp';\n *\n * throw new UPPError(\n * 'API key is invalid',\n * ErrorCode.AuthenticationFailed,\n * 'openai',\n * ModalityType.LLM,\n * 401\n * );\n * ```\n *\n * @example\n * ```typescript\n * import { ErrorCode, ModalityType } from 'upp';\n *\n * // Wrapping a provider error\n * try {\n * await openai.chat.completions.create({ ... });\n * } catch (err) {\n * throw new UPPError(\n * 'OpenAI request failed',\n * ErrorCode.ProviderError,\n * 'openai',\n * ModalityType.LLM,\n * err.status,\n * err\n * );\n * }\n * ```\n */\nexport class UPPError extends Error {\n /** Normalized error code for programmatic handling */\n readonly code: ErrorCode;\n\n /** Name of the provider that generated the error */\n readonly provider: string;\n\n /** The modality that was being used when the error occurred */\n readonly modality: Modality;\n\n /** HTTP status code from the provider's response, if available */\n readonly statusCode?: number;\n\n /** The original error that caused this UPPError, if wrapping another error */\n override readonly cause?: Error;\n\n /** Error class name, always 'UPPError' */\n override readonly name = 'UPPError';\n\n /**\n * Creates a new UPPError instance.\n *\n * @param message - Human-readable error description\n * @param code - Normalized error code for programmatic handling\n * @param provider - Name of the provider that generated the error\n * @param modality - The modality that was being used\n * @param statusCode - HTTP status code from the provider's response\n * @param cause - The original error being wrapped\n */\n constructor(\n message: string,\n code: ErrorCode,\n provider: string,\n modality: Modality,\n statusCode?: number,\n cause?: Error\n ) {\n super(message);\n this.code = code;\n this.provider = provider;\n this.modality = modality;\n this.statusCode = statusCode;\n this.cause = cause;\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, UPPError);\n }\n }\n\n /**\n * Creates a string representation of the error.\n *\n * @returns Formatted error string including code, message, provider, and modality\n */\n override toString(): string {\n let str = `UPPError [${this.code}]: ${this.message}`;\n str += ` (provider: ${this.provider}, modality: ${this.modality}`;\n if (this.statusCode) {\n str += `, status: ${this.statusCode}`;\n }\n str += ')';\n return str;\n }\n\n /**\n * Converts the error to a JSON-serializable object.\n *\n * @returns Plain object representation suitable for logging or transmission\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n provider: this.provider,\n modality: this.modality,\n statusCode: this.statusCode,\n cause: this.cause?.message,\n };\n }\n}\n","/**\n * @fileoverview Error normalization utilities.\n *\n * @module utils/error\n */\n\n/**\n * Converts an unknown thrown value into an Error instance.\n *\n * @param value - Unknown error value\n * @returns An Error instance\n */\nexport function toError(value: unknown): Error {\n if (value instanceof Error) {\n return value;\n }\n if (typeof value === 'string') {\n return new Error(value);\n }\n if (typeof value === 'object' && value !== null && 'message' in value) {\n const message = (value as { message?: unknown }).message;\n if (typeof message === 'string') {\n return new Error(message);\n }\n }\n return new Error(String(value));\n}\n","/**\n * HTTP error handling and normalization utilities.\n * @module http/errors\n */\n\nimport {\n UPPError,\n ErrorCode,\n type Modality,\n} from '../types/errors.ts';\nimport { toError } from '../utils/error.ts';\n\n/**\n * Maps HTTP status codes to standardized UPP error codes.\n *\n * This function provides consistent error categorization across all providers:\n * - 400 -> INVALID_REQUEST (bad request format or parameters)\n * - 401, 403 -> AUTHENTICATION_FAILED (invalid or missing credentials)\n * - 404 -> MODEL_NOT_FOUND (requested model does not exist)\n * - 408 -> TIMEOUT (request timed out)\n * - 413 -> CONTEXT_LENGTH_EXCEEDED (input too long)\n * - 429 -> RATE_LIMITED (too many requests)\n * - 5xx -> PROVIDER_ERROR (server-side issues)\n *\n * @param status - HTTP status code from the response\n * @returns The corresponding UPP ErrorCode\n *\n * @example\n * ```typescript\n * const errorCode = statusToErrorCode(429);\n * // Returns 'RATE_LIMITED'\n *\n * const serverError = statusToErrorCode(503);\n * // Returns 'PROVIDER_ERROR'\n * ```\n */\nexport function statusToErrorCode(status: number): ErrorCode {\n switch (status) {\n case 400:\n return ErrorCode.InvalidRequest;\n case 402:\n return ErrorCode.QuotaExceeded;\n case 401:\n case 403:\n return ErrorCode.AuthenticationFailed;\n case 404:\n return ErrorCode.ModelNotFound;\n case 408:\n return ErrorCode.Timeout;\n case 409:\n return ErrorCode.InvalidRequest;\n case 422:\n return ErrorCode.InvalidRequest;\n case 413:\n return ErrorCode.ContextLengthExceeded;\n case 451:\n return ErrorCode.ContentFiltered;\n case 429:\n return ErrorCode.RateLimited;\n case 500:\n case 502:\n case 503:\n case 504:\n return ErrorCode.ProviderError;\n default:\n return ErrorCode.ProviderError;\n }\n}\n\n/**\n * Normalizes HTTP error responses into standardized UPPError objects.\n *\n * This function performs several operations:\n * 1. Maps the HTTP status code to an appropriate ErrorCode\n * 2. Attempts to extract a meaningful error message from the response body\n * 3. Handles various provider-specific error response formats\n *\n * Supported error message formats:\n * - `{ error: { message: \"...\" } }` (OpenAI, Anthropic)\n * - `{ message: \"...\" }` (simple format)\n * - `{ error: { error: { message: \"...\" } } }` (nested format)\n * - `{ detail: \"...\" }` (FastAPI style)\n * - Plain text body (if under 200 characters)\n *\n * @param response - The HTTP Response object with non-2xx status\n * @param provider - Provider identifier for error context\n * @param modality - Request modality for error context\n * @returns A UPPError with normalized code and message\n *\n * @example\n * ```typescript\n * if (!response.ok) {\n * const error = await normalizeHttpError(response, 'openai', 'llm');\n * // error.code might be 'RATE_LIMITED' for 429\n * // error.message contains provider's error message\n * throw error;\n * }\n * ```\n */\nexport async function normalizeHttpError(\n response: Response,\n provider: string,\n modality: Modality\n): Promise<UPPError> {\n const code = statusToErrorCode(response.status);\n let message = `HTTP ${response.status}: ${response.statusText}`;\n let bodyReadError: Error | undefined;\n\n try {\n const body = await response.text();\n if (body) {\n try {\n const json = JSON.parse(body);\n const extractedMessage =\n json.error?.message ||\n json.message ||\n json.error?.error?.message ||\n json.detail;\n\n if (extractedMessage) {\n message = extractedMessage;\n }\n } catch {\n if (body.length < 200) {\n message = body;\n }\n }\n }\n } catch (error) {\n bodyReadError = toError(error);\n }\n\n return new UPPError(message, code, provider, modality, response.status, bodyReadError);\n}\n\n/**\n * Creates a UPPError for network failures (DNS, connection, etc.).\n *\n * Use this when the request fails before receiving any HTTP response,\n * such as DNS resolution failures, connection refused, or network unreachable.\n *\n * @param error - The underlying Error that caused the failure\n * @param provider - Provider identifier for error context\n * @param modality - Request modality for error context\n * @returns A UPPError with NETWORK_ERROR code and the original error attached\n */\nexport function networkError(\n error: Error,\n provider: string,\n modality: Modality\n): UPPError {\n return new UPPError(\n `Network error: ${error.message}`,\n ErrorCode.NetworkError,\n provider,\n modality,\n undefined,\n error\n );\n}\n\n/**\n * Creates a UPPError for request timeout.\n *\n * Use this when the request exceeds the configured timeout duration\n * and is aborted by the AbortController.\n *\n * @param timeout - The timeout duration in milliseconds that was exceeded\n * @param provider - Provider identifier for error context\n * @param modality - Request modality for error context\n * @returns A UPPError with TIMEOUT code\n */\nexport function timeoutError(\n timeout: number,\n provider: string,\n modality: Modality\n): UPPError {\n return new UPPError(\n `Request timed out after ${timeout}ms`,\n ErrorCode.Timeout,\n provider,\n modality\n );\n}\n\n/**\n * Creates a UPPError for user-initiated request cancellation.\n *\n * Use this when the request is aborted via a user-provided AbortSignal,\n * distinct from timeout-based cancellation.\n *\n * @param provider - Provider identifier for error context\n * @param modality - Request modality for error context\n * @returns A UPPError with CANCELLED code\n */\nexport function cancelledError(provider: string, modality: Modality): UPPError {\n return new UPPError(\n 'Request was cancelled',\n ErrorCode.Cancelled,\n provider,\n modality\n );\n}\n","/**\n * HTTP fetch utilities with retry, timeout, and error normalization.\n * @module http/fetch\n */\n\nimport type { ProviderConfig, RetryStrategy } from '../types/provider.ts';\nimport type { Modality } from '../types/errors.ts';\nimport { UPPError } from '../types/errors.ts';\nimport {\n normalizeHttpError,\n networkError,\n timeoutError,\n cancelledError,\n} from './errors.ts';\nimport { toError } from '../utils/error.ts';\n\n/** Default request timeout in milliseconds (2 minutes). */\nconst DEFAULT_TIMEOUT = 120000;\nconst MAX_RETRY_AFTER_SECONDS = 3600;\n\ntype ForkableRetryStrategy = RetryStrategy & {\n fork: () => RetryStrategy | undefined;\n};\n\nfunction hasFork(strategy: RetryStrategy | undefined): strategy is ForkableRetryStrategy {\n return !!strategy && typeof (strategy as { fork?: unknown }).fork === 'function';\n}\n\n/**\n * Executes an HTTP fetch request with automatic retry, timeout handling, and error normalization.\n *\n * This function wraps the standard fetch API with additional capabilities:\n * - Configurable timeout with automatic request cancellation (per attempt)\n * - Retry strategy support (exponential backoff, linear, token bucket, etc.)\n * - Pre-request delay support for rate limiting strategies\n * - Automatic Retry-After header parsing and handling\n * - Error normalization to UPPError format\n *\n * @param url - The URL to fetch\n * @param init - Standard fetch RequestInit options (method, headers, body, etc.)\n * @param config - Provider configuration containing fetch customization, timeout, and retry strategy\n * @param provider - Provider identifier for error context (e.g., 'openai', 'anthropic')\n * @param modality - Request modality for error context (e.g., 'llm', 'embedding', 'image')\n * @returns The successful Response object\n *\n * @throws {UPPError} RATE_LIMITED - When rate limited and retries exhausted\n * @throws {UPPError} NETWORK_ERROR - When a network failure occurs\n * @throws {UPPError} TIMEOUT - When the request times out\n * @throws {UPPError} CANCELLED - When the request is aborted via signal\n * @throws {UPPError} Various codes based on HTTP status (see statusToErrorCode)\n *\n * @example\n * ```typescript\n * const response = await doFetch(\n * 'https://api.openai.com/v1/chat/completions',\n * {\n * method: 'POST',\n * headers: { 'Authorization': 'Bearer sk-...' },\n * body: JSON.stringify({ model: 'gpt-4', messages: [] })\n * },\n * { timeout: 30000, retryStrategy: new ExponentialBackoff() },\n * 'openai',\n * 'llm'\n * );\n * ```\n */\nexport async function doFetch(\n url: string,\n init: RequestInit,\n config: ProviderConfig,\n provider: string,\n modality: Modality\n): Promise<Response> {\n const fetchFn = config.fetch ?? fetch;\n const timeout = config.timeout ?? DEFAULT_TIMEOUT;\n const baseStrategy = config.retryStrategy;\n const strategy = hasFork(baseStrategy) ? baseStrategy.fork() : baseStrategy;\n\n let attempt = 0;\n\n while (true) {\n attempt++;\n\n if (strategy?.beforeRequest) {\n const delay = await strategy.beforeRequest();\n if (delay > 0) {\n await sleep(delay);\n }\n }\n\n let response: Response;\n try {\n response = await fetchWithTimeout(\n fetchFn,\n url,\n init,\n timeout,\n provider,\n modality\n );\n } catch (error) {\n if (error instanceof UPPError) {\n if (strategy) {\n const delay = await strategy.onRetry(error, attempt);\n if (delay !== null) {\n await sleep(delay);\n continue;\n }\n }\n throw error;\n }\n\n const uppError = networkError(toError(error), provider, modality);\n\n if (strategy) {\n const delay = await strategy.onRetry(uppError, attempt);\n if (delay !== null) {\n await sleep(delay);\n continue;\n }\n }\n\n throw uppError;\n }\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, provider, modality);\n\n const retryAfterSeconds = parseRetryAfter(\n response.headers.get('Retry-After'),\n config.retryAfterMaxSeconds ?? MAX_RETRY_AFTER_SECONDS\n );\n if (retryAfterSeconds !== null && strategy && 'setRetryAfter' in strategy) {\n (strategy as { setRetryAfter: (s: number) => void }).setRetryAfter(\n retryAfterSeconds\n );\n }\n\n if (strategy) {\n const delay = await strategy.onRetry(error, attempt);\n if (delay !== null) {\n await sleep(delay);\n continue;\n }\n }\n\n throw error;\n }\n\n strategy?.reset?.();\n\n return response;\n }\n}\n\n/**\n * Executes a fetch request with configurable timeout.\n *\n * Creates an AbortController to cancel the request if it exceeds the timeout.\n * Properly handles both user-provided abort signals and timeout-based cancellation,\n * throwing appropriate error types for each case.\n *\n * @param fetchFn - The fetch function to use (allows custom implementations)\n * @param url - The URL to fetch\n * @param init - Standard fetch RequestInit options\n * @param timeout - Maximum time in milliseconds before aborting\n * @param provider - Provider identifier for error context\n * @param modality - Request modality for error context\n * @returns The Response from the fetch call\n *\n * @throws {UPPError} TIMEOUT - When the timeout is exceeded\n * @throws {UPPError} CANCELLED - When cancelled via user-provided signal\n * @throws {Error} Network errors are passed through unchanged\n */\nasync function fetchWithTimeout(\n fetchFn: typeof fetch,\n url: string,\n init: RequestInit,\n timeout: number,\n provider: string,\n modality: Modality\n): Promise<Response> {\n const existingSignal = init.signal;\n\n // Check if already aborted before starting\n if (existingSignal?.aborted) {\n throw cancelledError(provider, modality);\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const onAbort = () => controller.abort();\n if (existingSignal) {\n existingSignal.addEventListener('abort', onAbort, { once: true });\n }\n\n try {\n const response = await fetchFn(url, {\n ...init,\n signal: controller.signal,\n });\n return response;\n } catch (error) {\n if (toError(error).name === 'AbortError') {\n if (existingSignal?.aborted) {\n throw cancelledError(provider, modality);\n }\n throw timeoutError(timeout, provider, modality);\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n if (existingSignal) {\n existingSignal.removeEventListener('abort', onAbort);\n }\n }\n}\n\n/**\n * Delays execution for a specified duration.\n *\n * @param ms - Duration to sleep in milliseconds\n * @returns Promise that resolves after the specified delay\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Executes an HTTP fetch request for streaming responses.\n *\n * Unlike {@link doFetch}, this function returns the response immediately without\n * checking the HTTP status. This is necessary for Server-Sent Events (SSE) and\n * other streaming protocols where error information may be embedded in the stream.\n *\n * The caller is responsible for:\n * - Checking response.ok and handling HTTP errors\n * - Parsing the response stream (e.g., using parseSSEStream)\n * - Handling stream-specific error conditions\n *\n * Retries are not performed for streaming requests since partial data may have\n * already been consumed by the caller.\n *\n * @param url - The URL to fetch\n * @param init - Standard fetch RequestInit options\n * @param config - Provider configuration containing fetch customization and timeout\n * @param provider - Provider identifier for error context\n * @param modality - Request modality for error context\n * @returns The Response object (may have non-2xx status)\n *\n * @throws {UPPError} NETWORK_ERROR - When a network failure occurs\n * @throws {UPPError} TIMEOUT - When the request times out\n * @throws {UPPError} CANCELLED - When the request is aborted via signal\n *\n * @example\n * ```typescript\n * const response = await doStreamFetch(\n * 'https://api.openai.com/v1/chat/completions',\n * {\n * method: 'POST',\n * headers: { 'Authorization': 'Bearer sk-...' },\n * body: JSON.stringify({ model: 'gpt-4', messages: [], stream: true })\n * },\n * { timeout: 120000 },\n * 'openai',\n * 'llm'\n * );\n *\n * if (!response.ok) {\n * throw await normalizeHttpError(response, 'openai', 'llm');\n * }\n *\n * for await (const event of parseSSEStream(response.body!)) {\n * console.log(event);\n * }\n * ```\n */\nexport async function doStreamFetch(\n url: string,\n init: RequestInit,\n config: ProviderConfig,\n provider: string,\n modality: Modality\n): Promise<Response> {\n const fetchFn = config.fetch ?? fetch;\n const timeout = config.timeout ?? DEFAULT_TIMEOUT;\n const baseStrategy = config.retryStrategy;\n const strategy = hasFork(baseStrategy) ? baseStrategy.fork() : baseStrategy;\n\n if (strategy?.beforeRequest) {\n const delay = await strategy.beforeRequest();\n if (delay > 0) {\n await sleep(delay);\n }\n }\n\n try {\n const response = await fetchWithTimeout(\n fetchFn,\n url,\n init,\n timeout,\n provider,\n modality\n );\n return response;\n } catch (error) {\n if (error instanceof UPPError) {\n throw error;\n }\n throw networkError(toError(error), provider, modality);\n }\n}\n\n/**\n * Parses Retry-After header values into seconds.\n *\n * Supports both delta-seconds and HTTP-date formats.\n */\nfunction parseRetryAfter(headerValue: string | null, maxSeconds: number): number | null {\n if (!headerValue) {\n return null;\n }\n\n const seconds = parseInt(headerValue, 10);\n if (!Number.isNaN(seconds)) {\n return Math.min(maxSeconds, Math.max(0, seconds));\n }\n\n const dateMillis = Date.parse(headerValue);\n if (Number.isNaN(dateMillis)) {\n return null;\n }\n\n const deltaMs = dateMillis - Date.now();\n if (deltaMs <= 0) {\n return 0;\n }\n\n const deltaSeconds = Math.ceil(deltaMs / 1000);\n return Math.min(maxSeconds, Math.max(0, deltaSeconds));\n}\n"],"mappings":"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","names":[]}