@kernlang/agon 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{chunk-4NTH3EAR.js → chunk-3PDYVGRS.js} +77 -22
  2. package/dist/chunk-3PDYVGRS.js.map +1 -0
  3. package/dist/{chunk-GPYWJO2Q.js → chunk-6IF2AV4Y.js} +8 -7
  4. package/dist/{chunk-GPYWJO2Q.js.map → chunk-6IF2AV4Y.js.map} +1 -1
  5. package/dist/{chunk-73ETZFDH.js → chunk-7WZ2O5WZ.js} +4 -4
  6. package/dist/{chunk-DGTU4UWQ.js → chunk-NBV37VMW.js} +2 -2
  7. package/dist/{chunk-46WNYE4R.js → chunk-PUNBDLQO.js} +31 -31
  8. package/dist/chunk-PUNBDLQO.js.map +1 -0
  9. package/dist/{chunk-HAJIKZGU.js → chunk-TMNHJOKU.js} +408 -68
  10. package/dist/chunk-TMNHJOKU.js.map +1 -0
  11. package/dist/{chunk-SOUF7XTW.js → chunk-XWHC6VAH.js} +3 -2
  12. package/dist/chunk-XWHC6VAH.js.map +1 -0
  13. package/dist/{dispatch-XHLJ44TF.js → dispatch-S3CR5HKX.js} +2 -2
  14. package/dist/engines/codex.json +3 -0
  15. package/dist/{forge-ZI7NE73F.js → forge-GUOEJ5DJ.js} +6 -6
  16. package/dist/index.js +28 -24
  17. package/dist/index.js.map +1 -1
  18. package/dist/{plan-mode-KIXDKD63.js → plan-mode-35BONR7S.js} +6 -6
  19. package/dist/{src-4A5FVACG.js → src-3NWTITZM.js} +9 -3
  20. package/dist/{update-DLPMYTF3.js → update-H3LE4ZSI.js} +5 -5
  21. package/package.json +3 -2
  22. package/dist/chunk-46WNYE4R.js.map +0 -1
  23. package/dist/chunk-4NTH3EAR.js.map +0 -1
  24. package/dist/chunk-HAJIKZGU.js.map +0 -1
  25. package/dist/chunk-SOUF7XTW.js.map +0 -1
  26. /package/dist/{chunk-73ETZFDH.js.map → chunk-7WZ2O5WZ.js.map} +0 -0
  27. /package/dist/{chunk-DGTU4UWQ.js.map → chunk-NBV37VMW.js.map} +0 -0
  28. /package/dist/{dispatch-XHLJ44TF.js.map → dispatch-S3CR5HKX.js.map} +0 -0
  29. /package/dist/{forge-ZI7NE73F.js.map → forge-GUOEJ5DJ.js.map} +0 -0
  30. /package/dist/{plan-mode-KIXDKD63.js.map → plan-mode-35BONR7S.js.map} +0 -0
  31. /package/dist/{src-4A5FVACG.js.map → src-3NWTITZM.js.map} +0 -0
  32. /package/dist/{update-DLPMYTF3.js.map → update-H3LE4ZSI.js.map} +0 -0
@@ -129,7 +129,8 @@ ${message.content}`;
129
129
  if (msg.role === "system") {
130
130
  continue;
131
131
  } else if (msg.role === "user") {
132
- pushMessage({ role: "user", content: typeof msg.content === "string" ? msg.content : String(msg.content ?? "") });
132
+ const userContent = Array.isArray(msg.content) ? msg.content : typeof msg.content === "string" ? msg.content : String(msg.content ?? "");
133
+ pushMessage({ role: "user", content: userContent });
133
134
  } else if (msg.role === "assistant") {
134
135
  const parts = [];
135
136
  if (msg.content && typeof msg.content === "string") {
@@ -474,4 +475,4 @@ export {
474
475
  _formatHintEmitted,
475
476
  apiStreamDispatchWithHistory
476
477
  };
477
- //# sourceMappingURL=chunk-SOUF7XTW.js.map
478
+ //# sourceMappingURL=chunk-XWHC6VAH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../core/src/generated/api/dispatch.ts"],"sourcesContent":["// @generated by kern v3.5.8 — DO NOT EDIT. Source: src/kern/api/dispatch.kern\n\n// @kern-source: dispatch:290\n// @kern-source: dispatch:322\n\nimport { streamText, generateText, jsonSchema } from 'ai';\n\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible';\n\nimport { createAnthropic } from '@ai-sdk/anthropic';\n\nimport type { DispatchResult } from '../models/types.js';\n\n// @kern-source: dispatch:6\nexport interface ApiConfig {\n baseUrl: string;\n apiKeyEnv: string;\n model: string;\n maxTokens?: number;\n format?: 'openai'|'anthropic';\n firstChunkTimeoutMs?: number;\n idleTimeoutMs?: number;\n}\n\n// @kern-source: dispatch:16\nexport const _modelCache: Map<string,{model:any, apiKey:string}> = new Map<string,{model:any, apiKey:string}>();\n\n/**\n * Create AI SDK model instance from ApiConfig — routes to openai-compatible or anthropic provider. Cached by baseUrl+model+format; invalidated if API key changes.\n */\n// @kern-source: dispatch:18\nexport function buildModel(config: ApiConfig): any {\n const apiKey = process.env[config.apiKeyEnv];\n if (!apiKey) return null;\n\n const cacheKey = `${config.baseUrl}|${config.model}|${config.format ?? 'openai'}`;\n const cached = _modelCache.get(cacheKey);\n if (cached && cached.apiKey === apiKey) return cached.model;\n\n const base = config.baseUrl.replace(/\\/$/, '');\n\n let model: any;\n if (config.format === 'anthropic') {\n // createAnthropic baseURL should include /v1 — it appends /messages\n const baseURL = base.endsWith('/v1') ? base : base + '/v1';\n const provider = createAnthropic({ apiKey, baseURL });\n model = provider(config.model);\n } else {\n // OpenAI-compatible: baseURL is used as prefix, SDK appends /chat/completions\n const provider = createOpenAICompatible({\n name: 'agon-api',\n apiKey,\n baseURL: base,\n });\n model = provider.chatModel(config.model);\n }\n\n _modelCache.set(cacheKey, { model, apiKey });\n return model;\n}\n\n/**\n * Convert OpenAI-format tool definitions to AI SDK tool format.\n */\n// @kern-source: dispatch:50\nexport function convertToolsForSdk(tools: Array<{type:string,function:{name:string,description:string,parameters:Record<string,unknown>}}>): Record<string,any> {\n const result: Record<string, any> = {};\n for (const t of tools) {\n result[t.function.name] = {\n description: t.function.description,\n inputSchema: jsonSchema(t.function.parameters as any),\n // No execute — tool execution is handled by the caller (persistent-session)\n };\n }\n return result;\n}\n\n/**\n * Normalize tool call IDs per provider: Anthropic requires [a-zA-Z0-9_], Mistral max 9 chars.\n */\n// @kern-source: dispatch:64\nfunction normalizeToolCallId(id: string, format?: string): string {\n if (!id) {\n return `call_${Date.now()}`;\n }\n if (format === 'anthropic') {\n // Claude: alphanumeric + underscore only\n return id.replace(/[^a-zA-Z0-9_]/g, '_');\n }\n // Mistral: max 9 chars, alphanumeric only\n if (format === 'mistral') {\n return id.replace(/[^a-zA-Z0-9]/g, '').slice(0, 9) || `c${Date.now() % 100000000}`;\n }\n return id;\n}\n\n/**\n * Convert Agon message history (OpenAI wire format) to AI SDK CoreMessage format. Handles per-provider normalization.\n */\n// @kern-source: dispatch:77\nexport function convertMessagesForSdk(messages: Array<{role:string,content:any,tool_calls?:any[],tool_call_id?:string}>, format?: string): any[] {\n // Build original→normalized ID mapping, and record only immediately\n // following tool results for each assistant message. The AI SDK requires\n // every assistant tool-call part to be paired by the contiguous tool-result\n // block that follows it. If an interrupted stream left a dangling or\n // non-contiguous assistant tool_call in history, replay it as plain context\n // instead of letting the SDK throw MissingToolResultsError.\n const idMap = new Map<string, string>();\n for (const msg of messages) {\n if (msg.tool_calls) {\n for (const tc of msg.tool_calls) {\n if (tc.id && tc.function?.name) {\n const normalizedId = normalizeToolCallId(tc.id, format);\n idMap.set(tc.id, normalizedId);\n }\n }\n }\n }\n const contiguousResultIdsByAssistantIndex = new Map<number, Set<string>>();\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i] as any;\n if (msg?.role !== 'assistant' || !Array.isArray(msg.tool_calls) || msg.tool_calls.length === 0) continue;\n const resultIds = new Set<string>();\n for (let j = i + 1; j < messages.length; j++) {\n const candidate = messages[j] as any;\n if (candidate?.role !== 'tool') break;\n const originalId = typeof candidate.tool_call_id === 'string' ? candidate.tool_call_id : '';\n if (!originalId) continue;\n resultIds.add(idMap.get(originalId) ?? normalizeToolCallId(originalId, format));\n }\n contiguousResultIdsByAssistantIndex.set(i, resultIds);\n }\n\n const systemParts: string[] = [];\n for (const msg of messages) {\n if (msg.role !== 'system') continue;\n const content = typeof msg.content === 'string' ? msg.content : String(msg.content ?? '');\n if (content.trim()) systemParts.push(content);\n }\n\n const result: any[] = [];\n const activeToolNamesById = new Map<string, string>();\n if (systemParts.length > 0) {\n result.push({ role: 'system', content: systemParts.join('\\n\\n') });\n }\n const pushMessage = (message: any) => {\n const last = result[result.length - 1];\n if (\n message?.role === 'user'\n && last?.role === 'user'\n && typeof message.content === 'string'\n && typeof last.content === 'string'\n ) {\n last.content = `${last.content}\\n\\n${message.content}`;\n return;\n }\n result.push(message);\n };\n\n for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {\n const msg = messages[messageIndex];\n if (msg.role === 'system') {\n continue;\n } else if (msg.role === 'user') {\n // Multimodal user turns (text + {type:'image'} parts) pass through as an\n // array so the AI SDK forwards images to the provider; everything else is\n // coerced to a string. Array content is never merged (pushMessage only\n // merges string+string), so image parts stay intact.\n const userContent = Array.isArray(msg.content)\n ? msg.content\n : (typeof msg.content === 'string' ? msg.content : String(msg.content ?? ''));\n pushMessage({ role: 'user', content: userContent });\n } else if (msg.role === 'assistant') {\n const parts: any[] = [];\n if (msg.content && typeof msg.content === 'string') {\n parts.push({ type: 'text', text: msg.content });\n }\n if (msg.tool_calls) {\n const droppedToolCalls: string[] = [];\n const contiguousResultIds = contiguousResultIdsByAssistantIndex.get(messageIndex) ?? new Set<string>();\n for (const tc of msg.tool_calls) {\n let args: Record<string, unknown> = {};\n try {\n args = typeof tc.function?.arguments === 'string'\n ? JSON.parse(tc.function.arguments)\n : tc.function?.arguments ?? {};\n } catch { args = {}; /* malformed tool_calls JSON — use empty args */ }\n const normalizedId = idMap.get(tc.id) ?? normalizeToolCallId(tc.id ?? `call_${Date.now()}`, format);\n const toolName = tc.function?.name ?? 'unknown';\n if (!contiguousResultIds.has(normalizedId)) {\n droppedToolCalls.push(toolName);\n continue;\n }\n activeToolNamesById.set(normalizedId, toolName);\n parts.push({\n type: 'tool-call',\n toolCallId: normalizedId,\n toolName,\n input: args,\n });\n }\n if (droppedToolCalls.length > 0) {\n parts.push({\n type: 'text',\n text: `[Recovered incomplete tool call${droppedToolCalls.length > 1 ? 's' : ''} omitted from native tool channel: ${droppedToolCalls.join(', ')}]`,\n });\n }\n }\n if (parts.length > 0) {\n pushMessage({ role: 'assistant', content: parts });\n } else {\n pushMessage({ role: 'assistant', content: '' });\n }\n } else if (msg.role === 'tool') {\n const originalId = typeof (msg as any).tool_call_id === 'string' ? (msg as any).tool_call_id : '';\n const toolCallId = originalId ? (idMap.get(originalId) ?? normalizeToolCallId(originalId, format)) : '';\n const toolName = toolCallId ? activeToolNamesById.get(toolCallId) : undefined;\n const outputValue = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);\n if (!toolCallId || !toolName) {\n pushMessage({\n role: 'user',\n content: `[Recovered orphan tool result omitted from native tool channel]\\n${outputValue}`,\n });\n } else {\n pushMessage({\n role: 'tool',\n content: [{\n type: 'tool-result',\n toolCallId,\n toolName,\n output: {\n type: 'text' as const,\n value: outputValue,\n },\n }],\n });\n activeToolNamesById.delete(toolCallId);\n }\n }\n }\n\n // Mistral quirk: needs a dummy assistant message after consecutive tool results\n if (format === 'mistral') {\n for (let i = 1; i < result.length; i++) {\n if (result[i].role === 'tool' && result[i - 1].role === 'tool') {\n result.splice(i, 0, { role: 'assistant', content: '' });\n i++;\n }\n }\n }\n\n return result;\n}\n\n// @kern-source: dispatch:233\nexport async function apiDispatch(config: ApiConfig, prompt: string, timeout: number, signal?: AbortSignal, systemPrompt?: string): Promise<DispatchResult> {\n const model = buildModel(config);\n if (!model) {\n return {\n exitCode: 1,\n stdout: '',\n stderr: `Missing API key: set ${config.apiKeyEnv} environment variable`,\n durationMs: 0,\n timedOut: false,\n };\n }\n\n const startTime = Date.now();\n const messages: Array<{role: 'system'|'user', content: string}> = [];\n if (systemPrompt) messages.push({ role: 'system', content: systemPrompt });\n messages.push({ role: 'user', content: prompt });\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout * 1000);\n if (signal) {\n if (signal.aborted) { clearTimeout(timer); return { exitCode: 130, stdout: '', stderr: 'Aborted', durationMs: 0, timedOut: false }; }\n signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n try {\n const result = await generateText({\n model,\n messages,\n maxOutputTokens: config.maxTokens ?? 4096,\n abortSignal: controller.signal,\n maxRetries: 5,\n });\n clearTimeout(timer);\n const text = result.text || '';\n const usage = result.usage ? {\n promptTokens: result.usage.inputTokens ?? 0,\n completionTokens: result.usage.outputTokens ?? 0,\n totalTokens: (result.usage.inputTokens ?? 0) + (result.usage.outputTokens ?? 0),\n source: 'sdk' as const,\n } : undefined;\n return { exitCode: 0, stdout: text, stderr: '', durationMs: Date.now() - startTime, timedOut: false, usage };\n } catch (err) {\n clearTimeout(timer);\n const durationMs = Date.now() - startTime;\n if (err instanceof Error && err.name === 'AbortError') {\n return { exitCode: signal?.aborted ? 130 : 124, stdout: '', stderr: 'Request timed out', durationMs, timedOut: !signal?.aborted };\n }\n const isRateLimited = err instanceof Error && (\n err.message.includes('429') || err.message.includes('rate') || err.name === 'AI_RetryError' || err.name === 'RetryError'\n );\n const exitCode = isRateLimited ? 2 : 1;\n const prefix = isRateLimited ? 'API rate limited (retries exhausted)' : 'API request failed';\n return { exitCode, stdout: '', stderr: `${prefix}: ${err instanceof Error ? err.message : String(err)}`, durationMs, timedOut: false };\n }\n}\n\nexport async function* apiStreamDispatch(config: ApiConfig, prompt: string, timeout: number, signal?: AbortSignal, systemPrompt?: string): AsyncGenerator<string, DispatchResult, void> {\n const messages: Array<{role:string, content:string}> = [];\n if (systemPrompt) {\n messages.push({ role: 'system', content: systemPrompt });\n }\n messages.push({ role: 'user', content: prompt });\n return yield * apiStreamDispatchWithHistory(config, messages, timeout, signal);\n}\n\n// @kern-source: dispatch:304\nexport const _formatHintEmitted: Set<string> = new Set<string>();\n\n/**\n * Detect a common misconfiguration: format='anthropic' on a non-Anthropic base URL. Moonshot/Kimi/Groq/Together/DeepInfra etc. claim Anthropic compatibility loosely but actually serve OpenAI-shaped /chat/completions. Returns a one-line hint the first time we hit it for a given host, then null on subsequent calls for that host.\n */\n// @kern-source: dispatch:306\nfunction formatMismatchHint(config: ApiConfig): string|null {\n if (config.format !== 'anthropic') {\n return null;\n }\n try {\n const host = new URL(config.baseUrl).host.toLowerCase();\n if (host === 'api.anthropic.com' || host.endsWith('.anthropic.com')) {\n return null;\n }\n if (_formatHintEmitted.has(host)) {\n return null;\n }\n _formatHintEmitted.add(host);\n return `tip: format='anthropic' on '${host}' — many OpenAI-compat providers (Moonshot/Kimi, Groq, Together, DeepInfra) claim Anthropic but serve OpenAI /chat/completions. Try format='openai' (or remove the field) in the engine config.`;\n } catch (e) {\n return null;\n }\n}\n\n/**\n * Streaming dispatch with full message history + optional native function calling. Uses Vercel AI SDK for robust SSE handling and provider abstraction.\n */\nexport async function* apiStreamDispatchWithHistory(config: ApiConfig, messages: Array<{role:string,content:any,tool_calls?:any[],tool_call_id?:string}>, timeout: number, signal?: AbortSignal, tools?: Array<{type:string,function:{name:string,description:string,parameters:Record<string,unknown>}}>): AsyncGenerator<string, DispatchResult, void> {\n const model = buildModel(config);\n if (!model) {\n return { exitCode: 1, stdout: '', stderr: `Missing API key: set ${config.apiKeyEnv}`, durationMs: 0, timedOut: false };\n }\n\n const startTime = Date.now();\n\n // Convert messages to AI SDK CoreMessage format\n // Detect provider format for per-provider normalization\n const providerFormat = config.format === 'anthropic' ? 'anthropic'\n : config.baseUrl?.includes('mistral') ? 'mistral'\n : undefined;\n const coreMessages = convertMessagesForSdk(messages, providerFormat);\n\n // Set up timeout + external abort\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout * 1000);\n if (signal) {\n if (signal.aborted) { clearTimeout(timer); return { exitCode: 130, stdout: '', stderr: 'Aborted', durationMs: 0, timedOut: false }; }\n signal.addEventListener('abort', () => controller.abort(), { once: true });\n }\n\n let stdout = '';\n // Capture structured parts at stream time — compaction folds over these\n // instead of doing fragile regex extraction on flat text\n const capturedParts: Array<{kind:'text',text:string}|{kind:'reasoning',text:string}|{kind:'tool_call',toolName:string,toolCallId:string,args:Record<string,unknown>}> = [];\n let currentTextBuf = '';\n let currentReasoningBuf = '';\n\n try {\n const streamOpts: any = {\n model,\n messages: coreMessages,\n maxOutputTokens: config.maxTokens ?? 4096,\n abortSignal: controller.signal,\n maxRetries: 5,\n };\n\n if (tools && tools.length > 0) {\n streamOpts.tools = convertToolsForSdk(tools);\n }\n\n // Apply Anthropic cache control: mark system + last 2 messages as ephemeral\n // This saves input tokens on multi-turn conversations\n if (config.format === 'anthropic' && coreMessages.length > 0) {\n // Cache system prompt (stable across turns)\n for (const msg of coreMessages) {\n if ((msg as any).role === 'system') {\n (msg as any).experimental_providerMetadata = {\n anthropic: { cacheControl: { type: 'ephemeral' } },\n };\n break;\n }\n }\n // Cache last 2 user/assistant messages (recent context)\n let cached = 0;\n for (let i = coreMessages.length - 1; i >= 0 && cached < 2; i--) {\n const role = (coreMessages[i] as any).role;\n if (role === 'user' || role === 'assistant') {\n (coreMessages[i] as any).experimental_providerMetadata = {\n anthropic: { cacheControl: { type: 'ephemeral' } },\n };\n cached++;\n }\n }\n }\n\n const result = streamText(streamOpts);\n\n // Two-tier idle timeout: longer patience before first chunk (queuing/cold start),\n // tighter watchdog once streaming starts. Per-engine config overrides defaults.\n // IDLE_TIMEOUT was 15s, which killed API engines during silent reasoning or\n // tool-call phases — a real failure mode observed in agon forge where gemini,\n // kimi-for-coding, and zai-coding produced zero diff because their stream\n // went quiet for >15s while internally working. 90s gives coding engines\n // room to think without breaking the safety net for genuinely hung streams.\n const FIRST_CHUNK_TIMEOUT = config.firstChunkTimeoutMs ?? 60_000; // 60s default\n const IDLE_TIMEOUT = config.idleTimeoutMs ?? 90_000; // 90s default\n const iterator = result.fullStream[Symbol.asyncIterator]();\n let iterDone = false;\n let gotFirstChunk = false;\n\n while (!iterDone) {\n const timeoutMs = gotFirstChunk ? IDLE_TIMEOUT : FIRST_CHUNK_TIMEOUT;\n const next = iterator.next();\n const idle = new Promise<never>((_, reject) => {\n const t = setTimeout(() => reject(new Error('IDLE_TIMEOUT')), timeoutMs);\n next.then(() => clearTimeout(t), () => clearTimeout(t));\n });\n\n let iterResult: IteratorResult<any>;\n try {\n iterResult = await Promise.race([next, idle]);\n } catch (err: any) {\n if (err?.message === 'IDLE_TIMEOUT') {\n const phase = gotFirstChunk ? 'inter-chunk' : 'first-chunk';\n console.warn(`[agon] api-dispatch: ${phase} idle timeout (${timeoutMs / 1000}s) — breaking stream`);\n // First-chunk timeout on a non-Anthropic host using Anthropic format is almost\n // always a config mismatch — surface the hint via stderr so the session UI picks it up.\n if (!gotFirstChunk) {\n const hint = formatMismatchHint(config);\n if (hint) {\n clearTimeout(timer);\n controller.abort();\n return { exitCode: 1, stdout, stderr: `API first-chunk timeout (${timeoutMs / 1000}s). ${hint}`, durationMs: Date.now() - startTime, timedOut: true };\n }\n }\n controller.abort();\n break;\n }\n throw err;\n }\n\n if (iterResult.done) { iterDone = true; break; }\n const part = iterResult.value;\n\n // Any productive event switches to tighter inter-chunk timeout\n if (!gotFirstChunk && (part.type === 'text-delta' || part.type === 'reasoning-delta' || part.type === 'tool-call')) {\n gotFirstChunk = true;\n }\n\n switch (part.type) {\n case 'text-delta': {\n const text = (part as any).text;\n stdout += text;\n currentTextBuf += text;\n yield text;\n break;\n }\n case 'reasoning-delta': {\n const text = (part as any).delta ?? '';\n if (text) {\n currentReasoningBuf += text;\n }\n break;\n }\n case 'tool-call': {\n // Flush accumulated text/reasoning buffers as parts\n if (currentTextBuf) {\n capturedParts.push({ kind: 'text', text: currentTextBuf });\n currentTextBuf = '';\n }\n if (currentReasoningBuf) {\n capturedParts.push({ kind: 'reasoning', text: currentReasoningBuf });\n currentReasoningBuf = '';\n }\n // Capture tool call as structured part\n const toolName = (part as any).toolName ?? 'unknown';\n const toolCallId = (part as any).toolCallId ?? `call_${Date.now()}`;\n const toolInput = (part as any).input ?? {};\n capturedParts.push({ kind: 'tool_call', toolName, toolCallId, args: toolInput });\n\n // Emit as <tool> marker matching Agon's parseToolCalls regex\n const marker = `\\n<tool name=\"${toolName}\">${JSON.stringify(toolInput)}</tool>\\n`;\n stdout += marker;\n yield marker;\n break;\n }\n case 'error': {\n clearTimeout(timer);\n const errStr = String((part as any).error);\n // A 404/not-found before any output is almost always a wrong baseUrl\n // path or a wire-format mismatch (e.g. format='anthropic' on a host\n // whose Anthropic endpoint isn't at /v1/messages — MiniMax, etc.).\n // Surface the actionable hint inline so the user sees the fix rather\n // than a bare 404. (Same hint the idle-timeout + catch paths use.)\n // NOTE: deliberately narrower than brain.kern's deterministic-retry\n // classifier (which also matches 401/403/auth). The format hint says\n // \"try format='openai'\", which is right for a wrong-path/format 404\n // but MISLEADING on a genuine auth 401 — those already get brain.kern's\n // \"check /engines\" hint instead. Do NOT broaden this to auth codes.\n const routingShaped = stdout.length === 0 && /\\b404\\b|not found|no such (?:route|endpoint)/i.test(errStr);\n const hint = routingShaped ? formatMismatchHint(config) : null;\n return { exitCode: 1, stdout, stderr: hint ? `Stream error: ${errStr}\\n${hint}` : `Stream error: ${errStr}`, durationMs: Date.now() - startTime, timedOut: false };\n }\n }\n }\n\n // Flush final text/reasoning buffers\n if (currentTextBuf) capturedParts.push({ kind: 'text', text: currentTextBuf });\n if (currentReasoningBuf) capturedParts.push({ kind: 'reasoning', text: currentReasoningBuf });\n\n clearTimeout(timer);\n\n let usage: DispatchResult['usage'] = undefined;\n try {\n const finalUsage = await (result as any).usage;\n if (finalUsage) {\n usage = {\n promptTokens: finalUsage.inputTokens ?? 0,\n completionTokens: finalUsage.outputTokens ?? 0,\n totalTokens: (finalUsage.inputTokens ?? 0) + (finalUsage.outputTokens ?? 0),\n source: 'sdk' as const,\n };\n }\n } catch { /* usage tokens optional — extraction failure is non-critical */ }\n return { exitCode: 0, stdout, stderr: '', durationMs: Date.now() - startTime, timedOut: false, usage, parts: capturedParts };\n } catch (err) {\n clearTimeout(timer);\n const durationMs = Date.now() - startTime;\n if (err instanceof Error && err.name === 'AbortError') {\n return { exitCode: signal?.aborted ? 130 : 124, stdout, stderr: 'Request timed out', durationMs, timedOut: !signal?.aborted };\n }\n const isRateLimited = err instanceof Error && (\n err.message.includes('429') || err.message.includes('rate') || err.name === 'AI_RetryError' || err.name === 'RetryError'\n );\n const exitCode = isRateLimited ? 2 : 1;\n const prefix = isRateLimited ? 'API rate limited (retries exhausted)' : 'API stream failed';\n const baseMsg = `${prefix}: ${err instanceof Error ? err.message : String(err)}`;\n // Anthropic-format on non-Anthropic host is a common misconfig — append a hint\n // so the user sees it in the error toast instead of silently falling back every turn.\n const hint = stdout.length === 0 && !isRateLimited ? formatMismatchHint(config) : null;\n return { exitCode, stdout, stderr: hint ? `${baseMsg}\\n${hint}` : baseMsg, durationMs, timedOut: false };\n }\n}\n"],"mappings":"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","names":[]}
@@ -8,7 +8,7 @@ import {
8
8
  buildModel,
9
9
  convertMessagesForSdk,
10
10
  convertToolsForSdk
11
- } from "./chunk-SOUF7XTW.js";
11
+ } from "./chunk-XWHC6VAH.js";
12
12
  export {
13
13
  _formatHintEmitted,
14
14
  _modelCache,
@@ -19,4 +19,4 @@ export {
19
19
  convertMessagesForSdk,
20
20
  convertToolsForSdk
21
21
  };
22
- //# sourceMappingURL=dispatch-XHLJ44TF.js.map
22
+ //# sourceMappingURL=dispatch-S3CR5HKX.js.map
@@ -62,6 +62,9 @@
62
62
  "dynamicListCmd": ["__pty:/model"]
63
63
  },
64
64
 
65
+ "capabilities": ["vision"],
66
+ "imageFlag": "--image",
67
+
65
68
  "isolationHints": {
66
69
  "configEnv": "CODEX_HOME",
67
70
  "personalPaths": ["~/.codex"],
@@ -12,11 +12,11 @@ import {
12
12
  repairOverbroadForbiddenLiterals,
13
13
  taskWantsRepositoryLinkCheck,
14
14
  validateFitnessCommandIntent
15
- } from "./chunk-73ETZFDH.js";
16
- import "./chunk-4NTH3EAR.js";
17
- import "./chunk-DGTU4UWQ.js";
18
- import "./chunk-HAJIKZGU.js";
19
- import "./chunk-SOUF7XTW.js";
15
+ } from "./chunk-7WZ2O5WZ.js";
16
+ import "./chunk-3PDYVGRS.js";
17
+ import "./chunk-NBV37VMW.js";
18
+ import "./chunk-TMNHJOKU.js";
19
+ import "./chunk-XWHC6VAH.js";
20
20
  export {
21
21
  extractFitnessCommandFromCesarOutput,
22
22
  handleForge,
@@ -31,4 +31,4 @@ export {
31
31
  taskWantsRepositoryLinkCheck,
32
32
  validateFitnessCommandIntent
33
33
  };
34
- //# sourceMappingURL=forge-ZI7NE73F.js.map
34
+ //# sourceMappingURL=forge-GUOEJ5DJ.js.map
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  parseProseToRichLines,
27
27
  saveDismissedVersion,
28
28
  updateCommand
29
- } from "./chunk-GPYWJO2Q.js";
29
+ } from "./chunk-6IF2AV4Y.js";
30
30
  import {
31
31
  buildAgentApprovalCallback,
32
32
  buildConsensus,
@@ -38,7 +38,7 @@ import {
38
38
  runAgentTeam,
39
39
  runReviewCore,
40
40
  selectReviewEngine
41
- } from "./chunk-46WNYE4R.js";
41
+ } from "./chunk-PUNBDLQO.js";
42
42
  import {
43
43
  parsePatchPreview
44
44
  } from "./chunk-HSPQEDHX.js";
@@ -54,7 +54,7 @@ import {
54
54
  renderScoreboard,
55
55
  scoreboardFailEngine,
56
56
  scoreboardFinishEngine
57
- } from "./chunk-73ETZFDH.js";
57
+ } from "./chunk-7WZ2O5WZ.js";
58
58
  import {
59
59
  buildCesarSystemPrompt,
60
60
  buildOracleCheatPrompt,
@@ -105,7 +105,7 @@ import {
105
105
  synthesisRoutingAdvice,
106
106
  todosFromPlanSteps,
107
107
  yieldToInk
108
- } from "./chunk-4NTH3EAR.js";
108
+ } from "./chunk-3PDYVGRS.js";
109
109
  import {
110
110
  ENGINE_COLORS,
111
111
  bold,
@@ -127,7 +127,7 @@ import {
127
127
  truncateCodeLine,
128
128
  warn,
129
129
  yellow
130
- } from "./chunk-DGTU4UWQ.js";
130
+ } from "./chunk-NBV37VMW.js";
131
131
  import {
132
132
  AGON_HOME,
133
133
  CommandRegistry,
@@ -278,11 +278,11 @@ import {
278
278
  worktreeRemoveBestEffort,
279
279
  writeProvenanceReport,
280
280
  writeRunStatus
281
- } from "./chunk-HAJIKZGU.js";
281
+ } from "./chunk-TMNHJOKU.js";
282
282
  import {
283
283
  apiDispatch,
284
284
  apiStreamDispatch
285
- } from "./chunk-SOUF7XTW.js";
285
+ } from "./chunk-XWHC6VAH.js";
286
286
 
287
287
  // src/index.ts
288
288
  import { defineCommand as defineCommand31, runMain } from "citty";
@@ -7789,8 +7789,11 @@ function recordPastePlaceholder(hashMap, placeholder, fullHash) {
7789
7789
  hashes.push(fullHash);
7790
7790
  hashMap.set(placeholder, JSON.stringify(hashes));
7791
7791
  }
7792
+ function sanitizeInlinePaste(text) {
7793
+ return text.replace(/\x1b\[[0-?]*[ -\/]*[@-~]/g, "").replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "").replace(/[\x00-\x08\x0b-\x1f\x7f]/g, "");
7794
+ }
7792
7795
  function processPasteContent(raw) {
7793
- const normalized = raw.replace(/\r\n/g, "\n");
7796
+ const normalized = raw.replace(/\r\n?/g, "\n");
7794
7797
  const content = normalized.trimEnd();
7795
7798
  if (!content) {
7796
7799
  return { type: "empty" };
@@ -7806,7 +7809,7 @@ function processPasteContent(raw) {
7806
7809
  } catch (e) {
7807
7810
  }
7808
7811
  }
7809
- return { type: "direct", content: normalized };
7812
+ return { type: "direct", content: sanitizeInlinePaste(normalized) };
7810
7813
  }
7811
7814
  function expandPastePlaceholders(input, hashMap) {
7812
7815
  const takeHash = (key) => {
@@ -8162,20 +8165,21 @@ function buildPlanCallbacks(initialPlan, cb) {
8162
8165
  },
8163
8166
  onStepDone: (stepId, result) => {
8164
8167
  const step = currentPlan.steps.find((s) => s.id === stepId);
8165
- const icon = result.status === "success" ? "\u2713" : "\u2717";
8166
- const msgType = result.status === "success" ? "success" : "error";
8168
+ const isPausedResult = result.status === "paused";
8169
+ const icon = result.status === "success" ? "\u2713" : isPausedResult ? "\u23F8" : "\u2717";
8170
+ const msgType = result.status === "success" ? "success" : isPausedResult ? "warning" : "error";
8167
8171
  cb.dispatch({ type: "spinner-stop" });
8168
8172
  cb.dispatch({
8169
8173
  type: "tool-call",
8170
8174
  engineId: "cesar",
8171
8175
  tool: "PlanStep",
8172
8176
  input: JSON.stringify(buildPlanStepToolInput(stepId)),
8173
- status: result.status === "success" ? "done" : "error",
8177
+ status: result.status === "success" || isPausedResult ? "done" : "error",
8174
8178
  output: result.output ? result.output.slice(0, 4e3) : "",
8175
- error: result.error
8179
+ error: isPausedResult ? void 0 : result.error
8176
8180
  });
8177
8181
  cb.dispatch({ type: msgType, message: `${icon} ${step?.description ?? stepId} \u2014 ${result.status}${result.error ? ": " + result.error : ""} (${(result.durationMs / 1e3).toFixed(1)}s, $${result.actualCostUsd.toFixed(4)})` });
8178
- cb.dispatch({ type: "todos-update", id: stepId, state: result.status === "success" ? "done" : "failed", note: result.error ? result.error.slice(0, 80) : void 0 });
8182
+ cb.dispatch({ type: "todos-update", id: stepId, state: result.status === "success" ? "done" : isPausedResult ? "pending" : "failed", note: result.error ? result.error.slice(0, 80) : void 0 });
8179
8183
  },
8180
8184
  onPlanUpdate: (updated) => {
8181
8185
  const previousState = currentPlan.state;
@@ -9878,7 +9882,7 @@ async function handlePlanShow(dispatch, ctx, planId) {
9878
9882
  savePlan(approved);
9879
9883
  dispatch({ type: "success", message: "Plan approved." });
9880
9884
  if (approved.action.type === "forge") {
9881
- const { handleForge: handleForge2 } = await import("./forge-ZI7NE73F.js");
9885
+ const { handleForge: handleForge2 } = await import("./forge-GUOEJ5DJ.js");
9882
9886
  await handleForge2(approved.action.task, approved.action.fitnessCmd ?? null, dispatch, ctx, approved, approved.action.hardened);
9883
9887
  } else {
9884
9888
  dispatch({ type: "info", message: "Run the build again to execute." });
@@ -9904,7 +9908,7 @@ async function handleApprove(dispatch, ctx) {
9904
9908
  savePlan(plan);
9905
9909
  dispatch({ type: "success", message: "Plan approved." });
9906
9910
  if (plan.action.type === "forge") {
9907
- const { handleForge: handleForge2 } = await import("./forge-ZI7NE73F.js");
9911
+ const { handleForge: handleForge2 } = await import("./forge-GUOEJ5DJ.js");
9908
9912
  await handleForge2(plan.action.task, plan.action.fitnessCmd ?? null, dispatch, ctx, plan, plan.action.hardened);
9909
9913
  } else {
9910
9914
  dispatch({ type: "info", message: "Run the build again to execute." });
@@ -9932,7 +9936,7 @@ async function handleRetry(dispatch, ctx) {
9932
9936
  plan = startPlan(plan);
9933
9937
  ctx.setCurrentPlan(plan);
9934
9938
  savePlan(plan);
9935
- const { handleForge: handleForge2 } = await import("./forge-ZI7NE73F.js");
9939
+ const { handleForge: handleForge2 } = await import("./forge-GUOEJ5DJ.js");
9936
9940
  await handleForge2(plan.action.task, plan.action.fitnessCmd ?? null, dispatch, ctx, plan, plan.action.hardened);
9937
9941
  } else {
9938
9942
  dispatch({ type: "info", message: "Plan reset to approved. Run the build again to execute." });
@@ -12905,7 +12909,7 @@ async function runCesarBrainFallback(input, cb, crashDel, priorDeterministic) {
12905
12909
  const cesarEngine = cesarEngineDef ?? cb.ctx.registry.get(cesarId);
12906
12910
  const { join: join47 } = await import("path");
12907
12911
  const { mkdirSync: mkdirSync30 } = await import("fs");
12908
- const { resolveWorkingDir: resolveWorkingDir3, RUNS_DIR: RUNS_DIR3, appendMessage: appendMessage3 } = await import("./src-4A5FVACG.js");
12912
+ const { resolveWorkingDir: resolveWorkingDir3, RUNS_DIR: RUNS_DIR3, appendMessage: appendMessage3 } = await import("./src-3NWTITZM.js");
12909
12913
  const outDir = join47(RUNS_DIR3, `cesar-fallback-${Date.now()}`);
12910
12914
  mkdirSync30(outDir, { recursive: true });
12911
12915
  if (!_silentMode) cb.dispatch({ type: "warning", message: formatCesarRecoveryStatus("retry", cesarId, `log: ${outDir}`) });
@@ -13086,7 +13090,7 @@ ${historyContext}
13086
13090
  ` : ""}## USER MESSAGE
13087
13091
  ${input}`;
13088
13092
  try {
13089
- const { resolveWorkingDir: resolveWorkingDir3, RUNS_DIR: RUNS_DIR3, appendMessage: appendMessage3 } = await import("./src-4A5FVACG.js");
13093
+ const { resolveWorkingDir: resolveWorkingDir3, RUNS_DIR: RUNS_DIR3, appendMessage: appendMessage3 } = await import("./src-3NWTITZM.js");
13090
13094
  const { join: join47 } = await import("path");
13091
13095
  const { mkdirSync: mkdirSync30 } = await import("fs");
13092
13096
  const actingEngine = cb.ctx.registry.get(actingCesar);
@@ -14018,7 +14022,7 @@ async function dispatchSessionInfoIntent(intent, input, cb) {
14018
14022
  cb.setModelPickerTitle?.("Select model");
14019
14023
  cb.setModelPickerLoading(true);
14020
14024
  cb.setModelPickerOpen(true);
14021
- import("./src-4A5FVACG.js").then(({ fetchModelsRegistry: fetchModelsRegistry2, buildModelEntries: buildModelEntries2, buildCliGroupsImmediate, refreshCliGroup, refreshCliGroupVersion }) => {
14025
+ import("./src-3NWTITZM.js").then(({ fetchModelsRegistry: fetchModelsRegistry2, buildModelEntries: buildModelEntries2, buildCliGroupsImmediate, refreshCliGroup, refreshCliGroupVersion }) => {
14022
14026
  let cliGroups = buildCliGroupsImmediate();
14023
14027
  cb.setModelPickerCliGroups?.(cliGroups);
14024
14028
  for (const g of cliGroups) {
@@ -14076,7 +14080,7 @@ async function dispatchSessionInfoIntent(intent, input, cb) {
14076
14080
  await handlePlanShow(cb.dispatch, cb.ctx, intent.planId);
14077
14081
  break;
14078
14082
  case "plan-task": {
14079
- const { createCesarPlan } = await import("./src-4A5FVACG.js");
14083
+ const { createCesarPlan } = await import("./src-3NWTITZM.js");
14080
14084
  const cesarPlan = createCesarPlan(intent.task, []);
14081
14085
  cb.setActivePlan(cesarPlan);
14082
14086
  if (!cb.ctx.cesar) {
@@ -22231,7 +22235,7 @@ function App() {
22231
22235
  setEnginePickerOpen(false);
22232
22236
  setModelPickerOpen(true);
22233
22237
  setModelPickerCliGroups([]);
22234
- import("./src-4A5FVACG.js").then(({ fetchModelsRegistry: fetchModelsRegistry2, buildModelEntries: buildModelEntries2, buildCliGroupsImmediate, refreshCliGroup, refreshCliGroupVersion }) => {
22238
+ import("./src-3NWTITZM.js").then(({ fetchModelsRegistry: fetchModelsRegistry2, buildModelEntries: buildModelEntries2, buildCliGroupsImmediate, refreshCliGroup, refreshCliGroupVersion }) => {
22235
22239
  let cliGroups = buildCliGroupsImmediate();
22236
22240
  setModelPickerCliGroups(cliGroups);
22237
22241
  for (const g of cliGroups) {
@@ -22392,7 +22396,7 @@ function App() {
22392
22396
  if (ans === "later") return;
22393
22397
  if (ans === "update") {
22394
22398
  setUpdateInfo(null);
22395
- import("./update-DLPMYTF3.js").then((m) => m.runUpdate(latest)).catch((err) => {
22399
+ import("./update-H3LE4ZSI.js").then((m) => m.runUpdate(latest)).catch((err) => {
22396
22400
  console.error("[agon] failed to launch update:", err && err.message ? err.message : String(err));
22397
22401
  });
22398
22402
  return;
@@ -23898,7 +23902,7 @@ maybeNotifyIsolationMigration();
23898
23902
  var main = defineCommand31({
23899
23903
  meta: {
23900
23904
  name: "agon",
23901
- version: "0.1.5",
23905
+ version: "0.1.6",
23902
23906
  description: "Any AI can join. They compete. You ship."
23903
23907
  },
23904
23908
  subCommands: {