@kernlang/agon 0.1.0

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.
@@ -0,0 +1,473 @@
1
+ #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
7
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
8
+ }) : x)(function(x) {
9
+ if (typeof require !== "undefined") return require.apply(this, arguments);
10
+ throw Error('Dynamic require of "' + x + '" is not supported');
11
+ });
12
+ var __esm = (fn, res) => function __init() {
13
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
14
+ };
15
+ var __export = (target, all) => {
16
+ for (var name in all)
17
+ __defProp(target, name, { get: all[name], enumerable: true });
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
+ }
25
+ return to;
26
+ };
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // ../core/src/generated/api/dispatch.ts
30
+ import { streamText, generateText, jsonSchema } from "ai";
31
+ import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
32
+ import { createAnthropic } from "@ai-sdk/anthropic";
33
+ var _modelCache = /* @__PURE__ */ new Map();
34
+ function buildModel(config) {
35
+ const apiKey = process.env[config.apiKeyEnv];
36
+ if (!apiKey) return null;
37
+ const cacheKey = `${config.baseUrl}|${config.model}|${config.format ?? "openai"}`;
38
+ const cached = _modelCache.get(cacheKey);
39
+ if (cached && cached.apiKey === apiKey) return cached.model;
40
+ const base = config.baseUrl.replace(/\/$/, "");
41
+ let model;
42
+ if (config.format === "anthropic") {
43
+ const baseURL = base.endsWith("/v1") ? base : base + "/v1";
44
+ const provider = createAnthropic({ apiKey, baseURL });
45
+ model = provider(config.model);
46
+ } else {
47
+ const provider = createOpenAICompatible({
48
+ name: "agon-api",
49
+ apiKey,
50
+ baseURL: base
51
+ });
52
+ model = provider.chatModel(config.model);
53
+ }
54
+ _modelCache.set(cacheKey, { model, apiKey });
55
+ return model;
56
+ }
57
+ function convertToolsForSdk(tools) {
58
+ const result = {};
59
+ for (const t of tools) {
60
+ result[t.function.name] = {
61
+ description: t.function.description,
62
+ inputSchema: jsonSchema(t.function.parameters)
63
+ // No execute — tool execution is handled by the caller (persistent-session)
64
+ };
65
+ }
66
+ return result;
67
+ }
68
+ function normalizeToolCallId(id, format) {
69
+ if (!id) {
70
+ return `call_${Date.now()}`;
71
+ }
72
+ if (format === "anthropic") {
73
+ return id.replace(/[^a-zA-Z0-9_]/g, "_");
74
+ }
75
+ if (format === "mistral") {
76
+ return id.replace(/[^a-zA-Z0-9]/g, "").slice(0, 9) || `c${Date.now() % 1e8}`;
77
+ }
78
+ return id;
79
+ }
80
+ function convertMessagesForSdk(messages, format) {
81
+ const idMap = /* @__PURE__ */ new Map();
82
+ for (const msg of messages) {
83
+ if (msg.tool_calls) {
84
+ for (const tc of msg.tool_calls) {
85
+ if (tc.id && tc.function?.name) {
86
+ const normalizedId = normalizeToolCallId(tc.id, format);
87
+ idMap.set(tc.id, normalizedId);
88
+ }
89
+ }
90
+ }
91
+ }
92
+ const contiguousResultIdsByAssistantIndex = /* @__PURE__ */ new Map();
93
+ for (let i = 0; i < messages.length; i++) {
94
+ const msg = messages[i];
95
+ if (msg?.role !== "assistant" || !Array.isArray(msg.tool_calls) || msg.tool_calls.length === 0) continue;
96
+ const resultIds = /* @__PURE__ */ new Set();
97
+ for (let j = i + 1; j < messages.length; j++) {
98
+ const candidate = messages[j];
99
+ if (candidate?.role !== "tool") break;
100
+ const originalId = typeof candidate.tool_call_id === "string" ? candidate.tool_call_id : "";
101
+ if (!originalId) continue;
102
+ resultIds.add(idMap.get(originalId) ?? normalizeToolCallId(originalId, format));
103
+ }
104
+ contiguousResultIdsByAssistantIndex.set(i, resultIds);
105
+ }
106
+ const systemParts = [];
107
+ for (const msg of messages) {
108
+ if (msg.role !== "system") continue;
109
+ const content = typeof msg.content === "string" ? msg.content : String(msg.content ?? "");
110
+ if (content.trim()) systemParts.push(content);
111
+ }
112
+ const result = [];
113
+ const activeToolNamesById = /* @__PURE__ */ new Map();
114
+ if (systemParts.length > 0) {
115
+ result.push({ role: "system", content: systemParts.join("\n\n") });
116
+ }
117
+ const pushMessage = (message) => {
118
+ const last = result[result.length - 1];
119
+ if (message?.role === "user" && last?.role === "user" && typeof message.content === "string" && typeof last.content === "string") {
120
+ last.content = `${last.content}
121
+
122
+ ${message.content}`;
123
+ return;
124
+ }
125
+ result.push(message);
126
+ };
127
+ for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
128
+ const msg = messages[messageIndex];
129
+ if (msg.role === "system") {
130
+ continue;
131
+ } else if (msg.role === "user") {
132
+ pushMessage({ role: "user", content: typeof msg.content === "string" ? msg.content : String(msg.content ?? "") });
133
+ } else if (msg.role === "assistant") {
134
+ const parts = [];
135
+ if (msg.content && typeof msg.content === "string") {
136
+ parts.push({ type: "text", text: msg.content });
137
+ }
138
+ if (msg.tool_calls) {
139
+ const droppedToolCalls = [];
140
+ const contiguousResultIds = contiguousResultIdsByAssistantIndex.get(messageIndex) ?? /* @__PURE__ */ new Set();
141
+ for (const tc of msg.tool_calls) {
142
+ let args = {};
143
+ try {
144
+ args = typeof tc.function?.arguments === "string" ? JSON.parse(tc.function.arguments) : tc.function?.arguments ?? {};
145
+ } catch {
146
+ args = {};
147
+ }
148
+ const normalizedId = idMap.get(tc.id) ?? normalizeToolCallId(tc.id ?? `call_${Date.now()}`, format);
149
+ const toolName = tc.function?.name ?? "unknown";
150
+ if (!contiguousResultIds.has(normalizedId)) {
151
+ droppedToolCalls.push(toolName);
152
+ continue;
153
+ }
154
+ activeToolNamesById.set(normalizedId, toolName);
155
+ parts.push({
156
+ type: "tool-call",
157
+ toolCallId: normalizedId,
158
+ toolName,
159
+ input: args
160
+ });
161
+ }
162
+ if (droppedToolCalls.length > 0) {
163
+ parts.push({
164
+ type: "text",
165
+ text: `[Recovered incomplete tool call${droppedToolCalls.length > 1 ? "s" : ""} omitted from native tool channel: ${droppedToolCalls.join(", ")}]`
166
+ });
167
+ }
168
+ }
169
+ if (parts.length > 0) {
170
+ pushMessage({ role: "assistant", content: parts });
171
+ } else {
172
+ pushMessage({ role: "assistant", content: "" });
173
+ }
174
+ } else if (msg.role === "tool") {
175
+ const originalId = typeof msg.tool_call_id === "string" ? msg.tool_call_id : "";
176
+ const toolCallId = originalId ? idMap.get(originalId) ?? normalizeToolCallId(originalId, format) : "";
177
+ const toolName = toolCallId ? activeToolNamesById.get(toolCallId) : void 0;
178
+ const outputValue = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
179
+ if (!toolCallId || !toolName) {
180
+ pushMessage({
181
+ role: "user",
182
+ content: `[Recovered orphan tool result omitted from native tool channel]
183
+ ${outputValue}`
184
+ });
185
+ } else {
186
+ pushMessage({
187
+ role: "tool",
188
+ content: [{
189
+ type: "tool-result",
190
+ toolCallId,
191
+ toolName,
192
+ output: {
193
+ type: "text",
194
+ value: outputValue
195
+ }
196
+ }]
197
+ });
198
+ activeToolNamesById.delete(toolCallId);
199
+ }
200
+ }
201
+ }
202
+ if (format === "mistral") {
203
+ for (let i = 1; i < result.length; i++) {
204
+ if (result[i].role === "tool" && result[i - 1].role === "tool") {
205
+ result.splice(i, 0, { role: "assistant", content: "" });
206
+ i++;
207
+ }
208
+ }
209
+ }
210
+ return result;
211
+ }
212
+ async function apiDispatch(config, prompt, timeout, signal, systemPrompt) {
213
+ const model = buildModel(config);
214
+ if (!model) {
215
+ return {
216
+ exitCode: 1,
217
+ stdout: "",
218
+ stderr: `Missing API key: set ${config.apiKeyEnv} environment variable`,
219
+ durationMs: 0,
220
+ timedOut: false
221
+ };
222
+ }
223
+ const startTime = Date.now();
224
+ const messages = [];
225
+ if (systemPrompt) messages.push({ role: "system", content: systemPrompt });
226
+ messages.push({ role: "user", content: prompt });
227
+ const controller = new AbortController();
228
+ const timer = setTimeout(() => controller.abort(), timeout * 1e3);
229
+ if (signal) {
230
+ if (signal.aborted) {
231
+ clearTimeout(timer);
232
+ return { exitCode: 130, stdout: "", stderr: "Aborted", durationMs: 0, timedOut: false };
233
+ }
234
+ signal.addEventListener("abort", () => controller.abort(), { once: true });
235
+ }
236
+ try {
237
+ const result = await generateText({
238
+ model,
239
+ messages,
240
+ maxOutputTokens: config.maxTokens ?? 4096,
241
+ abortSignal: controller.signal,
242
+ maxRetries: 5
243
+ });
244
+ clearTimeout(timer);
245
+ const text = result.text || "";
246
+ const usage = result.usage ? {
247
+ promptTokens: result.usage.inputTokens ?? 0,
248
+ completionTokens: result.usage.outputTokens ?? 0,
249
+ totalTokens: (result.usage.inputTokens ?? 0) + (result.usage.outputTokens ?? 0),
250
+ source: "sdk"
251
+ } : void 0;
252
+ return { exitCode: 0, stdout: text, stderr: "", durationMs: Date.now() - startTime, timedOut: false, usage };
253
+ } catch (err) {
254
+ clearTimeout(timer);
255
+ const durationMs = Date.now() - startTime;
256
+ if (err instanceof Error && err.name === "AbortError") {
257
+ return { exitCode: signal?.aborted ? 130 : 124, stdout: "", stderr: "Request timed out", durationMs, timedOut: !signal?.aborted };
258
+ }
259
+ const isRateLimited = err instanceof Error && (err.message.includes("429") || err.message.includes("rate") || err.name === "AI_RetryError" || err.name === "RetryError");
260
+ const exitCode = isRateLimited ? 2 : 1;
261
+ const prefix = isRateLimited ? "API rate limited (retries exhausted)" : "API request failed";
262
+ return { exitCode, stdout: "", stderr: `${prefix}: ${err instanceof Error ? err.message : String(err)}`, durationMs, timedOut: false };
263
+ }
264
+ }
265
+ async function* apiStreamDispatch(config, prompt, timeout, signal, systemPrompt) {
266
+ const messages = [];
267
+ if (systemPrompt) {
268
+ messages.push({ role: "system", content: systemPrompt });
269
+ }
270
+ messages.push({ role: "user", content: prompt });
271
+ return yield* apiStreamDispatchWithHistory(config, messages, timeout, signal);
272
+ }
273
+ var _formatHintEmitted = /* @__PURE__ */ new Set();
274
+ function formatMismatchHint(config) {
275
+ if (config.format !== "anthropic") {
276
+ return null;
277
+ }
278
+ try {
279
+ const host = new URL(config.baseUrl).host.toLowerCase();
280
+ if (host === "api.anthropic.com" || host.endsWith(".anthropic.com")) {
281
+ return null;
282
+ }
283
+ if (_formatHintEmitted.has(host)) {
284
+ return null;
285
+ }
286
+ _formatHintEmitted.add(host);
287
+ return `tip: format='anthropic' on '${host}' \u2014 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.`;
288
+ } catch (e) {
289
+ return null;
290
+ }
291
+ }
292
+ async function* apiStreamDispatchWithHistory(config, messages, timeout, signal, tools) {
293
+ const model = buildModel(config);
294
+ if (!model) {
295
+ return { exitCode: 1, stdout: "", stderr: `Missing API key: set ${config.apiKeyEnv}`, durationMs: 0, timedOut: false };
296
+ }
297
+ const startTime = Date.now();
298
+ const providerFormat = config.format === "anthropic" ? "anthropic" : config.baseUrl?.includes("mistral") ? "mistral" : void 0;
299
+ const coreMessages = convertMessagesForSdk(messages, providerFormat);
300
+ const controller = new AbortController();
301
+ const timer = setTimeout(() => controller.abort(), timeout * 1e3);
302
+ if (signal) {
303
+ if (signal.aborted) {
304
+ clearTimeout(timer);
305
+ return { exitCode: 130, stdout: "", stderr: "Aborted", durationMs: 0, timedOut: false };
306
+ }
307
+ signal.addEventListener("abort", () => controller.abort(), { once: true });
308
+ }
309
+ let stdout = "";
310
+ const capturedParts = [];
311
+ let currentTextBuf = "";
312
+ let currentReasoningBuf = "";
313
+ try {
314
+ const streamOpts = {
315
+ model,
316
+ messages: coreMessages,
317
+ maxOutputTokens: config.maxTokens ?? 4096,
318
+ abortSignal: controller.signal,
319
+ maxRetries: 5
320
+ };
321
+ if (tools && tools.length > 0) {
322
+ streamOpts.tools = convertToolsForSdk(tools);
323
+ }
324
+ if (config.format === "anthropic" && coreMessages.length > 0) {
325
+ for (const msg of coreMessages) {
326
+ if (msg.role === "system") {
327
+ msg.experimental_providerMetadata = {
328
+ anthropic: { cacheControl: { type: "ephemeral" } }
329
+ };
330
+ break;
331
+ }
332
+ }
333
+ let cached = 0;
334
+ for (let i = coreMessages.length - 1; i >= 0 && cached < 2; i--) {
335
+ const role = coreMessages[i].role;
336
+ if (role === "user" || role === "assistant") {
337
+ coreMessages[i].experimental_providerMetadata = {
338
+ anthropic: { cacheControl: { type: "ephemeral" } }
339
+ };
340
+ cached++;
341
+ }
342
+ }
343
+ }
344
+ const result = streamText(streamOpts);
345
+ const FIRST_CHUNK_TIMEOUT = config.firstChunkTimeoutMs ?? 6e4;
346
+ const IDLE_TIMEOUT = config.idleTimeoutMs ?? 9e4;
347
+ const iterator = result.fullStream[Symbol.asyncIterator]();
348
+ let iterDone = false;
349
+ let gotFirstChunk = false;
350
+ while (!iterDone) {
351
+ const timeoutMs = gotFirstChunk ? IDLE_TIMEOUT : FIRST_CHUNK_TIMEOUT;
352
+ const next = iterator.next();
353
+ const idle = new Promise((_, reject) => {
354
+ const t = setTimeout(() => reject(new Error("IDLE_TIMEOUT")), timeoutMs);
355
+ next.then(() => clearTimeout(t), () => clearTimeout(t));
356
+ });
357
+ let iterResult;
358
+ try {
359
+ iterResult = await Promise.race([next, idle]);
360
+ } catch (err) {
361
+ if (err?.message === "IDLE_TIMEOUT") {
362
+ const phase = gotFirstChunk ? "inter-chunk" : "first-chunk";
363
+ console.warn(`[agon] api-dispatch: ${phase} idle timeout (${timeoutMs / 1e3}s) \u2014 breaking stream`);
364
+ if (!gotFirstChunk) {
365
+ const hint = formatMismatchHint(config);
366
+ if (hint) {
367
+ clearTimeout(timer);
368
+ controller.abort();
369
+ return { exitCode: 1, stdout, stderr: `API first-chunk timeout (${timeoutMs / 1e3}s). ${hint}`, durationMs: Date.now() - startTime, timedOut: true };
370
+ }
371
+ }
372
+ controller.abort();
373
+ break;
374
+ }
375
+ throw err;
376
+ }
377
+ if (iterResult.done) {
378
+ iterDone = true;
379
+ break;
380
+ }
381
+ const part = iterResult.value;
382
+ if (!gotFirstChunk && (part.type === "text-delta" || part.type === "reasoning-delta" || part.type === "tool-call")) {
383
+ gotFirstChunk = true;
384
+ }
385
+ switch (part.type) {
386
+ case "text-delta": {
387
+ const text = part.text;
388
+ stdout += text;
389
+ currentTextBuf += text;
390
+ yield text;
391
+ break;
392
+ }
393
+ case "reasoning-delta": {
394
+ const text = part.delta ?? "";
395
+ if (text) {
396
+ currentReasoningBuf += text;
397
+ }
398
+ break;
399
+ }
400
+ case "tool-call": {
401
+ if (currentTextBuf) {
402
+ capturedParts.push({ kind: "text", text: currentTextBuf });
403
+ currentTextBuf = "";
404
+ }
405
+ if (currentReasoningBuf) {
406
+ capturedParts.push({ kind: "reasoning", text: currentReasoningBuf });
407
+ currentReasoningBuf = "";
408
+ }
409
+ const toolName = part.toolName ?? "unknown";
410
+ const toolCallId = part.toolCallId ?? `call_${Date.now()}`;
411
+ const toolInput = part.input ?? {};
412
+ capturedParts.push({ kind: "tool_call", toolName, toolCallId, args: toolInput });
413
+ const marker = `
414
+ <tool name="${toolName}">${JSON.stringify(toolInput)}</tool>
415
+ `;
416
+ stdout += marker;
417
+ yield marker;
418
+ break;
419
+ }
420
+ case "error": {
421
+ clearTimeout(timer);
422
+ return { exitCode: 1, stdout, stderr: `Stream error: ${String(part.error)}`, durationMs: Date.now() - startTime, timedOut: false };
423
+ }
424
+ }
425
+ }
426
+ if (currentTextBuf) capturedParts.push({ kind: "text", text: currentTextBuf });
427
+ if (currentReasoningBuf) capturedParts.push({ kind: "reasoning", text: currentReasoningBuf });
428
+ clearTimeout(timer);
429
+ let usage = void 0;
430
+ try {
431
+ const finalUsage = await result.usage;
432
+ if (finalUsage) {
433
+ usage = {
434
+ promptTokens: finalUsage.inputTokens ?? 0,
435
+ completionTokens: finalUsage.outputTokens ?? 0,
436
+ totalTokens: (finalUsage.inputTokens ?? 0) + (finalUsage.outputTokens ?? 0),
437
+ source: "sdk"
438
+ };
439
+ }
440
+ } catch {
441
+ }
442
+ return { exitCode: 0, stdout, stderr: "", durationMs: Date.now() - startTime, timedOut: false, usage, parts: capturedParts };
443
+ } catch (err) {
444
+ clearTimeout(timer);
445
+ const durationMs = Date.now() - startTime;
446
+ if (err instanceof Error && err.name === "AbortError") {
447
+ return { exitCode: signal?.aborted ? 130 : 124, stdout, stderr: "Request timed out", durationMs, timedOut: !signal?.aborted };
448
+ }
449
+ const isRateLimited = err instanceof Error && (err.message.includes("429") || err.message.includes("rate") || err.name === "AI_RetryError" || err.name === "RetryError");
450
+ const exitCode = isRateLimited ? 2 : 1;
451
+ const prefix = isRateLimited ? "API rate limited (retries exhausted)" : "API stream failed";
452
+ const baseMsg = `${prefix}: ${err instanceof Error ? err.message : String(err)}`;
453
+ const hint = stdout.length === 0 && !isRateLimited ? formatMismatchHint(config) : null;
454
+ return { exitCode, stdout, stderr: hint ? `${baseMsg}
455
+ ${hint}` : baseMsg, durationMs, timedOut: false };
456
+ }
457
+ }
458
+
459
+ export {
460
+ __require,
461
+ __esm,
462
+ __export,
463
+ __toCommonJS,
464
+ _modelCache,
465
+ buildModel,
466
+ convertToolsForSdk,
467
+ convertMessagesForSdk,
468
+ apiDispatch,
469
+ apiStreamDispatch,
470
+ _formatHintEmitted,
471
+ apiStreamDispatchWithHistory
472
+ };
473
+ //# sourceMappingURL=chunk-ESSX7EFA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../core/src/generated/api/dispatch.ts"],"sourcesContent":["// @generated by kern v3.5.6 — DO NOT EDIT. Source: src/kern/api/dispatch.kern\n\n// @kern-source: dispatch:283\n// @kern-source: dispatch:315\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 pushMessage({ role: 'user', content: typeof msg.content === 'string' ? msg.content : String(msg.content ?? '') });\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:226\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:297\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:299\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 return { exitCode: 1, stdout, stderr: `Stream error: ${String((part as any).error)}`, 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":[]}