talon-agent 1.34.1 → 1.36.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 +3 -3
- package/src/backend/claude-sdk/options.ts +41 -1
- package/src/bootstrap.ts +1 -0
- package/src/core/engine/gateway-actions/index.ts +5 -0
- package/src/core/engine/gateway-actions/mesh.ts +49 -0
- package/src/core/engine/gateway-actions/native.ts +574 -0
- package/src/core/mcp-hub/index.ts +3 -0
- package/src/core/mcp-hub/talon-server.ts +3 -0
- package/src/core/mesh/index.ts +27 -0
- package/src/core/mesh/persist.ts +49 -0
- package/src/core/mesh/registry.ts +264 -0
- package/src/core/mesh/service.ts +1157 -0
- package/src/core/mesh/teleport.ts +104 -0
- package/src/core/mesh/transfers.ts +186 -0
- package/src/core/mesh/types.ts +137 -0
- package/src/core/tools/bridge.ts +85 -4
- package/src/core/tools/index.ts +25 -2
- package/src/core/tools/mesh.ts +153 -0
- package/src/core/tools/native.ts +138 -0
- package/src/core/tools/types.ts +3 -1
- package/src/frontend/native/actions.ts +17 -1
- package/src/frontend/native/index.ts +37 -0
- package/src/frontend/native/protocol.ts +30 -0
- package/src/frontend/native/server.ts +77 -0
- package/src/util/config.ts +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "talon-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.0",
|
|
4
4
|
"description": "Multi-frontend AI agent with full tool access, streaming, cron jobs, and plugin system",
|
|
5
5
|
"author": "Dylan Neve",
|
|
6
6
|
"license": "MIT",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"@kilocode/sdk": "^7.2.22",
|
|
102
102
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
103
103
|
"@openai/agents": "^0.13.0",
|
|
104
|
-
"@openai/codex-sdk": "^0.
|
|
104
|
+
"@openai/codex-sdk": "^0.144.0",
|
|
105
105
|
"@opencode-ai/sdk": "^1.17.4",
|
|
106
106
|
"@playwright/mcp": "^0.0.77",
|
|
107
107
|
"@types/cross-spawn": "^6.0.6",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"knip": "^6.3.1",
|
|
134
134
|
"oxlint": "^1.59.0",
|
|
135
135
|
"prettier": "^3.8.1",
|
|
136
|
-
"typescript": "^
|
|
136
|
+
"typescript": "^7.0.2",
|
|
137
137
|
"vitest": "^4.1.3"
|
|
138
138
|
},
|
|
139
139
|
"overrides": {
|
|
@@ -30,6 +30,23 @@ import { log, logError } from "../../util/log.js";
|
|
|
30
30
|
import { getConfig, getBridgePort } from "./state.js";
|
|
31
31
|
import { ALLOWED_TOOLS_CHAT, EFFORT_MAP } from "./constants.js";
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Built-in SDK tools that Talon's native tool set replaces when
|
|
35
|
+
* `config.nativeTools` is on. The shell/filesystem built-ins map 1:1 to
|
|
36
|
+
* bash/read/write/edit/glob/search; `Agent` (sub-agent dispatch) is dropped
|
|
37
|
+
* alongside them per the owner's preference for the native surface.
|
|
38
|
+
*/
|
|
39
|
+
const NATIVE_REPLACED_BUILTINS = new Set<string>([
|
|
40
|
+
"Read",
|
|
41
|
+
"Write",
|
|
42
|
+
"Edit",
|
|
43
|
+
"NotebookEdit",
|
|
44
|
+
"Bash",
|
|
45
|
+
"Glob",
|
|
46
|
+
"Grep",
|
|
47
|
+
"Agent",
|
|
48
|
+
]);
|
|
49
|
+
|
|
33
50
|
// ── Types ────────────────────────────────────────────────────────────────────
|
|
34
51
|
|
|
35
52
|
export type BuildSdkOptionsResult = {
|
|
@@ -61,8 +78,19 @@ export type HubMcpEntry = {
|
|
|
61
78
|
type: "http";
|
|
62
79
|
url: string;
|
|
63
80
|
alwaysLoad?: boolean;
|
|
81
|
+
/** Per-server tool-call timeout in ms (overrides MCP_TOOL_TIMEOUT). */
|
|
82
|
+
timeout?: number;
|
|
64
83
|
};
|
|
65
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Tool-call timeout for the Talon frontend tool servers. Must sit ABOVE the
|
|
87
|
+
* bridge's largest per-action budget (1h for uncapped device file transfers)
|
|
88
|
+
* so the layer that times out is the bridge — whose error names the action,
|
|
89
|
+
* the budget, and warns the operation may still be running — rather than the
|
|
90
|
+
* SDK's generic MCP timeout, which tells the model nothing actionable.
|
|
91
|
+
*/
|
|
92
|
+
const FRONTEND_TOOL_CALL_TIMEOUT_MS = 3_900_000; // 65 min
|
|
93
|
+
|
|
66
94
|
/**
|
|
67
95
|
* Build the MCP servers map for a chat query.
|
|
68
96
|
* Includes frontend-specific tool servers and Brave Search, if configured.
|
|
@@ -102,6 +130,8 @@ export function buildMcpServers(chatId: string): Record<string, HubMcpEntry> {
|
|
|
102
130
|
// lever here. Cost: ~50 frontend tool schemas loaded every turn (~10k
|
|
103
131
|
// tokens, cached, negligible on the 1M-context models Talon runs).
|
|
104
132
|
alwaysLoad: true,
|
|
133
|
+
// Outlast the bridge's 1h transfer budget — see the constant's doc.
|
|
134
|
+
timeout: FRONTEND_TOOL_CALL_TIMEOUT_MS,
|
|
105
135
|
};
|
|
106
136
|
}
|
|
107
137
|
|
|
@@ -388,7 +418,17 @@ export function buildSdkOptions(
|
|
|
388
418
|
// WebFetch, Monitor, PushNotification, RemoteTrigger, Plan/Worktree/Todo
|
|
389
419
|
// helpers, AskUserQuestion, ScheduleWakeup) is unavailable to the model.
|
|
390
420
|
// MCP tools are governed independently via `mcpServers` below.
|
|
391
|
-
|
|
421
|
+
//
|
|
422
|
+
// When `config.nativeTools` is on, the SDK's built-in shell/filesystem
|
|
423
|
+
// tools are dropped in favour of Talon's own native tools (which also
|
|
424
|
+
// teleport onto companion devices), and Agent (sub-agent dispatch) is
|
|
425
|
+
// removed too — the owner prefers the native surface without nested
|
|
426
|
+
// agents. Flip the flag back off to restore the built-ins instantly.
|
|
427
|
+
tools: config.nativeTools
|
|
428
|
+
? ALLOWED_TOOLS_CHAT.filter(
|
|
429
|
+
(t) => !NATIVE_REPLACED_BUILTINS.has(t as string),
|
|
430
|
+
)
|
|
431
|
+
: [...ALLOWED_TOOLS_CHAT],
|
|
392
432
|
...thinkingConfig,
|
|
393
433
|
mcpServers: {
|
|
394
434
|
...buildMcpServers(chatId),
|
package/src/bootstrap.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* - `skills` — markdown workflows
|
|
17
17
|
* - `plugins` — plugin hot-reload
|
|
18
18
|
* - `models` — model / backend discovery
|
|
19
|
+
* - `mesh` — companion device mesh (presence + location)
|
|
19
20
|
*/
|
|
20
21
|
|
|
21
22
|
import type { ActionResult } from "../../types.js";
|
|
@@ -30,6 +31,8 @@ import { scriptHandlers } from "./scripts.js";
|
|
|
30
31
|
import { skillHandlers } from "./skills.js";
|
|
31
32
|
import { pluginHandlers } from "./plugins.js";
|
|
32
33
|
import { modelHandlers } from "./models.js";
|
|
34
|
+
import { meshHandlers } from "./mesh.js";
|
|
35
|
+
import { nativeHandlers } from "./native.js";
|
|
33
36
|
|
|
34
37
|
// Null-prototype so a request `action` of "toString" / "constructor" / etc.
|
|
35
38
|
// can't resolve an inherited Object.prototype method — `handlers[action]` only
|
|
@@ -44,6 +47,8 @@ const handlers: SharedActionHandlers = Object.assign(Object.create(null), {
|
|
|
44
47
|
...skillHandlers,
|
|
45
48
|
...pluginHandlers,
|
|
46
49
|
...modelHandlers,
|
|
50
|
+
...meshHandlers,
|
|
51
|
+
...nativeHandlers,
|
|
47
52
|
});
|
|
48
53
|
|
|
49
54
|
export async function handleSharedAction(
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Device mesh — read tools (list_devices, get_device_location,
|
|
3
|
+
* get_device_history) and command tools (ring, live status).
|
|
4
|
+
*
|
|
5
|
+
* Shared actions, so the model has full mesh access from every frontend
|
|
6
|
+
* (Telegram, Discord, Teams, terminal, native) — not just chats running
|
|
7
|
+
* through the native bridge. The mesh itself is daemon-wide state
|
|
8
|
+
* (core/mesh); the native bridge is merely the transport companions
|
|
9
|
+
* register through and commands travel over.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { getMeshService } from "../../mesh/index.js";
|
|
13
|
+
import type { SharedActionHandlers } from "./types.js";
|
|
14
|
+
|
|
15
|
+
export const meshHandlers: SharedActionHandlers = {
|
|
16
|
+
list_devices: () => getMeshService().describeDevices(),
|
|
17
|
+
get_device_location: (body) => getMeshService().locateDevice(body.device),
|
|
18
|
+
get_device_history: (body) =>
|
|
19
|
+
getMeshService().deviceHistory(body.device, body.hours),
|
|
20
|
+
ring_device: (body) => getMeshService().ringDevice(body.device, body.message),
|
|
21
|
+
get_device_status: (body) => getMeshService().getDeviceStatus(body.device),
|
|
22
|
+
// Exec + filesystem surface — the substrate teleport routes through.
|
|
23
|
+
device_exec: (body) =>
|
|
24
|
+
getMeshService().execOnDevice(
|
|
25
|
+
body.device,
|
|
26
|
+
body.cmd,
|
|
27
|
+
body.cwd,
|
|
28
|
+
body.timeout_sec,
|
|
29
|
+
),
|
|
30
|
+
device_list_dir: (body) =>
|
|
31
|
+
getMeshService().listDirOnDevice(body.device, body.path),
|
|
32
|
+
device_stat: (body) => getMeshService().statOnDevice(body.device, body.path),
|
|
33
|
+
device_read_file: (body) =>
|
|
34
|
+
getMeshService().readFileFromDevice(body.device, body.path),
|
|
35
|
+
device_write_file: (body) =>
|
|
36
|
+
getMeshService().writeFileToDevice(body.device, body.path, body.content),
|
|
37
|
+
device_pull_file: (body) =>
|
|
38
|
+
getMeshService().pullFileFromDevice(
|
|
39
|
+
body.device,
|
|
40
|
+
body.remote_path,
|
|
41
|
+
body.local_path,
|
|
42
|
+
),
|
|
43
|
+
device_push_file: (body) =>
|
|
44
|
+
getMeshService().pushFileToDevice(
|
|
45
|
+
body.device,
|
|
46
|
+
body.local_path,
|
|
47
|
+
body.remote_path,
|
|
48
|
+
),
|
|
49
|
+
};
|