talon-agent 5.0.0 → 5.0.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 +1 -1
- package/src/app.ts +3 -3
- package/src/backend/claude-sdk/factory.ts +21 -41
- package/src/backend/claude-sdk/host/in-process.ts +147 -0
- package/src/backend/codex/mcp-config.ts +1 -1
- package/src/backend/openai-agents/mcp-pool.ts +1 -1
- package/src/backend/runtime/index.ts +2 -2
- 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 +387 -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/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/{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
package/package.json
CHANGED
package/src/app.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { getFrontends } from "./core/config/index.js";
|
|
10
|
-
import { startUploadCleanup, stopUploadCleanup } from "./
|
|
10
|
+
import { startUploadCleanup, stopUploadCleanup } from "./core/vfs/workspace.js";
|
|
11
11
|
import { flushDatabase } from "./storage/db.js";
|
|
12
12
|
import { getActiveCount, stopAllTurns } from "./core/engine/dispatcher.js";
|
|
13
13
|
import {
|
|
@@ -28,9 +28,9 @@ import {
|
|
|
28
28
|
import { shutdownTriggers } from "./core/background/triggers/index.js";
|
|
29
29
|
import { pruneSettledTriggers } from "./storage/triggers.js";
|
|
30
30
|
import { startWatchdog, stopWatchdog } from "./util/watchdog.js";
|
|
31
|
-
import { spawnSuccessor } from "./
|
|
31
|
+
import { spawnSuccessor } from "./core/daemon/respawn.js";
|
|
32
32
|
import { log, logError, logWarn } from "./util/log.js";
|
|
33
|
-
import { bootPhase, bootReport } from "./
|
|
33
|
+
import { bootPhase, bootReport } from "./core/daemon/boot-timer.js";
|
|
34
34
|
import {
|
|
35
35
|
getVfs,
|
|
36
36
|
mountNamespaceFs,
|
|
@@ -24,23 +24,12 @@ import {
|
|
|
24
24
|
type ToolRuntime,
|
|
25
25
|
type UsageTelemetry,
|
|
26
26
|
} from "../../core/agent-runtime/capabilities.js";
|
|
27
|
-
import { getPlanUsage } from "./plan-usage.js";
|
|
28
27
|
|
|
29
28
|
import {
|
|
30
|
-
initAgent as initClaudeAgent,
|
|
31
29
|
updateSystemPrompt as claudeUpdateSystemPrompt,
|
|
32
|
-
warmSession as claudeWarmSession,
|
|
33
|
-
getActiveQuery,
|
|
34
|
-
buildMcpServers,
|
|
35
|
-
buildPluginMcpServers,
|
|
36
|
-
runOneShotAgent as claudeRunOneShotAgent,
|
|
37
30
|
evictOrphanSubprocesses as claudeEvictOrphanSubprocesses,
|
|
38
31
|
} from "./index.js";
|
|
39
|
-
import {
|
|
40
|
-
runChatTurn as claudeRunChatTurn,
|
|
41
|
-
interruptChatTurn as claudeInterruptChatTurn,
|
|
42
|
-
} from "./handler.js";
|
|
43
|
-
import { waitForMcpServersReady } from "./mcp-ready.js";
|
|
32
|
+
import { createInProcessAgentHost } from "./host/in-process.js";
|
|
44
33
|
|
|
45
34
|
import * as modelProvider from "./model-provider.js";
|
|
46
35
|
import { claudeDoctorChecks } from "./doctor.js";
|
|
@@ -54,16 +43,25 @@ const claudeSdkFactory: BackendFactory = {
|
|
|
54
43
|
doctor: (config, isActive) => claudeDoctorChecks(config, isActive),
|
|
55
44
|
|
|
56
45
|
async init(config, ctx) {
|
|
57
|
-
|
|
46
|
+
// Everything SDK-side goes through the agent-host seam
|
|
47
|
+
// (docs/agent-host-sidecar.md). Phase 1 binds the in-process client,
|
|
48
|
+
// which calls the same functions this factory used to call inline;
|
|
49
|
+
// Phase 2 swaps in a process-backed client behind the same interface.
|
|
50
|
+
const host = createInProcessAgentHost(config, ctx.getBridgePort);
|
|
51
|
+
await host.hello();
|
|
58
52
|
log("bot", "Backend: Claude SDK (@anthropic-ai/claude-agent-sdk)");
|
|
59
53
|
|
|
60
54
|
const chat: ChatBackend = {
|
|
61
|
-
runChatTurn: (params) =>
|
|
62
|
-
interruptChatTurn: (chatId) =>
|
|
55
|
+
runChatTurn: (params) => host.runTurn(params),
|
|
56
|
+
interruptChatTurn: (chatId) => host.interrupt(chatId),
|
|
63
57
|
};
|
|
64
58
|
|
|
65
59
|
const background: BackgroundRunner = {
|
|
66
|
-
runOneShotAgent: (p) =>
|
|
60
|
+
runOneShotAgent: (p) => host.runOneShot(p),
|
|
61
|
+
// Not a protocol-table row yet: subprocess eviction reaches into
|
|
62
|
+
// the SDK's own children, so it belongs to the host — but the
|
|
63
|
+
// design's message table has no request for it. Tracked as an open
|
|
64
|
+
// question against Phase 2; bound directly until it gains one.
|
|
67
65
|
evictOrphanSubprocesses: (label) => claudeEvictOrphanSubprocesses(label),
|
|
68
66
|
};
|
|
69
67
|
|
|
@@ -81,7 +79,10 @@ const claudeSdkFactory: BackendFactory = {
|
|
|
81
79
|
getProviderModels: (p, pg, ps) =>
|
|
82
80
|
modelProvider.getProviderModels(p, pg, ps),
|
|
83
81
|
formatModelError: (q, r) => modelProvider.formatModelError(q, r),
|
|
84
|
-
|
|
82
|
+
// The one catalog member that asks the host: `list_models` is the
|
|
83
|
+
// protocol's model row. The seven above are daemon-side formatting
|
|
84
|
+
// over `core/models/catalog.ts`, which `hello` populates.
|
|
85
|
+
listModels: (f) => host.listModels(f),
|
|
85
86
|
};
|
|
86
87
|
|
|
87
88
|
// Claude SDK's per-turn subprocess model has no shared session
|
|
@@ -89,32 +90,11 @@ const claudeSdkFactory: BackendFactory = {
|
|
|
89
90
|
// dispatcher's `/reset` clears Talon's stored session id via
|
|
90
91
|
// `storage/sessions.ts:resetSession` regardless.
|
|
91
92
|
const sessions: SessionBackend = {
|
|
92
|
-
warmSession: (chatId) =>
|
|
93
|
+
warmSession: (chatId) => host.warmSession(chatId),
|
|
93
94
|
};
|
|
94
95
|
|
|
95
96
|
const tools: ToolRuntime = {
|
|
96
|
-
refreshTools:
|
|
97
|
-
const qi = getActiveQuery(chatId);
|
|
98
|
-
if (!qi) return null;
|
|
99
|
-
// Two-phase teardown: remove all MCP servers first so each
|
|
100
|
-
// subprocess receives an OS-agnostic shutdown via stdio, then
|
|
101
|
-
// install the fresh set.
|
|
102
|
-
await qi.setMcpServers({});
|
|
103
|
-
const freshServers = {
|
|
104
|
-
...buildMcpServers(chatId),
|
|
105
|
-
...buildPluginMcpServers(chatId),
|
|
106
|
-
};
|
|
107
|
-
const result = await qi.setMcpServers(freshServers);
|
|
108
|
-
// setMcpServers resolves on REGISTER, not CONNECT — MCP startup is
|
|
109
|
-
// non-blocking. A stdio server that dials a slow remote (e.g. the
|
|
110
|
-
// playwright plugin connecting to the Camoufox websocket) is still
|
|
111
|
-
// 'pending' at this point and its tools are absent from the live
|
|
112
|
-
// registry, so the turn would proceed with mcp__playwright-tools__*
|
|
113
|
-
// stuck "connecting" until the next refresh. Wait (bounded) for the
|
|
114
|
-
// newly-added servers to finish connecting before returning.
|
|
115
|
-
await waitForMcpServersReady(qi, result.added);
|
|
116
|
-
return result;
|
|
117
|
-
},
|
|
97
|
+
refreshTools: (chatId) => host.refreshTools(chatId),
|
|
118
98
|
};
|
|
119
99
|
|
|
120
100
|
const control: SystemControl = {
|
|
@@ -124,7 +104,7 @@ const claudeSdkFactory: BackendFactory = {
|
|
|
124
104
|
// No per-session snapshot to offer (each turn is a fresh subprocess),
|
|
125
105
|
// but the subscription's rate-limit windows are readable.
|
|
126
106
|
const usage: UsageTelemetry = {
|
|
127
|
-
getPlanUsage: () =>
|
|
107
|
+
getPlanUsage: () => host.planUsage(),
|
|
128
108
|
};
|
|
129
109
|
|
|
130
110
|
const backend = composeBackend({
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The in-process agent host — `AgentHostClient` implemented as direct
|
|
3
|
+
* calls into `backend/claude-sdk/`.
|
|
4
|
+
*
|
|
5
|
+
* `docs/agent-host-sidecar.md` Phase 1. This is the implementation that
|
|
6
|
+
* keeps today's behaviour exactly: every method is a call-through to the
|
|
7
|
+
* function the claude-sdk `BackendFactory` used to call itself. There is
|
|
8
|
+
* no process, no framing and no logic of its own — the only code that
|
|
9
|
+
* moved here is `refreshTools`' two-phase MCP teardown, which had to,
|
|
10
|
+
* because it drives a `Query` handle and handles do not cross a process
|
|
11
|
+
* boundary.
|
|
12
|
+
*
|
|
13
|
+
* Phase 2 adds a sibling that speaks the same interface over a child
|
|
14
|
+
* process's stdio. Nothing above this file changes when it does.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type {
|
|
18
|
+
AgentHostClient,
|
|
19
|
+
HostReadyInfo,
|
|
20
|
+
HostSessionInfo,
|
|
21
|
+
HostToolRefresh,
|
|
22
|
+
} from "../../../core/agent-runtime/agent-host.js";
|
|
23
|
+
import { AGENT_HOST_PROTOCOL_VERSION } from "../../../core/agent-runtime/agent-host.js";
|
|
24
|
+
import type { TalonConfig } from "../../../core/config/index.js";
|
|
25
|
+
import { getSession } from "../../../storage/sessions.js";
|
|
26
|
+
import { talonVersion } from "../../../util/version.js";
|
|
27
|
+
|
|
28
|
+
import {
|
|
29
|
+
initAgent as claudeInitAgent,
|
|
30
|
+
warmSession as claudeWarmSession,
|
|
31
|
+
getActiveQuery,
|
|
32
|
+
buildMcpServers,
|
|
33
|
+
buildPluginMcpServers,
|
|
34
|
+
runOneShotAgent as claudeRunOneShotAgent,
|
|
35
|
+
} from "../index.js";
|
|
36
|
+
import {
|
|
37
|
+
runChatTurn as claudeRunChatTurn,
|
|
38
|
+
interruptChatTurn as claudeInterruptChatTurn,
|
|
39
|
+
} from "../handler.js";
|
|
40
|
+
import { waitForMcpServersReady } from "../mcp-ready.js";
|
|
41
|
+
import { listModels as claudeListModels } from "../model-provider.js";
|
|
42
|
+
import { getPlanUsage } from "../plan-usage.js";
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Install an MCP server set on the chat's live query. `null` when the
|
|
46
|
+
* chat has no query in flight — the same "nothing to refresh" answer
|
|
47
|
+
* `ToolRuntime.refreshTools` has always given.
|
|
48
|
+
*/
|
|
49
|
+
async function setMcpServers(
|
|
50
|
+
chatId: string,
|
|
51
|
+
servers: Record<string, unknown>,
|
|
52
|
+
): Promise<HostToolRefresh | null> {
|
|
53
|
+
const qi = getActiveQuery(chatId);
|
|
54
|
+
if (!qi) return null;
|
|
55
|
+
return qi.setMcpServers(servers as Parameters<typeof qi.setMcpServers>[0]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Re-derive the chat's MCP config from the live plugin registry. Body
|
|
60
|
+
* lifted verbatim from the claude-sdk factory's `tools.refreshTools`,
|
|
61
|
+
* comments included — the ordering is load-bearing.
|
|
62
|
+
*/
|
|
63
|
+
async function refreshTools(chatId: string): Promise<HostToolRefresh | null> {
|
|
64
|
+
const qi = getActiveQuery(chatId);
|
|
65
|
+
if (!qi) return null;
|
|
66
|
+
// Two-phase teardown: remove all MCP servers first so each
|
|
67
|
+
// subprocess receives an OS-agnostic shutdown via stdio, then
|
|
68
|
+
// install the fresh set.
|
|
69
|
+
await qi.setMcpServers({});
|
|
70
|
+
const freshServers = {
|
|
71
|
+
...buildMcpServers(chatId),
|
|
72
|
+
...buildPluginMcpServers(chatId),
|
|
73
|
+
};
|
|
74
|
+
const result = await qi.setMcpServers(freshServers);
|
|
75
|
+
// setMcpServers resolves on REGISTER, not CONNECT — MCP startup is
|
|
76
|
+
// non-blocking. A stdio server that dials a slow remote (e.g. the
|
|
77
|
+
// playwright plugin connecting to the Camoufox websocket) is still
|
|
78
|
+
// 'pending' at this point and its tools are absent from the live
|
|
79
|
+
// registry, so the turn would proceed with mcp__playwright-tools__*
|
|
80
|
+
// stuck "connecting" until the next refresh. Wait (bounded) for the
|
|
81
|
+
// newly-added servers to finish connecting before returning.
|
|
82
|
+
await waitForMcpServersReady(qi, result.added);
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The context figures `warm_session` populates, read back out of the
|
|
88
|
+
* daemon's session store. In-process the host and the store share a
|
|
89
|
+
* process, so this is a lookup; in Phase 2 it is the reply that carries
|
|
90
|
+
* those numbers home.
|
|
91
|
+
*/
|
|
92
|
+
async function sessionInfo(chatId: string): Promise<HostSessionInfo> {
|
|
93
|
+
const session = getSession(chatId);
|
|
94
|
+
return {
|
|
95
|
+
chatId,
|
|
96
|
+
sessionId: session.sessionId,
|
|
97
|
+
turns: session.turns,
|
|
98
|
+
contextTokens: session.usage.contextTokens,
|
|
99
|
+
contextWindow: session.usage.contextWindow,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The Claude SDK backend keeps no conversation memory of its own — each
|
|
105
|
+
* turn is a fresh subprocess — so the only per-chat state the host holds
|
|
106
|
+
* is the in-flight query handle. Dropping it is interrupting it.
|
|
107
|
+
*
|
|
108
|
+
* Not bound into the `Backend` object: claude-sdk has no `resetChat`
|
|
109
|
+
* slot today and Phase 1 does not add one. `/reset` still clears the
|
|
110
|
+
* stored session id through `storage/sessions.ts`, as it always has.
|
|
111
|
+
*/
|
|
112
|
+
async function resetSession(chatId: string): Promise<boolean> {
|
|
113
|
+
return claudeInterruptChatTurn(chatId);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Build the in-process host. `config` and `getBridgePort` are held only
|
|
118
|
+
* for `hello()`, which performs the same `initAgent(config,
|
|
119
|
+
* getBridgePort)` the factory used to call inline.
|
|
120
|
+
*/
|
|
121
|
+
export function createInProcessAgentHost(
|
|
122
|
+
config: TalonConfig,
|
|
123
|
+
getBridgePort?: () => number,
|
|
124
|
+
): AgentHostClient {
|
|
125
|
+
return {
|
|
126
|
+
async hello(): Promise<HostReadyInfo> {
|
|
127
|
+
await claudeInitAgent(config, getBridgePort);
|
|
128
|
+
// `sdk` is omitted: in-process there is no separately-pinned SDK
|
|
129
|
+
// build to name — the daemon's own lockfile is the answer, and
|
|
130
|
+
// Phase 4 gives the host a `package.json` of its own to report.
|
|
131
|
+
return { protocol: AGENT_HOST_PROTOCOL_VERSION, host: talonVersion() };
|
|
132
|
+
},
|
|
133
|
+
runTurn: (params) => claudeRunChatTurn(params),
|
|
134
|
+
interrupt: (chatId) => claudeInterruptChatTurn(chatId),
|
|
135
|
+
runOneShot: (params) => claudeRunOneShotAgent(params),
|
|
136
|
+
warmSession: (chatId) => claudeWarmSession(chatId),
|
|
137
|
+
setMcpServers,
|
|
138
|
+
refreshTools,
|
|
139
|
+
listModels: (filter) => claudeListModels(filter),
|
|
140
|
+
planUsage: () => getPlanUsage(),
|
|
141
|
+
sessionInfo,
|
|
142
|
+
resetSession,
|
|
143
|
+
// Nothing to drain while the host is this process: the daemon's own
|
|
144
|
+
// shutdown path already aborts in-flight turns.
|
|
145
|
+
shutdown: async () => undefined,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
@@ -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
|
/**
|
|
@@ -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
|
|
|
@@ -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";
|
|
@@ -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:
|