@providerprotocol/ai 0.0.22 → 0.0.24
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.
- package/README.md +188 -6
- package/dist/anthropic/index.d.ts +1 -1
- package/dist/anthropic/index.js +95 -36
- package/dist/anthropic/index.js.map +1 -1
- package/dist/{chunk-7WYBJPJJ.js → chunk-55X3W2MN.js} +4 -3
- package/dist/chunk-55X3W2MN.js.map +1 -0
- package/dist/{chunk-M4BMM5IB.js → chunk-6AZVUI6H.js} +20 -4
- package/dist/chunk-6AZVUI6H.js.map +1 -0
- package/dist/chunk-73IIE3QT.js +120 -0
- package/dist/chunk-73IIE3QT.js.map +1 -0
- package/dist/{chunk-RFWLEFAB.js → chunk-QNJO7DSD.js} +61 -16
- package/dist/chunk-QNJO7DSD.js.map +1 -0
- package/dist/{chunk-RS7C25LS.js → chunk-SBCATNHA.js} +9 -5
- package/dist/chunk-SBCATNHA.js.map +1 -0
- package/dist/{chunk-NWS5IKNR.js → chunk-TOJCZMVU.js} +3 -12
- package/dist/chunk-TOJCZMVU.js.map +1 -0
- package/dist/{chunk-I2VHCGQE.js → chunk-Z6DKC37J.js} +6 -5
- package/dist/chunk-Z6DKC37J.js.map +1 -0
- package/dist/google/index.d.ts +36 -4
- package/dist/google/index.js +98 -53
- package/dist/google/index.js.map +1 -1
- package/dist/http/index.d.ts +2 -2
- package/dist/http/index.js +4 -4
- package/dist/index.d.ts +8 -6
- package/dist/index.js +92 -122
- package/dist/index.js.map +1 -1
- package/dist/ollama/index.d.ts +5 -2
- package/dist/ollama/index.js +47 -36
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/openai/index.js +117 -56
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +1 -1
- package/dist/openrouter/index.js +58 -53
- package/dist/openrouter/index.js.map +1 -1
- package/dist/{provider-DWEAzeM5.d.ts → provider-x4RocsnK.d.ts} +199 -54
- package/dist/proxy/index.d.ts +2 -2
- package/dist/proxy/index.js +11 -9
- package/dist/proxy/index.js.map +1 -1
- package/dist/{retry-DmPmqZL6.d.ts → retry-DTfjXXPh.d.ts} +1 -1
- package/dist/{stream-DbkLOIbJ.d.ts → stream-ITNFNnO4.d.ts} +95 -38
- package/dist/xai/index.d.ts +1 -1
- package/dist/xai/index.js +221 -97
- package/dist/xai/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-7WYBJPJJ.js.map +0 -1
- package/dist/chunk-I2VHCGQE.js.map +0 -1
- package/dist/chunk-M4BMM5IB.js.map +0 -1
- package/dist/chunk-NWS5IKNR.js.map +0 -1
- package/dist/chunk-RFWLEFAB.js.map +0 -1
- package/dist/chunk-RS7C25LS.js.map +0 -1
package/dist/proxy/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/proxy/serialization.ts","../../src/providers/proxy/llm.ts","../../src/providers/proxy/server/express.ts","../../src/providers/proxy/server/fastify.ts","../../src/providers/proxy/server/h3.ts","../../src/providers/proxy/server/webapi.ts","../../src/providers/proxy/server/index.ts","../../src/providers/proxy/index.ts"],"sourcesContent":["/**\n * @fileoverview Serialization utilities for proxy transport.\n *\n * Handles converting PP types to/from JSON for HTTP transport.\n * These are pure functions with no side effects.\n *\n * @module providers/proxy/serialization\n */\n\nimport {\n UserMessage,\n AssistantMessage,\n ToolResultMessage,\n type Message,\n type MessageJSON,\n} from '../../types/messages.ts';\nimport type { UserContent, AssistantContent } from '../../types/content.ts';\nimport type { StreamEvent, EventDelta } from '../../types/stream.ts';\nimport type { Turn, TurnJSON } from '../../types/turn.ts';\nimport { UPPError } from '../../types/errors.ts';\n\n/**\n * Convert a Message to MessageJSON format.\n */\nexport function serializeMessage(m: Message): MessageJSON {\n const base: MessageJSON = {\n id: m.id,\n type: m.type,\n content: [],\n metadata: m.metadata,\n timestamp: m.timestamp.toISOString(),\n };\n\n if (m instanceof UserMessage) {\n base.content = m.content;\n } else if (m instanceof AssistantMessage) {\n base.content = m.content;\n base.toolCalls = m.toolCalls;\n } else if (m instanceof ToolResultMessage) {\n base.results = m.results;\n }\n\n return base;\n}\n\n/**\n * Reconstruct a Message from MessageJSON format.\n */\nexport function deserializeMessage(json: MessageJSON): Message {\n const options = {\n id: json.id,\n metadata: json.metadata,\n };\n\n switch (json.type) {\n case 'user':\n return new UserMessage(json.content as UserContent[], options);\n case 'assistant':\n return new AssistantMessage(\n json.content as AssistantContent[],\n json.toolCalls,\n options\n );\n case 'tool_result':\n return new ToolResultMessage(json.results ?? [], options);\n default:\n throw new UPPError(\n `Unknown message type: ${json.type}`,\n 'INVALID_RESPONSE',\n 'proxy',\n 'llm'\n );\n }\n}\n\n/**\n * Serialize a Turn to JSON-transportable format.\n */\nexport function serializeTurn(turn: Turn): TurnJSON {\n return {\n messages: turn.messages.map(serializeMessage),\n toolExecutions: turn.toolExecutions,\n usage: turn.usage,\n cycles: turn.cycles,\n data: turn.data,\n };\n}\n\n/**\n * Serialize a StreamEvent for JSON transport.\n * Converts Uint8Array data to base64 string.\n */\nexport function serializeStreamEvent(event: StreamEvent): StreamEvent {\n if (event.delta.data instanceof Uint8Array) {\n const { data, ...rest } = event.delta;\n const bytes = Array.from(data);\n const base64 = btoa(bytes.map((b) => String.fromCharCode(b)).join(''));\n return {\n type: event.type,\n index: event.index,\n delta: { ...rest, data: base64 as unknown as Uint8Array },\n };\n }\n return event;\n}\n\n/**\n * Deserialize a StreamEvent from JSON transport.\n * Converts base64 string data back to Uint8Array.\n */\nexport function deserializeStreamEvent(event: StreamEvent): StreamEvent {\n const delta = event.delta as EventDelta & { data?: string | Uint8Array };\n if (typeof delta.data === 'string') {\n const binaryString = atob(delta.data);\n const bytes = Uint8Array.from(binaryString, (c) => c.charCodeAt(0));\n return {\n type: event.type,\n index: event.index,\n delta: { ...delta, data: bytes },\n };\n }\n return event;\n}\n","/**\n * @fileoverview Proxy LLM handler implementation.\n *\n * Transports PP LLM requests over HTTP to a backend server.\n * Supports both synchronous completion and streaming via SSE.\n * Full support for retry strategies, timeouts, and custom headers.\n *\n * @module providers/proxy/llm\n */\n\nimport type {\n LLMHandler,\n BoundLLMModel,\n LLMRequest,\n LLMResponse,\n LLMStreamResult,\n LLMCapabilities,\n} from '../../types/llm.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { TurnJSON } from '../../types/turn.ts';\nimport { AssistantMessage } from '../../types/messages.ts';\nimport { emptyUsage } from '../../types/turn.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { ProxyLLMParams, ProxyProviderOptions } from './types.ts';\nimport {\n serializeMessage,\n deserializeMessage,\n deserializeStreamEvent,\n} from './serialization.ts';\n\n/**\n * Capability flags for proxy provider.\n * All capabilities are enabled since the backend determines actual support.\n */\nconst PROXY_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n videoInput: true,\n audioInput: true,\n};\n\n/**\n * Creates a proxy LLM handler.\n *\n * Supports full ProviderConfig options including retry strategies, timeouts,\n * custom headers, and custom fetch implementations. This allows client-side\n * retry logic for network failures to the proxy server.\n *\n * @param options - Proxy configuration options\n * @returns An LLM handler that transports requests over HTTP\n *\n * @example\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { proxy } from '@providerprotocol/ai/proxy';\n * import { ExponentialBackoff } from '@providerprotocol/ai/http';\n *\n * const claude = llm({\n * model: proxy('https://api.myplatform.com/ai'),\n * config: {\n * headers: { 'Authorization': 'Bearer user-token' },\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * timeout: 30000,\n * },\n * });\n * ```\n */\nexport function createLLMHandler(options: ProxyProviderOptions): LLMHandler<ProxyLLMParams> {\n const { endpoint, headers: defaultHeaders = {} } = options;\n\n let providerRef: LLMProvider<ProxyLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<ProxyLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<ProxyLLMParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n 'INVALID_REQUEST',\n 'proxy',\n 'llm'\n );\n }\n\n const model: BoundLLMModel<ProxyLLMParams> = {\n modelId,\n capabilities: PROXY_CAPABILITIES,\n\n get provider(): LLMProvider<ProxyLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<ProxyLLMParams>): Promise<LLMResponse> {\n const body = serializeRequest(request);\n const headers = mergeHeaders(request.config.headers, defaultHeaders);\n\n const response = await doFetch(\n endpoint,\n {\n method: 'POST',\n headers: {\n ...headers,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'proxy',\n 'llm'\n );\n\n const data = await parseJsonResponse<TurnJSON>(response, 'proxy', 'llm');\n return turnJSONToLLMResponse(data);\n },\n\n stream(request: LLMRequest<ProxyLLMParams>): LLMStreamResult {\n const body = serializeRequest(request);\n const headers = mergeHeaders(request.config.headers, defaultHeaders);\n\n let resolveResponse: (value: LLMResponse) => void;\n let rejectResponse: (error: Error) => void;\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n resolveResponse = resolve;\n rejectResponse = reject;\n });\n\n const generator = async function* (): AsyncGenerator<StreamEvent> {\n try {\n const response = await doStreamFetch(\n endpoint,\n {\n method: 'POST',\n headers: {\n ...headers,\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n },\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'proxy',\n 'llm'\n );\n\n if (!response.ok) {\n throw await normalizeHttpError(response, 'proxy', 'llm');\n }\n\n if (!response.body) {\n throw new UPPError(\n 'Response body is null',\n 'PROVIDER_ERROR',\n 'proxy',\n 'llm'\n );\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (!line.trim() || line.startsWith(':')) continue;\n\n if (line.startsWith('data:')) {\n let data = line.slice(5);\n if (data.startsWith(' ')) {\n data = data.slice(1);\n }\n if (data === '[DONE]') continue;\n\n try {\n const parsed = JSON.parse(data);\n\n // Check if this is the final turn data\n if ('messages' in parsed && 'usage' in parsed && 'cycles' in parsed) {\n resolveResponse(turnJSONToLLMResponse(parsed as TurnJSON));\n } else {\n // It's a StreamEvent\n yield deserializeStreamEvent(parsed as StreamEvent);\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n const remaining = decoder.decode();\n if (remaining) {\n buffer += remaining;\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.trim() || line.startsWith(':')) continue;\n if (line.startsWith('data:')) {\n let data = line.slice(5);\n if (data.startsWith(' ')) {\n data = data.slice(1);\n }\n if (data === '[DONE]') continue;\n try {\n const parsed = JSON.parse(data);\n if ('messages' in parsed && 'usage' in parsed && 'cycles' in parsed) {\n resolveResponse(turnJSONToLLMResponse(parsed as TurnJSON));\n } else {\n yield deserializeStreamEvent(parsed as StreamEvent);\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n } catch (error) {\n rejectResponse(toError(error));\n throw error;\n }\n };\n\n return {\n [Symbol.asyncIterator]: generator,\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n\n/**\n * Serialize an LLMRequest for HTTP transport.\n */\nfunction serializeRequest(request: LLMRequest<ProxyLLMParams>): Record<string, unknown> {\n return {\n messages: request.messages.map(serializeMessage),\n system: request.system,\n params: request.params,\n tools: request.tools?.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n metadata: t.metadata,\n })),\n structure: request.structure,\n };\n}\n\n/**\n * Merge request headers with default headers.\n */\nfunction mergeHeaders(\n requestHeaders: Record<string, string | undefined> | undefined,\n defaultHeaders: Record<string, string>\n): Record<string, string> {\n const headers: Record<string, string> = { ...defaultHeaders };\n if (requestHeaders) {\n for (const [key, value] of Object.entries(requestHeaders)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n return headers;\n}\n\n/**\n * Convert TurnJSON to LLMResponse.\n */\nfunction turnJSONToLLMResponse(data: TurnJSON): LLMResponse {\n const messages = data.messages.map(deserializeMessage);\n const lastAssistant = messages\n .filter((m): m is AssistantMessage => m.type === 'assistant')\n .pop();\n\n const stopReason = deriveStopReason(lastAssistant);\n\n return {\n message: lastAssistant ?? new AssistantMessage(''),\n usage: data.usage ?? emptyUsage(),\n stopReason,\n data: data.data,\n };\n}\n\nfunction deriveStopReason(message: AssistantMessage | undefined): string {\n if (!message) {\n return 'end_turn';\n }\n\n if (message.toolCalls && message.toolCalls.length > 0) {\n return 'tool_use';\n }\n\n const metadata = message.metadata;\n const openaiMeta = metadata?.openai as { finish_reason?: string; status?: string } | undefined;\n if (openaiMeta?.status) {\n if (openaiMeta.status === 'failed') {\n return 'error';\n }\n if (openaiMeta.status === 'completed') {\n return 'end_turn';\n }\n }\n if (openaiMeta?.finish_reason) {\n return mapCompletionStopReason(openaiMeta.finish_reason);\n }\n\n const openrouterMeta = metadata?.openrouter as { finish_reason?: string } | undefined;\n if (openrouterMeta?.finish_reason) {\n return mapCompletionStopReason(openrouterMeta.finish_reason);\n }\n\n const xaiMeta = metadata?.xai as { finish_reason?: string; status?: string } | undefined;\n if (xaiMeta?.status) {\n if (xaiMeta.status === 'failed') {\n return 'error';\n }\n if (xaiMeta.status === 'completed') {\n return 'end_turn';\n }\n }\n if (xaiMeta?.finish_reason) {\n return mapCompletionStopReason(xaiMeta.finish_reason);\n }\n\n const anthropicMeta = metadata?.anthropic as { stop_reason?: string } | undefined;\n if (anthropicMeta?.stop_reason) {\n return mapAnthropicStopReason(anthropicMeta.stop_reason);\n }\n\n const googleMeta = metadata?.google as { finishReason?: string } | undefined;\n if (googleMeta?.finishReason) {\n return mapGoogleStopReason(googleMeta.finishReason);\n }\n\n const ollamaMeta = metadata?.ollama as { done_reason?: string } | undefined;\n if (ollamaMeta?.done_reason) {\n return mapOllamaStopReason(ollamaMeta.done_reason);\n }\n\n return 'end_turn';\n}\n\nfunction mapCompletionStopReason(reason: string): string {\n switch (reason) {\n case 'stop':\n return 'end_turn';\n case 'length':\n return 'max_tokens';\n case 'tool_calls':\n return 'tool_use';\n case 'content_filter':\n return 'content_filter';\n default:\n return 'end_turn';\n }\n}\n\nfunction mapAnthropicStopReason(reason: string): string {\n switch (reason) {\n case 'tool_use':\n return 'tool_use';\n case 'max_tokens':\n return 'max_tokens';\n case 'end_turn':\n return 'end_turn';\n case 'stop_sequence':\n return 'end_turn';\n default:\n return 'end_turn';\n }\n}\n\nfunction mapGoogleStopReason(reason: string): string {\n switch (reason) {\n case 'STOP':\n return 'end_turn';\n case 'MAX_TOKENS':\n return 'max_tokens';\n case 'SAFETY':\n return 'content_filter';\n case 'RECITATION':\n return 'content_filter';\n case 'OTHER':\n return 'end_turn';\n default:\n return 'end_turn';\n }\n}\n\nfunction mapOllamaStopReason(reason: string): string {\n if (reason === 'length') {\n return 'max_tokens';\n }\n if (reason === 'stop') {\n return 'end_turn';\n }\n return 'end_turn';\n}\n","/**\n * @fileoverview Express/Connect adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Express.js or Connect-based servers.\n * These adapters convert PP types to Express-compatible responses.\n *\n * @module providers/proxy/server/express\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\n\n/**\n * Express Response interface (minimal type to avoid dependency).\n */\ninterface ExpressResponse {\n setHeader(name: string, value: string): void;\n status(code: number): ExpressResponse;\n write(chunk: string): boolean;\n end(): void;\n json(body: unknown): void;\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param res - Express response object\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * expressAdapter.sendJSON(turn, res);\n * ```\n */\nexport function sendJSON(turn: Turn, res: ExpressResponse): void {\n res.setHeader('Content-Type', 'application/json');\n res.json(serializeTurn(turn));\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * @param stream - The StreamResult from instance.stream()\n * @param res - Express response object\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * expressAdapter.streamSSE(stream, res);\n * ```\n */\nexport function streamSSE(stream: StreamResult, res: ExpressResponse): void {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n (async () => {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n res.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n res.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n res.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n res.end();\n }\n })();\n}\n\n/**\n * Send an error response.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param res - Express response object\n */\nexport function sendError(message: string, status: number, res: ExpressResponse): void {\n res.status(status).json({ error: message });\n}\n\n/**\n * Express adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * import express from 'express';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { express as expressAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = express();\n * app.use(express.json());\n *\n * app.post('/api/ai', async (req, res) => {\n * const { messages, system, params } = parseBody(req.body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (req.headers.accept?.includes('text/event-stream')) {\n * expressAdapter.streamSSE(instance.stream(messages), res);\n * } else {\n * const turn = await instance.generate(messages);\n * expressAdapter.sendJSON(turn, res);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import express from 'express';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { express as expressAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = express();\n * app.use(express.json());\n *\n * // Your platform's auth middleware\n * async function authMiddleware(req, res, next) {\n * const token = req.headers.authorization?.replace('Bearer ', '');\n * const user = await validatePlatformToken(token);\n * if (!user) return res.status(401).json({ error: 'Unauthorized' });\n * req.user = user;\n * next();\n * }\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * app.post('/api/ai', authMiddleware, async (req, res) => {\n * // Track usage per user\n * // await trackUsage(req.user.id);\n *\n * const { messages, system, params } = parseBody(req.body);\n *\n * if (params?.stream) {\n * expressAdapter.streamSSE(claude.stream(messages, { system }), res);\n * } else {\n * const turn = await claude.generate(messages, { system });\n * expressAdapter.sendJSON(turn, res);\n * }\n * });\n * ```\n */\nexport const express = {\n sendJSON,\n streamSSE,\n sendError,\n};\n","/**\n * @fileoverview Fastify adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Fastify servers.\n * These adapters convert PP types to Fastify-compatible responses.\n *\n * @module providers/proxy/server/fastify\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\n\n/**\n * Fastify Reply interface (minimal type to avoid dependency).\n */\ninterface FastifyReply {\n header(name: string, value: string): FastifyReply;\n status(code: number): FastifyReply;\n send(payload: unknown): FastifyReply;\n raw: {\n write(chunk: string): boolean;\n end(): void;\n };\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return fastifyAdapter.sendJSON(turn, reply);\n * ```\n */\nexport function sendJSON(turn: Turn, reply: FastifyReply): FastifyReply {\n return reply\n .header('Content-Type', 'application/json')\n .send(serializeTurn(turn));\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * @param stream - The StreamResult from instance.stream()\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return fastifyAdapter.streamSSE(stream, reply);\n * ```\n */\nexport function streamSSE(stream: StreamResult, reply: FastifyReply): FastifyReply {\n reply\n .header('Content-Type', 'text/event-stream')\n .header('Cache-Control', 'no-cache')\n .header('Connection', 'keep-alive');\n\n const raw = reply.raw;\n\n (async () => {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n raw.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n raw.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n raw.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n raw.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n raw.end();\n }\n })();\n\n return reply;\n}\n\n/**\n * Send an error response.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param reply - Fastify reply object\n */\nexport function sendError(message: string, status: number, reply: FastifyReply): FastifyReply {\n return reply.status(status).send({ error: message });\n}\n\n/**\n * Fastify adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * import Fastify from 'fastify';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { fastify as fastifyAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = Fastify();\n *\n * app.post('/api/ai', async (request, reply) => {\n * const { messages, system, params } = parseBody(request.body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (request.headers.accept?.includes('text/event-stream')) {\n * return fastifyAdapter.streamSSE(instance.stream(messages), reply);\n * } else {\n * const turn = await instance.generate(messages);\n * return fastifyAdapter.sendJSON(turn, reply);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import Fastify from 'fastify';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { fastify as fastifyAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = Fastify();\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * // Auth hook for your platform\n * app.addHook('preHandler', async (request, reply) => {\n * const token = request.headers.authorization?.replace('Bearer ', '');\n * const user = await validatePlatformToken(token);\n * if (!user) {\n * reply.status(401).send({ error: 'Unauthorized' });\n * return;\n * }\n * request.user = user;\n * });\n *\n * app.post('/api/ai', async (request, reply) => {\n * // Track usage per user\n * // await trackUsage(request.user.id);\n *\n * const { messages, system, params } = parseBody(request.body);\n *\n * if (params?.stream) {\n * return fastifyAdapter.streamSSE(claude.stream(messages, { system }), reply);\n * }\n * const turn = await claude.generate(messages, { system });\n * return fastifyAdapter.sendJSON(turn, reply);\n * });\n * ```\n */\nexport const fastify = {\n sendJSON,\n streamSSE,\n sendError,\n};\n","/**\n * @fileoverview H3/Nitro/Nuxt adapter for proxy server.\n *\n * Provides utilities for using PP proxy with H3-based servers\n * (Nuxt, Nitro, or standalone H3).\n *\n * @module providers/proxy/server/h3\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\n\n/**\n * H3 Event interface (minimal type to avoid dependency).\n */\ninterface H3Event {\n node: {\n res: {\n setHeader(name: string, value: string): void;\n write(chunk: string): boolean;\n end(): void;\n };\n };\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param event - H3 event object\n * @returns Serialized turn data\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return h3Adapter.sendJSON(turn, event);\n * ```\n */\nexport function sendJSON(turn: Turn, event: H3Event): unknown {\n event.node.res.setHeader('Content-Type', 'application/json');\n return serializeTurn(turn);\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * @param stream - The StreamResult from instance.stream()\n * @param event - H3 event object\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return h3Adapter.streamSSE(stream, event);\n * ```\n */\nexport function streamSSE(stream: StreamResult, event: H3Event): void {\n const res = event.node.res;\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n (async () => {\n try {\n for await (const evt of stream) {\n const serialized = serializeStreamEvent(evt);\n res.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n res.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n res.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n res.end();\n }\n })();\n}\n\n/**\n * Create a ReadableStream for H3's sendStream utility.\n *\n * Use this with H3's sendStream for better integration:\n * ```typescript\n * import { sendStream } from 'h3';\n * return sendStream(event, h3Adapter.createSSEStream(stream));\n * ```\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns A ReadableStream of SSE data\n */\nexport function createSSEStream(stream: StreamResult): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(serialized)}\\n\\n`));\n }\n\n const turn = await stream.turn;\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: message })}\\n\\n`));\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Send an error response.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param event - H3 event object\n * @returns Error object for H3 to serialize\n */\nexport function sendError(message: string, status: number, event: H3Event): { error: string; statusCode: number } {\n return { error: message, statusCode: status };\n}\n\n/**\n * H3/Nitro/Nuxt adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * // Nuxt server route: server/api/ai.post.ts\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { h3 as h3Adapter } from '@providerprotocol/ai/proxy/server';\n *\n * export default defineEventHandler(async (event) => {\n * const body = await readBody(event);\n * const { messages, system, params } = parseBody(body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * const wantsStream = getHeader(event, 'accept')?.includes('text/event-stream');\n * if (wantsStream) {\n * return h3Adapter.streamSSE(instance.stream(messages), event);\n * } else {\n * const turn = await instance.generate(messages);\n * return h3Adapter.sendJSON(turn, event);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication (Nuxt)\n * ```typescript\n * // server/api/ai.post.ts\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { h3 as h3Adapter } from '@providerprotocol/ai/proxy/server';\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([\n * process.env.ANTHROPIC_KEY_1!,\n * process.env.ANTHROPIC_KEY_2!,\n * ]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * export default defineEventHandler(async (event) => {\n * // Authenticate with your platform credentials\n * const token = getHeader(event, 'authorization')?.replace('Bearer ', '');\n * const user = await validatePlatformToken(token);\n * if (!user) {\n * throw createError({ statusCode: 401, message: 'Unauthorized' });\n * }\n *\n * // Track usage per user\n * // await trackUsage(user.id);\n *\n * const body = await readBody(event);\n * const { messages, system, params } = parseBody(body);\n *\n * if (params?.stream) {\n * return h3Adapter.streamSSE(claude.stream(messages, { system }), event);\n * }\n * const turn = await claude.generate(messages, { system });\n * return h3Adapter.sendJSON(turn, event);\n * });\n * ```\n */\nexport const h3 = {\n sendJSON,\n streamSSE,\n createSSEStream,\n sendError,\n};\n","/**\n * @fileoverview Web API adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Web API native frameworks\n * (Bun, Deno, Next.js App Router, Cloudflare Workers).\n *\n * These utilities return standard Web API Response objects that work\n * directly with modern runtimes.\n *\n * @module providers/proxy/server/webapi\n */\n\nimport type { Message } from '../../../types/messages.ts';\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { MessageJSON } from '../../../types/thread.ts';\nimport type { JSONSchema } from '../../../types/schema.ts';\nimport type { Tool, ToolMetadata } from '../../../types/tool.ts';\nimport {\n deserializeMessage,\n serializeTurn,\n serializeStreamEvent,\n} from '../serialization.ts';\n\n/**\n * Parsed request body from a proxy HTTP request.\n * This is just the deserialized PP data from the request body.\n */\nexport interface ParsedRequest {\n messages: Message[];\n system?: string | unknown[];\n params?: Record<string, unknown>;\n tools?: Array<{\n name: string;\n description: string;\n parameters: JSONSchema;\n metadata?: ToolMetadata;\n }>;\n structure?: JSONSchema;\n}\n\n/**\n * Parse an HTTP request body into PP types.\n *\n * @param body - The JSON-parsed request body\n * @returns Deserialized PP data\n *\n * @example\n * ```typescript\n * const body = await req.json();\n * const { messages, system, params } = parseBody(body);\n *\n * const instance = llm({ model: anthropic('...'), system, params });\n * const turn = await instance.generate(messages);\n * ```\n */\nexport function parseBody(body: unknown): ParsedRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.messages)) {\n throw new Error('Request body must have a messages array');\n }\n\n for (const message of data.messages) {\n if (!message || typeof message !== 'object') {\n throw new Error('Each message must be an object');\n }\n const msg = message as Record<string, unknown>;\n if (typeof msg.id !== 'string') {\n throw new Error('Each message must have a string id');\n }\n if (typeof msg.type !== 'string') {\n throw new Error('Each message must have a string type');\n }\n if (typeof msg.timestamp !== 'string') {\n throw new Error('Each message must have a string timestamp');\n }\n if ((msg.type === 'user' || msg.type === 'assistant') && !Array.isArray(msg.content)) {\n throw new Error('User and assistant messages must have a content array');\n }\n }\n\n return {\n messages: (data.messages as MessageJSON[]).map(deserializeMessage),\n system: data.system as string | unknown[] | undefined,\n params: data.params as Record<string, unknown> | undefined,\n tools: data.tools as ParsedRequest['tools'],\n structure: data.structure as JSONSchema | undefined,\n };\n}\n\n/**\n * Create a JSON Response from a Turn.\n *\n * @param turn - The completed inference turn\n * @returns HTTP Response with JSON body\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return toJSON(turn);\n * ```\n */\nexport function toJSON(turn: Turn): Response {\n return new Response(JSON.stringify(serializeTurn(turn)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create an SSE Response from a StreamResult.\n *\n * Streams PP StreamEvents as SSE, then sends the final Turn data.\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns HTTP Response with SSE body\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return toSSE(stream);\n * ```\n */\nexport function toSSE(stream: StreamResult): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n // Send the final turn data\n const turn = await stream.turn;\n const turnData = serializeTurn(turn);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(turnData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: {\"error\":\"${errorMsg}\"}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an error Response.\n *\n * @param message - Error message\n * @param status - HTTP status code (default: 500)\n * @returns HTTP Response with error body\n */\nexport function toError(message: string, status = 500): Response {\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Bind tool schemas to implementation functions.\n *\n * Takes tool schemas from the request and binds them to your\n * server-side implementations.\n *\n * @param schemas - Tool schemas from the request\n * @param implementations - Map of tool name to implementation\n * @returns Array of complete Tool objects\n *\n * @example\n * ```typescript\n * const { tools: schemas } = parseBody(body);\n *\n * const tools = bindTools(schemas, {\n * get_weather: async ({ location }) => fetchWeather(location),\n * search: async ({ query }) => searchDB(query),\n * });\n *\n * const instance = llm({ model, tools });\n * ```\n */\nexport function bindTools(\n schemas: ParsedRequest['tools'],\n implementations: Record<string, (params: unknown) => unknown | Promise<unknown>>\n): Tool[] {\n if (!schemas) return [];\n\n return schemas.map((schema) => {\n const run = implementations[schema.name];\n if (!run) {\n throw new Error(`No implementation for tool: ${schema.name}`);\n }\n return { ...schema, run };\n });\n}\n\n/**\n * Web API adapter utilities.\n *\n * For use with Bun, Deno, Next.js App Router, Cloudflare Workers,\n * and other frameworks that support Web API Response.\n *\n * **Security Note:** The proxy works without configuration, meaning no\n * authentication by default. Always add your own auth layer in production.\n *\n * @example Basic usage\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, toJSON, toSSE } from '@providerprotocol/ai/proxy';\n *\n * // Bun.serve / Deno.serve / Next.js App Router\n * export async function POST(req: Request) {\n * const { messages, system } = parseBody(await req.json());\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (req.headers.get('accept')?.includes('text/event-stream')) {\n * return toSSE(instance.stream(messages));\n * }\n * return toJSON(await instance.generate(messages));\n * }\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody, toJSON, toSSE, toError } from '@providerprotocol/ai/proxy';\n *\n * // Your platform's user validation\n * async function validateToken(token: string): Promise<{ id: string } | null> {\n * // Verify JWT, check database, etc.\n * return token ? { id: 'user-123' } : null;\n * }\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * Bun.serve({\n * port: 3000,\n * async fetch(req) {\n * // Authenticate with YOUR platform credentials\n * const token = req.headers.get('Authorization')?.replace('Bearer ', '');\n * const user = await validateToken(token ?? '');\n * if (!user) return toError('Unauthorized', 401);\n *\n * // Rate limit, track usage, bill user, etc.\n * // await trackUsage(user.id);\n *\n * const { messages, system, params } = parseBody(await req.json());\n *\n * if (params?.stream) {\n * return toSSE(claude.stream(messages, { system }));\n * }\n * return toJSON(await claude.generate(messages, { system }));\n * },\n * });\n * ```\n */\nexport const webapi = {\n parseBody,\n toJSON,\n toSSE,\n toError,\n bindTools,\n};\n","/**\n * @fileoverview Framework adapters for proxy server utilities.\n *\n * Provides framework-specific adapters for using PP proxy with various\n * server frameworks. The base Web API utilities (toJSON, toSSE) work with\n * modern frameworks like Bun, Deno, and Next.js App Router. These adapters\n * provide native integration for Express, Fastify, and H3/Nuxt.\n *\n * @module providers/proxy/server\n */\n\nimport { express } from './express.ts';\nimport { fastify } from './fastify.ts';\nimport { h3 } from './h3.ts';\nimport { webapi, parseBody, toJSON, toSSE, toError, bindTools } from './webapi.ts';\n\nexport { express, fastify, h3, webapi };\nexport { parseBody, toJSON, toSSE, toError, bindTools };\nexport type { ParsedRequest } from './webapi.ts';\n\nexport type {\n ParsedBody,\n ProxyHandler,\n RequestMeta,\n AdapterOptions,\n} from './types.ts';\n\n/**\n * Server adapters namespace.\n *\n * Contains framework-specific adapters for Web API, Express, Fastify, and H3.\n *\n * @example Express\n * ```typescript\n * import { express } from '@providerprotocol/ai/proxy/server';\n *\n * app.post('/api/ai', async (req, res) => {\n * const { messages } = parseBody(req.body);\n * if (req.headers.accept?.includes('text/event-stream')) {\n * express.streamSSE(instance.stream(messages), res);\n * } else {\n * express.sendJSON(await instance.generate(messages), res);\n * }\n * });\n * ```\n *\n * @example Fastify\n * ```typescript\n * import { fastify } from '@providerprotocol/ai/proxy/server';\n *\n * app.post('/api/ai', async (request, reply) => {\n * const { messages } = parseBody(request.body);\n * if (request.headers.accept?.includes('text/event-stream')) {\n * return fastify.streamSSE(instance.stream(messages), reply);\n * }\n * return fastify.sendJSON(await instance.generate(messages), reply);\n * });\n * ```\n *\n * @example H3/Nuxt\n * ```typescript\n * import { h3 } from '@providerprotocol/ai/proxy/server';\n *\n * export default defineEventHandler(async (event) => {\n * const { messages } = parseBody(await readBody(event));\n * if (getHeader(event, 'accept')?.includes('text/event-stream')) {\n * return h3.streamSSE(instance.stream(messages), event);\n * }\n * return h3.sendJSON(await instance.generate(messages), event);\n * });\n * ```\n */\nexport const server = {\n /** Web API adapter (Bun, Deno, Next.js, Workers) */\n webapi,\n /** Express/Connect adapter */\n express,\n /** Fastify adapter */\n fastify,\n /** H3/Nitro/Nuxt adapter */\n h3,\n};\n","import { createProvider } from '../../core/provider.ts';\nimport type { ModelReference } from '../../types/provider.ts';\nimport { createLLMHandler } from './llm.ts';\nimport type { ProxyProviderOptions, ProxyRequestOptions } from './types.ts';\n\n/**\n * Creates a proxy provider that transports PP requests over HTTP to a backend server.\n *\n * The proxy acts as a pure transport layer - PP types go in, PP types come out.\n * The modelId is passed through to the backend, which decides which actual model to use.\n *\n * @param options - Configuration for the proxy endpoint\n * @returns A provider that can be used with llm()\n *\n * @example\n * ```typescript\n * import { proxy } from './providers/proxy';\n * import { llm } from './core/llm';\n *\n * const backend = proxy({ endpoint: '/api/ai' });\n *\n * const model = llm({\n * model: backend('gpt-4o'),\n * system: 'You are a helpful assistant.',\n * });\n *\n * const turn = await model.generate('Hello!');\n * ```\n */\nexport function proxy(options: ProxyProviderOptions) {\n return createProvider<ProxyRequestOptions>({\n name: 'proxy',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(options),\n },\n });\n}\n\n/**\n * Shorthand for creating a proxy model reference with default model ID.\n *\n * Creates a proxy provider and immediately returns a model reference using\n * 'default' as the model identifier. Useful for simple single-endpoint setups.\n *\n * @param endpoint - The URL to proxy requests to\n * @returns A model reference for use with llm()\n *\n * @example\n * ```typescript\n * import { proxyModel } from './providers/proxy';\n * import { llm } from './core/llm';\n *\n * const model = llm({ model: proxyModel('/api/ai') });\n * const turn = await model.generate('Hello!');\n * ```\n */\nexport function proxyModel(endpoint: string): ModelReference<ProxyRequestOptions> {\n return proxy({ endpoint })('default');\n}\n\n// Re-export types\nexport type {\n ProxyLLMParams,\n ProxyProviderOptions,\n ProxyRequestOptions,\n} from './types.ts';\n\n// Re-export serialization utilities\nexport {\n serializeMessage,\n deserializeMessage,\n serializeTurn,\n serializeStreamEvent,\n deserializeStreamEvent,\n} from './serialization.ts';\n\n// Re-export server adapters\nexport { server, express, fastify, h3 } from './server/index.ts';\nexport type { ParsedBody, ProxyHandler, RequestMeta, AdapterOptions } from './server/index.ts';\n"],"mappings":"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","names":["sendJSON","streamSSE","sendError","sendJSON","streamSSE","sendError","toError"]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/proxy/serialization.ts","../../src/providers/proxy/llm.ts","../../src/providers/proxy/server/express.ts","../../src/providers/proxy/server/fastify.ts","../../src/providers/proxy/server/h3.ts","../../src/providers/proxy/server/webapi.ts","../../src/providers/proxy/server/index.ts","../../src/providers/proxy/index.ts"],"sourcesContent":["/**\n * @fileoverview Serialization utilities for proxy transport.\n *\n * Handles converting PP types to/from JSON for HTTP transport.\n * These are pure functions with no side effects.\n *\n * @module providers/proxy/serialization\n */\n\nimport {\n UserMessage,\n AssistantMessage,\n ToolResultMessage,\n type Message,\n type MessageJSON,\n} from '../../types/messages.ts';\nimport type { UserContent, AssistantContent } from '../../types/content.ts';\nimport type { StreamEvent, EventDelta } from '../../types/stream.ts';\nimport type { Turn, TurnJSON } from '../../types/turn.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\n\n/**\n * Convert a Message to MessageJSON format.\n */\nexport function serializeMessage(m: Message): MessageJSON {\n const base: MessageJSON = {\n id: m.id,\n type: m.type,\n content: [],\n metadata: m.metadata,\n timestamp: m.timestamp.toISOString(),\n };\n\n if (m instanceof UserMessage) {\n base.content = m.content;\n } else if (m instanceof AssistantMessage) {\n base.content = m.content;\n base.toolCalls = m.toolCalls;\n } else if (m instanceof ToolResultMessage) {\n base.results = m.results;\n }\n\n return base;\n}\n\n/**\n * Reconstruct a Message from MessageJSON format.\n */\nexport function deserializeMessage(json: MessageJSON): Message {\n const options = {\n id: json.id,\n metadata: json.metadata,\n };\n\n switch (json.type) {\n case 'user':\n return new UserMessage(json.content as UserContent[], options);\n case 'assistant':\n return new AssistantMessage(\n json.content as AssistantContent[],\n json.toolCalls,\n options\n );\n case 'tool_result':\n return new ToolResultMessage(json.results ?? [], options);\n default:\n throw new UPPError(\n `Unknown message type: ${json.type}`,\n ErrorCode.InvalidResponse,\n 'proxy',\n ModalityType.LLM\n );\n }\n}\n\n/**\n * Serialize a Turn to JSON-transportable format.\n */\nexport function serializeTurn(turn: Turn): TurnJSON {\n return {\n messages: turn.messages.map(serializeMessage),\n toolExecutions: turn.toolExecutions,\n usage: turn.usage,\n cycles: turn.cycles,\n data: turn.data,\n };\n}\n\n/**\n * Serialize a StreamEvent for JSON transport.\n * Converts Uint8Array data to base64 string.\n */\nexport function serializeStreamEvent(event: StreamEvent): StreamEvent {\n if (event.delta.data instanceof Uint8Array) {\n const { data, ...rest } = event.delta;\n const bytes = Array.from(data);\n const base64 = btoa(bytes.map((b) => String.fromCharCode(b)).join(''));\n return {\n type: event.type,\n index: event.index,\n delta: { ...rest, data: base64 as unknown as Uint8Array },\n };\n }\n return event;\n}\n\n/**\n * Deserialize a StreamEvent from JSON transport.\n * Converts base64 string data back to Uint8Array.\n */\nexport function deserializeStreamEvent(event: StreamEvent): StreamEvent {\n const delta = event.delta as EventDelta & { data?: string | Uint8Array };\n if (typeof delta.data === 'string') {\n const binaryString = atob(delta.data);\n const bytes = Uint8Array.from(binaryString, (c) => c.charCodeAt(0));\n return {\n type: event.type,\n index: event.index,\n delta: { ...delta, data: bytes },\n };\n }\n return event;\n}\n","/**\n * @fileoverview Proxy LLM handler implementation.\n *\n * Transports PP LLM requests over HTTP to a backend server.\n * Supports both synchronous completion and streaming via SSE.\n * Full support for retry strategies, timeouts, and custom headers.\n *\n * @module providers/proxy/llm\n */\n\nimport type {\n LLMHandler,\n BoundLLMModel,\n LLMRequest,\n LLMResponse,\n LLMStreamResult,\n LLMCapabilities,\n} from '../../types/llm.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { TurnJSON } from '../../types/turn.ts';\nimport { AssistantMessage } from '../../types/messages.ts';\nimport { emptyUsage } from '../../types/turn.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { ProxyLLMParams, ProxyProviderOptions } from './types.ts';\nimport {\n serializeMessage,\n deserializeMessage,\n deserializeStreamEvent,\n} from './serialization.ts';\n\n/**\n * Capability flags for proxy provider.\n * All capabilities are enabled since the backend determines actual support.\n */\nconst PROXY_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n videoInput: true,\n audioInput: true,\n};\n\n/**\n * Creates a proxy LLM handler.\n *\n * Supports full ProviderConfig options including retry strategies, timeouts,\n * custom headers, and custom fetch implementations. This allows client-side\n * retry logic for network failures to the proxy server.\n *\n * @param options - Proxy configuration options\n * @returns An LLM handler that transports requests over HTTP\n *\n * @example\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { proxy } from '@providerprotocol/ai/proxy';\n * import { ExponentialBackoff } from '@providerprotocol/ai/http';\n *\n * const claude = llm({\n * model: proxy('https://api.myplatform.com/ai'),\n * config: {\n * headers: { 'Authorization': 'Bearer user-token' },\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * timeout: 30000,\n * },\n * });\n * ```\n */\nexport function createLLMHandler(options: ProxyProviderOptions): LLMHandler<ProxyLLMParams> {\n const { endpoint, headers: defaultHeaders = {} } = options;\n\n let providerRef: LLMProvider<ProxyLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<ProxyLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<ProxyLLMParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'proxy',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<ProxyLLMParams> = {\n modelId,\n capabilities: PROXY_CAPABILITIES,\n\n get provider(): LLMProvider<ProxyLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<ProxyLLMParams>): Promise<LLMResponse> {\n const body = serializeRequest(request);\n const headers = mergeHeaders(request.config.headers, defaultHeaders);\n\n const response = await doFetch(\n endpoint,\n {\n method: 'POST',\n headers: {\n ...headers,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'proxy',\n 'llm'\n );\n\n const data = await parseJsonResponse<TurnJSON>(response, 'proxy', 'llm');\n return turnJSONToLLMResponse(data);\n },\n\n stream(request: LLMRequest<ProxyLLMParams>): LLMStreamResult {\n const body = serializeRequest(request);\n const headers = mergeHeaders(request.config.headers, defaultHeaders);\n\n let resolveResponse: (value: LLMResponse) => void;\n let rejectResponse: (error: Error) => void;\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n resolveResponse = resolve;\n rejectResponse = reject;\n });\n\n const generator = async function* (): AsyncGenerator<StreamEvent> {\n try {\n const response = await doStreamFetch(\n endpoint,\n {\n method: 'POST',\n headers: {\n ...headers,\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n },\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'proxy',\n 'llm'\n );\n\n if (!response.ok) {\n throw await normalizeHttpError(response, 'proxy', 'llm');\n }\n\n if (!response.body) {\n throw new UPPError(\n 'Response body is null',\n ErrorCode.ProviderError,\n 'proxy',\n ModalityType.LLM\n );\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (!line.trim() || line.startsWith(':')) continue;\n\n if (line.startsWith('data:')) {\n let data = line.slice(5);\n if (data.startsWith(' ')) {\n data = data.slice(1);\n }\n if (data === '[DONE]') continue;\n\n try {\n const parsed = JSON.parse(data);\n\n // Check if this is the final turn data\n if ('messages' in parsed && 'usage' in parsed && 'cycles' in parsed) {\n resolveResponse(turnJSONToLLMResponse(parsed as TurnJSON));\n } else {\n // It's a StreamEvent\n yield deserializeStreamEvent(parsed as StreamEvent);\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n const remaining = decoder.decode();\n if (remaining) {\n buffer += remaining;\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.trim() || line.startsWith(':')) continue;\n if (line.startsWith('data:')) {\n let data = line.slice(5);\n if (data.startsWith(' ')) {\n data = data.slice(1);\n }\n if (data === '[DONE]') continue;\n try {\n const parsed = JSON.parse(data);\n if ('messages' in parsed && 'usage' in parsed && 'cycles' in parsed) {\n resolveResponse(turnJSONToLLMResponse(parsed as TurnJSON));\n } else {\n yield deserializeStreamEvent(parsed as StreamEvent);\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n }\n } catch (error) {\n rejectResponse(toError(error));\n throw error;\n }\n };\n\n return {\n [Symbol.asyncIterator]: generator,\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n\n/**\n * Serialize an LLMRequest for HTTP transport.\n */\nfunction serializeRequest(request: LLMRequest<ProxyLLMParams>): Record<string, unknown> {\n return {\n messages: request.messages.map(serializeMessage),\n system: request.system,\n params: request.params,\n tools: request.tools?.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n metadata: t.metadata,\n })),\n structure: request.structure,\n };\n}\n\n/**\n * Merge request headers with default headers.\n */\nfunction mergeHeaders(\n requestHeaders: Record<string, string | undefined> | undefined,\n defaultHeaders: Record<string, string>\n): Record<string, string> {\n const headers: Record<string, string> = { ...defaultHeaders };\n if (requestHeaders) {\n for (const [key, value] of Object.entries(requestHeaders)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n return headers;\n}\n\n/**\n * Convert TurnJSON to LLMResponse.\n */\nfunction turnJSONToLLMResponse(data: TurnJSON): LLMResponse {\n const messages = data.messages.map(deserializeMessage);\n const lastAssistant = messages\n .filter((m): m is AssistantMessage => m.type === 'assistant')\n .pop();\n\n const stopReason = deriveStopReason(lastAssistant);\n\n return {\n message: lastAssistant ?? new AssistantMessage(''),\n usage: data.usage ?? emptyUsage(),\n stopReason,\n data: data.data,\n };\n}\n\nfunction deriveStopReason(message: AssistantMessage | undefined): string {\n if (!message) {\n return 'end_turn';\n }\n\n if (message.toolCalls && message.toolCalls.length > 0) {\n return 'tool_use';\n }\n\n const metadata = message.metadata;\n const openaiMeta = metadata?.openai as { finish_reason?: string; status?: string } | undefined;\n if (openaiMeta?.status) {\n if (openaiMeta.status === 'failed') {\n return 'error';\n }\n if (openaiMeta.status === 'completed') {\n return 'end_turn';\n }\n }\n if (openaiMeta?.finish_reason) {\n return mapCompletionStopReason(openaiMeta.finish_reason);\n }\n\n const openrouterMeta = metadata?.openrouter as { finish_reason?: string } | undefined;\n if (openrouterMeta?.finish_reason) {\n return mapCompletionStopReason(openrouterMeta.finish_reason);\n }\n\n const xaiMeta = metadata?.xai as { finish_reason?: string; status?: string } | undefined;\n if (xaiMeta?.status) {\n if (xaiMeta.status === 'failed') {\n return 'error';\n }\n if (xaiMeta.status === 'completed') {\n return 'end_turn';\n }\n }\n if (xaiMeta?.finish_reason) {\n return mapCompletionStopReason(xaiMeta.finish_reason);\n }\n\n const anthropicMeta = metadata?.anthropic as { stop_reason?: string } | undefined;\n if (anthropicMeta?.stop_reason) {\n return mapAnthropicStopReason(anthropicMeta.stop_reason);\n }\n\n const googleMeta = metadata?.google as { finishReason?: string } | undefined;\n if (googleMeta?.finishReason) {\n return mapGoogleStopReason(googleMeta.finishReason);\n }\n\n const ollamaMeta = metadata?.ollama as { done_reason?: string } | undefined;\n if (ollamaMeta?.done_reason) {\n return mapOllamaStopReason(ollamaMeta.done_reason);\n }\n\n return 'end_turn';\n}\n\nfunction mapCompletionStopReason(reason: string): string {\n switch (reason) {\n case 'stop':\n return 'end_turn';\n case 'length':\n return 'max_tokens';\n case 'tool_calls':\n return 'tool_use';\n case 'content_filter':\n return 'content_filter';\n default:\n return 'end_turn';\n }\n}\n\nfunction mapAnthropicStopReason(reason: string): string {\n switch (reason) {\n case 'tool_use':\n return 'tool_use';\n case 'max_tokens':\n return 'max_tokens';\n case 'end_turn':\n return 'end_turn';\n case 'stop_sequence':\n return 'end_turn';\n default:\n return 'end_turn';\n }\n}\n\nfunction mapGoogleStopReason(reason: string): string {\n switch (reason) {\n case 'STOP':\n return 'end_turn';\n case 'MAX_TOKENS':\n return 'max_tokens';\n case 'SAFETY':\n return 'content_filter';\n case 'RECITATION':\n return 'content_filter';\n case 'OTHER':\n return 'end_turn';\n default:\n return 'end_turn';\n }\n}\n\nfunction mapOllamaStopReason(reason: string): string {\n if (reason === 'length') {\n return 'max_tokens';\n }\n if (reason === 'stop') {\n return 'end_turn';\n }\n return 'end_turn';\n}\n","/**\n * @fileoverview Express/Connect adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Express.js or Connect-based servers.\n * These adapters convert PP types to Express-compatible responses.\n *\n * @module providers/proxy/server/express\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\n\n/**\n * Express Response interface (minimal type to avoid dependency).\n */\ninterface ExpressResponse {\n setHeader(name: string, value: string): void;\n status(code: number): ExpressResponse;\n write(chunk: string): boolean;\n end(): void;\n json(body: unknown): void;\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param res - Express response object\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * expressAdapter.sendJSON(turn, res);\n * ```\n */\nexport function sendJSON(turn: Turn, res: ExpressResponse): void {\n res.setHeader('Content-Type', 'application/json');\n res.json(serializeTurn(turn));\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * @param stream - The StreamResult from instance.stream()\n * @param res - Express response object\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * expressAdapter.streamSSE(stream, res);\n * ```\n */\nexport function streamSSE(stream: StreamResult, res: ExpressResponse): void {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n (async () => {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n res.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n res.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n res.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n res.end();\n }\n })();\n}\n\n/**\n * Send an error response.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param res - Express response object\n */\nexport function sendError(message: string, status: number, res: ExpressResponse): void {\n res.status(status).json({ error: message });\n}\n\n/**\n * Express adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * import express from 'express';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { express as expressAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = express();\n * app.use(express.json());\n *\n * app.post('/api/ai', async (req, res) => {\n * const { messages, system, params } = parseBody(req.body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (req.headers.accept?.includes('text/event-stream')) {\n * expressAdapter.streamSSE(instance.stream(messages), res);\n * } else {\n * const turn = await instance.generate(messages);\n * expressAdapter.sendJSON(turn, res);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import express from 'express';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { express as expressAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = express();\n * app.use(express.json());\n *\n * // Your platform's auth middleware\n * async function authMiddleware(req, res, next) {\n * const token = req.headers.authorization?.replace('Bearer ', '');\n * const user = await validatePlatformToken(token);\n * if (!user) return res.status(401).json({ error: 'Unauthorized' });\n * req.user = user;\n * next();\n * }\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * app.post('/api/ai', authMiddleware, async (req, res) => {\n * // Track usage per user\n * // await trackUsage(req.user.id);\n *\n * const { messages, system, params } = parseBody(req.body);\n *\n * if (params?.stream) {\n * expressAdapter.streamSSE(claude.stream(messages, { system }), res);\n * } else {\n * const turn = await claude.generate(messages, { system });\n * expressAdapter.sendJSON(turn, res);\n * }\n * });\n * ```\n */\nexport const express = {\n sendJSON,\n streamSSE,\n sendError,\n};\n","/**\n * @fileoverview Fastify adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Fastify servers.\n * These adapters convert PP types to Fastify-compatible responses.\n *\n * @module providers/proxy/server/fastify\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\n\n/**\n * Fastify Reply interface (minimal type to avoid dependency).\n */\ninterface FastifyReply {\n header(name: string, value: string): FastifyReply;\n status(code: number): FastifyReply;\n send(payload: unknown): FastifyReply;\n raw: {\n write(chunk: string): boolean;\n end(): void;\n };\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return fastifyAdapter.sendJSON(turn, reply);\n * ```\n */\nexport function sendJSON(turn: Turn, reply: FastifyReply): FastifyReply {\n return reply\n .header('Content-Type', 'application/json')\n .send(serializeTurn(turn));\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * @param stream - The StreamResult from instance.stream()\n * @param reply - Fastify reply object\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return fastifyAdapter.streamSSE(stream, reply);\n * ```\n */\nexport function streamSSE(stream: StreamResult, reply: FastifyReply): FastifyReply {\n reply\n .header('Content-Type', 'text/event-stream')\n .header('Cache-Control', 'no-cache')\n .header('Connection', 'keep-alive');\n\n const raw = reply.raw;\n\n (async () => {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n raw.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n raw.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n raw.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n raw.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n raw.end();\n }\n })();\n\n return reply;\n}\n\n/**\n * Send an error response.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param reply - Fastify reply object\n */\nexport function sendError(message: string, status: number, reply: FastifyReply): FastifyReply {\n return reply.status(status).send({ error: message });\n}\n\n/**\n * Fastify adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * import Fastify from 'fastify';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { fastify as fastifyAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = Fastify();\n *\n * app.post('/api/ai', async (request, reply) => {\n * const { messages, system, params } = parseBody(request.body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (request.headers.accept?.includes('text/event-stream')) {\n * return fastifyAdapter.streamSSE(instance.stream(messages), reply);\n * } else {\n * const turn = await instance.generate(messages);\n * return fastifyAdapter.sendJSON(turn, reply);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import Fastify from 'fastify';\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { fastify as fastifyAdapter } from '@providerprotocol/ai/proxy/server';\n *\n * const app = Fastify();\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * // Auth hook for your platform\n * app.addHook('preHandler', async (request, reply) => {\n * const token = request.headers.authorization?.replace('Bearer ', '');\n * const user = await validatePlatformToken(token);\n * if (!user) {\n * reply.status(401).send({ error: 'Unauthorized' });\n * return;\n * }\n * request.user = user;\n * });\n *\n * app.post('/api/ai', async (request, reply) => {\n * // Track usage per user\n * // await trackUsage(request.user.id);\n *\n * const { messages, system, params } = parseBody(request.body);\n *\n * if (params?.stream) {\n * return fastifyAdapter.streamSSE(claude.stream(messages, { system }), reply);\n * }\n * const turn = await claude.generate(messages, { system });\n * return fastifyAdapter.sendJSON(turn, reply);\n * });\n * ```\n */\nexport const fastify = {\n sendJSON,\n streamSSE,\n sendError,\n};\n","/**\n * @fileoverview H3/Nitro/Nuxt adapter for proxy server.\n *\n * Provides utilities for using PP proxy with H3-based servers\n * (Nuxt, Nitro, or standalone H3).\n *\n * @module providers/proxy/server/h3\n */\n\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport { serializeTurn, serializeStreamEvent } from '../serialization.ts';\n\n/**\n * H3 Event interface (minimal type to avoid dependency).\n */\ninterface H3Event {\n node: {\n res: {\n setHeader(name: string, value: string): void;\n write(chunk: string): boolean;\n end(): void;\n };\n };\n}\n\n/**\n * Send a Turn as JSON response.\n *\n * @param turn - The completed inference turn\n * @param event - H3 event object\n * @returns Serialized turn data\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return h3Adapter.sendJSON(turn, event);\n * ```\n */\nexport function sendJSON(turn: Turn, event: H3Event): unknown {\n event.node.res.setHeader('Content-Type', 'application/json');\n return serializeTurn(turn);\n}\n\n/**\n * Stream a StreamResult as Server-Sent Events.\n *\n * @param stream - The StreamResult from instance.stream()\n * @param event - H3 event object\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return h3Adapter.streamSSE(stream, event);\n * ```\n */\nexport function streamSSE(stream: StreamResult, event: H3Event): void {\n const res = event.node.res;\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n (async () => {\n try {\n for await (const evt of stream) {\n const serialized = serializeStreamEvent(evt);\n res.write(`data: ${JSON.stringify(serialized)}\\n\\n`);\n }\n\n const turn = await stream.turn;\n res.write(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`);\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n res.write(`data: ${JSON.stringify({ error: message })}\\n\\n`);\n } finally {\n res.end();\n }\n })();\n}\n\n/**\n * Create a ReadableStream for H3's sendStream utility.\n *\n * Use this with H3's sendStream for better integration:\n * ```typescript\n * import { sendStream } from 'h3';\n * return sendStream(event, h3Adapter.createSSEStream(stream));\n * ```\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns A ReadableStream of SSE data\n */\nexport function createSSEStream(stream: StreamResult): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(serialized)}\\n\\n`));\n }\n\n const turn = await stream.turn;\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(serializeTurn(turn))}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: message })}\\n\\n`));\n } finally {\n controller.close();\n }\n },\n });\n}\n\n/**\n * Send an error response.\n *\n * @param message - Error message\n * @param status - HTTP status code\n * @param event - H3 event object\n * @returns Error object for H3 to serialize\n */\nexport function sendError(message: string, status: number, event: H3Event): { error: string; statusCode: number } {\n return { error: message, statusCode: status };\n}\n\n/**\n * H3/Nitro/Nuxt adapter utilities.\n *\n * @example Basic usage\n * ```typescript\n * // Nuxt server route: server/api/ai.post.ts\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { h3 as h3Adapter } from '@providerprotocol/ai/proxy/server';\n *\n * export default defineEventHandler(async (event) => {\n * const body = await readBody(event);\n * const { messages, system, params } = parseBody(body);\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * const wantsStream = getHeader(event, 'accept')?.includes('text/event-stream');\n * if (wantsStream) {\n * return h3Adapter.streamSSE(instance.stream(messages), event);\n * } else {\n * const turn = await instance.generate(messages);\n * return h3Adapter.sendJSON(turn, event);\n * }\n * });\n * ```\n *\n * @example API Gateway with authentication (Nuxt)\n * ```typescript\n * // server/api/ai.post.ts\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody } from '@providerprotocol/ai/proxy';\n * import { h3 as h3Adapter } from '@providerprotocol/ai/proxy/server';\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([\n * process.env.ANTHROPIC_KEY_1!,\n * process.env.ANTHROPIC_KEY_2!,\n * ]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * export default defineEventHandler(async (event) => {\n * // Authenticate with your platform credentials\n * const token = getHeader(event, 'authorization')?.replace('Bearer ', '');\n * const user = await validatePlatformToken(token);\n * if (!user) {\n * throw createError({ statusCode: 401, message: 'Unauthorized' });\n * }\n *\n * // Track usage per user\n * // await trackUsage(user.id);\n *\n * const body = await readBody(event);\n * const { messages, system, params } = parseBody(body);\n *\n * if (params?.stream) {\n * return h3Adapter.streamSSE(claude.stream(messages, { system }), event);\n * }\n * const turn = await claude.generate(messages, { system });\n * return h3Adapter.sendJSON(turn, event);\n * });\n * ```\n */\nexport const h3 = {\n sendJSON,\n streamSSE,\n createSSEStream,\n sendError,\n};\n","/**\n * @fileoverview Web API adapter for proxy server.\n *\n * Provides utilities for using PP proxy with Web API native frameworks\n * (Bun, Deno, Next.js App Router, Cloudflare Workers).\n *\n * These utilities return standard Web API Response objects that work\n * directly with modern runtimes.\n *\n * @module providers/proxy/server/webapi\n */\n\nimport type { Message } from '../../../types/messages.ts';\nimport type { Turn } from '../../../types/turn.ts';\nimport type { StreamResult } from '../../../types/stream.ts';\nimport type { MessageJSON } from '../../../types/thread.ts';\nimport type { JSONSchema } from '../../../types/schema.ts';\nimport type { Tool, ToolMetadata } from '../../../types/tool.ts';\nimport {\n deserializeMessage,\n serializeTurn,\n serializeStreamEvent,\n} from '../serialization.ts';\n\n/**\n * Parsed request body from a proxy HTTP request.\n * This is just the deserialized PP data from the request body.\n */\nexport interface ParsedRequest {\n messages: Message[];\n system?: string | unknown[];\n params?: Record<string, unknown>;\n tools?: Array<{\n name: string;\n description: string;\n parameters: JSONSchema;\n metadata?: ToolMetadata;\n }>;\n structure?: JSONSchema;\n}\n\n/**\n * Parse an HTTP request body into PP types.\n *\n * @param body - The JSON-parsed request body\n * @returns Deserialized PP data\n *\n * @example\n * ```typescript\n * const body = await req.json();\n * const { messages, system, params } = parseBody(body);\n *\n * const instance = llm({ model: anthropic('...'), system, params });\n * const turn = await instance.generate(messages);\n * ```\n */\nexport function parseBody(body: unknown): ParsedRequest {\n if (!body || typeof body !== 'object') {\n throw new Error('Request body must be an object');\n }\n\n const data = body as Record<string, unknown>;\n\n if (!Array.isArray(data.messages)) {\n throw new Error('Request body must have a messages array');\n }\n\n for (const message of data.messages) {\n if (!message || typeof message !== 'object') {\n throw new Error('Each message must be an object');\n }\n const msg = message as Record<string, unknown>;\n if (typeof msg.id !== 'string') {\n throw new Error('Each message must have a string id');\n }\n if (typeof msg.type !== 'string') {\n throw new Error('Each message must have a string type');\n }\n if (typeof msg.timestamp !== 'string') {\n throw new Error('Each message must have a string timestamp');\n }\n if ((msg.type === 'user' || msg.type === 'assistant') && !Array.isArray(msg.content)) {\n throw new Error('User and assistant messages must have a content array');\n }\n }\n\n return {\n messages: (data.messages as MessageJSON[]).map(deserializeMessage),\n system: data.system as string | unknown[] | undefined,\n params: data.params as Record<string, unknown> | undefined,\n tools: data.tools as ParsedRequest['tools'],\n structure: data.structure as JSONSchema | undefined,\n };\n}\n\n/**\n * Create a JSON Response from a Turn.\n *\n * @param turn - The completed inference turn\n * @returns HTTP Response with JSON body\n *\n * @example\n * ```typescript\n * const turn = await instance.generate(messages);\n * return toJSON(turn);\n * ```\n */\nexport function toJSON(turn: Turn): Response {\n return new Response(JSON.stringify(serializeTurn(turn)), {\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Create an SSE Response from a StreamResult.\n *\n * Streams PP StreamEvents as SSE, then sends the final Turn data.\n *\n * @param stream - The StreamResult from instance.stream()\n * @returns HTTP Response with SSE body\n *\n * @example\n * ```typescript\n * const stream = instance.stream(messages);\n * return toSSE(stream);\n * ```\n */\nexport function toSSE(stream: StreamResult): Response {\n const encoder = new TextEncoder();\n\n const readable = new ReadableStream({\n async start(controller) {\n try {\n for await (const event of stream) {\n const serialized = serializeStreamEvent(event);\n const data = `data: ${JSON.stringify(serialized)}\\n\\n`;\n controller.enqueue(encoder.encode(data));\n }\n\n // Send the final turn data\n const turn = await stream.turn;\n const turnData = serializeTurn(turn);\n controller.enqueue(encoder.encode(`data: ${JSON.stringify(turnData)}\\n\\n`));\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n controller.close();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n controller.enqueue(encoder.encode(`data: {\"error\":\"${errorMsg}\"}\\n\\n`));\n controller.close();\n }\n },\n });\n\n return new Response(readable, {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n\n/**\n * Create an error Response.\n *\n * @param message - Error message\n * @param status - HTTP status code (default: 500)\n * @returns HTTP Response with error body\n */\nexport function toError(message: string, status = 500): Response {\n return new Response(JSON.stringify({ error: message }), {\n status,\n headers: { 'Content-Type': 'application/json' },\n });\n}\n\n/**\n * Bind tool schemas to implementation functions.\n *\n * Takes tool schemas from the request and binds them to your\n * server-side implementations.\n *\n * @param schemas - Tool schemas from the request\n * @param implementations - Map of tool name to implementation\n * @returns Array of complete Tool objects\n *\n * @example\n * ```typescript\n * const { tools: schemas } = parseBody(body);\n *\n * const tools = bindTools(schemas, {\n * get_weather: async ({ location }) => fetchWeather(location),\n * search: async ({ query }) => searchDB(query),\n * });\n *\n * const instance = llm({ model, tools });\n * ```\n */\nexport function bindTools(\n schemas: ParsedRequest['tools'],\n implementations: Record<string, (params: unknown) => unknown | Promise<unknown>>\n): Tool[] {\n if (!schemas) return [];\n\n return schemas.map((schema) => {\n const run = implementations[schema.name];\n if (!run) {\n throw new Error(`No implementation for tool: ${schema.name}`);\n }\n return { ...schema, run };\n });\n}\n\n/**\n * Web API adapter utilities.\n *\n * For use with Bun, Deno, Next.js App Router, Cloudflare Workers,\n * and other frameworks that support Web API Response.\n *\n * **Security Note:** The proxy works without configuration, meaning no\n * authentication by default. Always add your own auth layer in production.\n *\n * @example Basic usage\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { parseBody, toJSON, toSSE } from '@providerprotocol/ai/proxy';\n *\n * // Bun.serve / Deno.serve / Next.js App Router\n * export async function POST(req: Request) {\n * const { messages, system } = parseBody(await req.json());\n * const instance = llm({ model: anthropic('claude-sonnet-4-20250514'), system });\n *\n * if (req.headers.get('accept')?.includes('text/event-stream')) {\n * return toSSE(instance.stream(messages));\n * }\n * return toJSON(await instance.generate(messages));\n * }\n * ```\n *\n * @example API Gateway with authentication\n * ```typescript\n * import { llm } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n * import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';\n * import { parseBody, toJSON, toSSE, toError } from '@providerprotocol/ai/proxy';\n *\n * // Your platform's user validation\n * async function validateToken(token: string): Promise<{ id: string } | null> {\n * // Verify JWT, check database, etc.\n * return token ? { id: 'user-123' } : null;\n * }\n *\n * // Server manages AI provider keys - users never see them\n * const claude = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * config: {\n * apiKey: new RoundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),\n * retryStrategy: new ExponentialBackoff({ maxAttempts: 3 }),\n * },\n * });\n *\n * Bun.serve({\n * port: 3000,\n * async fetch(req) {\n * // Authenticate with YOUR platform credentials\n * const token = req.headers.get('Authorization')?.replace('Bearer ', '');\n * const user = await validateToken(token ?? '');\n * if (!user) return toError('Unauthorized', 401);\n *\n * // Rate limit, track usage, bill user, etc.\n * // await trackUsage(user.id);\n *\n * const { messages, system, params } = parseBody(await req.json());\n *\n * if (params?.stream) {\n * return toSSE(claude.stream(messages, { system }));\n * }\n * return toJSON(await claude.generate(messages, { system }));\n * },\n * });\n * ```\n */\nexport const webapi = {\n parseBody,\n toJSON,\n toSSE,\n toError,\n bindTools,\n};\n","/**\n * @fileoverview Framework adapters for proxy server utilities.\n *\n * Provides framework-specific adapters for using PP proxy with various\n * server frameworks. The base Web API utilities (toJSON, toSSE) work with\n * modern frameworks like Bun, Deno, and Next.js App Router. These adapters\n * provide native integration for Express, Fastify, and H3/Nuxt.\n *\n * @module providers/proxy/server\n */\n\nimport { express } from './express.ts';\nimport { fastify } from './fastify.ts';\nimport { h3 } from './h3.ts';\nimport { webapi, parseBody, toJSON, toSSE, toError, bindTools } from './webapi.ts';\n\nexport { express, fastify, h3, webapi };\nexport { parseBody, toJSON, toSSE, toError, bindTools };\nexport type { ParsedRequest } from './webapi.ts';\n\nexport type {\n ParsedBody,\n ProxyHandler,\n RequestMeta,\n AdapterOptions,\n} from './types.ts';\n\n/**\n * Server adapters namespace.\n *\n * Contains framework-specific adapters for Web API, Express, Fastify, and H3.\n *\n * @example Express\n * ```typescript\n * import { express } from '@providerprotocol/ai/proxy/server';\n *\n * app.post('/api/ai', async (req, res) => {\n * const { messages } = parseBody(req.body);\n * if (req.headers.accept?.includes('text/event-stream')) {\n * express.streamSSE(instance.stream(messages), res);\n * } else {\n * express.sendJSON(await instance.generate(messages), res);\n * }\n * });\n * ```\n *\n * @example Fastify\n * ```typescript\n * import { fastify } from '@providerprotocol/ai/proxy/server';\n *\n * app.post('/api/ai', async (request, reply) => {\n * const { messages } = parseBody(request.body);\n * if (request.headers.accept?.includes('text/event-stream')) {\n * return fastify.streamSSE(instance.stream(messages), reply);\n * }\n * return fastify.sendJSON(await instance.generate(messages), reply);\n * });\n * ```\n *\n * @example H3/Nuxt\n * ```typescript\n * import { h3 } from '@providerprotocol/ai/proxy/server';\n *\n * export default defineEventHandler(async (event) => {\n * const { messages } = parseBody(await readBody(event));\n * if (getHeader(event, 'accept')?.includes('text/event-stream')) {\n * return h3.streamSSE(instance.stream(messages), event);\n * }\n * return h3.sendJSON(await instance.generate(messages), event);\n * });\n * ```\n */\nexport const server = {\n /** Web API adapter (Bun, Deno, Next.js, Workers) */\n webapi,\n /** Express/Connect adapter */\n express,\n /** Fastify adapter */\n fastify,\n /** H3/Nitro/Nuxt adapter */\n h3,\n};\n","import { createProvider } from '../../core/provider.ts';\nimport type { ModelReference } from '../../types/provider.ts';\nimport { createLLMHandler } from './llm.ts';\nimport type { ProxyProviderOptions, ProxyRequestOptions } from './types.ts';\n\n/**\n * Creates a proxy provider that transports PP requests over HTTP to a backend server.\n *\n * The proxy acts as a pure transport layer - PP types go in, PP types come out.\n * The modelId is passed through to the backend, which decides which actual model to use.\n *\n * @param options - Configuration for the proxy endpoint\n * @returns A provider that can be used with llm()\n *\n * @example\n * ```typescript\n * import { proxy } from './providers/proxy';\n * import { llm } from './core/llm';\n *\n * const backend = proxy({ endpoint: '/api/ai' });\n *\n * const model = llm({\n * model: backend('gpt-4o'),\n * system: 'You are a helpful assistant.',\n * });\n *\n * const turn = await model.generate('Hello!');\n * ```\n */\nexport function proxy(options: ProxyProviderOptions) {\n return createProvider<ProxyRequestOptions>({\n name: 'proxy',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(options),\n },\n });\n}\n\n/**\n * Shorthand for creating a proxy model reference with default model ID.\n *\n * Creates a proxy provider and immediately returns a model reference using\n * 'default' as the model identifier. Useful for simple single-endpoint setups.\n *\n * @param endpoint - The URL to proxy requests to\n * @returns A model reference for use with llm()\n *\n * @example\n * ```typescript\n * import { proxyModel } from './providers/proxy';\n * import { llm } from './core/llm';\n *\n * const model = llm({ model: proxyModel('/api/ai') });\n * const turn = await model.generate('Hello!');\n * ```\n */\nexport function proxyModel(endpoint: string): ModelReference<ProxyRequestOptions> {\n return proxy({ endpoint })('default');\n}\n\n// Re-export types\nexport type {\n ProxyLLMParams,\n ProxyProviderOptions,\n ProxyRequestOptions,\n} from './types.ts';\n\n// Re-export serialization utilities\nexport {\n serializeMessage,\n deserializeMessage,\n serializeTurn,\n serializeStreamEvent,\n deserializeStreamEvent,\n} from './serialization.ts';\n\n// Re-export server adapters\nexport { server, express, fastify, h3 } from './server/index.ts';\nexport type { ParsedBody, ProxyHandler, RequestMeta, AdapterOptions } from './server/index.ts';\n"],"mappings":"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","names":["sendJSON","streamSSE","sendError","sendJSON","streamSSE","sendError","toError"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as KeyStrategy, a as ProviderConfig,
|
|
1
|
+
import { K as KeyStrategy, a as ProviderConfig, l as Modality, D as RetryStrategy, i as UPPError } from './provider-x4RocsnK.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* API key management strategies for load balancing and dynamic key selection.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ContentBlock,
|
|
1
|
+
import { C as ContentBlock, m as ImageBlock, n as AudioBlock, V as VideoBlock, R as ReasoningBlock, A as AssistantContent, U as UserContent } from './provider-x4RocsnK.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @fileoverview JSON Schema types for tool parameters and structured outputs.
|
|
@@ -436,11 +436,41 @@ type MessageJSON = Pick<Message, 'id' | 'type' | 'metadata'> & {
|
|
|
436
436
|
results?: ToolResult[];
|
|
437
437
|
};
|
|
438
438
|
/**
|
|
439
|
-
* Message type discriminator.
|
|
439
|
+
* Message type discriminator union.
|
|
440
440
|
*
|
|
441
|
-
*
|
|
441
|
+
* This type is derived from {@link MessageRole} constants. The name `MessageType`
|
|
442
|
+
* is kept for backward compatibility; `MessageRole` works as both the const
|
|
443
|
+
* object and this type.
|
|
442
444
|
*/
|
|
443
|
-
type MessageType =
|
|
445
|
+
type MessageType = (typeof MessageRole)[keyof typeof MessageRole];
|
|
446
|
+
/**
|
|
447
|
+
* Message role/type constants.
|
|
448
|
+
*
|
|
449
|
+
* Use these constants instead of raw strings for type-safe message handling:
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```typescript
|
|
453
|
+
* import { MessageRole, isUserMessage } from 'upp';
|
|
454
|
+
*
|
|
455
|
+
* if (message.type === MessageRole.User) {
|
|
456
|
+
* console.log('User said:', message.text);
|
|
457
|
+
* } else if (message.type === MessageRole.Assistant) {
|
|
458
|
+
* console.log('Assistant replied:', message.text);
|
|
459
|
+
* }
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
declare const MessageRole: {
|
|
463
|
+
/** User message */
|
|
464
|
+
readonly User: "user";
|
|
465
|
+
/** Assistant/model response */
|
|
466
|
+
readonly Assistant: "assistant";
|
|
467
|
+
/** Tool execution result */
|
|
468
|
+
readonly ToolResult: "tool_result";
|
|
469
|
+
};
|
|
470
|
+
/**
|
|
471
|
+
* Type alias for MessageType, allowing `MessageRole` to work as both const and type.
|
|
472
|
+
*/
|
|
473
|
+
type MessageRole = MessageType;
|
|
444
474
|
/**
|
|
445
475
|
* Provider-namespaced metadata for messages.
|
|
446
476
|
*
|
|
@@ -519,6 +549,11 @@ declare abstract class Message {
|
|
|
519
549
|
* All video content blocks in this message.
|
|
520
550
|
*/
|
|
521
551
|
get video(): VideoBlock[];
|
|
552
|
+
/**
|
|
553
|
+
* All reasoning/thinking content blocks in this message.
|
|
554
|
+
* Available when using extended thinking models.
|
|
555
|
+
*/
|
|
556
|
+
get reasoning(): ReasoningBlock[];
|
|
522
557
|
}
|
|
523
558
|
/**
|
|
524
559
|
* User input message.
|
|
@@ -840,36 +875,54 @@ declare function aggregateUsage(usages: TokenUsage[]): TokenUsage;
|
|
|
840
875
|
*/
|
|
841
876
|
|
|
842
877
|
/**
|
|
843
|
-
* Stream event type
|
|
844
|
-
*
|
|
845
|
-
*
|
|
846
|
-
*
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
/** Incremental
|
|
860
|
-
|
|
861
|
-
/**
|
|
862
|
-
|
|
863
|
-
/**
|
|
864
|
-
|
|
865
|
-
/**
|
|
866
|
-
|
|
867
|
-
/**
|
|
868
|
-
|
|
869
|
-
/**
|
|
870
|
-
|
|
871
|
-
/**
|
|
872
|
-
|
|
878
|
+
* Stream event type constants.
|
|
879
|
+
*
|
|
880
|
+
* Use these constants instead of raw strings for type-safe event handling:
|
|
881
|
+
*
|
|
882
|
+
* @example
|
|
883
|
+
* ```typescript
|
|
884
|
+
* import { StreamEventType } from 'upp';
|
|
885
|
+
*
|
|
886
|
+
* for await (const event of stream) {
|
|
887
|
+
* if (event.type === StreamEventType.TextDelta) {
|
|
888
|
+
* process.stdout.write(event.delta.text ?? '');
|
|
889
|
+
* }
|
|
890
|
+
* }
|
|
891
|
+
* ```
|
|
892
|
+
*/
|
|
893
|
+
declare const StreamEventType: {
|
|
894
|
+
/** Incremental text output */
|
|
895
|
+
readonly TextDelta: "text_delta";
|
|
896
|
+
/** Incremental reasoning/thinking output */
|
|
897
|
+
readonly ReasoningDelta: "reasoning_delta";
|
|
898
|
+
/** Incremental image data */
|
|
899
|
+
readonly ImageDelta: "image_delta";
|
|
900
|
+
/** Incremental audio data */
|
|
901
|
+
readonly AudioDelta: "audio_delta";
|
|
902
|
+
/** Incremental video data */
|
|
903
|
+
readonly VideoDelta: "video_delta";
|
|
904
|
+
/** Incremental tool call data (arguments being streamed) */
|
|
905
|
+
readonly ToolCallDelta: "tool_call_delta";
|
|
906
|
+
/** Tool execution has started (may be emitted after completion in some implementations) */
|
|
907
|
+
readonly ToolExecutionStart: "tool_execution_start";
|
|
908
|
+
/** Tool execution has completed */
|
|
909
|
+
readonly ToolExecutionEnd: "tool_execution_end";
|
|
910
|
+
/** Beginning of a message */
|
|
911
|
+
readonly MessageStart: "message_start";
|
|
912
|
+
/** End of a message */
|
|
913
|
+
readonly MessageStop: "message_stop";
|
|
914
|
+
/** Beginning of a content block */
|
|
915
|
+
readonly ContentBlockStart: "content_block_start";
|
|
916
|
+
/** End of a content block */
|
|
917
|
+
readonly ContentBlockStop: "content_block_stop";
|
|
918
|
+
};
|
|
919
|
+
/**
|
|
920
|
+
* Stream event type discriminator union.
|
|
921
|
+
*
|
|
922
|
+
* This type is derived from {@link StreamEventType} constants. Use `StreamEventType.TextDelta`
|
|
923
|
+
* for constants or `type MyType = StreamEventType` for type annotations.
|
|
924
|
+
*/
|
|
925
|
+
type StreamEventType = (typeof StreamEventType)[keyof typeof StreamEventType];
|
|
873
926
|
/**
|
|
874
927
|
* Event delta data payload.
|
|
875
928
|
*
|
|
@@ -902,10 +955,12 @@ interface EventDelta {
|
|
|
902
955
|
*
|
|
903
956
|
* @example
|
|
904
957
|
* ```typescript
|
|
958
|
+
* import { StreamEventType } from 'upp';
|
|
959
|
+
*
|
|
905
960
|
* for await (const event of stream) {
|
|
906
|
-
* if (event.type ===
|
|
961
|
+
* if (event.type === StreamEventType.TextDelta) {
|
|
907
962
|
* process.stdout.write(event.delta.text ?? '');
|
|
908
|
-
* } else if (event.type ===
|
|
963
|
+
* } else if (event.type === StreamEventType.ToolCallDelta) {
|
|
909
964
|
* console.log('Tool:', event.delta.toolName);
|
|
910
965
|
* }
|
|
911
966
|
* }
|
|
@@ -929,11 +984,13 @@ interface StreamEvent {
|
|
|
929
984
|
*
|
|
930
985
|
* @example
|
|
931
986
|
* ```typescript
|
|
987
|
+
* import { StreamEventType } from 'upp';
|
|
988
|
+
*
|
|
932
989
|
* const stream = instance.stream('Tell me a story');
|
|
933
990
|
*
|
|
934
991
|
* // Consume streaming events
|
|
935
992
|
* for await (const event of stream) {
|
|
936
|
-
* if (event.type ===
|
|
993
|
+
* if (event.type === StreamEventType.TextDelta) {
|
|
937
994
|
* process.stdout.write(event.delta.text ?? '');
|
|
938
995
|
* }
|
|
939
996
|
* }
|
|
@@ -1020,4 +1077,4 @@ declare function contentBlockStart(index: number): StreamEvent;
|
|
|
1020
1077
|
*/
|
|
1021
1078
|
declare function contentBlockStop(index: number): StreamEvent;
|
|
1022
1079
|
|
|
1023
|
-
export { AssistantMessage as A, type BeforeCallResult as B,
|
|
1080
|
+
export { AssistantMessage as A, type BeforeCallResult as B, toolCallDelta as C, messageStart as D, type EventDelta as E, messageStop as F, contentBlockStart as G, contentBlockStop as H, type TurnJSON as I, type JSONSchema as J, Message as M, type StreamResult as S, type Turn as T, UserMessage as U, type MessageType as a, type MessageJSON as b, type Tool as c, type ToolUseStrategy as d, type TokenUsage as e, type StreamEvent as f, type JSONSchemaProperty as g, type JSONSchemaPropertyType as h, type ToolCall as i, type ToolResult as j, type ToolMetadata as k, type AfterCallResult as l, type ToolExecution as m, ToolResultMessage as n, MessageRole as o, isUserMessage as p, isAssistantMessage as q, isToolResultMessage as r, type MessageMetadata as s, type MessageOptions as t, createTurn as u, emptyUsage as v, aggregateUsage as w, StreamEventType as x, createStreamResult as y, textDelta as z };
|
package/dist/xai/index.d.ts
CHANGED