talon-agent 3.33.4 → 3.34.1
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/package.json +5 -2
- package/src/app.ts +16 -8
- package/src/backend/claude-sdk/handler.ts +428 -415
- package/src/backend/claude-sdk/stream.ts +76 -53
- package/src/backend/codex/handler/message.ts +275 -366
- package/src/backend/codex/handler/rollout-accounting.ts +137 -0
- package/src/backend/openai-agents/handler/message.ts +282 -356
- package/src/backend/remote-server/chat-turn.ts +66 -122
- package/src/backend/remote-server/index.ts +4 -0
- package/src/backend/remote-server/mcp.ts +73 -9
- package/src/backend/remote-server/model-catalog/presentation.ts +269 -228
- package/src/backend/remote-server/sessions.ts +2 -2
- package/src/backend/remote-server/turn.ts +58 -55
- package/src/backend/shared/cache-telemetry.ts +17 -1
- package/src/backend/shared/handler-to-events.ts +11 -16
- package/src/backend/shared/index.ts +14 -15
- package/src/backend/shared/result-events.ts +30 -0
- package/src/backend/shared/turn-phases.ts +277 -0
- package/src/bootstrap.ts +120 -79
- package/src/cli/setup.ts +375 -349
- package/src/core/background/cron-spec.ts +273 -0
- package/src/core/background/heartbeat/agent.ts +167 -104
- package/src/core/background/triggers/exit.ts +19 -2
- package/src/core/background/triggers/resume.ts +14 -7
- package/src/core/background/triggers/state.ts +9 -0
- package/src/core/engine/backend-controller/pool.ts +2 -0
- package/src/core/engine/backend-controller/state.ts +25 -12
- package/src/core/engine/gateway-actions/cron.ts +28 -292
- package/src/core/engine/gateway-routes.ts +239 -0
- package/src/core/engine/gateway.ts +66 -238
- package/src/core/mcp-hub/child-transport.ts +215 -0
- package/src/core/mcp-hub/children.ts +72 -13
- package/src/core/mcp-hub/index.ts +32 -13
- package/src/core/models/active-model.ts +29 -6
- package/src/core/vfs/mounts/files.ts +128 -115
- package/src/core/weaver/shuttle.ts +33 -2
- package/src/core/weaver/weaver.ts +37 -6
- package/src/frontend/discord/callbacks/components/agent-buttons.ts +82 -0
- package/src/frontend/discord/callbacks/components/backend-select.ts +149 -0
- package/src/frontend/discord/callbacks/components/effort.ts +72 -0
- package/src/frontend/discord/callbacks/components/index.ts +120 -0
- package/src/frontend/discord/callbacks/components/metrics.ts +24 -0
- package/src/frontend/discord/callbacks/components/model-nav.ts +93 -0
- package/src/frontend/discord/callbacks/components/model-select.ts +118 -0
- package/src/frontend/discord/callbacks/components/model.ts +33 -0
- package/src/frontend/discord/callbacks/components/pulse.ts +93 -0
- package/src/frontend/discord/callbacks/components/settings.ts +243 -0
- package/src/frontend/discord/callbacks/components/types.ts +34 -0
- package/src/frontend/discord/callbacks/index.ts +4 -4
- package/src/frontend/discord/connection.ts +36 -0
- package/src/frontend/discord/diagnostics.ts +62 -0
- package/src/frontend/discord/guild-policy.ts +89 -0
- package/src/frontend/discord/index.ts +44 -305
- package/src/frontend/discord/outbound.ts +61 -0
- package/src/frontend/discord/ready.ts +73 -0
- package/src/frontend/discord/runtime.ts +55 -0
- package/src/frontend/native/chat-lifecycle.ts +39 -0
- package/src/frontend/native/chat-wire.ts +69 -0
- package/src/frontend/native/context.ts +106 -0
- package/src/frontend/native/control.ts +78 -0
- package/src/frontend/native/emit.ts +167 -0
- package/src/frontend/native/empty-chat-sweep.ts +50 -0
- package/src/frontend/native/handlers.ts +121 -0
- package/src/frontend/native/history.ts +101 -0
- package/src/frontend/native/index.ts +90 -1293
- package/src/frontend/native/media.ts +43 -0
- package/src/frontend/native/models.ts +221 -0
- package/src/frontend/native/queue.ts +47 -0
- package/src/frontend/native/reset.ts +50 -0
- package/src/frontend/native/routes/chats.ts +115 -0
- package/src/frontend/native/routes/daemon.ts +70 -0
- package/src/frontend/native/routes/host.ts +151 -0
- package/src/frontend/native/routes/index.ts +22 -0
- package/src/frontend/native/routes/mesh.ts +72 -0
- package/src/frontend/native/routes/models.ts +54 -0
- package/src/frontend/native/routes/params.ts +29 -0
- package/src/frontend/native/routes/pre-auth.ts +94 -0
- package/src/frontend/native/routes/table.ts +92 -0
- package/src/frontend/native/runtime.ts +109 -0
- package/src/frontend/native/server.ts +30 -555
- package/src/frontend/native/status.ts +26 -0
- package/src/frontend/native/tool-result.ts +48 -0
- package/src/frontend/native/turn.ts +341 -0
- package/src/frontend/telegram/admin.ts +75 -52
- package/src/frontend/whatsapp/access.ts +67 -0
- package/src/frontend/whatsapp/connection.ts +280 -0
- package/src/frontend/whatsapp/inbound.ts +327 -0
- package/src/frontend/whatsapp/index.ts +28 -599
- package/src/frontend/whatsapp/runtime.ts +74 -0
- package/src/storage/metrics.ts +18 -0
- package/src/storage/session-record.ts +29 -0
- package/src/storage/sessions.ts +24 -0
- package/src/storage/trigger-store.ts +8 -0
- package/src/util/boot-timer.ts +31 -0
- package/src/util/concurrency.ts +28 -0
- package/src/util/watchdog.ts +32 -7
- package/src/frontend/discord/callbacks/components.ts +0 -793
- package/src/frontend/discord/callbacks/shared.ts +0 -22
|
@@ -334,6 +334,79 @@ export function extractToolResults(msg: SDKUserMessage): ToolResultInfo[] {
|
|
|
334
334
|
return results;
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
+
/** Context fill of the last API iteration + whether the turn's first request hit the cache. */
|
|
338
|
+
function readContextFill(
|
|
339
|
+
state: StreamState,
|
|
340
|
+
usage: SDKResultMessage["usage"],
|
|
341
|
+
): void {
|
|
342
|
+
if (
|
|
343
|
+
!usage ||
|
|
344
|
+
!Array.isArray(usage.iterations) ||
|
|
345
|
+
usage.iterations.length === 0
|
|
346
|
+
)
|
|
347
|
+
return;
|
|
348
|
+
const last = usage.iterations[usage.iterations.length - 1];
|
|
349
|
+
state.contextTokens =
|
|
350
|
+
(last.input_tokens ?? 0) +
|
|
351
|
+
(last.cache_read_input_tokens ?? 0) +
|
|
352
|
+
(last.cache_creation_input_tokens ?? 0);
|
|
353
|
+
// The same array answers a question the per-turn totals can't: whether
|
|
354
|
+
// the FIRST request of this turn read a cache or paid to write one.
|
|
355
|
+
state.cacheStats = turnCacheStats(usage.iterations);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Token counts from the ACTIVE model's usage only. modelUsage is keyed by
|
|
360
|
+
* the exact SDK model string (e.g. "sonnet[1m]") and holds cumulative
|
|
361
|
+
* session totals per model — summing all entries double-counts when
|
|
362
|
+
* switching models mid-session.
|
|
363
|
+
*/
|
|
364
|
+
function readModelUsage(
|
|
365
|
+
state: StreamState,
|
|
366
|
+
modelUsage: Record<string, ModelUsage>,
|
|
367
|
+
sdkModel: string,
|
|
368
|
+
): void {
|
|
369
|
+
// Drift check: modelUsage is keyed by the model that ACTUALLY served
|
|
370
|
+
// the turn. If none of the keys is (an alias of) the model we asked
|
|
371
|
+
// for, the API substituted — warn instead of burying it in the
|
|
372
|
+
// accounting line.
|
|
373
|
+
checkModelDrift(sdkModel, Object.keys(modelUsage ?? {}));
|
|
374
|
+
const mu = modelUsage[sdkModel] ?? Object.values(modelUsage).at(-1);
|
|
375
|
+
if (!mu) return;
|
|
376
|
+
state.sdkInputTokens = mu.inputTokens ?? 0;
|
|
377
|
+
state.sdkOutputTokens = mu.outputTokens ?? 0;
|
|
378
|
+
state.sdkCacheRead = mu.cacheReadInputTokens ?? 0;
|
|
379
|
+
state.sdkCacheWrite = mu.cacheCreationInputTokens ?? 0;
|
|
380
|
+
if (mu.contextWindow > 0) {
|
|
381
|
+
state.contextWindow = mu.contextWindow;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Failed turn. Two shapes (see StreamState.resultErrorText):
|
|
387
|
+
* - error subtype: no `result` field, but `errors[]` carries diagnostics.
|
|
388
|
+
* - success subtype with is_error: `result` (and the trailing assistant
|
|
389
|
+
* text) IS the API error message, e.g. "You've hit your weekly limit
|
|
390
|
+
* · resets Jul 10, 9am". Prefer that text — it's the user-facing one.
|
|
391
|
+
*/
|
|
392
|
+
function readResultError(msg: SDKResultMessage, state: StreamState): void {
|
|
393
|
+
if (msg.subtype !== "success") {
|
|
394
|
+
const diagnostics = (msg.errors ?? [])
|
|
395
|
+
.filter((e) => typeof e === "string" && !e.startsWith("[ede_diagnostic]"))
|
|
396
|
+
.join("; ")
|
|
397
|
+
.slice(0, 500);
|
|
398
|
+
state.resultErrorText =
|
|
399
|
+
state.lastTrailingText.trim() ||
|
|
400
|
+
diagnostics ||
|
|
401
|
+
`Claude SDK turn failed (${msg.subtype})`;
|
|
402
|
+
} else if (msg.is_error) {
|
|
403
|
+
state.resultErrorText =
|
|
404
|
+
(typeof msg.result === "string" && msg.result.trim()) ||
|
|
405
|
+
state.lastTrailingText.trim() ||
|
|
406
|
+
"Claude SDK turn failed (API error)";
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
337
410
|
/**
|
|
338
411
|
* Process the final result message — extracts token counts, context info,
|
|
339
412
|
* and API call counts from the typed SDK result.
|
|
@@ -350,39 +423,8 @@ export function processResultMessage(
|
|
|
350
423
|
state.costUsd = msg.total_cost_usd;
|
|
351
424
|
}
|
|
352
425
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if (usage && Array.isArray(usage.iterations) && usage.iterations.length > 0) {
|
|
356
|
-
const last = usage.iterations[usage.iterations.length - 1];
|
|
357
|
-
state.contextTokens =
|
|
358
|
-
(last.input_tokens ?? 0) +
|
|
359
|
-
(last.cache_read_input_tokens ?? 0) +
|
|
360
|
-
(last.cache_creation_input_tokens ?? 0);
|
|
361
|
-
// The same array answers a question the per-turn totals can't: whether
|
|
362
|
-
// the FIRST request of this turn read a cache or paid to write one.
|
|
363
|
-
state.cacheStats = turnCacheStats(usage.iterations);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// Read token counts from the ACTIVE model's usage only.
|
|
367
|
-
// modelUsage is keyed by the exact SDK model string (e.g. "sonnet[1m]")
|
|
368
|
-
// and contains cumulative session totals per model — summing all entries
|
|
369
|
-
// double-counts when switching models mid-session.
|
|
370
|
-
const modelUsage: Record<string, ModelUsage> = msg.modelUsage;
|
|
371
|
-
// Drift check: modelUsage is keyed by the model that ACTUALLY served
|
|
372
|
-
// the turn. If none of the keys is (an alias of) the model we asked
|
|
373
|
-
// for, the API substituted — warn instead of burying it in the
|
|
374
|
-
// accounting line.
|
|
375
|
-
checkModelDrift(sdkModel, Object.keys(modelUsage ?? {}));
|
|
376
|
-
const mu = modelUsage[sdkModel] ?? Object.values(modelUsage).at(-1);
|
|
377
|
-
if (mu) {
|
|
378
|
-
state.sdkInputTokens = mu.inputTokens ?? 0;
|
|
379
|
-
state.sdkOutputTokens = mu.outputTokens ?? 0;
|
|
380
|
-
state.sdkCacheRead = mu.cacheReadInputTokens ?? 0;
|
|
381
|
-
state.sdkCacheWrite = mu.cacheCreationInputTokens ?? 0;
|
|
382
|
-
if (mu.contextWindow > 0) {
|
|
383
|
-
state.contextWindow = mu.contextWindow;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
426
|
+
readContextFill(state, msg.usage);
|
|
427
|
+
readModelUsage(state, msg.modelUsage, sdkModel);
|
|
386
428
|
|
|
387
429
|
log(
|
|
388
430
|
"agent",
|
|
@@ -400,26 +442,7 @@ export function processResultMessage(
|
|
|
400
442
|
state.currentBlockText = msg.result;
|
|
401
443
|
}
|
|
402
444
|
|
|
403
|
-
|
|
404
|
-
// - error subtype: no `result` field, but `errors[]` carries diagnostics.
|
|
405
|
-
// - success subtype with is_error: `result` (and the trailing assistant
|
|
406
|
-
// text) IS the API error message, e.g. "You've hit your weekly limit
|
|
407
|
-
// · resets Jul 10, 9am". Prefer that text — it's the user-facing one.
|
|
408
|
-
if (msg.subtype !== "success") {
|
|
409
|
-
const diagnostics = (msg.errors ?? [])
|
|
410
|
-
.filter((e) => typeof e === "string" && !e.startsWith("[ede_diagnostic]"))
|
|
411
|
-
.join("; ")
|
|
412
|
-
.slice(0, 500);
|
|
413
|
-
state.resultErrorText =
|
|
414
|
-
state.lastTrailingText.trim() ||
|
|
415
|
-
diagnostics ||
|
|
416
|
-
`Claude SDK turn failed (${msg.subtype})`;
|
|
417
|
-
} else if (msg.is_error) {
|
|
418
|
-
state.resultErrorText =
|
|
419
|
-
(typeof msg.result === "string" && msg.result.trim()) ||
|
|
420
|
-
state.lastTrailingText.trim() ||
|
|
421
|
-
"Claude SDK turn failed (API error)";
|
|
422
|
-
}
|
|
445
|
+
readResultError(msg, state);
|
|
423
446
|
}
|
|
424
447
|
|
|
425
448
|
// ── Trailing-text fallback dedup ────────────────────────────────────────────
|