zidane 6.2.24 → 6.2.27
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/dist/{acp-CTn1kFvP.js → acp-R4-zVIud.js} +4 -4
- package/dist/{acp-CTn1kFvP.js.map → acp-R4-zVIud.js.map} +1 -1
- package/dist/acp-cli.js +5 -5
- package/dist/acp.d.ts +1 -1
- package/dist/acp.js +1 -1
- package/dist/{agent-tLfGSSQw.js → agent-DIe8yzcb.js} +343 -30
- package/dist/agent-DIe8yzcb.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +2 -2
- package/dist/{anthropic-uKvj1yle.js → anthropic-BEYY0hVK.js} +66 -10
- package/dist/anthropic-BEYY0hVK.js.map +1 -0
- package/dist/{auth-CpdQebUy.js → auth-C4YPRDN4.js} +3 -3
- package/dist/{auth-CpdQebUy.js.map → auth-C4YPRDN4.js.map} +1 -1
- package/dist/chat/pure.d.ts +3 -3
- package/dist/chat/pure.js +1 -1
- package/dist/chat.d.ts +4 -4
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +5 -5
- package/dist/contexts/daytona.d.ts +1 -1
- package/dist/contexts/daytona.d.ts.map +1 -1
- package/dist/contexts/daytona.js +9 -2
- package/dist/contexts/daytona.js.map +1 -1
- package/dist/contexts/docker.js +1 -1
- package/dist/contexts/e2b.d.ts +1 -1
- package/dist/contexts/e2b.d.ts.map +1 -1
- package/dist/contexts/e2b.js +3 -4
- package/dist/contexts/e2b.js.map +1 -1
- package/dist/{contexts-A4ep-iJs.js → contexts-0rmrBhTK.js} +8 -5
- package/dist/contexts-0rmrBhTK.js.map +1 -0
- package/dist/contexts.js +1 -1
- package/dist/eval.d.ts +1 -1
- package/dist/eval.js +2 -2
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +1 -1
- package/dist/{output-cap-kBUHBlnq.js → glob-DluQFSw1.js} +2 -50
- package/dist/glob-DluQFSw1.js.map +1 -0
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +5 -5
- package/dist/history-search-worker.js +6 -1
- package/dist/history-search-worker.js.map +1 -1
- package/dist/{index-8zm_hwdY.d.ts → index-B6eBI_OD.d.ts} +312 -96
- package/dist/index-B6eBI_OD.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -9
- package/dist/index.js.map +1 -1
- package/dist/{inline-autocomplete-BAwBcZtD.js → inline-autocomplete-CbcdZpfC.js} +2 -1
- package/dist/inline-autocomplete-CbcdZpfC.js.map +1 -0
- package/dist/{login-DfJGuHUj.js → login-afiadwf0.js} +34 -18
- package/dist/login-afiadwf0.js.map +1 -0
- package/dist/mcp.d.ts +1 -1
- package/dist/{messages-CvHfYB7f.js → messages-Dy9t7DbQ.js} +97 -6
- package/dist/messages-Dy9t7DbQ.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -1
- package/dist/output/terminal.d.ts +1 -1
- package/dist/output-cap-DM1HrgIp.js +100 -0
- package/dist/output-cap-DM1HrgIp.js.map +1 -0
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.js +1 -1
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +4 -3
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +1 -1
- package/dist/restate.d.ts +1 -1
- package/dist/{run-summary-nD3IQ4ZQ.js → run-summary-BU_NgwUT.js} +17 -1
- package/dist/run-summary-BU_NgwUT.js.map +1 -0
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/{session-jLsc_kMH.js → session-DkVnYGm9.js} +2 -2
- package/dist/{session-jLsc_kMH.js.map → session-DkVnYGm9.js.map} +1 -1
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/skills.d.ts +1 -1
- package/dist/{tool-formatters-CZJYzP4x.d.ts → tool-formatters-DdchId_3.d.ts} +2 -2
- package/dist/{tool-formatters-CZJYzP4x.d.ts.map → tool-formatters-DdchId_3.d.ts.map} +1 -1
- package/dist/tools/fetch-url.d.ts +1 -1
- package/dist/tools/web-search.d.ts +1 -1
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-Ded7iJjG.js → transcript-anchors-DOuzgpJx.js} +88 -12
- package/dist/transcript-anchors-DOuzgpJx.js.map +1 -0
- package/dist/{transcript-anchors-CJ2dmpQk.d.ts → transcript-anchors-DvXLpbIc.d.ts} +2 -2
- package/dist/transcript-anchors-DvXLpbIc.d.ts.map +1 -0
- package/dist/tui.d.ts +44 -7
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +1387 -1106
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-ClGa1vnb.js → turn-operations-4tnvKwfJ.js} +77 -13
- package/dist/turn-operations-4tnvKwfJ.js.map +1 -0
- package/dist/{turn-operations-DZYpXcU1.d.ts → turn-operations-HRTRJIcy.d.ts} +3 -3
- package/dist/{turn-operations-DZYpXcU1.d.ts.map → turn-operations-HRTRJIcy.d.ts.map} +1 -1
- package/dist/types-BIarq1qE.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +2 -1
- package/dist/agent-tLfGSSQw.js.map +0 -1
- package/dist/anthropic-uKvj1yle.js.map +0 -1
- package/dist/contexts-A4ep-iJs.js.map +0 -1
- package/dist/index-8zm_hwdY.d.ts.map +0 -1
- package/dist/inline-autocomplete-BAwBcZtD.js.map +0 -1
- package/dist/login-DfJGuHUj.js.map +0 -1
- package/dist/messages-CvHfYB7f.js.map +0 -1
- package/dist/output-cap-kBUHBlnq.js.map +0 -1
- package/dist/run-summary-nD3IQ4ZQ.js.map +0 -1
- package/dist/transcript-anchors-CJ2dmpQk.d.ts.map +0 -1
- package/dist/transcript-anchors-Ded7iJjG.js.map +0 -1
- package/dist/turn-operations-ClGa1vnb.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","names":["getModel","streamOpenAIResponses","streamOpenAICodexResponses","stream"],"sources":["../../src/providers/openai.ts"],"sourcesContent":["import type {\n AssistantMessage as PiAssistantMessage,\n Context as PiContext,\n Message as PiMessage,\n Model as PiModel,\n Tool as PiTool,\n Usage as PiUsage,\n} from '@earendil-works/pi-ai'\nimport type { Provider, StreamCallbacks, StreamOptions, ToolSpec, TurnResult } from '.'\nimport type { ClassifiedError } from '../errors'\nimport type { SessionContentBlock, SessionMessage, ToolResultDocumentContent, TurnFinishReason, TurnUsage } from '../types'\nimport type { OAuthParams } from './oauth'\nimport { stream as streamOpenAICodexResponses } from '@earendil-works/pi-ai/api/openai-codex-responses'\nimport { stream as streamOpenAIResponses } from '@earendil-works/pi-ai/api/openai-responses'\nimport { getBuiltinModel as getModel } from '@earendil-works/pi-ai/providers/all'\nimport { classifyErrorPrelude, isRetryableHttpStatus, matchesContextExceeded, matchesToolPairingError } from '../errors'\nimport { unsupportedMediaError } from '../prompt'\nimport { SYNTHETIC_TOOL_RESULT_PLACEHOLDER } from '../session/messages'\nimport { renderSystemForWire } from '../system-prompt'\nimport { assertResolvedMediaBlock, documentBlockMarker } from '../types'\nimport { fillEstimatedCost } from './cost'\nimport { extractRuntimeCredentials, resolveOAuthApiKey } from './oauth'\nimport {\n assistantMessage,\n toolResultsMessage,\n userMessage,\n} from './openai-compat'\nimport { createOpenAIToolNameBoundary } from './openai-tool-names'\nimport { sanitizeToolSpecs } from './schema-sanitize'\n\nconst PROVIDER_ID = 'openai-codex'\n/**\n * pi-ai registry id for the standard platform API (`api.openai.com`).\n * The provider auto-detects the backend per stream from the credential\n * shape: a Codex OAuth JWT (`eyJ…`) streams via the ChatGPT Codex backend,\n * a platform API key (`sk-…`) via the standard Responses API. Same model\n * ids, same event contract — only the wire endpoint and billing differ.\n */\nconst PLATFORM_PROVIDER_ID = 'openai'\nconst DEFAULT_MODEL = 'gpt-5.5'\n\n// Metadata aliases for model ids OpenAI publishes as shorthand (e.g. `gpt-5.6`\n// → the Sol flagship). Used ONLY to resolve extra-model metadata (cost,\n// context window, output ceiling); the requested id is preserved on the wire,\n// which OpenAI accepts. Mirrors `openaiDescriptor.modelAliases` in the chat\n// layer (`src/chat/providers.ts`) — the provider layer can't import that\n// descriptor without a layering cycle. Keep the two in sync.\nconst MODEL_ALIASES: Readonly<Record<string, string>> = {\n 'gpt-5.6': 'gpt-5.6-sol',\n}\n\ntype CodexModel = PiModel<'openai-codex-responses'>\ntype PlatformModel = PiModel<'openai-responses'>\n\nexport interface OpenAIParams extends OAuthParams {\n accountId?: string\n defaultModel?: string\n transport?: 'sse' | 'websocket' | 'auto'\n /**\n * Extra HTTP headers merged into every request (the streaming Responses call\n * and the token-count endpoint). Use for routing/attribution headers a proxy\n * in front of the OpenAI Codex endpoint consumes. Merged with provider\n * defaults; pi-ai lets these override defaults, so avoid `authorization` /\n * `content-type` unless you intend to replace them.\n */\n extraHeaders?: Record<string, string>\n}\n\n// pi-ai's `getModel` is typed for `KnownProvider` × `keyof models[P]`;\n// we look up by free-form `modelId` (the registry holds string ids at\n// runtime) and let pi-ai's miss-throw fall through via the wider lookup.\nconst lookupModel = getModel as (provider: string, modelId: string) => CodexModel | undefined\n\nfunction resolveModel(modelId: string, providerId: string = PROVIDER_ID): CodexModel {\n const model = lookupModel(providerId, modelId)\n if (model)\n return model\n\n // Shorthand aliases (`gpt-5.6` → `gpt-5.6-sol`): use the canonical\n // registry entry's metadata (cost, context window, output ceiling) while\n // keeping the requested id on the wire — OpenAI accepts the shorthand,\n // and pi-ai's usage accounting must bill at the real rates rather than\n // the default-model fallback's.\n const aliasId = MODEL_ALIASES[modelId]\n const aliased = aliasId ? lookupModel(providerId, aliasId) : undefined\n if (aliased)\n return { ...aliased, id: modelId }\n\n const fallback = lookupModel(providerId, DEFAULT_MODEL)\n if (!fallback)\n throw new Error(`OpenAI model registry (${providerId}) is missing the default model: ${DEFAULT_MODEL}`)\n\n return { ...fallback, id: modelId, name: modelId }\n}\n\nfunction emptyUsage(): PiUsage {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n }\n}\n\nfunction formatTools(tools: ToolSpec[]): PiTool[] {\n // Codex's Responses API runs the same schema validator as the OpenAI\n // Chat Completions endpoint — apply the same sanitisation pass so MCP\n // tools with non-standard root shapes don't 400 here either.\n const sanitized = sanitizeToolSpecs(tools, { profile: 'openai' })\n return sanitized.map(t => ({\n name: t.name,\n description: t.description,\n parameters: t.inputSchema as PiTool['parameters'],\n }))\n}\n\nfunction documentMarker(doc: ToolResultDocumentContent): string {\n return documentBlockMarker(doc, 'document omitted')\n}\n\nfunction piToolResultMessage(\n result: Extract<SessionContentBlock, { type: 'tool_result' }>,\n toolName = '',\n): PiMessage {\n // pi-ai's ToolResultMessage natively accepts (TextContent | ImageContent)[].\n // Map zidane's canonical union directly — no flattening needed.\n const content = typeof result.output === 'string'\n ? [{ type: 'text' as const, text: result.output }]\n : result.output.map((block) => {\n if (block.type === 'image') {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'image' as const, data: block.data, mimeType: block.mediaType }\n }\n if (block.type === 'audio')\n throw unsupportedMediaError('audio', 'openai')\n if (block.type === 'video')\n throw unsupportedMediaError('video', 'openai')\n if (block.type === 'document') {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'text' as const, text: documentMarker(block) }\n }\n return { type: 'text' as const, text: block.text }\n })\n\n return {\n role: 'toolResult',\n toolCallId: result.callId,\n toolName,\n content,\n isError: result.isError ?? false,\n timestamp: Date.now(),\n }\n}\n\nfunction piUserMessage(\n content: SessionContentBlock[],\n): PiMessage | null {\n for (const b of content) {\n if (b.type === 'audio')\n throw unsupportedMediaError('audio', 'openai')\n if (b.type === 'video')\n throw unsupportedMediaError('video', 'openai')\n }\n\n const textBlocks = content.filter(b => b.type === 'text')\n const imageBlocks = content.filter(b => b.type === 'image')\n const documentBlocks = content.filter(b => b.type === 'document')\n\n if (imageBlocks.length === 0 && textBlocks.length === 0 && documentBlocks.length === 0)\n return null\n\n if (imageBlocks.length === 0 && documentBlocks.length === 0 && textBlocks.length === 1)\n return { role: 'user', content: textBlocks[0].text, timestamp: Date.now() }\n\n return {\n role: 'user',\n content: [\n ...imageBlocks.map((img) => {\n assertResolvedMediaBlock(img, 'OpenAI wire messages')\n return { type: 'image' as const, data: img.data, mimeType: img.mediaType }\n }),\n // NOTE: OpenAI's API natively accepts PDFs (Responses `input_file` /\n // Chat Completions `file`), but pi-ai's message content union is\n // text|image only — it has no file content type — so documents degrade to\n // a marker here. To forward PDFs to OpenAI, route via:\n // openaiCompat({ name: 'openai', apiKey, baseURL: 'https://api.openai.com/v1',\n // capabilities: { documents: true } })\n // which emits the `{type:'file'}` Chat Completions part directly. (That\n // path accepts application/pdf only; spreadsheets/.docx need the\n // Responses API, which would require an input_file content type in pi-ai.)\n ...documentBlocks.map((block) => {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'text' as const, text: documentMarker(block) }\n }),\n ...textBlocks.map(block => ({ type: 'text' as const, text: block.text })),\n ],\n timestamp: Date.now(),\n }\n}\n\nfunction piAssistantMessage(\n content: SessionContentBlock[],\n modelId: string,\n): PiAssistantMessage {\n const piContent: PiAssistantMessage['content'] = []\n for (const block of content) {\n if (block.type === 'text') {\n piContent.push({ type: 'text', text: block.text })\n }\n else if (block.type === 'thinking') {\n // Drop thinking blocks minted by another provider — Anthropic signatures\n // are not valid OpenAI `encrypted_content` and Responses API rejects them.\n if (block.signatureProducer === 'anthropic')\n continue\n piContent.push({ type: 'thinking', thinking: block.text, thinkingSignature: block.signature })\n }\n else if (block.type === 'tool_call') {\n piContent.push({ type: 'toolCall', id: block.id, name: block.name, arguments: block.input })\n }\n // `redacted_thinking` (Anthropic-only) and `provider_reasoning` (provider-\n // bound reasoning state) are intentionally dropped — Codex Responses\n // doesn't accept them.\n }\n\n return {\n role: 'assistant',\n content: piContent,\n api: 'openai-codex-responses',\n provider: PROVIDER_ID,\n model: modelId,\n usage: emptyUsage(),\n stopReason: 'stop',\n timestamp: Date.now(),\n }\n}\n\nexport function toPiMessages(messages: SessionMessage[], modelId: string): PiMessage[] {\n const out: PiMessage[] = []\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]\n const toolCalls = msg.content.filter((b): b is Extract<SessionContentBlock, { type: 'tool_call' }> => b.type === 'tool_call')\n\n if (msg.role === 'assistant' && toolCalls.length > 0) {\n const next = messages[i + 1]\n const nextToolResults = next?.role === 'user'\n ? next.content.filter((b): b is Extract<SessionContentBlock, { type: 'tool_result' }> => b.type === 'tool_result')\n : []\n const resultById = new Map(nextToolResults.map(result => [result.callId, result]))\n\n let assistantContent: SessionContentBlock[] = []\n for (const block of msg.content) {\n assistantContent.push(block)\n if (block.type !== 'tool_call')\n continue\n\n out.push(piAssistantMessage(assistantContent, modelId))\n assistantContent = []\n\n const result = resultById.get(block.id)\n if (result) {\n out.push(piToolResultMessage(result, block.name))\n }\n else {\n out.push(piToolResultMessage({\n type: 'tool_result',\n callId: block.id,\n output: SYNTHETIC_TOOL_RESULT_PLACEHOLDER,\n isError: true,\n }, block.name))\n }\n }\n if (assistantContent.length > 0)\n out.push(piAssistantMessage(assistantContent, modelId))\n\n if (next?.role === 'user') {\n const remainingUserContent = next.content.filter((block) => {\n if (block.type !== 'tool_result')\n return true\n // Orphan/duplicate tool results should already be removed by the\n // canonical repair pass. If one reaches this adapter, do not send it\n // as an unpaired provider message.\n return false\n })\n const userMessage = piUserMessage(remainingUserContent)\n if (userMessage)\n out.push(userMessage)\n i++\n }\n continue\n }\n\n const toolResults = msg.content.filter(b => b.type === 'tool_result')\n if (toolResults.length > 0) {\n const userMsg = msg.role === 'user'\n ? piUserMessage(msg.content.filter(b => b.type !== 'tool_result'))\n : null\n if (userMsg)\n out.push(userMsg)\n continue\n }\n\n if (msg.role === 'user') {\n const userMsg = piUserMessage(msg.content)\n if (userMsg)\n out.push(userMsg)\n continue\n }\n\n out.push(piAssistantMessage(msg.content, modelId))\n }\n\n return out\n}\n\n/**\n * Map pi-ai's `StopReason` to the zidane `TurnFinishReason` union — the same\n * native-stop-reason fidelity anthropic's `mapStopReason` / openai-compat's\n * `mapOAIFinishReason` provide. Notably `length` (max-token truncation) is no\n * longer misreported as a clean `stop`. `hasToolCalls` is the fallback for\n * messages whose stop reason is missing or doesn't carry the tool-call signal.\n */\nexport function mapCodexStopReason(stopReason: string | undefined, hasToolCalls: boolean): TurnFinishReason {\n switch (stopReason) {\n case 'toolUse':\n return 'tool-calls'\n case 'length':\n return 'length'\n case 'error':\n return 'error'\n case 'stop':\n return hasToolCalls ? 'tool-calls' : 'stop'\n case 'aborted':\n return 'other'\n default:\n return hasToolCalls ? 'tool-calls' : 'stop'\n }\n}\n\nfunction fromPiAssistantMessage(message: PiAssistantMessage): SessionMessage {\n const content: SessionContentBlock[] = []\n\n for (const block of message.content) {\n if (block.type === 'text') {\n content.push({ type: 'text', text: block.text })\n }\n else if (block.type === 'thinking') {\n const out: Extract<SessionContentBlock, { type: 'thinking' }> = {\n type: 'thinking',\n text: block.thinking,\n }\n if (typeof block.thinkingSignature === 'string') {\n out.signature = block.thinkingSignature\n out.signatureProducer = 'openai'\n }\n content.push(out)\n }\n else if (block.type === 'toolCall') {\n content.push({ type: 'tool_call', id: block.id, name: block.name, input: block.arguments })\n }\n }\n\n return { role: 'assistant', content }\n}\n\nfunction extractToolCalls(message: PiAssistantMessage) {\n return message.content\n .filter(block => block.type === 'toolCall')\n .map(block => ({\n id: block.id,\n name: block.name,\n input: block.arguments as Record<string, unknown>,\n }))\n}\n\nfunction extractText(message: PiAssistantMessage): string {\n return message.content\n .filter((block): block is Extract<PiAssistantMessage['content'][number], { type: 'text' }> => block.type === 'text')\n .map(block => block.text)\n .join('')\n}\n\nfunction toTurnUsage(usage: PiUsage, finishReason: TurnFinishReason | undefined, modelId: string): Promise<TurnUsage> {\n return fillEstimatedCost({\n input: usage.input,\n output: usage.output,\n cacheRead: usage.cacheRead || undefined,\n cacheCreation: usage.cacheWrite || undefined,\n cost: usage.cost.total || undefined,\n ...(finishReason ? { finishReason } : {}),\n modelId,\n }, 'openai')\n}\n\n/**\n * Transient pi-ai error patterns worth a loop-level retry. pi-ai already retries\n * 429 / 5xx pre-stream 3× internally (see `openai-codex-responses.js`); by the\n * time the error reaches us, that budget is exhausted. The loop-level retry\n * with its longer backoff is a second line of defense for capacity events\n * that persist past pi-ai's short retry window, plus mid-stream emissions\n * (pi-ai surfaces those as plain `Error`s with no status).\n *\n * Mirrors pi-ai's own `isRetryableError` regex so the two retry layers\n * recognize the same failure modes.\n */\nconst TRANSIENT_OPENAI_MESSAGE_RE = /rate.?limit|overloaded|service.?unavailable|upstream.?connect|connection.?refused|gateway.?time.?out|temporarily.?unavailable/i\n\n/** Numeric HTTP status codes pi-ai sometimes attaches when bubbling structured errors. */\nfunction isRetryableStatusCode(err: object): boolean {\n const status = (err as { status?: unknown }).status\n if (typeof status !== 'number')\n return false\n return isRetryableHttpStatus(status)\n}\n\n/**\n * Classify an OpenAI Codex error. pi-ai surfaces errors either as thrown `Error`s\n * (wrapping `event.error.errorMessage`) or via stream event types.\n *\n * Retryable hint is set when pi-ai's own retry budget is exhausted on a\n * transient failure — pattern-matched against `message` since pi-ai strips\n * structured fields on plain-Error throws. Set `behavior.retry.maxAttempts: 1`\n * to disable the loop-level retry.\n */\nexport function classifyOpenAIError(err: unknown): ClassifiedError | null {\n const prelude = classifyErrorPrelude(err)\n if (prelude === 'not-object')\n return null\n if (prelude === 'aborted')\n return { kind: 'aborted' }\n\n const anyErr = err as { name?: string, message?: string, code?: string, type?: string }\n\n const message = anyErr.message ?? ''\n const code = anyErr.code ?? anyErr.type\n\n if (code === 'context_length_exceeded' || matchesContextExceeded(message)) {\n return {\n kind: 'context_exceeded',\n providerCode: code ?? 'context_length_exceeded',\n message,\n }\n }\n\n if (matchesToolPairingError(message)) {\n return {\n kind: 'tool_pairing_corruption',\n providerCode: code ?? 'invalid_request_error',\n message,\n }\n }\n\n // pi-ai wraps API errors in generic `Error` — treat as provider_error when we have a message.\n if (message.length > 0) {\n const retryable = isRetryableStatusCode(anyErr) || TRANSIENT_OPENAI_MESSAGE_RE.test(message)\n return {\n kind: 'provider_error',\n providerCode: code,\n message,\n ...(retryable ? { retryable: true } : {}),\n }\n }\n\n return null\n}\n\n/**\n * A standard OpenAI API key usable against `api.openai.com` (for the exact\n * token-count endpoint), or `null` when only a Codex-OAuth credential is\n * available. Codex OAuth access tokens are JWTs (`eyJ…`) and are NOT valid\n * bearers for the standard API; a real key looks like `sk-…` (but not the\n * Anthropic `sk-ant-…` form). Checks `params.apiKey` then `OPENAI_API_KEY`.\n */\n/**\n * OpenAI's org-verification rejection for `reasoning.summary` — e.g.\n * \"Your organization must be verified to generate reasoning summaries\".\n * Matched loosely on the two load-bearing words so minor copy changes\n * don't defeat the platform-branch fallback.\n */\nfunction isReasoningSummaryVerificationError(err: unknown): boolean {\n if (!(err instanceof Error))\n return false\n return /reasoning summar/i.test(err.message) && /verif/i.test(err.message)\n}\n\nfunction pickStandardOpenAIKey(params?: OpenAIParams): string | null {\n const candidates = [params?.apiKey, process.env.OPENAI_API_KEY]\n for (const key of candidates) {\n if (typeof key === 'string' && key.startsWith('sk-') && !key.startsWith('sk-ant-'))\n return key\n }\n return null\n}\n\n/**\n * Convert canonical {@link SessionMessage}s to OpenAI Responses-API `input`\n * items for the token-count endpoint. Only the text-bearing shape is needed\n * here (the count path sends a tiny dummy message); images/tool-results are\n * down-converted to text so the count never throws on an exotic block.\n */\nfunction toResponsesInput(messages: SessionMessage[]): unknown[] {\n return messages.map((msg) => {\n const text = msg.content\n .map(b => (b.type === 'text' ? b.text : ''))\n .filter(Boolean)\n .join('\\n')\n const part = msg.role === 'assistant' ? 'output_text' : 'input_text'\n return { role: msg.role === 'assistant' ? 'assistant' : 'user', content: [{ type: part, text }] }\n })\n}\n\n/** Convert pi-ai `PiTool` specs to Responses-API function tools. */\nfunction toResponsesTools(tools: unknown[]): unknown[] {\n return tools.map((t) => {\n const tool = t as { name?: string, description?: string, parameters?: unknown }\n return {\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }\n })\n}\n\nfunction applyPayloadOverrides(payload: unknown, options: StreamOptions, toWireToolName: (name: string) => string = name => name): unknown {\n const body = payload as Record<string, unknown>\n\n if (options.toolChoice) {\n if (options.toolChoice.type === 'tool' && options.toolChoice.name)\n body.tool_choice = { type: 'function', name: toWireToolName(options.toolChoice.name) }\n else if (options.toolChoice.type === 'required')\n body.tool_choice = 'required'\n else\n body.tool_choice = 'auto'\n }\n\n return body\n}\n\nexport function openai(params?: OpenAIParams): Provider {\n const defaultModel = params?.defaultModel || DEFAULT_MODEL\n const baseCredentials = extractRuntimeCredentials(params)\n let runtimeCredentials = baseCredentials\n ? { ...baseCredentials, ...(params?.accountId ? { accountId: params.accountId } : {}) }\n : undefined\n\n return {\n name: 'openai',\n meta: {\n defaultModel,\n isOAuth: true,\n capabilities: {\n vision: true,\n imageInToolResult: true,\n // pi-ai's Codex Responses wire has no audio/video input content type.\n audio: false,\n video: false,\n },\n },\n formatTools,\n userMessage,\n assistantMessage,\n toolResultsMessage,\n classifyError: classifyOpenAIError,\n\n async countTokens(payload, signal): Promise<number | null> {\n // The exact count endpoint (`POST /v1/responses/input_tokens`) lives on\n // the standard OpenAI API and needs a standard `OPENAI_API_KEY` bearer.\n // This provider authenticates via Codex OAuth against the Codex backend,\n // whose token is NOT valid for that endpoint — so we only attempt the\n // count when a standard key is present (env or params.apiKey that isn't\n // an OAuth/JWT token). Otherwise return null → heuristic fallback.\n const standardKey = pickStandardOpenAIKey(params)\n if (!standardKey)\n return null\n try {\n const tools = payload.tools as PiTool[]\n const nameBoundary = createOpenAIToolNameBoundary(payload.messages, tools.map(tool => tool.name))\n const res = await fetch('https://api.openai.com/v1/responses/input_tokens', {\n method: 'POST',\n headers: {\n ...params?.extraHeaders,\n 'authorization': `Bearer ${standardKey}`,\n 'content-type': 'application/json',\n },\n // The Responses `input_tokens` endpoint takes the same shape as\n // `responses.create`: `instructions` (system), `input` (Responses\n // input items — NOT pi-ai messages), and function-shaped `tools`.\n body: JSON.stringify({\n model: payload.model || defaultModel,\n instructions: renderSystemForWire(payload.system),\n input: toResponsesInput(nameBoundary.messages),\n tools: toResponsesTools(tools.map(tool => ({ ...tool, name: nameBoundary.toWire(tool.name) }))),\n }),\n ...(signal ? { signal } : {}),\n })\n if (!res.ok)\n return null\n const json = (await res.json()) as { input_tokens?: unknown }\n return typeof json.input_tokens === 'number' ? json.input_tokens : null\n }\n catch {\n return null\n }\n },\n\n async stream(options: StreamOptions, callbacks: StreamCallbacks): Promise<TurnResult> {\n const modelId = options.model || defaultModel\n const apiKey = await resolveOAuthApiKey(\n {\n provider: 'openai',\n providerId: PROVIDER_ID,\n params: runtimeCredentials ? { ...params, ...runtimeCredentials } : params,\n envKey: 'OPENAI_CODEX_API_KEY',\n extraCredentialKeys: ['accountId'],\n missingError: 'No OpenAI Codex OAuth token found. Run `bun run auth --openai` first.',\n refreshError: reason => `OpenAI Codex OAuth token refresh failed. Run \\`bun run auth --openai\\` again. ${reason}`,\n },\n {\n ...callbacks,\n async onOAuthRefresh(ctx) {\n if (ctx.source === 'params') {\n runtimeCredentials = {\n access: ctx.credentials.access,\n refresh: ctx.credentials.refresh,\n expires: ctx.credentials.expires,\n ...(typeof ctx.credentials.accountId === 'string' ? { accountId: ctx.credentials.accountId } : {}),\n }\n }\n await callbacks.onOAuthRefresh?.(ctx)\n },\n },\n )\n // Backend auto-detection by credential shape. A Codex OAuth access\n // token is a JWT whose claims carry the `chatgpt_account_id` the Codex\n // backend requires per request; a standard `sk-…` platform key can\n // NEVER stream there (pi-ai fails with an opaque \"Failed to extract\n // accountId from token\") — but it's a first-class credential for the\n // standard Responses API, so route it there instead. Scoped to the\n // unambiguous `sk-` shape: exotic bearers (test harnesses, relays)\n // keep flowing to the Codex path untouched.\n const usePlatformApi = apiKey.startsWith('sk-')\n const model = resolveModel(modelId, usePlatformApi ? PLATFORM_PROVIDER_ID : PROVIDER_ID)\n const tools = options.tools as PiTool[]\n const nameBoundary = createOpenAIToolNameBoundary(options.messages, tools.map(tool => tool.name))\n // Codex's Responses API has no `cache_control` analogue, but the\n // system-prompt boundary marker is structural metadata that should\n // never reach the model. Strip it via `renderSystemForWire`; the\n // doctrine + env are collapsed into a single byte stream the model\n // sees as one logical prompt.\n const context: PiContext = {\n systemPrompt: renderSystemForWire(options.system),\n messages: toPiMessages(nameBoundary.messages, modelId),\n tools: tools.map(tool => ({ ...tool, name: nameBoundary.toWire(tool.name) })),\n }\n // OpenAI's `reasoning_effort` accepts minimal/low/medium/high/xhigh, and\n // the GPT-5.6 line adds a native `max` tier. Clamp `max` to `xhigh` on\n // older models only; `'adaptive'` degrades to no reasoning rather than\n // forwarding an unknown value the API would reject.\n const supportsMaxEffort = modelId.startsWith('gpt-5.6')\n const reasoningLevel\n = options.thinking && options.thinking !== 'off' && options.thinking !== 'adaptive'\n ? options.thinking === 'max' && !supportsMaxEffort ? 'xhigh' : options.thinking\n : undefined\n // Options are shared verbatim across both backends — the platform\n // Responses API and the Codex bridge take the same reasoning / service\n // tier knobs; only the websocket `transport` toggle is Codex-specific.\n const makeStream = (reasoningSummary: 'auto' | undefined) => {\n const streamOptions = {\n apiKey,\n ...(options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n signal: options.signal,\n reasoningEffort: reasoningLevel,\n reasoningSummary,\n ...(options.modelOptions?.fast ? { serviceTier: 'priority' as const } : {}),\n ...(params?.extraHeaders ? { headers: params.extraHeaders } : {}),\n // pi-ai types the payload as `unknown`; both backends send the\n // Responses-API body shape `applyPayloadOverrides` expects.\n onPayload: (payload: unknown) => applyPayloadOverrides(payload as Record<string, unknown>, options, nameBoundary.toWire),\n }\n return usePlatformApi\n ? streamOpenAIResponses(model as unknown as PlatformModel, context, streamOptions)\n : streamOpenAICodexResponses(model, context, { ...streamOptions, transport: params?.transport })\n }\n let stream = makeStream(reasoningLevel ? 'auto' : undefined)\n\n let finalMessage: PiAssistantMessage | undefined\n let text = ''\n let thinking = ''\n\n const consume = async (s: ReturnType<typeof makeStream>) => {\n for await (const event of s) {\n if (event.type === 'text_delta') {\n text += event.delta\n callbacks.onText(event.delta)\n }\n else if (event.type === 'thinking_delta') {\n thinking += event.delta\n callbacks.onThinking?.(event.delta)\n }\n else if (event.type === 'thinking_end') {\n const delta = event.content.startsWith(thinking)\n ? event.content.slice(thinking.length)\n : (thinking ? '' : event.content)\n if (delta) {\n thinking += delta\n callbacks.onThinking?.(delta)\n }\n }\n else if (event.type === 'done') {\n finalMessage = event.message\n }\n else if (event.type === 'error') {\n throw new Error(event.error.errorMessage || (usePlatformApi ? 'OpenAI API error' : 'OpenAI Codex API error'))\n }\n }\n }\n\n try {\n await consume(stream)\n }\n catch (err) {\n // The platform Responses API rejects reasoning summaries for\n // organizations that haven't completed verification (the Codex\n // backend has no such gate). That 400 fails request validation, so\n // nothing has streamed yet — retry once without the summary rather\n // than bricking every reasoning-enabled stream for those orgs.\n const nothingStreamed = text.length === 0 && thinking.length === 0 && finalMessage === undefined\n if (usePlatformApi && reasoningLevel && nothingStreamed && isReasoningSummaryVerificationError(err)) {\n stream = makeStream(undefined)\n await consume(stream)\n }\n else {\n throw err\n }\n }\n\n finalMessage ??= await stream.result()\n text ||= extractText(finalMessage)\n\n const toolCalls = extractToolCalls(finalMessage)\n .map(call => ({ ...call, name: nameBoundary.fromWire(call.name) }))\n const assistantTurn = fromPiAssistantMessage(finalMessage)\n assistantTurn.content = assistantTurn.content.map(block =>\n block.type === 'tool_call' ? { ...block, name: nameBoundary.fromWire(block.name) } : block,\n )\n const finishReason = mapCodexStopReason(finalMessage.stopReason, toolCalls.length > 0)\n const usage = await toTurnUsage(finalMessage.usage, finishReason, modelId)\n\n return {\n assistantMessage: assistantTurn,\n text,\n toolCalls,\n done: toolCalls.length === 0,\n usage,\n }\n },\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"openai.js","names":["getModel","streamOpenAIResponses","streamOpenAICodexResponses","stream"],"sources":["../../src/providers/openai.ts"],"sourcesContent":["import type {\n AssistantMessage as PiAssistantMessage,\n Context as PiContext,\n Message as PiMessage,\n Model as PiModel,\n Tool as PiTool,\n Usage as PiUsage,\n} from '@earendil-works/pi-ai'\nimport type { Provider, StreamCallbacks, StreamOptions, ToolSpec, TurnResult } from '.'\nimport type { ClassifiedError } from '../errors'\nimport type { SessionContentBlock, SessionMessage, ToolResultDocumentContent, TurnFinishReason, TurnUsage } from '../types'\nimport type { OAuthParams } from './oauth'\nimport { stream as streamOpenAICodexResponses } from '@earendil-works/pi-ai/api/openai-codex-responses'\nimport { stream as streamOpenAIResponses } from '@earendil-works/pi-ai/api/openai-responses'\nimport { getBuiltinModel as getModel } from '@earendil-works/pi-ai/providers/all'\nimport { classifyErrorPrelude, isRetryableHttpStatus, matchesContextExceeded, matchesToolPairingError } from '../errors'\nimport { unsupportedMediaError } from '../prompt'\nimport { reasoningWireAction, SYNTHETIC_TOOL_RESULT_PLACEHOLDER } from '../session/messages'\nimport { renderSystemForWire } from '../system-prompt'\nimport { assertResolvedMediaBlock, documentBlockMarker } from '../types'\nimport { fillEstimatedCost } from './cost'\nimport { extractRuntimeCredentials, resolveOAuthApiKey } from './oauth'\nimport {\n assistantMessage,\n toolResultsMessage,\n userMessage,\n} from './openai-compat'\nimport { createOpenAIToolNameBoundary } from './openai-tool-names'\nimport { sanitizeToolSpecs } from './schema-sanitize'\n\nconst PROVIDER_ID = 'openai-codex'\n/**\n * pi-ai registry id for the standard platform API (`api.openai.com`).\n * The provider auto-detects the backend per stream from the credential\n * shape: a Codex OAuth JWT (`eyJ…`) streams via the ChatGPT Codex backend,\n * a platform API key (`sk-…`) via the standard Responses API. Same model\n * ids, same event contract — only the wire endpoint and billing differ.\n */\nconst PLATFORM_PROVIDER_ID = 'openai'\nconst DEFAULT_MODEL = 'gpt-5.5'\n\n// Metadata aliases for model ids OpenAI publishes as shorthand (e.g. `gpt-5.6`\n// → the Sol flagship). Used ONLY to resolve extra-model metadata (cost,\n// context window, output ceiling); the requested id is preserved on the wire,\n// which OpenAI accepts. Mirrors `openaiDescriptor.modelAliases` in the chat\n// layer (`src/chat/providers.ts`) — the provider layer can't import that\n// descriptor without a layering cycle. Keep the two in sync.\nconst MODEL_ALIASES: Readonly<Record<string, string>> = {\n 'gpt-5.6': 'gpt-5.6-sol',\n}\n\ntype CodexModel = PiModel<'openai-codex-responses'>\ntype PlatformModel = PiModel<'openai-responses'>\n\nexport interface OpenAIParams extends OAuthParams {\n accountId?: string\n defaultModel?: string\n transport?: 'sse' | 'websocket' | 'auto'\n /**\n * Extra HTTP headers merged into every request (the streaming Responses call\n * and the token-count endpoint). Use for routing/attribution headers a proxy\n * in front of the OpenAI Codex endpoint consumes. Merged with provider\n * defaults; pi-ai lets these override defaults, so avoid `authorization` /\n * `content-type` unless you intend to replace them.\n */\n extraHeaders?: Record<string, string>\n}\n\n// pi-ai's `getModel` is typed for `KnownProvider` × `keyof models[P]`;\n// we look up by free-form `modelId` (the registry holds string ids at\n// runtime) and let pi-ai's miss-throw fall through via the wider lookup.\nconst lookupModel = getModel as (provider: string, modelId: string) => CodexModel | undefined\n\nfunction resolveModel(modelId: string, providerId: string = PROVIDER_ID): CodexModel {\n const model = lookupModel(providerId, modelId)\n if (model)\n return model\n\n // Shorthand aliases (`gpt-5.6` → `gpt-5.6-sol`): use the canonical\n // registry entry's metadata (cost, context window, output ceiling) while\n // keeping the requested id on the wire — OpenAI accepts the shorthand,\n // and pi-ai's usage accounting must bill at the real rates rather than\n // the default-model fallback's.\n const aliasId = MODEL_ALIASES[modelId]\n const aliased = aliasId ? lookupModel(providerId, aliasId) : undefined\n if (aliased)\n return { ...aliased, id: modelId }\n\n const fallback = lookupModel(providerId, DEFAULT_MODEL)\n if (!fallback)\n throw new Error(`OpenAI model registry (${providerId}) is missing the default model: ${DEFAULT_MODEL}`)\n\n return { ...fallback, id: modelId, name: modelId }\n}\n\nfunction emptyUsage(): PiUsage {\n return {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n }\n}\n\nfunction formatTools(tools: ToolSpec[]): PiTool[] {\n // Codex's Responses API runs the same schema validator as the OpenAI\n // Chat Completions endpoint — apply the same sanitisation pass so MCP\n // tools with non-standard root shapes don't 400 here either.\n const sanitized = sanitizeToolSpecs(tools, { profile: 'openai' })\n return sanitized.map(t => ({\n name: t.name,\n description: t.description,\n parameters: t.inputSchema as PiTool['parameters'],\n }))\n}\n\nfunction documentMarker(doc: ToolResultDocumentContent): string {\n return documentBlockMarker(doc, 'document omitted')\n}\n\nfunction piToolResultMessage(\n result: Extract<SessionContentBlock, { type: 'tool_result' }>,\n toolName = '',\n): PiMessage {\n // pi-ai's ToolResultMessage natively accepts (TextContent | ImageContent)[].\n // Map zidane's canonical union directly — no flattening needed.\n const content = typeof result.output === 'string'\n ? [{ type: 'text' as const, text: result.output }]\n : result.output.map((block) => {\n if (block.type === 'image') {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'image' as const, data: block.data, mimeType: block.mediaType }\n }\n if (block.type === 'audio')\n throw unsupportedMediaError('audio', 'openai')\n if (block.type === 'video')\n throw unsupportedMediaError('video', 'openai')\n if (block.type === 'document') {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'text' as const, text: documentMarker(block) }\n }\n return { type: 'text' as const, text: block.text }\n })\n\n return {\n role: 'toolResult',\n toolCallId: result.callId,\n toolName,\n content,\n isError: result.isError ?? false,\n timestamp: Date.now(),\n }\n}\n\nfunction piUserMessage(\n content: SessionContentBlock[],\n): PiMessage | null {\n for (const b of content) {\n if (b.type === 'audio')\n throw unsupportedMediaError('audio', 'openai')\n if (b.type === 'video')\n throw unsupportedMediaError('video', 'openai')\n }\n\n const textBlocks = content.filter(b => b.type === 'text')\n const imageBlocks = content.filter(b => b.type === 'image')\n const documentBlocks = content.filter(b => b.type === 'document')\n\n if (imageBlocks.length === 0 && textBlocks.length === 0 && documentBlocks.length === 0)\n return null\n\n if (imageBlocks.length === 0 && documentBlocks.length === 0 && textBlocks.length === 1)\n return { role: 'user', content: textBlocks[0].text, timestamp: Date.now() }\n\n return {\n role: 'user',\n content: [\n ...imageBlocks.map((img) => {\n assertResolvedMediaBlock(img, 'OpenAI wire messages')\n return { type: 'image' as const, data: img.data, mimeType: img.mediaType }\n }),\n // NOTE: OpenAI's API natively accepts PDFs (Responses `input_file` /\n // Chat Completions `file`), but pi-ai's message content union is\n // text|image only — it has no file content type — so documents degrade to\n // a marker here. To forward PDFs to OpenAI, route via:\n // openaiCompat({ name: 'openai', apiKey, baseURL: 'https://api.openai.com/v1',\n // capabilities: { documents: true } })\n // which emits the `{type:'file'}` Chat Completions part directly. (That\n // path accepts application/pdf only; spreadsheets/.docx need the\n // Responses API, which would require an input_file content type in pi-ai.)\n ...documentBlocks.map((block) => {\n assertResolvedMediaBlock(block, 'OpenAI wire messages')\n return { type: 'text' as const, text: documentMarker(block) }\n }),\n ...textBlocks.map(block => ({ type: 'text' as const, text: block.text })),\n ],\n timestamp: Date.now(),\n }\n}\n\nfunction piAssistantMessage(\n content: SessionContentBlock[],\n modelId: string,\n): PiAssistantMessage {\n const piContent: PiAssistantMessage['content'] = []\n for (const block of content) {\n if (block.type === 'text') {\n piContent.push({ type: 'text', text: block.text })\n }\n else if (block.type === 'thinking') {\n // Shared cross-provider policy (`reasoningWireAction`): drop blocks\n // minted by Anthropic (their HMAC is not valid `encrypted_content`),\n // strip the signature from untagged legacy blocks (no signature-400\n // recovery exists on this path), forward openai-tagged ones intact.\n const action = reasoningWireAction(block, 'openai')\n if (action === 'drop')\n continue\n piContent.push({\n type: 'thinking',\n thinking: block.text,\n ...(action === 'keep' && block.signature !== undefined ? { thinkingSignature: block.signature } : {}),\n })\n }\n else if (block.type === 'tool_call') {\n piContent.push({ type: 'toolCall', id: block.id, name: block.name, arguments: block.input })\n }\n // `redacted_thinking` (Anthropic-only) and `provider_reasoning` (provider-\n // bound reasoning state) are intentionally dropped — Codex Responses\n // doesn't accept them.\n }\n\n return {\n role: 'assistant',\n content: piContent,\n api: 'openai-codex-responses',\n provider: PROVIDER_ID,\n model: modelId,\n usage: emptyUsage(),\n stopReason: 'stop',\n timestamp: Date.now(),\n }\n}\n\nexport function toPiMessages(messages: SessionMessage[], modelId: string): PiMessage[] {\n const out: PiMessage[] = []\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]\n const toolCalls = msg.content.filter((b): b is Extract<SessionContentBlock, { type: 'tool_call' }> => b.type === 'tool_call')\n\n if (msg.role === 'assistant' && toolCalls.length > 0) {\n const next = messages[i + 1]\n const nextToolResults = next?.role === 'user'\n ? next.content.filter((b): b is Extract<SessionContentBlock, { type: 'tool_result' }> => b.type === 'tool_result')\n : []\n const resultById = new Map(nextToolResults.map(result => [result.callId, result]))\n\n let assistantContent: SessionContentBlock[] = []\n for (const block of msg.content) {\n assistantContent.push(block)\n if (block.type !== 'tool_call')\n continue\n\n out.push(piAssistantMessage(assistantContent, modelId))\n assistantContent = []\n\n const result = resultById.get(block.id)\n if (result) {\n out.push(piToolResultMessage(result, block.name))\n }\n else {\n out.push(piToolResultMessage({\n type: 'tool_result',\n callId: block.id,\n output: SYNTHETIC_TOOL_RESULT_PLACEHOLDER,\n isError: true,\n }, block.name))\n }\n }\n if (assistantContent.length > 0)\n out.push(piAssistantMessage(assistantContent, modelId))\n\n if (next?.role === 'user') {\n const remainingUserContent = next.content.filter((block) => {\n if (block.type !== 'tool_result')\n return true\n // Orphan/duplicate tool results should already be removed by the\n // canonical repair pass. If one reaches this adapter, do not send it\n // as an unpaired provider message.\n return false\n })\n const userMessage = piUserMessage(remainingUserContent)\n if (userMessage)\n out.push(userMessage)\n i++\n }\n continue\n }\n\n const toolResults = msg.content.filter(b => b.type === 'tool_result')\n if (toolResults.length > 0) {\n const userMsg = msg.role === 'user'\n ? piUserMessage(msg.content.filter(b => b.type !== 'tool_result'))\n : null\n if (userMsg)\n out.push(userMsg)\n continue\n }\n\n if (msg.role === 'user') {\n const userMsg = piUserMessage(msg.content)\n if (userMsg)\n out.push(userMsg)\n continue\n }\n\n out.push(piAssistantMessage(msg.content, modelId))\n }\n\n return out\n}\n\n/**\n * Map pi-ai's `StopReason` to the zidane `TurnFinishReason` union — the same\n * native-stop-reason fidelity anthropic's `mapStopReason` / openai-compat's\n * `mapOAIFinishReason` provide. Notably `length` (max-token truncation) is no\n * longer misreported as a clean `stop`. `hasToolCalls` is the fallback for\n * messages whose stop reason is missing or doesn't carry the tool-call signal.\n */\nexport function mapCodexStopReason(stopReason: string | undefined, hasToolCalls: boolean): TurnFinishReason {\n switch (stopReason) {\n case 'toolUse':\n return 'tool-calls'\n case 'length':\n return 'length'\n case 'error':\n return 'error'\n case 'stop':\n return hasToolCalls ? 'tool-calls' : 'stop'\n case 'aborted':\n return 'other'\n default:\n return hasToolCalls ? 'tool-calls' : 'stop'\n }\n}\n\nfunction fromPiAssistantMessage(message: PiAssistantMessage): SessionMessage {\n const content: SessionContentBlock[] = []\n\n for (const block of message.content) {\n if (block.type === 'text') {\n content.push({ type: 'text', text: block.text })\n }\n else if (block.type === 'thinking') {\n const out: Extract<SessionContentBlock, { type: 'thinking' }> = {\n type: 'thinking',\n text: block.thinking,\n }\n if (typeof block.thinkingSignature === 'string') {\n out.signature = block.thinkingSignature\n out.signatureProducer = 'openai'\n }\n content.push(out)\n }\n else if (block.type === 'toolCall') {\n content.push({ type: 'tool_call', id: block.id, name: block.name, input: block.arguments })\n }\n }\n\n return { role: 'assistant', content }\n}\n\nfunction extractToolCalls(message: PiAssistantMessage) {\n return message.content\n .filter(block => block.type === 'toolCall')\n .map(block => ({\n id: block.id,\n name: block.name,\n input: block.arguments as Record<string, unknown>,\n }))\n}\n\nfunction extractText(message: PiAssistantMessage): string {\n return message.content\n .filter((block): block is Extract<PiAssistantMessage['content'][number], { type: 'text' }> => block.type === 'text')\n .map(block => block.text)\n .join('')\n}\n\nfunction toTurnUsage(usage: PiUsage, finishReason: TurnFinishReason | undefined, modelId: string): Promise<TurnUsage> {\n return fillEstimatedCost({\n input: usage.input,\n output: usage.output,\n cacheRead: usage.cacheRead || undefined,\n cacheCreation: usage.cacheWrite || undefined,\n cost: usage.cost.total || undefined,\n ...(finishReason ? { finishReason } : {}),\n modelId,\n }, 'openai')\n}\n\n/**\n * Transient pi-ai error patterns worth a loop-level retry. pi-ai already retries\n * 429 / 5xx pre-stream 3× internally (see `openai-codex-responses.js`); by the\n * time the error reaches us, that budget is exhausted. The loop-level retry\n * with its longer backoff is a second line of defense for capacity events\n * that persist past pi-ai's short retry window, plus mid-stream emissions\n * (pi-ai surfaces those as plain `Error`s with no status).\n *\n * Mirrors pi-ai's own `isRetryableError` regex so the two retry layers\n * recognize the same failure modes.\n */\nconst TRANSIENT_OPENAI_MESSAGE_RE = /rate.?limit|overloaded|service.?unavailable|upstream.?connect|connection.?refused|gateway.?time.?out|temporarily.?unavailable/i\n\n/** Numeric HTTP status codes pi-ai sometimes attaches when bubbling structured errors. */\nfunction isRetryableStatusCode(err: object): boolean {\n const status = (err as { status?: unknown }).status\n if (typeof status !== 'number')\n return false\n return isRetryableHttpStatus(status)\n}\n\n/**\n * Classify an OpenAI Codex error. pi-ai surfaces errors either as thrown `Error`s\n * (wrapping `event.error.errorMessage`) or via stream event types.\n *\n * Retryable hint is set when pi-ai's own retry budget is exhausted on a\n * transient failure — pattern-matched against `message` since pi-ai strips\n * structured fields on plain-Error throws. Set `behavior.retry.maxAttempts: 1`\n * to disable the loop-level retry.\n */\nexport function classifyOpenAIError(err: unknown): ClassifiedError | null {\n const prelude = classifyErrorPrelude(err)\n if (prelude === 'not-object')\n return null\n if (prelude === 'aborted')\n return { kind: 'aborted' }\n\n const anyErr = err as { name?: string, message?: string, code?: string, type?: string }\n\n const message = anyErr.message ?? ''\n const code = anyErr.code ?? anyErr.type\n\n if (code === 'context_length_exceeded' || matchesContextExceeded(message)) {\n return {\n kind: 'context_exceeded',\n providerCode: code ?? 'context_length_exceeded',\n message,\n }\n }\n\n if (matchesToolPairingError(message)) {\n return {\n kind: 'tool_pairing_corruption',\n providerCode: code ?? 'invalid_request_error',\n message,\n }\n }\n\n // pi-ai wraps API errors in generic `Error` — treat as provider_error when we have a message.\n if (message.length > 0) {\n const retryable = isRetryableStatusCode(anyErr) || TRANSIENT_OPENAI_MESSAGE_RE.test(message)\n return {\n kind: 'provider_error',\n providerCode: code,\n message,\n ...(retryable ? { retryable: true } : {}),\n }\n }\n\n return null\n}\n\n/**\n * A standard OpenAI API key usable against `api.openai.com` (for the exact\n * token-count endpoint), or `null` when only a Codex-OAuth credential is\n * available. Codex OAuth access tokens are JWTs (`eyJ…`) and are NOT valid\n * bearers for the standard API; a real key looks like `sk-…` (but not the\n * Anthropic `sk-ant-…` form). Checks `params.apiKey` then `OPENAI_API_KEY`.\n */\n/**\n * OpenAI's org-verification rejection for `reasoning.summary` — e.g.\n * \"Your organization must be verified to generate reasoning summaries\".\n * Matched loosely on the two load-bearing words so minor copy changes\n * don't defeat the platform-branch fallback.\n */\nfunction isReasoningSummaryVerificationError(err: unknown): boolean {\n if (!(err instanceof Error))\n return false\n return /reasoning summar/i.test(err.message) && /verif/i.test(err.message)\n}\n\nfunction pickStandardOpenAIKey(params?: OpenAIParams): string | null {\n const candidates = [params?.apiKey, process.env.OPENAI_API_KEY]\n for (const key of candidates) {\n if (typeof key === 'string' && key.startsWith('sk-') && !key.startsWith('sk-ant-'))\n return key\n }\n return null\n}\n\n/**\n * Convert canonical {@link SessionMessage}s to OpenAI Responses-API `input`\n * items for the token-count endpoint. Only the text-bearing shape is needed\n * here (the count path sends a tiny dummy message); images/tool-results are\n * down-converted to text so the count never throws on an exotic block.\n */\nfunction toResponsesInput(messages: SessionMessage[]): unknown[] {\n return messages.map((msg) => {\n const text = msg.content\n .map(b => (b.type === 'text' ? b.text : ''))\n .filter(Boolean)\n .join('\\n')\n const part = msg.role === 'assistant' ? 'output_text' : 'input_text'\n return { role: msg.role === 'assistant' ? 'assistant' : 'user', content: [{ type: part, text }] }\n })\n}\n\n/** Convert pi-ai `PiTool` specs to Responses-API function tools. */\nfunction toResponsesTools(tools: unknown[]): unknown[] {\n return tools.map((t) => {\n const tool = t as { name?: string, description?: string, parameters?: unknown }\n return {\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }\n })\n}\n\nfunction applyPayloadOverrides(payload: unknown, options: StreamOptions, toWireToolName: (name: string) => string = name => name): unknown {\n const body = payload as Record<string, unknown>\n\n if (options.toolChoice) {\n if (options.toolChoice.type === 'tool' && options.toolChoice.name)\n body.tool_choice = { type: 'function', name: toWireToolName(options.toolChoice.name) }\n else if (options.toolChoice.type === 'required')\n body.tool_choice = 'required'\n else\n body.tool_choice = 'auto'\n }\n\n return body\n}\n\nexport function openai(params?: OpenAIParams): Provider {\n const defaultModel = params?.defaultModel || DEFAULT_MODEL\n const baseCredentials = extractRuntimeCredentials(params)\n let runtimeCredentials = baseCredentials\n ? { ...baseCredentials, ...(params?.accountId ? { accountId: params.accountId } : {}) }\n : undefined\n\n return {\n name: 'openai',\n meta: {\n defaultModel,\n isOAuth: true,\n capabilities: {\n vision: true,\n imageInToolResult: true,\n // pi-ai's Codex Responses wire has no audio/video input content type.\n audio: false,\n video: false,\n },\n },\n formatTools,\n userMessage,\n assistantMessage,\n toolResultsMessage,\n classifyError: classifyOpenAIError,\n\n async countTokens(payload, signal): Promise<number | null> {\n // The exact count endpoint (`POST /v1/responses/input_tokens`) lives on\n // the standard OpenAI API and needs a standard `OPENAI_API_KEY` bearer.\n // This provider authenticates via Codex OAuth against the Codex backend,\n // whose token is NOT valid for that endpoint — so we only attempt the\n // count when a standard key is present (env or params.apiKey that isn't\n // an OAuth/JWT token). Otherwise return null → heuristic fallback.\n const standardKey = pickStandardOpenAIKey(params)\n if (!standardKey)\n return null\n try {\n const tools = payload.tools as PiTool[]\n const nameBoundary = createOpenAIToolNameBoundary(payload.messages, tools.map(tool => tool.name))\n const res = await fetch('https://api.openai.com/v1/responses/input_tokens', {\n method: 'POST',\n headers: {\n ...params?.extraHeaders,\n 'authorization': `Bearer ${standardKey}`,\n 'content-type': 'application/json',\n },\n // The Responses `input_tokens` endpoint takes the same shape as\n // `responses.create`: `instructions` (system), `input` (Responses\n // input items — NOT pi-ai messages), and function-shaped `tools`.\n body: JSON.stringify({\n model: payload.model || defaultModel,\n instructions: renderSystemForWire(payload.system),\n input: toResponsesInput(nameBoundary.messages),\n tools: toResponsesTools(tools.map(tool => ({ ...tool, name: nameBoundary.toWire(tool.name) }))),\n }),\n ...(signal ? { signal } : {}),\n })\n if (!res.ok)\n return null\n const json = (await res.json()) as { input_tokens?: unknown }\n return typeof json.input_tokens === 'number' ? json.input_tokens : null\n }\n catch {\n return null\n }\n },\n\n async stream(options: StreamOptions, callbacks: StreamCallbacks): Promise<TurnResult> {\n const modelId = options.model || defaultModel\n const apiKey = await resolveOAuthApiKey(\n {\n provider: 'openai',\n providerId: PROVIDER_ID,\n params: runtimeCredentials ? { ...params, ...runtimeCredentials } : params,\n envKey: 'OPENAI_CODEX_API_KEY',\n extraCredentialKeys: ['accountId'],\n missingError: 'No OpenAI Codex OAuth token found. Run `bun run auth --openai` first.',\n refreshError: reason => `OpenAI Codex OAuth token refresh failed. Run \\`bun run auth --openai\\` again. ${reason}`,\n },\n {\n ...callbacks,\n async onOAuthRefresh(ctx) {\n if (ctx.source === 'params') {\n runtimeCredentials = {\n access: ctx.credentials.access,\n refresh: ctx.credentials.refresh,\n expires: ctx.credentials.expires,\n ...(typeof ctx.credentials.accountId === 'string' ? { accountId: ctx.credentials.accountId } : {}),\n }\n }\n await callbacks.onOAuthRefresh?.(ctx)\n },\n },\n )\n // Backend auto-detection by credential shape. A Codex OAuth access\n // token is a JWT whose claims carry the `chatgpt_account_id` the Codex\n // backend requires per request; a standard `sk-…` platform key can\n // NEVER stream there (pi-ai fails with an opaque \"Failed to extract\n // accountId from token\") — but it's a first-class credential for the\n // standard Responses API, so route it there instead. Scoped to the\n // unambiguous `sk-` shape: exotic bearers (test harnesses, relays)\n // keep flowing to the Codex path untouched.\n const usePlatformApi = apiKey.startsWith('sk-')\n const model = resolveModel(modelId, usePlatformApi ? PLATFORM_PROVIDER_ID : PROVIDER_ID)\n const tools = options.tools as PiTool[]\n const nameBoundary = createOpenAIToolNameBoundary(options.messages, tools.map(tool => tool.name))\n // Codex's Responses API has no `cache_control` analogue, but the\n // system-prompt boundary marker is structural metadata that should\n // never reach the model. Strip it via `renderSystemForWire`; the\n // doctrine + env are collapsed into a single byte stream the model\n // sees as one logical prompt.\n const context: PiContext = {\n systemPrompt: renderSystemForWire(options.system),\n messages: toPiMessages(nameBoundary.messages, modelId),\n tools: tools.map(tool => ({ ...tool, name: nameBoundary.toWire(tool.name) })),\n }\n // OpenAI's `reasoning_effort` accepts minimal/low/medium/high/xhigh, and\n // the GPT-5.6 line adds a native `max` tier. Clamp `max` to `xhigh` on\n // older models only; `'adaptive'` degrades to no reasoning rather than\n // forwarding an unknown value the API would reject.\n const supportsMaxEffort = modelId.startsWith('gpt-5.6')\n const reasoningLevel\n = options.thinking && options.thinking !== 'off' && options.thinking !== 'adaptive'\n ? options.thinking === 'max' && !supportsMaxEffort ? 'xhigh' : options.thinking\n : undefined\n // Options are shared verbatim across both backends — the platform\n // Responses API and the Codex bridge take the same reasoning / service\n // tier knobs; only the websocket `transport` toggle is Codex-specific.\n const makeStream = (reasoningSummary: 'auto' | undefined) => {\n const streamOptions = {\n apiKey,\n ...(options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n signal: options.signal,\n reasoningEffort: reasoningLevel,\n reasoningSummary,\n ...(options.modelOptions?.fast ? { serviceTier: 'priority' as const } : {}),\n ...(params?.extraHeaders ? { headers: params.extraHeaders } : {}),\n // pi-ai types the payload as `unknown`; both backends send the\n // Responses-API body shape `applyPayloadOverrides` expects.\n onPayload: (payload: unknown) => applyPayloadOverrides(payload as Record<string, unknown>, options, nameBoundary.toWire),\n }\n return usePlatformApi\n ? streamOpenAIResponses(model as unknown as PlatformModel, context, streamOptions)\n : streamOpenAICodexResponses(model, context, { ...streamOptions, transport: params?.transport })\n }\n let stream = makeStream(reasoningLevel ? 'auto' : undefined)\n\n let finalMessage: PiAssistantMessage | undefined\n let text = ''\n let thinking = ''\n\n const consume = async (s: ReturnType<typeof makeStream>) => {\n for await (const event of s) {\n if (event.type === 'text_delta') {\n text += event.delta\n callbacks.onText(event.delta)\n }\n else if (event.type === 'thinking_delta') {\n thinking += event.delta\n callbacks.onThinking?.(event.delta)\n }\n else if (event.type === 'thinking_end') {\n const delta = event.content.startsWith(thinking)\n ? event.content.slice(thinking.length)\n : (thinking ? '' : event.content)\n if (delta) {\n thinking += delta\n callbacks.onThinking?.(delta)\n }\n }\n else if (event.type === 'done') {\n finalMessage = event.message\n }\n else if (event.type === 'error') {\n throw new Error(event.error.errorMessage || (usePlatformApi ? 'OpenAI API error' : 'OpenAI Codex API error'))\n }\n }\n }\n\n try {\n await consume(stream)\n }\n catch (err) {\n // The platform Responses API rejects reasoning summaries for\n // organizations that haven't completed verification (the Codex\n // backend has no such gate). That 400 fails request validation, so\n // nothing has streamed yet — retry once without the summary rather\n // than bricking every reasoning-enabled stream for those orgs.\n const nothingStreamed = text.length === 0 && thinking.length === 0 && finalMessage === undefined\n if (usePlatformApi && reasoningLevel && nothingStreamed && isReasoningSummaryVerificationError(err)) {\n stream = makeStream(undefined)\n await consume(stream)\n }\n else {\n throw err\n }\n }\n\n finalMessage ??= await stream.result()\n text ||= extractText(finalMessage)\n\n const toolCalls = extractToolCalls(finalMessage)\n .map(call => ({ ...call, name: nameBoundary.fromWire(call.name) }))\n const assistantTurn = fromPiAssistantMessage(finalMessage)\n assistantTurn.content = assistantTurn.content.map(block =>\n block.type === 'tool_call' ? { ...block, name: nameBoundary.fromWire(block.name) } : block,\n )\n const finishReason = mapCodexStopReason(finalMessage.stopReason, toolCalls.length > 0)\n const usage = await toTurnUsage(finalMessage.usage, finishReason, modelId)\n\n return {\n assistantMessage: assistantTurn,\n text,\n toolCalls,\n done: toolCalls.length === 0,\n usage,\n }\n },\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bm as normalizeOpenRouterModelId, xm as openrouter, ym as OpenRouterParams } from "../index-B6eBI_OD.js";
|
|
2
2
|
export { OpenRouterParams, normalizeOpenRouterModelId, openrouter };
|
package/dist/providers/xai.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fm as XaiParams, pm as xai } from "../index-B6eBI_OD.js";
|
|
2
2
|
export { XaiParams, xai };
|
package/dist/providers.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $m as
|
|
1
|
+
import { $m as cerebras, Dm as OpenAICompatParams, Em as OpenAICompatHttpError, Jm as LocalParams, Km as openai, Lm as mapOAIFinishReason, Pm as classifyOpenAICompatError, Qm as CerebrasParams, Tm as OpenAICompatAuthHeader, Um as OpenAIParams, Xm as CursorParams, Ym as local, Zm as cursor, _m as sanitizeToolSchema, am as StreamCallbacks, ch as anthropic, cm as ToolCall, dm as TurnResult, eh as BasetenParams, fm as XaiParams, gm as SchemaSanitizeResult, hm as SchemaSanitizeProfile, ih as arcee, im as ProviderCapabilities, lh as applyAnthropicCacheBreakpoints, lm as ToolResult, mm as SchemaSanitizeOptions, nh as planBasetenReasoning, nm as HistoryRepair, oh as AnthropicParams, om as StreamOptions, pm as xai, rh as ArceeParams, rm as Provider, sm as TokenCountPayload, th as baseten, um as ToolSpec, vm as sanitizeToolSpecs, xm as openrouter, ym as OpenRouterParams, zm as openaiCompat } from "./index-B6eBI_OD.js";
|
|
2
2
|
export { type AnthropicParams, type ArceeParams, type BasetenParams, type CerebrasParams, type CursorParams, HistoryRepair, type LocalParams, type OpenAICompatAuthHeader, OpenAICompatHttpError, type OpenAICompatParams, type OpenAIParams, type OpenRouterParams, Provider, ProviderCapabilities, type SchemaSanitizeOptions, type SchemaSanitizeProfile, type SchemaSanitizeResult, StreamCallbacks, StreamOptions, TokenCountPayload, ToolCall, ToolResult, ToolSpec, TurnResult, type XaiParams, anthropic, applyAnthropicCacheBreakpoints, arcee, baseten, cerebras, classifyOpenAICompatError, cursor, local, mapOAIFinishReason, openai, openaiCompat, openrouter, planBasetenReasoning, sanitizeToolSchema, sanitizeToolSpecs, xai };
|
package/dist/providers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { f as mapOAIFinishReason, l as classifyOpenAICompatError, m as openaiCompat, n as OpenAICompatHttpError, v as sanitizeToolSchema, y as sanitizeToolSpecs } from "./openai-compat-pHI0kBWH.js";
|
|
2
|
-
import { n as applyAnthropicCacheBreakpoints, t as anthropic } from "./anthropic-
|
|
2
|
+
import { n as applyAnthropicCacheBreakpoints, t as anthropic } from "./anthropic-BEYY0hVK.js";
|
|
3
3
|
import { arcee } from "./providers/arcee.js";
|
|
4
4
|
import { baseten, planBasetenReasoning } from "./providers/baseten.js";
|
|
5
5
|
import { cerebras } from "./providers/cerebras.js";
|
package/dist/restate.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Bi as McpToolWrap, Md as AgentBehavior, Nd as AgentClock, Rf as ToolContext, Tf as ToolResultContent,
|
|
1
|
+
import { Bi as McpToolWrap, Md as AgentBehavior, Nd as AgentClock, Rf as ToolContext, Tf as ToolResultContent, om as StreamOptions, rm as Provider, sp as SessionStore, xf as ToolBatchExecutor, zf as ToolDef, zi as McpToolMeta } from "./index-B6eBI_OD.js";
|
|
2
2
|
import { h as TaskExitInfo, l as ExecutionHandle, m as TaskEntry, o as DetachedTasksCapability } from "./types-BDccavwj.js";
|
|
3
3
|
|
|
4
4
|
//#region src/restate/types.d.ts
|
|
@@ -33,6 +33,7 @@ function createRunSummaryCollector(options = {}) {
|
|
|
33
33
|
const validationRejects = [];
|
|
34
34
|
const budgetEvents = [];
|
|
35
35
|
const repeatGuardEvents = [];
|
|
36
|
+
const streamRetries = [];
|
|
36
37
|
const pairingRepairs = {};
|
|
37
38
|
const children = [];
|
|
38
39
|
function resetForNewRun() {
|
|
@@ -42,6 +43,7 @@ function createRunSummaryCollector(options = {}) {
|
|
|
42
43
|
validationRejects.length = 0;
|
|
43
44
|
budgetEvents.length = 0;
|
|
44
45
|
repeatGuardEvents.length = 0;
|
|
46
|
+
streamRetries.length = 0;
|
|
45
47
|
for (const k of Object.keys(pairingRepairs)) delete pairingRepairs[k];
|
|
46
48
|
children.length = 0;
|
|
47
49
|
}
|
|
@@ -57,6 +59,18 @@ function createRunSummaryCollector(options = {}) {
|
|
|
57
59
|
unregisters.push(hooks.hook("agent:abort", () => {
|
|
58
60
|
aborted = true;
|
|
59
61
|
}));
|
|
62
|
+
unregisters.push(hooks.hook("stream:retry", (ctx) => {
|
|
63
|
+
const msg = ctx.err instanceof Error ? ctx.err.message : String(ctx.err);
|
|
64
|
+
streamRetries.push({
|
|
65
|
+
attempt: ctx.attempt,
|
|
66
|
+
delayMs: ctx.delayMs,
|
|
67
|
+
message: msg,
|
|
68
|
+
...ctx.err instanceof Error ? { errorType: ctx.err.name } : {},
|
|
69
|
+
...ctx.statusCode !== void 0 ? { statusCode: ctx.statusCode } : {},
|
|
70
|
+
...ctx.requestId !== void 0 ? { requestId: ctx.requestId } : {},
|
|
71
|
+
turnId: ctx.turnId
|
|
72
|
+
});
|
|
73
|
+
}));
|
|
60
74
|
unregisters.push(hooks.hook("stream:error", (ctx) => {
|
|
61
75
|
const msg = ctx.err instanceof Error ? ctx.err.message : String(ctx.err);
|
|
62
76
|
const errorType = ctx.err instanceof Error ? ctx.err.name : "unknown";
|
|
@@ -183,6 +197,7 @@ function createRunSummaryCollector(options = {}) {
|
|
|
183
197
|
blocks: blocks.slice(),
|
|
184
198
|
validationRejects: validationRejects.slice(),
|
|
185
199
|
budgetEvents: budgetEvents.slice(),
|
|
200
|
+
streamRetries: streamRetries.slice(),
|
|
186
201
|
repeatGuardEvents: repeatGuardEvents.slice(),
|
|
187
202
|
pairingRepairs: { ...pairingRepairs },
|
|
188
203
|
...children.length > 0 ? { children: children.slice() } : {}
|
|
@@ -242,6 +257,7 @@ function minimalSummaryFromStats(stats, meta) {
|
|
|
242
257
|
blocks: [],
|
|
243
258
|
validationRejects: [],
|
|
244
259
|
budgetEvents: [],
|
|
260
|
+
streamRetries: [],
|
|
245
261
|
repeatGuardEvents: [],
|
|
246
262
|
pairingRepairs: {},
|
|
247
263
|
...children.length > 0 ? { children } : {}
|
|
@@ -250,4 +266,4 @@ function minimalSummaryFromStats(stats, meta) {
|
|
|
250
266
|
//#endregion
|
|
251
267
|
export { createRunSummaryCollector as t };
|
|
252
268
|
|
|
253
|
-
//# sourceMappingURL=run-summary-
|
|
269
|
+
//# sourceMappingURL=run-summary-BU_NgwUT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-summary-BU_NgwUT.js","names":[],"sources":["../src/run-summary.ts"],"sourcesContent":["/**\n * Run summary collector — one JSON postmortem per `agent.run()`.\n *\n * `AgentStats` is great for billing and per-turn accounting but doesn't\n * carry a record of the *interesting* events that happened during a run\n * (errors, gate blocks, validation rejects, budget hits, MCP failures).\n * Reconstructing that from a hook stream after the fact is exactly the\n * kind of plumbing every consumer ends up re-implementing.\n *\n * This module ships:\n *\n * - {@link RunSummary} — a serializable shape that bundles totals,\n * per-model breakdown, and all the per-run incident lists.\n * - {@link createRunSummaryCollector} — installs hook listeners that\n * build up a {@link RunSummary} during the run and surfaces it on\n * `agent:done`. Calls an optional `onSummary` callback so the host can\n * forward to a log aggregator / DB / postmortem dashboard without\n * touching `agent.run()`'s return value.\n *\n * The collector is purely additive — it doesn't touch the agent loop,\n * doesn't change return shapes, and doesn't suppress any other hook\n * handlers. Drop it in alongside tracing / metrics / logging or use it\n * standalone when you only need the summary.\n */\n\nimport type { Hookable } from 'hookable'\nimport type { AgentHooks } from './agent'\nimport type { AgentStats } from './types'\nimport { statsByModel } from './stats'\n\n// ---------------------------------------------------------------------------\n// Public shape\n// ---------------------------------------------------------------------------\n\nexport interface RunSummaryTokens {\n input: number\n output: number\n cacheRead: number\n cacheCreation: number\n cost?: number\n /** First observable byte from the provider, ms from run start. */\n ttftMs?: number\n}\n\nexport interface RunSummaryByModel {\n modelId: string\n input: number\n output: number\n cacheRead: number\n cacheCreation: number\n cost: number\n turns: number\n}\n\nexport interface RunSummaryError {\n kind: 'stream' | 'tool' | 'mcp-tool' | 'mcp' | 'spawn'\n message: string\n errorType?: string\n turnId?: string\n callId?: string\n server?: string\n toolName?: string\n childId?: string\n statusCode?: number\n requestId?: string\n}\n\nexport interface RunSummaryBlock {\n callId: string\n toolName: string\n outcome: 'gate-block' | 'unknown' | 'invalid-input'\n reason?: string\n}\n\nexport interface RunSummaryValidation {\n callId: string\n toolName: string\n reason: string\n}\n\nexport interface RunSummaryBudget {\n kind: 'bytes' | 'tool-count'\n /** Tool name (for `'tool-count'`); absent for byte budgets. */\n toolName?: string\n /** `mode` for `'tool-count'`; absent for byte budgets. */\n mode?: 'steer' | 'block'\n observed: number\n limit: number\n turnId?: string\n}\n\nexport interface RunSummaryRepeatGuard {\n toolName: string\n /** Observed repeat count that tripped the guard. */\n count: number\n threshold: number\n action: 'block' | 'steer' | 'abort'\n turnId?: string\n}\n\n/**\n * One absorbed provider-stream retry. Retries are invisible in the transcript\n * (no turn, no tool result) yet their backoff is real wall time the user\n * waited — measured in production as unexplained 30-90s gaps before trivial\n * tool calls. Recording them makes \"LLM residual\" stalls attributable.\n */\nexport interface RunSummaryRetry {\n /** 1-based attempt number that failed and triggered this retry. */\n attempt: number\n /** Backoff delay taken before the next attempt (ms, after retry-after/cap). */\n delayMs: number\n message: string\n errorType?: string\n statusCode?: number\n requestId?: string\n turnId?: string\n}\n\n/**\n * Postmortem snapshot of one `agent.run()`. Strictly serializable — every\n * field round-trips through `JSON.stringify` / `JSON.parse` without loss\n * so a log aggregator can ingest it as-is.\n */\nexport interface RunSummary {\n runId?: string\n parentRunId?: string\n depth: number\n agentName?: string\n startedAt: number\n endedAt: number\n durationMs: number\n status: 'completed' | 'aborted'\n turns: number\n totals: RunSummaryTokens\n byModel: RunSummaryByModel[]\n errors: RunSummaryError[]\n blocks: RunSummaryBlock[]\n validationRejects: RunSummaryValidation[]\n budgetEvents: RunSummaryBudget[]\n /**\n * Provider-stream retries the loop absorbed. Empty on healthy runs; on\n * incident runs the summed `delayMs` explains wall time that appears\n * nowhere else (not in turns, not in tool durations).\n */\n streamRetries: RunSummaryRetry[]\n /**\n * Repeat-guard escalations. An `action: 'steer'` entry means the tool still\n * executed and got a steering message appended to its result. An\n * `action: 'abort'` entry means the guard terminated the run via the agent's\n * AbortController (the run finalizes as `'aborted'`).\n */\n repeatGuardEvents: RunSummaryRepeatGuard[]\n /** Counts of pairing repairs, keyed by repair mode. */\n pairingRepairs: Record<string, number>\n /**\n * Postmortem snapshots of child runs that bubbled their stats up via\n * `spawn:complete`. Only present when the run actually spawned.\n */\n children?: RunSummary[]\n}\n\n// ---------------------------------------------------------------------------\n// Collector\n// ---------------------------------------------------------------------------\n\nexport interface RunSummaryCollectorOptions {\n /**\n * Called with the assembled {@link RunSummary} on every `agent:done`.\n * Synchronous — heavy I/O should be deferred (e.g. via `setImmediate`).\n */\n onSummary?: (summary: RunSummary) => void\n}\n\nexport interface RunSummaryCollector {\n /** Install the collector's hook handlers. Returns an uninstall fn. */\n install: (hooks: Hookable<AgentHooks>) => () => void\n /** Most-recent summary; `undefined` until the first `agent:done` fires. */\n latest: () => RunSummary | undefined\n}\n\n/**\n * Build a run-summary collector. State is created fresh inside each\n * `install()` call, so a single collector instance can be installed\n * across multiple agents without attribution cross-talk. `latest()`\n * returns the most-recent summary across **any** install — install\n * per-agent collectors if you need separate post-run snapshots.\n *\n * @example\n * ```ts\n * const collector = createRunSummaryCollector({\n * onSummary: s => console.log(JSON.stringify(s)),\n * })\n * const uninstall = collector.install(agent.hooks)\n * try { await agent.run({ prompt }) }\n * finally { uninstall() }\n * ```\n */\nexport function createRunSummaryCollector(\n options: RunSummaryCollectorOptions = {},\n): RunSummaryCollector {\n let last: RunSummary | undefined\n\n return {\n latest: () => last,\n install(hooks: Hookable<AgentHooks>): () => void {\n // Per-run in-progress accumulators. The hookable bus serializes\n // agent.run lifecycles per agent — we reset between runs on\n // `agent:start` and consume on `agent:done`.\n let runId: string | undefined\n let parentRunId: string | undefined\n let depth = 0\n let agentName: string | undefined\n let startedAt = Date.now()\n let aborted = false\n const errors: RunSummaryError[] = []\n const blocks: RunSummaryBlock[] = []\n const validationRejects: RunSummaryValidation[] = []\n const budgetEvents: RunSummaryBudget[] = []\n const repeatGuardEvents: RunSummaryRepeatGuard[] = []\n const streamRetries: RunSummaryRetry[] = []\n const pairingRepairs: Record<string, number> = {}\n const children: RunSummary[] = []\n\n function resetForNewRun(): void {\n aborted = false\n errors.length = 0\n blocks.length = 0\n validationRejects.length = 0\n budgetEvents.length = 0\n repeatGuardEvents.length = 0\n streamRetries.length = 0\n for (const k of Object.keys(pairingRepairs))\n delete pairingRepairs[k]\n children.length = 0\n }\n\n const unregisters: Array<() => void> = []\n\n unregisters.push(hooks.hook('agent:start', (ctx) => {\n resetForNewRun()\n runId = ctx.runId\n parentRunId = ctx.parentRunId\n depth = ctx.depth\n agentName = ctx.agentName\n startedAt = ctx.startedAt\n }))\n\n unregisters.push(hooks.hook('agent:abort', () => {\n aborted = true\n }))\n\n unregisters.push(hooks.hook('stream:retry', (ctx) => {\n const msg = ctx.err instanceof Error ? ctx.err.message : String(ctx.err)\n streamRetries.push({\n attempt: ctx.attempt,\n delayMs: ctx.delayMs,\n message: msg,\n ...(ctx.err instanceof Error ? { errorType: ctx.err.name } : {}),\n ...(ctx.statusCode !== undefined ? { statusCode: ctx.statusCode } : {}),\n ...(ctx.requestId !== undefined ? { requestId: ctx.requestId } : {}),\n turnId: ctx.turnId,\n })\n }))\n\n unregisters.push(hooks.hook('stream:error', (ctx) => {\n const msg = ctx.err instanceof Error ? ctx.err.message : String(ctx.err)\n const errorType = ctx.err instanceof Error ? ctx.err.name : 'unknown'\n errors.push({\n kind: 'stream',\n message: msg,\n errorType,\n turnId: ctx.turnId,\n ...(ctx.statusCode !== undefined ? { statusCode: ctx.statusCode } : {}),\n ...(ctx.requestId !== undefined ? { requestId: ctx.requestId } : {}),\n })\n }))\n\n unregisters.push(hooks.hook('tool:error', (ctx) => {\n errors.push({\n kind: 'tool',\n message: ctx.error.message,\n errorType: ctx.error.name,\n turnId: ctx.turnId,\n callId: ctx.callId,\n toolName: ctx.name,\n })\n }))\n\n unregisters.push(hooks.hook('mcp:tool:error', (ctx) => {\n errors.push({\n kind: 'mcp-tool',\n message: ctx.error.message,\n errorType: ctx.error.name,\n turnId: ctx.turnId,\n callId: ctx.callId,\n server: ctx.server,\n toolName: ctx.displayName,\n })\n }))\n\n unregisters.push(hooks.hook('mcp:error', (ctx) => {\n errors.push({\n kind: 'mcp',\n message: ctx.error.message,\n errorType: ctx.error.name,\n server: ctx.name,\n })\n }))\n\n unregisters.push(hooks.hook('spawn:error', (ctx) => {\n errors.push({\n kind: 'spawn',\n message: ctx.error.message,\n errorType: ctx.error.name,\n childId: ctx.id,\n })\n }))\n\n unregisters.push(hooks.hook('tool:dispatched', (ctx) => {\n if (ctx.outcome === 'gate-block' || ctx.outcome === 'unknown' || ctx.outcome === 'invalid-input') {\n blocks.push({\n callId: ctx.callId,\n toolName: ctx.name,\n outcome: ctx.outcome,\n ...(ctx.reason ? { reason: ctx.reason } : {}),\n })\n }\n }))\n\n unregisters.push(hooks.hook('validation:reject', (ctx) => {\n validationRejects.push({\n callId: ctx.callId,\n toolName: ctx.name,\n reason: ctx.reason,\n })\n }))\n\n unregisters.push(hooks.hook('budget:exceeded', (ctx) => {\n budgetEvents.push({\n kind: 'bytes',\n observed: ctx.bytes,\n limit: ctx.budget,\n turnId: ctx.turnId,\n })\n }))\n\n unregisters.push(hooks.hook('tool-budget:exceeded', (ctx) => {\n budgetEvents.push({\n kind: 'tool-count',\n toolName: ctx.tool,\n mode: ctx.mode,\n observed: ctx.count,\n limit: ctx.max,\n turnId: ctx.turnId,\n })\n }))\n\n unregisters.push(hooks.hook('repeat-guard:exceeded', (ctx) => {\n repeatGuardEvents.push({\n toolName: ctx.tool,\n count: ctx.count,\n threshold: ctx.threshold,\n action: ctx.action,\n turnId: ctx.turnId,\n })\n }))\n\n unregisters.push(hooks.hook('pairing:repair', (ctx) => {\n pairingRepairs[ctx.mode] = (pairingRepairs[ctx.mode] ?? 0) + 1\n }))\n\n unregisters.push(hooks.hook('agent:done', (stats) => {\n const endedAt = Date.now()\n\n // Build per-model rollup via the existing `statsByModel` helper\n // so we stay in lockstep with how the rest of the harness\n // attributes cost and tokens by model id.\n const byModel: RunSummaryByModel[] = []\n for (const [modelId, usage] of statsByModel(stats)) {\n byModel.push({\n modelId,\n input: usage.input,\n output: usage.output,\n cacheRead: usage.cacheRead,\n cacheCreation: usage.cacheCreation,\n cost: usage.cost,\n turns: usage.turns,\n })\n }\n\n // Flatten child stats into nested summaries. We don't have the\n // child's full event lists here (those landed on the child's\n // own hooks), so the nested entry is a minimal totals-only\n // record — enough for a flat per-run audit trail; consumers\n // wanting full per-child event lists install a collector on\n // each subagent.\n for (const c of stats.children ?? []) {\n children.push(minimalSummaryFromStats(c.stats, {\n depth: c.depth ?? depth + 1,\n status: c.status === 'aborted' ? 'aborted' : 'completed',\n }))\n }\n\n const summary: RunSummary = {\n ...(runId ? { runId } : {}),\n ...(parentRunId ? { parentRunId } : {}),\n depth,\n ...(agentName ? { agentName } : {}),\n startedAt,\n endedAt,\n durationMs: endedAt - startedAt,\n status: aborted ? 'aborted' : 'completed',\n turns: stats.turns,\n totals: buildTotals(stats),\n byModel,\n errors: errors.slice(),\n blocks: blocks.slice(),\n validationRejects: validationRejects.slice(),\n budgetEvents: budgetEvents.slice(),\n streamRetries: streamRetries.slice(),\n repeatGuardEvents: repeatGuardEvents.slice(),\n pairingRepairs: { ...pairingRepairs },\n ...(children.length > 0 ? { children: children.slice() } : {}),\n }\n\n last = summary\n try {\n options.onSummary?.(summary)\n }\n catch {\n // Sink errors are not the collector's concern.\n }\n }))\n\n let disposed = false\n return function uninstall() {\n if (disposed)\n return\n disposed = true\n for (const un of unregisters) {\n try {\n un()\n }\n catch { /* ignore */ }\n }\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction buildTotals(stats: AgentStats): RunSummaryTokens {\n return {\n input: stats.totalIn,\n output: stats.totalOut,\n cacheRead: stats.totalCacheRead,\n cacheCreation: stats.totalCacheCreation,\n ...(typeof stats.cost === 'number' ? { cost: stats.cost } : {}),\n ...(typeof stats.timeTillFirstTokenMs === 'number' ? { ttftMs: stats.timeTillFirstTokenMs } : {}),\n }\n}\n\nfunction minimalSummaryFromStats(\n stats: AgentStats,\n meta: { depth: number, status: 'completed' | 'aborted' },\n): RunSummary {\n const byModel: RunSummaryByModel[] = []\n for (const [modelId, usage] of statsByModel(stats)) {\n byModel.push({\n modelId,\n input: usage.input,\n output: usage.output,\n cacheRead: usage.cacheRead,\n cacheCreation: usage.cacheCreation,\n cost: usage.cost,\n turns: usage.turns,\n })\n }\n const children: RunSummary[] = []\n for (const c of stats.children ?? []) {\n children.push(minimalSummaryFromStats(c.stats, {\n depth: c.depth ?? meta.depth + 1,\n status: c.status === 'aborted' ? 'aborted' : 'completed',\n }))\n }\n return {\n depth: meta.depth,\n startedAt: 0,\n endedAt: 0,\n durationMs: stats.elapsed,\n status: meta.status,\n turns: stats.turns,\n totals: buildTotals(stats),\n byModel,\n errors: [],\n blocks: [],\n validationRejects: [],\n budgetEvents: [],\n streamRetries: [],\n repeatGuardEvents: [],\n pairingRepairs: {},\n ...(children.length > 0 ? { children } : {}),\n }\n}\n"],"mappings":"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"}
|
package/dist/session/sqlite.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as toWireMessages } from "./messages-Dy9t7DbQ.js";
|
|
2
2
|
import { Buffer } from "node:buffer";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
//#region src/session/file-map.ts
|
|
@@ -665,4 +665,4 @@ function assertJsonBounded(value, maxBytes, label) {
|
|
|
665
665
|
//#endregion
|
|
666
666
|
export { getExtensionSessionState as a, setExtensionSessionState as c, createMemoryStore as d, createFileMapStore as f, demoteStaleRunningStatus as i, withExtensionSession as l, currentExtensionSession as n, loadSession as o, deleteExtensionSessionState as r, resumeChainRunIds as s, createSession as t, createRemoteStore as u };
|
|
667
667
|
|
|
668
|
-
//# sourceMappingURL=session-
|
|
668
|
+
//# sourceMappingURL=session-DkVnYGm9.js.map
|