talon-agent 5.0.0 → 5.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.
- package/package.json +2 -2
- package/src/app.ts +3 -3
- package/src/backend/claude-sdk/factory.ts +21 -41
- package/src/backend/claude-sdk/handler.ts +191 -69
- package/src/backend/claude-sdk/host/in-process.ts +147 -0
- package/src/backend/claude-sdk/one-shot.ts +17 -2
- package/src/backend/claude-sdk/stream.ts +9 -0
- package/src/backend/codex/mcp-config.ts +1 -1
- package/src/backend/codex/one-shot.ts +18 -4
- package/src/backend/openai-agents/mcp-pool.ts +1 -1
- package/src/backend/remote-server/one-shot.ts +16 -3
- package/src/backend/runtime/index.ts +2 -2
- package/src/backend/runtime/one-shot-hooks.ts +45 -0
- package/src/backend/runtime/turn/delivery.ts +1 -1
- package/src/backend/runtime/turn/turn-phases.ts +1 -1
- package/src/bootstrap.ts +2 -2
- package/src/cli.ts +5 -2
- package/src/core/agent-runtime/README.md +15 -0
- package/src/core/agent-runtime/agent-host.ts +388 -0
- package/src/core/agent-runtime/capabilities.ts +3 -0
- package/src/core/background/cron/scheduler.ts +1 -1
- package/src/core/background/triggers/command.ts +1 -1
- package/src/{util → core/config}/harden.ts +1 -1
- package/src/core/config/index.ts +1 -1
- package/src/core/daemon/pidfile.ts +1 -1
- package/src/core/daemon/resource-sampler.ts +2 -2
- package/src/{util → core/daemon}/respawn.ts +1 -1
- package/src/core/doctor/index.ts +1 -1
- package/src/core/engine/gateway-actions/fetch-url.ts +1 -1
- package/src/core/engine/gateway-actions/index.ts +1 -1
- package/src/core/engine/gateway-actions/memory.ts +2 -2
- package/src/core/engine/gateway-actions/native/exec-background.ts +129 -0
- package/src/core/engine/gateway-actions/native/exec-remote.ts +85 -0
- package/src/core/engine/gateway-actions/native/exec.ts +182 -0
- package/src/core/engine/gateway-actions/native/index.ts +46 -0
- package/src/core/engine/gateway-actions/native/params.ts +46 -0
- package/src/core/engine/gateway-actions/native/read.ts +182 -0
- package/src/core/engine/gateway-actions/native/results.ts +34 -0
- package/src/core/engine/gateway-actions/native/search.ts +212 -0
- package/src/core/engine/gateway-actions/native/shell.ts +39 -0
- package/src/core/engine/gateway-actions/native/teleport.ts +55 -0
- package/src/core/engine/gateway-actions/native/write.ts +170 -0
- package/src/core/frontend-runtime/builtins.ts +2 -2
- package/src/core/mcp-hub/children.ts +21 -5
- package/src/core/mcp-hub/index.ts +1 -1
- package/src/core/mcp-hub/talon-server.ts +1 -1
- package/src/core/memory/taps.ts +1 -1
- package/src/core/plugin/mcp.ts +1 -1
- package/src/core/scripts/lua.ts +1 -1
- package/src/core/tools/{chat.ts → chat/chat.ts} +1 -1
- package/src/core/tools/{cross-send.ts → chat/cross-send.ts} +1 -1
- package/src/core/tools/{history.ts → chat/history.ts} +2 -2
- package/src/core/tools/{media.ts → chat/media.ts} +1 -1
- package/src/core/tools/{members.ts → chat/members.ts} +2 -2
- package/src/core/tools/{messaging.ts → chat/messaging.ts} +2 -2
- package/src/core/tools/{moderation.ts → chat/moderation.ts} +2 -2
- package/src/core/tools/{stickers.ts → chat/stickers.ts} +2 -2
- package/src/core/tools/{whatsapp.ts → chat/whatsapp.ts} +1 -1
- package/src/core/tools/{memory.ts → content/memory.ts} +2 -2
- package/src/core/tools/{web.ts → content/web.ts} +1 -1
- package/src/core/tools/index.ts +20 -20
- package/src/core/tools/{admin.ts → ops/admin.ts} +1 -1
- package/src/core/tools/{bridge.ts → ops/bridge.ts} +2 -2
- package/src/core/tools/{goals.ts → ops/goals.ts} +2 -2
- package/src/core/tools/{mesh.ts → ops/mesh.ts} +1 -1
- package/src/core/tools/{models.ts → ops/models.ts} +1 -1
- package/src/core/tools/{native.ts → ops/native.ts} +1 -1
- package/src/core/tools/{scheduling.ts → ops/scheduling.ts} +1 -1
- package/src/core/tools/{scripts.ts → ops/scripts.ts} +1 -1
- package/src/core/tools/{skills.ts → ops/skills.ts} +1 -1
- package/src/core/tools/{triggers.ts → ops/triggers.ts} +1 -1
- package/src/core/types.ts +11 -0
- package/src/{util → core/vfs}/workspace.ts +2 -2
- package/src/frontend/discord/callbacks/components/effort.ts +1 -1
- package/src/frontend/discord/callbacks/components/index.ts +1 -1
- package/src/frontend/discord/callbacks/components/settings.ts +1 -1
- package/src/frontend/discord/commands/admin.ts +1 -1
- package/src/frontend/discord/commands/info.ts +1 -1
- package/src/frontend/discord/commands/interaction.ts +1 -1
- package/src/frontend/discord/commands/session.ts +3 -3
- package/src/frontend/discord/commands/settings.ts +1 -1
- package/src/frontend/discord/handlers/messages.ts +1 -1
- package/src/frontend/discord/handlers/state.ts +1 -1
- package/src/frontend/discord/middleware.ts +1 -1
- package/src/frontend/discord/ready.ts +1 -1
- package/src/frontend/discord/render.ts +41 -259
- package/src/frontend/native/chats/chats.ts +1 -1
- package/src/frontend/native/surface/models.ts +1 -1
- package/src/frontend/native/turn/context.ts +1 -1
- package/src/frontend/native/turn/emit.ts +1 -1
- package/src/frontend/{shared → presentation}/format.ts +4 -3
- package/src/frontend/{shared → presentation}/reasoning-levels.ts +12 -0
- package/src/frontend/presentation/reports.ts +493 -0
- package/src/frontend/{shared → presentation}/session-status.ts +1 -1
- package/src/frontend/teams/commands.ts +2 -2
- package/src/frontend/teams/turn.ts +1 -1
- package/src/frontend/telegram/admin/health.ts +1 -1
- package/src/frontend/telegram/admin/sessions.ts +1 -1
- package/src/frontend/telegram/callbacks/effort.ts +2 -2
- package/src/frontend/telegram/callbacks/metrics.ts +1 -1
- package/src/frontend/telegram/callbacks/model/views.ts +1 -1
- package/src/frontend/telegram/callbacks/query.ts +1 -1
- package/src/frontend/telegram/callbacks/settings.ts +2 -2
- package/src/frontend/telegram/commands/admin.ts +4 -4
- package/src/frontend/telegram/commands/info.ts +2 -2
- package/src/frontend/telegram/commands/session.ts +4 -4
- package/src/frontend/telegram/commands/settings.ts +4 -2
- package/src/frontend/telegram/handlers/state.ts +1 -1
- package/src/frontend/telegram/model-menu.ts +1 -1
- package/src/frontend/telegram/render/html.ts +30 -0
- package/src/frontend/telegram/{helpers → render}/menu.ts +46 -19
- package/src/frontend/telegram/render/reports.ts +182 -0
- package/src/frontend/terminal/builtins/context.ts +2 -2
- package/src/frontend/terminal/builtins/session.ts +1 -1
- package/src/frontend/terminal/builtins/status.ts +2 -2
- package/src/frontend/terminal/index.ts +2 -2
- package/src/frontend/terminal/renderer.ts +1 -1
- package/src/frontend/whatsapp/commands.ts +5 -5
- package/src/frontend/whatsapp/registry.ts +1 -1
- package/src/index.ts +5 -2
- package/src/util/runtime.ts +1 -1
- package/src/core/engine/gateway-actions/native.ts +0 -1035
- package/src/frontend/telegram/helpers/diagnostics.ts +0 -428
- package/src/frontend/telegram/helpers/format.ts +0 -42
- package/src/frontend/telegram/helpers/index.ts +0 -13
- package/src/util/cleanup-registry.ts +0 -36
- /package/src/{util → core/daemon}/boot-timer.ts +0 -0
- /package/src/{util → core/frontend-runtime}/chat-id.ts +0 -0
- /package/src/{util/mcp-launcher.ts → core/mcp-hub/launcher.ts} +0 -0
- /package/src/{util → core/tools/content}/web-content.ts +0 -0
- /package/src/core/tools/{mcp-env.ts → ops/mcp-env.ts} +0 -0
- /package/src/{util → core/weaver}/session-name.ts +0 -0
- /package/src/frontend/{shared → presentation}/access.ts +0 -0
- /package/src/frontend/{shared → presentation}/model-commands.ts +0 -0
- /package/src/frontend/{shared → presentation}/plan-usage-report.ts +0 -0
- /package/src/frontend/{shared → presentation}/status-context.ts +0 -0
|
@@ -20,6 +20,7 @@ import { ALLOWED_TOOLS_BACKGROUND } from "../../core/constants.js";
|
|
|
20
20
|
import { EFFORT_MAP } from "./constants.js";
|
|
21
21
|
import { buildMcpServers, buildPluginMcpServers } from "./options.js";
|
|
22
22
|
import { warnIfBelowCacheMinimum } from "../runtime/cache/cache-telemetry.js";
|
|
23
|
+
import { emitAssistantText } from "../runtime/one-shot-hooks.js";
|
|
23
24
|
|
|
24
25
|
const DEFAULT_SUBPROCESS_KILL_GRACE_MS = 5 * 1000;
|
|
25
26
|
|
|
@@ -65,6 +66,7 @@ export async function runOneShotAgent(
|
|
|
65
66
|
contextLabel,
|
|
66
67
|
abortController,
|
|
67
68
|
appendLog,
|
|
69
|
+
onAssistantText,
|
|
68
70
|
} = params;
|
|
69
71
|
|
|
70
72
|
// Reasoning effort is opt-in for background runs (config `heartbeatEffort`
|
|
@@ -126,7 +128,7 @@ export async function runOneShotAgent(
|
|
|
126
128
|
// settlement figure the task table records.
|
|
127
129
|
let usage: OneShotUsage | undefined;
|
|
128
130
|
for await (const msg of qi) {
|
|
129
|
-
await formatAndAppendMessage(appendLog, msg);
|
|
131
|
+
await formatAndAppendMessage(appendLog, msg, onAssistantText);
|
|
130
132
|
if (msg.type === "result") {
|
|
131
133
|
const u = msg.usage;
|
|
132
134
|
usage = {
|
|
@@ -183,6 +185,7 @@ function assembleMcpServers(contextLabel: string): Record<string, unknown> {
|
|
|
183
185
|
async function formatAndAppendMessage(
|
|
184
186
|
appendLog: (text: string) => Promise<void>,
|
|
185
187
|
msg: SDKMessage,
|
|
188
|
+
onAssistantText?: OneShotAgentParams["onAssistantText"],
|
|
186
189
|
): Promise<void> {
|
|
187
190
|
try {
|
|
188
191
|
const ts = new Date().toISOString().slice(11, 19);
|
|
@@ -200,7 +203,11 @@ async function formatAndAppendMessage(
|
|
|
200
203
|
});
|
|
201
204
|
|
|
202
205
|
if (textBlocks.length > 0) {
|
|
203
|
-
|
|
206
|
+
const assistantText = textBlocks.join("\n");
|
|
207
|
+
// Report before the log write: an append failure (full disk, closed
|
|
208
|
+
// handle) must not also swallow the run's result for a hook caller.
|
|
209
|
+
emitAssistantText(onAssistantText, assistantText);
|
|
210
|
+
await appendLog(`\n## [${ts}] Assistant\n${assistantText}\n`);
|
|
204
211
|
}
|
|
205
212
|
if (toolUseBlocks.length > 0) {
|
|
206
213
|
await appendLog(`\n${toolUseBlocks.join("\n\n")}\n`);
|
|
@@ -208,6 +215,14 @@ async function formatAndAppendMessage(
|
|
|
208
215
|
break;
|
|
209
216
|
}
|
|
210
217
|
case "result": {
|
|
218
|
+
// Deliberately NOT reported through `onAssistantText`. The SDK's
|
|
219
|
+
// terminal `result` message restates the last assistant turn's text
|
|
220
|
+
// (`subtype: "success"`) or carries an error string (the
|
|
221
|
+
// `error_*` subtypes) — never anything the `assistant` case above
|
|
222
|
+
// has not already emitted. Reporting it too would hand every hook
|
|
223
|
+
// caller a duplicate final segment, and the truncated copy at that
|
|
224
|
+
// (2000 chars, below). The log keeps it because a run log wants the
|
|
225
|
+
// settlement line; a sub-agent result does not.
|
|
211
226
|
const result =
|
|
212
227
|
"result" in msg
|
|
213
228
|
? (msg as { result: string }).result
|
|
@@ -422,6 +422,15 @@ function readResultError(msg: SDKResultMessage, state: StreamState): void {
|
|
|
422
422
|
.filter((e) => typeof e === "string" && !e.startsWith("[ede_diagnostic]"))
|
|
423
423
|
.join("; ")
|
|
424
424
|
.slice(0, 500);
|
|
425
|
+
// A known startup failure (SDK ≥ 0.3.274) names its cause — the CLI
|
|
426
|
+
// never ran a turn, so nothing else in the result says why. Lead with
|
|
427
|
+
// it; the diagnostics text is the same line stderr carried.
|
|
428
|
+
if (msg.startup_failure_reason) {
|
|
429
|
+
state.resultErrorText =
|
|
430
|
+
`Claude Code failed to start (${msg.startup_failure_reason})` +
|
|
431
|
+
(diagnostics ? `: ${diagnostics}` : "");
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
425
434
|
state.resultErrorText =
|
|
426
435
|
state.lastTrailingText.trim() ||
|
|
427
436
|
diagnostics ||
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
pluginHubUrl,
|
|
30
30
|
hubPluginServerNames,
|
|
31
31
|
} from "../../core/mcp-hub/index.js";
|
|
32
|
-
import type { ToolExclusionConfig } from "../../core/tools/mcp-env.js";
|
|
32
|
+
import type { ToolExclusionConfig } from "../../core/tools/ops/mcp-env.js";
|
|
33
33
|
import { frontendsForChat } from "../runtime/frontends.js";
|
|
34
34
|
|
|
35
35
|
/**
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import type { OneShotAgentParams, OneShotUsage } from "../../core/types.js";
|
|
21
21
|
import { log, logWarn } from "../../util/log.js";
|
|
22
22
|
import { appendBackendSuffix } from "../runtime/index.js";
|
|
23
|
+
import { emitAssistantText } from "../runtime/one-shot-hooks.js";
|
|
23
24
|
import { ensureCodex, getCodexAuthInfo } from "./init.js";
|
|
24
25
|
import {
|
|
25
26
|
CODEX_SYSTEM_PROMPT_SUFFIX,
|
|
@@ -79,6 +80,7 @@ export async function runOneShotAgent(
|
|
|
79
80
|
contextLabel,
|
|
80
81
|
abortController,
|
|
81
82
|
appendLog,
|
|
83
|
+
onAssistantText,
|
|
82
84
|
} = params;
|
|
83
85
|
|
|
84
86
|
const codex = ensureCodex(contextLabel);
|
|
@@ -143,7 +145,7 @@ export async function runOneShotAgent(
|
|
|
143
145
|
let usage: OneShotUsage | undefined;
|
|
144
146
|
for await (const event of events) {
|
|
145
147
|
if (abortController.signal.aborted) break;
|
|
146
|
-
await appendCodexEvent(appendLog, event);
|
|
148
|
+
await appendCodexEvent(appendLog, event, onAssistantText);
|
|
147
149
|
if (event.type === "turn.completed") {
|
|
148
150
|
const u = (event as { usage?: Record<string, number> }).usage;
|
|
149
151
|
if (u) {
|
|
@@ -217,6 +219,7 @@ export async function runOneShotAgent(
|
|
|
217
219
|
async function appendCodexEvent(
|
|
218
220
|
appendLog: (text: string) => Promise<void>,
|
|
219
221
|
event: { type: string } & Record<string, unknown>,
|
|
222
|
+
onAssistantText?: OneShotAgentParams["onAssistantText"],
|
|
220
223
|
): Promise<void> {
|
|
221
224
|
const ts = new Date().toISOString().slice(11, 19);
|
|
222
225
|
|
|
@@ -260,7 +263,7 @@ async function appendCodexEvent(
|
|
|
260
263
|
case "item.completed": {
|
|
261
264
|
const item = (event as unknown as { item?: Record<string, unknown> })
|
|
262
265
|
.item;
|
|
263
|
-
if (item) await appendCodexItem(appendLog, item, ts);
|
|
266
|
+
if (item) await appendCodexItem(appendLog, item, ts, onAssistantText);
|
|
264
267
|
return;
|
|
265
268
|
}
|
|
266
269
|
default:
|
|
@@ -268,17 +271,28 @@ async function appendCodexEvent(
|
|
|
268
271
|
}
|
|
269
272
|
}
|
|
270
273
|
|
|
271
|
-
/**
|
|
274
|
+
/**
|
|
275
|
+
* Append one `ThreadItem` to the run log, and report the model's final
|
|
276
|
+
* answers to the run's optional `onAssistantText` consumer.
|
|
277
|
+
*
|
|
278
|
+
* Only `agent_message` items are reported: `reasoning` items are the model's
|
|
279
|
+
* thinking and the rest are tool/command/diff payloads, none of which is the
|
|
280
|
+
* run's answer.
|
|
281
|
+
*/
|
|
272
282
|
async function appendCodexItem(
|
|
273
283
|
appendLog: (text: string) => Promise<void>,
|
|
274
284
|
item: Record<string, unknown>,
|
|
275
285
|
ts: string,
|
|
286
|
+
onAssistantText?: OneShotAgentParams["onAssistantText"],
|
|
276
287
|
): Promise<void> {
|
|
277
288
|
const type = typeof item.type === "string" ? item.type : "unknown";
|
|
278
289
|
|
|
279
290
|
if (type === "agent_message") {
|
|
280
291
|
const text = typeof item.text === "string" ? item.text : "";
|
|
281
|
-
if (text)
|
|
292
|
+
if (text) {
|
|
293
|
+
emitAssistantText(onAssistantText, text);
|
|
294
|
+
await appendLog(`\n## [${ts}] Assistant\n${text}\n`);
|
|
295
|
+
}
|
|
282
296
|
return;
|
|
283
297
|
}
|
|
284
298
|
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
pluginHubUrl,
|
|
31
31
|
hubPluginServerNames,
|
|
32
32
|
} from "../../core/mcp-hub/index.js";
|
|
33
|
-
import type { ToolExclusionConfig } from "../../core/tools/mcp-env.js";
|
|
33
|
+
import type { ToolExclusionConfig } from "../../core/tools/ops/mcp-env.js";
|
|
34
34
|
import { frontendsForChat } from "../runtime/frontends.js";
|
|
35
35
|
import { log, logWarn } from "../../util/log.js";
|
|
36
36
|
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
type RemoteAssistantInfo,
|
|
43
43
|
} from "./session-helpers.js";
|
|
44
44
|
import { appendBackendSuffix, sleep } from "../runtime/index.js";
|
|
45
|
+
import { emitAssistantText } from "../runtime/one-shot-hooks.js";
|
|
45
46
|
import { buildPermissionRuleset } from "./sessions.js";
|
|
46
47
|
|
|
47
48
|
// ── Client surface ──────────────────────────────────────────────────────────
|
|
@@ -108,6 +109,7 @@ export async function runRemoteOneShotAgent<
|
|
|
108
109
|
contextLabel,
|
|
109
110
|
abortController,
|
|
110
111
|
appendLog,
|
|
112
|
+
onAssistantText,
|
|
111
113
|
} = params;
|
|
112
114
|
const { label, errMsg } = bindings;
|
|
113
115
|
|
|
@@ -210,7 +212,7 @@ export async function runRemoteOneShotAgent<
|
|
|
210
212
|
: [];
|
|
211
213
|
|
|
212
214
|
for (const part of parts) {
|
|
213
|
-
await appendResponsePart(appendLog, part);
|
|
215
|
+
await appendResponsePart(appendLog, part, onAssistantText);
|
|
214
216
|
}
|
|
215
217
|
|
|
216
218
|
// The prompt response's assistant info carries the run's token usage —
|
|
@@ -250,17 +252,28 @@ export async function runRemoteOneShotAgent<
|
|
|
250
252
|
|
|
251
253
|
// ── Run-log rendering ───────────────────────────────────────────────────────
|
|
252
254
|
|
|
253
|
-
/**
|
|
255
|
+
/**
|
|
256
|
+
* Render one response part into the Markdown run log, and report the
|
|
257
|
+
* assistant's final text to the run's optional `onAssistantText` consumer.
|
|
258
|
+
*
|
|
259
|
+
* Only the `text` parts are reported: `reasoning` parts are the model's
|
|
260
|
+
* thinking and tool parts are call payloads, neither of which is the run's
|
|
261
|
+
* answer.
|
|
262
|
+
*/
|
|
254
263
|
async function appendResponsePart(
|
|
255
264
|
appendLog: (text: string) => Promise<void>,
|
|
256
265
|
part: Record<string, unknown>,
|
|
266
|
+
onAssistantText?: OneShotAgentParams["onAssistantText"],
|
|
257
267
|
): Promise<void> {
|
|
258
268
|
const ts = new Date().toISOString().slice(11, 19);
|
|
259
269
|
const type = typeof part.type === "string" ? part.type : "unknown";
|
|
260
270
|
|
|
261
271
|
if (type === "text") {
|
|
262
272
|
const text = typeof part.text === "string" ? part.text : "";
|
|
263
|
-
if (text)
|
|
273
|
+
if (text) {
|
|
274
|
+
emitAssistantText(onAssistantText, text);
|
|
275
|
+
await appendLog(`\n## [${ts}] Assistant\n${text}\n`);
|
|
276
|
+
}
|
|
264
277
|
return;
|
|
265
278
|
}
|
|
266
279
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* - `prompt/prompt-format` — user-prompt formatter
|
|
21
21
|
* ([time] [Name] [msg_id:N]).
|
|
22
22
|
* - `frontends` — config `frontend` → messaging-frontend list.
|
|
23
|
-
* - `extractSessionName` — re-exported from `
|
|
23
|
+
* - `extractSessionName` — re-exported from `core/weaver/session-name` so the
|
|
24
24
|
* backends keep one import site; the helper itself is frontend-neutral.
|
|
25
25
|
* - `usage` — cache-hit % + log summarisers.
|
|
26
26
|
* - `prompt/system-prompt` — per-session prompt snapshots + backend
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
* - SDK-specific event types — those live in each backend.
|
|
38
38
|
* - Session storage — that's `src/storage/sessions.ts`.
|
|
39
39
|
* - MCP server registration — backend-specific transport details
|
|
40
|
-
* (the spawn/env contract they share is `core/tools/mcp-env.ts`).
|
|
40
|
+
* (the spawn/env contract they share is `core/tools/ops/mcp-env.ts`).
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
43
|
export { captureDeliveredText } from "./turn/delivered-text.js";
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot run hooks — the shared, throw-proof call site for
|
|
3
|
+
* `OneShotAgentParams.onAssistantText`.
|
|
4
|
+
*
|
|
5
|
+
* Every backend's isolated runner (`BackgroundRunner.runOneShotAgent`) already
|
|
6
|
+
* renders the model's assistant text into the run log as markdown. The hook is
|
|
7
|
+
* the same text as data, so a caller (the sub-agent runner) can take a run's
|
|
8
|
+
* result without parsing the log back apart. It lives here rather than in each
|
|
9
|
+
* backend so all four report it identically: same "final answer only" meaning,
|
|
10
|
+
* same empty-string skip, same swallow-and-log on a throwing callback.
|
|
11
|
+
*
|
|
12
|
+
* Contract:
|
|
13
|
+
* - Final assistant text only. Reasoning/thinking blocks and tool-call
|
|
14
|
+
* payloads are log-only; they never reach the hook.
|
|
15
|
+
* - Synchronous. The runner does not await the consumer, so a hook that
|
|
16
|
+
* wants to do async work owns its own queueing.
|
|
17
|
+
* - Never throws into the run. A consumer bug must not abort a heartbeat.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { OneShotAgentParams } from "../../core/types.js";
|
|
21
|
+
import { logWarn } from "../../util/log.js";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Report one assistant text segment to the run's optional consumer.
|
|
25
|
+
*
|
|
26
|
+
* No-ops when there is no hook (the heartbeat/dream/cron path) or when the
|
|
27
|
+
* text is empty — the backends guard their log appends the same way, so the
|
|
28
|
+
* hook sees exactly the segments the log does.
|
|
29
|
+
*/
|
|
30
|
+
export function emitAssistantText(
|
|
31
|
+
onAssistantText: OneShotAgentParams["onAssistantText"],
|
|
32
|
+
text: string,
|
|
33
|
+
): void {
|
|
34
|
+
if (!onAssistantText || !text) return;
|
|
35
|
+
try {
|
|
36
|
+
onAssistantText(text);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
logWarn(
|
|
39
|
+
"agent",
|
|
40
|
+
`one-shot onAssistantText hook threw (ignored): ${
|
|
41
|
+
err instanceof Error ? err.message : String(err)
|
|
42
|
+
}`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Routes:
|
|
10
10
|
*
|
|
11
11
|
* - `tool` — a delivery tool (`end_turn` / `send` / `react`) already
|
|
12
|
-
* bridged the message to the platform via `core/tools/messaging.ts`.
|
|
12
|
+
* bridged the message to the platform via `core/tools/chat/messaging.ts`.
|
|
13
13
|
* The message is already in the chat; we don't re-emit. We may
|
|
14
14
|
* have captured `deliveredTextNorms` for dedup, or just have
|
|
15
15
|
* `hadBridgeDelivery` set (e.g. `send(type="photo")` — non-text
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
setSessionName,
|
|
26
26
|
} from "../../../storage/sessions.js";
|
|
27
27
|
import { log } from "../../../util/log.js";
|
|
28
|
-
import { extractSessionName } from "../../../
|
|
28
|
+
import { extractSessionName } from "../../../core/weaver/session-name.js";
|
|
29
29
|
import { traceMessage } from "../../../util/trace.js";
|
|
30
30
|
import {
|
|
31
31
|
FLOW_VIOLATION_MAX_RETRIES,
|
package/src/bootstrap.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { loadConfig, rebuildSystemPrompt } from "./core/config/index.js";
|
|
13
|
-
import { initWorkspace } from "./
|
|
13
|
+
import { initWorkspace } from "./core/vfs/workspace.js";
|
|
14
14
|
import { loadSessions, resetSession } from "./storage/sessions.js";
|
|
15
15
|
import { loadChatSettings } from "./storage/chat-settings.js";
|
|
16
16
|
import { loadCronJobs } from "./storage/cron.js";
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
import { initDream, maybeStartDream } from "./core/background/dream/index.js";
|
|
37
37
|
import { initHeartbeat } from "./core/background/heartbeat/index.js";
|
|
38
38
|
import { log, logWarn, logDebug } from "./util/log.js";
|
|
39
|
-
import { bootPhase } from "./
|
|
39
|
+
import { bootPhase } from "./core/daemon/boot-timer.js";
|
|
40
40
|
import { mapConcurrent } from "./util/concurrency.js";
|
|
41
41
|
import type { TalonConfig } from "./core/config/index.js";
|
|
42
42
|
import { resolveFrontendIdAmong } from "./core/frontend-runtime/routing.js";
|
package/src/cli.ts
CHANGED
|
@@ -16,13 +16,16 @@
|
|
|
16
16
|
* `cli/index.ts`. Everything else lives under `cli/`.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
MCP_LAUNCH_SUBCOMMAND,
|
|
21
|
+
runSupervisor,
|
|
22
|
+
} from "./core/mcp-hub/launcher.js";
|
|
20
23
|
import { LUA_RUN_SUBCOMMAND, runLuaMain } from "./core/scripts/lua.js";
|
|
21
24
|
|
|
22
25
|
// Hidden subcommand dispatch — must run before anything else. Talon
|
|
23
26
|
// supervises MCP stdio children (`_mcp-launch`) and runs WASM-sandboxed
|
|
24
27
|
// Lua trigger scripts (`_lua-run`) by re-invoking its own entrypoint
|
|
25
|
-
// (see
|
|
28
|
+
// (see core/mcp-hub/launcher.ts). Neither call resolves; the helper process
|
|
26
29
|
// exits from its own handlers.
|
|
27
30
|
if (process.argv[2] === MCP_LAUNCH_SUBCOMMAND) {
|
|
28
31
|
await runSupervisor(process.argv.slice(3));
|
|
@@ -69,6 +69,21 @@ onto the SQLite layer in `src/storage/` (typed tables or the `kv`
|
|
|
69
69
|
singleton store). Legacy files import once at boot via
|
|
70
70
|
`storage/legacy-import.ts` and are renamed `*.imported`.
|
|
71
71
|
|
|
72
|
+
### `agent-host.ts`
|
|
73
|
+
|
|
74
|
+
The seam the Claude Agent SDK moves out of the daemon across
|
|
75
|
+
(`docs/agent-host-sidecar.md`). Two halves: the NDJSON wire vocabulary
|
|
76
|
+
(`HostRequest` / `HostReply` / `HostEvent` / `HostNotice`, plus
|
|
77
|
+
`parseHostMessage` / `serializeHostMessage` — unknown types parse to a
|
|
78
|
+
typed `unknown` the reader logs and drops, never a throw), and
|
|
79
|
+
`AgentHostClient`, the interface the daemon holds. Phase 1 ships one
|
|
80
|
+
implementation, `backend/claude-sdk/host/in-process.ts`; Phase 2 adds a
|
|
81
|
+
process-backed one behind the same interface. Fixtures:
|
|
82
|
+
`protocol/fixtures/agent-host_v1.json`.
|
|
83
|
+
|
|
84
|
+
The interface and codec live here, not in `backend/`, because `core/` may
|
|
85
|
+
not import `backend/` — the implementations live under `backend/`.
|
|
86
|
+
|
|
72
87
|
### `contract-tests.ts`
|
|
73
88
|
|
|
74
89
|
Backend contract assertions any conforming `Backend` must pass:
|