@burtson-labs/host-kit 0.3.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/LICENSE +201 -0
- package/README.md +55 -0
- package/dist/backgroundTasks.d.ts +113 -0
- package/dist/backgroundTasks.d.ts.map +1 -0
- package/dist/backgroundTasks.js +137 -0
- package/dist/backgroundTasks.js.map +1 -0
- package/dist/checkpoints.d.ts +99 -0
- package/dist/checkpoints.d.ts.map +1 -0
- package/dist/checkpoints.js +227 -0
- package/dist/checkpoints.js.map +1 -0
- package/dist/hooks.d.ts +51 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +152 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/insights.d.ts +398 -0
- package/dist/insights.d.ts.map +1 -0
- package/dist/insights.js +1933 -0
- package/dist/insights.js.map +1 -0
- package/dist/mcp.d.ts +60 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +281 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mcpConnectors.d.ts +108 -0
- package/dist/mcpConnectors.d.ts.map +1 -0
- package/dist/mcpConnectors.js +217 -0
- package/dist/mcpConnectors.js.map +1 -0
- package/dist/mcpToolCache.d.ts +43 -0
- package/dist/mcpToolCache.d.ts.map +1 -0
- package/dist/mcpToolCache.js +150 -0
- package/dist/mcpToolCache.js.map +1 -0
- package/dist/mcpTrust.d.ts +22 -0
- package/dist/mcpTrust.d.ts.map +1 -0
- package/dist/mcpTrust.js +104 -0
- package/dist/mcpTrust.js.map +1 -0
- package/dist/memory.d.ts +38 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +151 -0
- package/dist/memory.js.map +1 -0
- package/dist/memoryIndex.d.ts +38 -0
- package/dist/memoryIndex.d.ts.map +1 -0
- package/dist/memoryIndex.js +142 -0
- package/dist/memoryIndex.js.map +1 -0
- package/dist/mentions.d.ts +33 -0
- package/dist/mentions.d.ts.map +1 -0
- package/dist/mentions.js +126 -0
- package/dist/mentions.js.map +1 -0
- package/dist/ollamaModels.d.ts +36 -0
- package/dist/ollamaModels.d.ts.map +1 -0
- package/dist/ollamaModels.js +83 -0
- package/dist/ollamaModels.js.map +1 -0
- package/dist/permissions.d.ts +72 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +271 -0
- package/dist/permissions.js.map +1 -0
- package/dist/tools/extraTools.d.ts +80 -0
- package/dist/tools/extraTools.d.ts.map +1 -0
- package/dist/tools/extraTools.js +471 -0
- package/dist/tools/extraTools.js.map +1 -0
- package/dist/tools/readMemoryTool.d.ts +3 -0
- package/dist/tools/readMemoryTool.d.ts.map +1 -0
- package/dist/tools/readMemoryTool.js +115 -0
- package/dist/tools/readMemoryTool.js.map +1 -0
- package/dist/tools/taskTool.d.ts +119 -0
- package/dist/tools/taskTool.d.ts.map +1 -0
- package/dist/tools/taskTool.js +466 -0
- package/dist/tools/taskTool.js.map +1 -0
- package/dist/tools/testRunTool.d.ts +59 -0
- package/dist/tools/testRunTool.d.ts.map +1 -0
- package/dist/tools/testRunTool.js +308 -0
- package/dist/tools/testRunTool.js.map +1 -0
- package/dist/turnLog.d.ts +89 -0
- package/dist/turnLog.d.ts.map +1 -0
- package/dist/turnLog.js +469 -0
- package/dist/turnLog.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task tool — spawns a focused subagent to investigate a scoped question or
|
|
3
|
+
* complete a bounded task without polluting the parent conversation.
|
|
4
|
+
*
|
|
5
|
+
* The subagent runs its own ToolUseLoop with:
|
|
6
|
+
* - A scoped system prompt (focused on the stated goal, asked for a synopsis)
|
|
7
|
+
* - Its own iteration budget (default 6, separate from the parent's)
|
|
8
|
+
* - Access to the parent's tools EXCEPT `task` itself (no recursion)
|
|
9
|
+
* - The parent's beforeToolExecute gate (so PreToolUse hooks still apply)
|
|
10
|
+
*
|
|
11
|
+
* The subagent's final response is returned as the tool result. The parent
|
|
12
|
+
* model sees only the synopsis — not the subagent's intermediate tool calls.
|
|
13
|
+
*/
|
|
14
|
+
import { ToolRegistry, type AgentTool, type ChatFn, type ToolExecutionContext, type ToolUseLoopOptions } from '@burtson-labs/agent-core';
|
|
15
|
+
import type { BackgroundTaskStore } from '../backgroundTasks';
|
|
16
|
+
type SubagentLoopOptions = Pick<ToolUseLoopOptions, 'nativeTools' | 'nativeToolFailureFallback' | 'messageTokenBudget' | 'maxParallelTools' | 'maxTotalTools' | 'outputBudgetTokens' | 'outputBudgetRatio'>;
|
|
17
|
+
export interface TaskToolOptions {
|
|
18
|
+
/** Streaming chat function — same signature as the parent loop uses. */
|
|
19
|
+
chat: ChatFn;
|
|
20
|
+
/** The parent's tool registry. Subagent gets a copy minus `task` itself. */
|
|
21
|
+
parentRegistry: ToolRegistry;
|
|
22
|
+
/** Execution context the subagent should use (usually the parent's). */
|
|
23
|
+
ctx: ToolExecutionContext;
|
|
24
|
+
/** Max iterations for the subagent. Default: 6. */
|
|
25
|
+
maxIterations?: number;
|
|
26
|
+
/** Optional hook gate — typically forwarded from the parent. */
|
|
27
|
+
beforeToolExecute?: ToolUseLoopOptions['beforeToolExecute'];
|
|
28
|
+
/** Called with every subagent event. Hosts can display progress inline. */
|
|
29
|
+
onEvent?: (type: string, payload?: unknown) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Optional background-task store. When present, the agent can pass
|
|
32
|
+
* `run_in_background: true` to the `task` tool and the subagent runs
|
|
33
|
+
* detached — the tool returns a task id immediately and the subagent
|
|
34
|
+
* eventually pushes its synopsis through this store. Hosts that don't
|
|
35
|
+
* supply a store get the legacy synchronous behaviour only.
|
|
36
|
+
*/
|
|
37
|
+
backgroundStore?: BackgroundTaskStore;
|
|
38
|
+
/**
|
|
39
|
+
* Resolves the parent's full system prompt at subagent-spawn time.
|
|
40
|
+
* When provided, the subagent inherits this prompt verbatim and a
|
|
41
|
+
* thin scope wrapper is appended. This eliminates the dual-prompt
|
|
42
|
+
* drift that caused subagents to stall: the hand-rolled fallback
|
|
43
|
+
* below forbade `<tool_call>` markup in prose but never showed the
|
|
44
|
+
* format anywhere, so the model would close its reasoning fence and
|
|
45
|
+
* never emit a tool call (confirmed via diagnostic traces 2026-05-08
|
|
46
|
+
* across 8 subagents — `hasToolCallMarkup: false` on every retry).
|
|
47
|
+
*
|
|
48
|
+
* Accepts string OR getter so callers can register the task tool
|
|
49
|
+
* BEFORE per-turn prompt construction completes; the getter is
|
|
50
|
+
* resolved when the subagent actually spawns.
|
|
51
|
+
*
|
|
52
|
+
* Falls back to the legacy SUBAGENT_PROMPT_FALLBACK when not set.
|
|
53
|
+
*/
|
|
54
|
+
parentSystemPrompt?: string | (() => string | undefined);
|
|
55
|
+
/**
|
|
56
|
+
* Parent loop tuning that should carry into spawned subagents.
|
|
57
|
+
* Critical for native-tool models such as bandit-logic/Qwen: without
|
|
58
|
+
* `nativeTools`, the subagent gets XML prompt instructions but no
|
|
59
|
+
* provider `tools` field, so the model reasons about tool calls without
|
|
60
|
+
* emitting one. Keep this narrow to transport budget/protocol settings,
|
|
61
|
+
* not lifecycle hooks owned by the task tool itself.
|
|
62
|
+
*/
|
|
63
|
+
subagentLoopOptions?: SubagentLoopOptions | (() => SubagentLoopOptions | undefined);
|
|
64
|
+
/**
|
|
65
|
+
* Returns the parent loop's AbortSignal so subagents can honor it.
|
|
66
|
+
* v1.7.338+: without this hookup, hitting Stop in the IDE aborted
|
|
67
|
+
* the parent loop but background subagents kept running in their own
|
|
68
|
+
* loops — backgroundStore stayed "N running" and the only way to
|
|
69
|
+
* recover was to kill the extension process. With the getter wired
|
|
70
|
+
* up, every spawned subagent (foreground OR background) passes the
|
|
71
|
+
* parent signal as its loop's `signal`; when the parent aborts, the
|
|
72
|
+
* subagent loop sees it on its next iteration check and exits
|
|
73
|
+
* cleanly, the store records the task as cancelled, and the UI
|
|
74
|
+
* clears.
|
|
75
|
+
*
|
|
76
|
+
* Getter rather than value so subagents spawned mid-turn pick up the
|
|
77
|
+
* CURRENT turn's controller, not whichever one was active when the
|
|
78
|
+
* tool was registered.
|
|
79
|
+
*/
|
|
80
|
+
getParentSignal?: () => AbortSignal | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Maximum number of background subagents that can be running at once.
|
|
83
|
+
* When the cap is hit, a `task(run_in_background)` call returns
|
|
84
|
+
* immediately with a non-error result telling the model how many are
|
|
85
|
+
* running and how to wait. Without this cap, the model can fan out
|
|
86
|
+
* unboundedly — with 7 concurrent subagents all
|
|
87
|
+
* hitting Ollama simultaneously, which starved the host's token
|
|
88
|
+
* budget and left the chat card stuck on 0 iter / 0 tools.
|
|
89
|
+
*
|
|
90
|
+
* Defaults to 3 (a reasonable floor for parallel investigation
|
|
91
|
+
* without overwhelming a local model server). Set to 0 to disable
|
|
92
|
+
* the cap entirely. Foreground (synchronous) tasks ignore this cap
|
|
93
|
+
* because they're already serial by construction.
|
|
94
|
+
*/
|
|
95
|
+
maxConcurrentBackground?: number;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Build the `task` tool. Register it on the parent agent's registry so the
|
|
99
|
+
* model can delegate scoped work to a subagent.
|
|
100
|
+
*/
|
|
101
|
+
export declare function buildTaskTool(opts: TaskToolOptions): AgentTool;
|
|
102
|
+
/**
|
|
103
|
+
* `check_task` tool — query the current state of a single background
|
|
104
|
+
* subagent. Returns a friendly status line + the synopsis when the
|
|
105
|
+
* task has completed. The agent rarely needs to call this because the
|
|
106
|
+
* host auto-injects completion events into the next turn, but it's
|
|
107
|
+
* here for explicit "are we there yet" polling and for cases where
|
|
108
|
+
* the agent wants to wait on a specific task before doing the next
|
|
109
|
+
* thing.
|
|
110
|
+
*/
|
|
111
|
+
export declare function buildCheckTaskTool(store: BackgroundTaskStore): AgentTool;
|
|
112
|
+
/**
|
|
113
|
+
* `list_tasks` tool — list every background subagent task in the
|
|
114
|
+
* current session. Cheap status overview; the agent typically only
|
|
115
|
+
* calls this if the user asks "what's still running" or similar.
|
|
116
|
+
*/
|
|
117
|
+
export declare function buildListTasksTool(store: BackgroundTaskStore): AgentTool;
|
|
118
|
+
export {};
|
|
119
|
+
//# sourceMappingURL=taskTool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskTool.d.ts","sourceRoot":"","sources":["../../src/tools/taskTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAEL,YAAY,EACZ,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,oBAAoB,EAEzB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,KAAK,mBAAmB,GAAG,IAAI,CAC7B,kBAAkB,EAClB,aAAa,GAAG,2BAA2B,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,eAAe,GAAG,oBAAoB,GAAG,mBAAmB,CACvJ,CAAC;AA+BF,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,cAAc,EAAE,YAAY,CAAC;IAC7B,wEAAwE;IACxE,GAAG,EAAE,oBAAoB,CAAC;IAC1B,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;IAC5D,2EAA2E;IAC3E,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;IACzD;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC,CAAC;IACpF;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,EAAE,MAAM,WAAW,GAAG,SAAS,CAAC;IAChD;;;;;;;;;;;;;OAaG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAgCD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,CAsT9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,CAmCxE;AAwBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,CAmBxE"}
|
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Task tool — spawns a focused subagent to investigate a scoped question or
|
|
4
|
+
* complete a bounded task without polluting the parent conversation.
|
|
5
|
+
*
|
|
6
|
+
* The subagent runs its own ToolUseLoop with:
|
|
7
|
+
* - A scoped system prompt (focused on the stated goal, asked for a synopsis)
|
|
8
|
+
* - Its own iteration budget (default 6, separate from the parent's)
|
|
9
|
+
* - Access to the parent's tools EXCEPT `task` itself (no recursion)
|
|
10
|
+
* - The parent's beforeToolExecute gate (so PreToolUse hooks still apply)
|
|
11
|
+
*
|
|
12
|
+
* The subagent's final response is returned as the tool result. The parent
|
|
13
|
+
* model sees only the synopsis — not the subagent's intermediate tool calls.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.buildTaskTool = buildTaskTool;
|
|
17
|
+
exports.buildCheckTaskTool = buildCheckTaskTool;
|
|
18
|
+
exports.buildListTasksTool = buildListTasksTool;
|
|
19
|
+
const agent_core_1 = require("@burtson-labs/agent-core");
|
|
20
|
+
function resolveSubagentLoopOptions(value) {
|
|
21
|
+
const resolved = typeof value === 'function' ? value() : value;
|
|
22
|
+
return resolved ?? {};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Strip reasoning fences (```bandit-reasoning … ``` and <think>…</think>)
|
|
26
|
+
* from the subagent's final response so the synopsis the parent sees is
|
|
27
|
+
* the actual analysis, not the model's internal monologue. Observed
|
|
28
|
+
* 2026-05-06: subagents that stalled in reasoning without ever calling a
|
|
29
|
+
* tool returned a `finalResponse` that was JUST the reasoning fence, and
|
|
30
|
+
* the chat card in the IDE rendered "I need to actually emit tool calls.
|
|
31
|
+
* Let me start by reading the package.json…" as the synopsis — looked
|
|
32
|
+
* like the subagent had thoughts but hadn't shipped them. Now we strip
|
|
33
|
+
* the fences first; if nothing useful remains, we surface that as a
|
|
34
|
+
* "subagent stalled in reasoning" error instead of pretending we got an
|
|
35
|
+
* answer.
|
|
36
|
+
*/
|
|
37
|
+
function sanitizeSubagentSynopsis(raw) {
|
|
38
|
+
return raw
|
|
39
|
+
.replace(/```bandit-reasoning\b[\s\S]*?```/gi, '')
|
|
40
|
+
.replace(/```bandit-reasoning\b[\s\S]*$/i, '')
|
|
41
|
+
.replace(/<think\b[\s\S]*?<\/think\s*>/gi, '')
|
|
42
|
+
.replace(/<think\b[\s\S]*$/i, '')
|
|
43
|
+
.trim();
|
|
44
|
+
}
|
|
45
|
+
const DEFAULT_MAX_CONCURRENT_BACKGROUND = 3;
|
|
46
|
+
/**
|
|
47
|
+
* Defensive fallback when the host doesn't pass `parentSystemPrompt`.
|
|
48
|
+
*
|
|
49
|
+
* Self-sufficient — works on its own without inheritance.
|
|
50
|
+
* tightening: the format example is INLINE on a single line after a
|
|
51
|
+
* colon (same pattern as the fix to extensionSystemPrompt.ts).
|
|
52
|
+
* Putting it on its own line surrounded by whitespace triggers
|
|
53
|
+
* Ollama's qwen parser as a real tool call, xml.Unmarshal hits EOF on
|
|
54
|
+
* the JSON inside, and upstream returns 500. Don't reformat this.
|
|
55
|
+
*
|
|
56
|
+
* Why explicit + emphatic: subagents on bandit-logic 27B would
|
|
57
|
+
* literally read the old prompt's "NEVER write <tool_call> markup"
|
|
58
|
+
* rule and comply by closing their reasoning fence and stopping —
|
|
59
|
+
* never emitting an actual tool call. The fix is to combine the
|
|
60
|
+
* format example (inline, parser-safe) with explicit "your FIRST
|
|
61
|
+
* response must emit one of these" framing so the model knows what
|
|
62
|
+
* to do AND that it's required.
|
|
63
|
+
*/
|
|
64
|
+
const SUBAGENT_PROMPT_FALLBACK = `You are a focused coding subagent built by Burtson Labs. You have one bounded goal and the same tool registry as the parent agent (read, search, shell, write, git, todo_write) EXCEPT \`task\` — you cannot spawn further subagents.
|
|
65
|
+
|
|
66
|
+
Call tools by outputting on a single line: <tool_call>{"name": "tool_name", "params": {"key": "value"}}</tool_call>
|
|
67
|
+
|
|
68
|
+
Your FIRST response MUST contain a real tool call. Reasoning is fine — but the response must include an actual <tool_call> envelope, not just talk about one. The goal needs information you don't have; the only way to get it is via tools. Pick the most obvious starting tool (\`list_files\` for "what's in this dir", \`read_file\` for "what does X look like", \`search_code\` for "where is Y") and emit it.
|
|
69
|
+
|
|
70
|
+
When *describing* tool calls in prose (in synopsis or explanations), use words: "I called read_file with path=...". NEVER emit the literal angle-bracket markup outside an actual invocation — it breaks Ollama's qwen parser (xml.Unmarshal returns EOF on the JSON inside, upstream 500). Same rule for tool_result and think tokens: never as prose.
|
|
71
|
+
|
|
72
|
+
When the goal is complete, return a 2-6 line synopsis. No preamble. If the goal is ambiguous, make ONE reasonable interpretation and state it.`;
|
|
73
|
+
/**
|
|
74
|
+
* Build the `task` tool. Register it on the parent agent's registry so the
|
|
75
|
+
* model can delegate scoped work to a subagent.
|
|
76
|
+
*/
|
|
77
|
+
function buildTaskTool(opts) {
|
|
78
|
+
// Tool registry the subagent uses — same one whether the call is
|
|
79
|
+
// foreground or background. Exclude `task` itself so subagents can't
|
|
80
|
+
// spawn further subagents (recursion + budget blowup).
|
|
81
|
+
const subRegistry = new agent_core_1.ToolRegistry();
|
|
82
|
+
for (const tool of opts.parentRegistry.getAll()) {
|
|
83
|
+
if (tool.name === 'task')
|
|
84
|
+
continue;
|
|
85
|
+
subRegistry.register(tool);
|
|
86
|
+
}
|
|
87
|
+
const maxIterations = opts.maxIterations ?? 6;
|
|
88
|
+
const emit = opts.onEvent ?? (() => undefined);
|
|
89
|
+
/** Run a subagent loop and return its result. Used by both the
|
|
90
|
+
* foreground and background paths so the actual run logic stays
|
|
91
|
+
* in one place. The `progressEmitter` is called per-iteration with
|
|
92
|
+
* the running iteration count + tool counts so the BackgroundTaskStore
|
|
93
|
+
* can keep its progress fields current. */
|
|
94
|
+
const runSubagent = async (goal, context, progressEmitter, taskId) => {
|
|
95
|
+
let iterations = 0;
|
|
96
|
+
let toolCalls = 0;
|
|
97
|
+
let lastTool;
|
|
98
|
+
const inheritedLoopOptions = resolveSubagentLoopOptions(opts.subagentLoopOptions);
|
|
99
|
+
const subagent = new agent_core_1.ToolUseLoop(subRegistry, opts.ctx, {
|
|
100
|
+
...inheritedLoopOptions,
|
|
101
|
+
maxIterations,
|
|
102
|
+
beforeToolExecute: opts.beforeToolExecute,
|
|
103
|
+
// Mark this loop as a subagent so the loop's iter-0-no-tool-call
|
|
104
|
+
// detector can force a tool call when bandit-logic stalls in
|
|
105
|
+
// reasoning. Without this, the model emits prose + reasoning on
|
|
106
|
+
// iter 0 (not matching the announce-intent or narrate verb
|
|
107
|
+
// patterns), the loop treats it as a final answer, and the
|
|
108
|
+
// parent gets a 0-iteration "stalled in reasoning" failure.
|
|
109
|
+
isSubagent: true,
|
|
110
|
+
emitEvent: (type, payload) => {
|
|
111
|
+
// Track progress fields that hosts care about — iteration count,
|
|
112
|
+
// tool-call count, last tool name. Cheap counters, not the full
|
|
113
|
+
// event log; the latter would be too noisy for the status display
|
|
114
|
+
// that the agent / user actually look at.
|
|
115
|
+
//
|
|
116
|
+
// the loop never emits `iteration:start`. The
|
|
117
|
+
// canonical per-iteration marker is `tool_loop:llm_start`,
|
|
118
|
+
// whose payload carries the loop's own zero-indexed `iteration`
|
|
119
|
+
// counter. Pre-fix, this branch listened for `iteration:start`
|
|
120
|
+
// and the local counter never incremented, so every background
|
|
121
|
+
// task in the host's grouped UI showed "0 iter" forever. Read
|
|
122
|
+
// from the payload so the count tracks the loop's truth, not
|
|
123
|
+
// a hand-rolled increment.
|
|
124
|
+
if (type === 'tool_loop:llm_start') {
|
|
125
|
+
const iter = payload?.iteration;
|
|
126
|
+
if (typeof iter === 'number' && Number.isFinite(iter)) {
|
|
127
|
+
iterations = Math.max(iterations, iter + 1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (type === 'tool_loop:tool_execute') {
|
|
131
|
+
toolCalls += 1;
|
|
132
|
+
const name = payload?.name;
|
|
133
|
+
if (typeof name === 'string')
|
|
134
|
+
lastTool = name;
|
|
135
|
+
}
|
|
136
|
+
progressEmitter?.({ iterations, toolCalls, lastTool });
|
|
137
|
+
// Tag every relayed event with the owning taskId when this is a
|
|
138
|
+
// backgrounded run, so a host with multiple concurrent background
|
|
139
|
+
// subagents can route events to the right card. Without this all
|
|
140
|
+
// events arrive flat and the host can't tell tools-of-task-A from
|
|
141
|
+
// tools-of-task-B — with 7 concurrent tasks
|
|
142
|
+
// where the chat card stayed at 0 iter / 0 tools because the
|
|
143
|
+
// single global buffer was being clobbered by every task:start.
|
|
144
|
+
const tagged = taskId !== undefined && payload && typeof payload === 'object'
|
|
145
|
+
? { ...payload, taskId }
|
|
146
|
+
: payload;
|
|
147
|
+
emit(`subagent:${type}`, tagged);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
// Inherit the parent's system prompt verbatim when supplied — this is
|
|
151
|
+
// the fix for the recurring subagent stall. A hand-rolled
|
|
152
|
+
// subagent prompt always drifts from the parent's protocol (the
|
|
153
|
+
// legacy SUBAGENT_PROMPT forbade `<tool_call>` markup but never
|
|
154
|
+
// showed the format). Inheriting + appending a thin scope wrapper
|
|
155
|
+
// keeps tool-call format, behavior policies, and operational hints
|
|
156
|
+
// consistent across parent and subagent.
|
|
157
|
+
const inherited = typeof opts.parentSystemPrompt === 'function'
|
|
158
|
+
? opts.parentSystemPrompt()
|
|
159
|
+
: opts.parentSystemPrompt;
|
|
160
|
+
const baseSystemPrompt = inherited && inherited.trim().length > 0
|
|
161
|
+
? inherited
|
|
162
|
+
: SUBAGENT_PROMPT_FALLBACK;
|
|
163
|
+
const subagentScope = [
|
|
164
|
+
'',
|
|
165
|
+
'',
|
|
166
|
+
'## Subagent Scope',
|
|
167
|
+
'You are operating as a SUBAGENT — a focused sub-process spawned by the parent agent to accomplish a single bounded goal.',
|
|
168
|
+
'',
|
|
169
|
+
`Your goal: ${goal}`,
|
|
170
|
+
context ? `\nContext: ${context}` : '',
|
|
171
|
+
'',
|
|
172
|
+
'Subagent rules:',
|
|
173
|
+
'- Stay strictly on the goal. No adjacent work, refactors, or "while I\'m here" cleanups.',
|
|
174
|
+
'- When the goal is complete, return a 2-6 line synopsis. No preamble.',
|
|
175
|
+
'- You CANNOT spawn further subagents (the `task` tool is not in your registry).',
|
|
176
|
+
'- If the goal is ambiguous, make ONE reasonable interpretation and state it in your synopsis.',
|
|
177
|
+
'- If you cannot reach the goal (tool errors, missing files, etc.), return what you learned and why you stopped.'
|
|
178
|
+
].filter((line, idx, arr) => !(line === '' && arr[idx - 1] === '')).join('\n');
|
|
179
|
+
const systemPrompt = `${baseSystemPrompt}${subagentScope}`;
|
|
180
|
+
// Telemetry: log the subagent's system prompt size +
|
|
181
|
+
// inheritance source. Lets us correlate "huge inherited prompt"
|
|
182
|
+
// with stalls/watchdog fires in the turn log without having to
|
|
183
|
+
// recompute the size from chunks. Surfaced via subagent:task:spawn
|
|
184
|
+
// event so hosts append it to the turn log alongside task:start.
|
|
185
|
+
emit('subagent:task:spawn', {
|
|
186
|
+
taskId,
|
|
187
|
+
goal,
|
|
188
|
+
systemPromptChars: systemPrompt.length,
|
|
189
|
+
inheritedFromParent: Boolean(inherited && inherited.trim().length > 0),
|
|
190
|
+
nativeTools: Boolean(inheritedLoopOptions.nativeTools),
|
|
191
|
+
registryToolCount: subRegistry.getAll().length
|
|
192
|
+
});
|
|
193
|
+
// Pass the parent loop's AbortSignal through so Stop in the host
|
|
194
|
+
// (Esc in CLI, cancel button in IDE) cascades down to in-flight
|
|
195
|
+
// subagents. v1.7.338+: without this, hitting Stop aborted the
|
|
196
|
+
// parent but every backgrounded subagent kept running and the
|
|
197
|
+
// user had to kill the process to recover. The getter is read at
|
|
198
|
+
// EACH spawn (not cached at registration time) so a subagent
|
|
199
|
+
// spawned mid-turn picks up the current turn's controller.
|
|
200
|
+
return subagent.run(goal, opts.chat, systemPrompt, {
|
|
201
|
+
signal: opts.getParentSignal?.()
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
return {
|
|
205
|
+
name: 'task',
|
|
206
|
+
description: 'Spawn a focused subagent to investigate a specific question or complete a bounded task. Do NOT use this for first-pass repo overviews like "what is this project" or "tell me about this repo" — answer those with direct list/read/search calls first. Use task for explicit exhaustive audits or a narrow branch of work whose intermediate details are not worth surfacing in the main conversation. The subagent returns a concise synopsis; its intermediate tool calls are hidden from you. Does NOT support nested task spawning. Pass run_in_background="true" for long-running or parallel investigations — the tool returns a task id immediately and the subagent\'s synopsis is delivered to you on a later turn so you can keep working with the user in the meantime.',
|
|
207
|
+
parameters: [
|
|
208
|
+
{ name: 'goal', description: 'The specific question or task for the subagent. Be concrete — "find all call sites of foo() and list their files" beats "look at foo usage".', required: true },
|
|
209
|
+
{ name: 'context', description: 'Optional: one or two sentences of background the subagent needs that is not obvious from the goal alone.', required: false },
|
|
210
|
+
{ name: 'run_in_background', description: 'Optional. When "true", spawn the subagent in the background and return immediately with a task id. The subagent\'s synopsis is auto-injected into a later turn when it completes, so you can keep responding to the user while it runs. Use this for investigations that would otherwise take 30+ seconds and don\'t block the user\'s next question. Default: false (synchronous, parent waits).', required: false }
|
|
211
|
+
],
|
|
212
|
+
async execute(params, _ctx) {
|
|
213
|
+
const goal = params.goal?.trim();
|
|
214
|
+
if (!goal) {
|
|
215
|
+
return { output: 'Error: goal parameter is required.', isError: true };
|
|
216
|
+
}
|
|
217
|
+
const context = params.context?.trim();
|
|
218
|
+
const wantsBackground = String(params.run_in_background ?? '').toLowerCase() === 'true';
|
|
219
|
+
// Background path: spawn detached, return immediately with a task
|
|
220
|
+
// id. Requires the host to have wired up a backgroundStore — fall
|
|
221
|
+
// back to synchronous if the store isn't available, with a note
|
|
222
|
+
// so the agent knows why it didn't actually go async.
|
|
223
|
+
if (wantsBackground && opts.backgroundStore) {
|
|
224
|
+
const store = opts.backgroundStore;
|
|
225
|
+
// Concurrency cap: refuse to spawn when the configured ceiling
|
|
226
|
+
// of in-flight backgrounds is already reached. This is flow
|
|
227
|
+
// control, not an error — isError stays false so the model can
|
|
228
|
+
// calmly pick from the offered options (wait, check_task on a
|
|
229
|
+
// running id, or re-issue without backgrounding) without the
|
|
230
|
+
// hallucination-prone "tool failed" framing.
|
|
231
|
+
const cap = opts.maxConcurrentBackground ?? DEFAULT_MAX_CONCURRENT_BACKGROUND;
|
|
232
|
+
if (cap > 0) {
|
|
233
|
+
const running = store.listByStatus('running');
|
|
234
|
+
if (running.length >= cap) {
|
|
235
|
+
emit('task:cap-hit', {
|
|
236
|
+
goal,
|
|
237
|
+
cap,
|
|
238
|
+
runningCount: running.length,
|
|
239
|
+
runningIds: running.map((r) => r.id)
|
|
240
|
+
});
|
|
241
|
+
const ids = running.map((r) => r.id).join(', ');
|
|
242
|
+
return {
|
|
243
|
+
output: `Background subagent limit reached (${running.length} / ${cap} already running). ` +
|
|
244
|
+
`Pick one: (a) wait for a running task to complete and call task(run_in_background="true") again, ` +
|
|
245
|
+
`(b) call check_task on one of [${ids}] to block on a specific task, or ` +
|
|
246
|
+
`(c) re-issue this task without run_in_background to run it inline now.`,
|
|
247
|
+
isError: false
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const taskId = store.start(goal);
|
|
252
|
+
emit('task:start', { goal, maxIterations, background: true, taskId });
|
|
253
|
+
// Detached run. We deliberately do NOT await — the parent tool
|
|
254
|
+
// call returns synchronously below.
|
|
255
|
+
void (async () => {
|
|
256
|
+
try {
|
|
257
|
+
const result = await runSubagent(goal, context, (p) => {
|
|
258
|
+
store.progress(taskId, p);
|
|
259
|
+
}, taskId);
|
|
260
|
+
// Parent abort cascaded down — mark cancelled, NOT failed.
|
|
261
|
+
// (v1.7.338+) Without this branch, a parent-aborted subagent
|
|
262
|
+
// landed in the failure path with a misleading "stalled in
|
|
263
|
+
// reasoning, 0 iterations" message, because cancelled
|
|
264
|
+
// runs return finalResponse='[cancelled]' which strips to
|
|
265
|
+
// an empty synopsis.
|
|
266
|
+
if (result.cancelled) {
|
|
267
|
+
store.cancel(taskId);
|
|
268
|
+
emit('task:cancel', { goal, taskId, iterations: result.iterations });
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const synopsis = sanitizeSubagentSynopsis(result.finalResponse);
|
|
272
|
+
if (!synopsis) {
|
|
273
|
+
const reason = result.iterations === 0
|
|
274
|
+
? 'Subagent stalled in reasoning without emitting a tool call or final answer (0 iterations). The model thought through the goal but never committed to an action.'
|
|
275
|
+
: `Subagent finished in ${result.iterations} iteration(s) but returned no synopsis.${result.hitLimit ? ' (Hit iteration limit.)' : ''}`;
|
|
276
|
+
store.fail(taskId, reason);
|
|
277
|
+
emit('task:error', { goal, taskId, error: reason });
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const limitNote = result.hitLimit ? `\n\n[Note: subagent hit ${maxIterations}-iteration limit, synopsis may be incomplete.]` : '';
|
|
281
|
+
// same directive wrap as the sync path so the
|
|
282
|
+
// parent's next turn treats the auto-injected background
|
|
283
|
+
// synopsis as "the answer to my delegation" rather than
|
|
284
|
+
// raw text it can ignore. See sync-path comment for the
|
|
285
|
+
// observed-failure context.
|
|
286
|
+
const bgDirective = '=== SUBAGENT REPORT — this is the answer to your delegation ===\n\n' +
|
|
287
|
+
'The subagent you dispatched in the background has finished. The findings BELOW are what it found in the actual codebase. Synthesize THESE into your answer.\n\n' +
|
|
288
|
+
'Do NOT speak as if the subagent is still running, restate your initial hypothesis, or invent gap categories that weren\'t in the report. DO cite the subagent\'s specific findings by name (file paths, function names, exact labels) and lead with anything it flagged as a real bug or missing capability.\n\n' +
|
|
289
|
+
'--- Subagent findings ---\n\n';
|
|
290
|
+
store.complete(taskId, `${bgDirective}${synopsis}${limitNote}`);
|
|
291
|
+
emit('task:done', { goal, taskId, iterations: result.iterations, hitLimit: result.hitLimit });
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
295
|
+
store.fail(taskId, msg);
|
|
296
|
+
emit('task:error', { goal, taskId, error: msg });
|
|
297
|
+
}
|
|
298
|
+
})();
|
|
299
|
+
return {
|
|
300
|
+
output: `Spawned background subagent (task id: ${taskId}) — goal: "${goal}". ` +
|
|
301
|
+
`You'll receive a synthetic system message with the synopsis when it completes. ` +
|
|
302
|
+
`In the meantime, keep responding to the user. ` +
|
|
303
|
+
`Call check_task with this id if you need to poll, or list_tasks to see all background work.`,
|
|
304
|
+
isError: false
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
if (wantsBackground && !opts.backgroundStore) {
|
|
308
|
+
emit('task:warn', { goal, warning: 'background-not-supported' });
|
|
309
|
+
// Fall through to synchronous path with a note appended.
|
|
310
|
+
}
|
|
311
|
+
// Synchronous path — same as v1.7.x and earlier. Parent waits.
|
|
312
|
+
emit('task:start', { goal, maxIterations, background: false });
|
|
313
|
+
try {
|
|
314
|
+
const result = await runSubagent(goal, context);
|
|
315
|
+
emit('task:done', { goal, iterations: result.iterations, hitLimit: result.hitLimit });
|
|
316
|
+
const synopsis = sanitizeSubagentSynopsis(result.finalResponse);
|
|
317
|
+
if (!synopsis) {
|
|
318
|
+
const reason = result.iterations === 0
|
|
319
|
+
? 'Subagent stalled in reasoning without emitting a tool call or final answer (0 iterations). The model thought through the goal but never committed to an action.'
|
|
320
|
+
: `Subagent finished in ${result.iterations} iteration(s) but returned no synopsis.${result.hitLimit ? ' (Hit iteration limit.)' : ''}`;
|
|
321
|
+
return { output: reason, isError: true };
|
|
322
|
+
}
|
|
323
|
+
const limitNote = result.hitLimit ? `\n\n[Note: subagent hit ${maxIterations}-iteration limit, synopsis may be incomplete.]` : '';
|
|
324
|
+
const fallbackNote = wantsBackground && !opts.backgroundStore
|
|
325
|
+
? '\n\n[Note: run_in_background was requested but this host does not support background tasks; ran synchronously.]'
|
|
326
|
+
: '';
|
|
327
|
+
// wrap the synopsis with a directive header so the
|
|
328
|
+
// parent model treats this as "the answer to my delegation" and
|
|
329
|
+
// synthesizes it into the final response. Without this header,
|
|
330
|
+
// Gemma 4 (bandit-core-1) was ignoring real subagent findings
|
|
331
|
+
// and restating its iter-0 hypothesis as if the subagent were
|
|
332
|
+
// still running. turn 4kec: subagent
|
|
333
|
+
// returned 2.2 KB of concrete findings (Underutilized Git
|
|
334
|
+
// tools, missing LSP integration, semantic-search gap, real
|
|
335
|
+
// technical debt in resolveRepoPath); parent's iter-1
|
|
336
|
+
// response cloned the iter-0 prose with the same 4 invented
|
|
337
|
+
// gaps and present-tense "while it digs into the source."
|
|
338
|
+
// The header is structural ("=== SUBAGENT REPORT ===" + an
|
|
339
|
+
// explicit directive) so it's hard to overlook even when the
|
|
340
|
+
// model is in "restate-my-hypothesis" mode.
|
|
341
|
+
const directive = '=== SUBAGENT REPORT — this is the answer to your delegation ===\n\n' +
|
|
342
|
+
'The subagent you dispatched has finished its investigation. The findings BELOW are what it found in the actual codebase. Synthesize THESE into your final answer.\n\n' +
|
|
343
|
+
'Do NOT:\n' +
|
|
344
|
+
' - Speak in present tense as if the subagent is still running ("while it digs into…").\n' +
|
|
345
|
+
' - Restate your initial hypothesis about what the subagent might find.\n' +
|
|
346
|
+
' - Invent gap categories that weren\'t in the report.\n\n' +
|
|
347
|
+
'Do:\n' +
|
|
348
|
+
' - Cite the subagent\'s specific findings by name (file paths, function names, exact gap labels it used).\n' +
|
|
349
|
+
' - If the subagent flagged a real bug or missing capability, lead with that.\n' +
|
|
350
|
+
' - If the subagent\'s report contradicted your initial hypothesis, update your answer accordingly.\n\n' +
|
|
351
|
+
'--- Subagent findings ---\n\n';
|
|
352
|
+
return { output: `${directive}${synopsis}${limitNote}${fallbackNote}`, isError: false };
|
|
353
|
+
}
|
|
354
|
+
catch (err) {
|
|
355
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
356
|
+
emit('task:error', { goal, error: msg });
|
|
357
|
+
// Categorize for the model so it knows whether to pivot
|
|
358
|
+
// (upstream/network — try a different approach OR the same one
|
|
359
|
+
// again later) or to give up (logic — won't get better on retry).
|
|
360
|
+
// The most common failure in practice is an upstream gateway 5xx
|
|
361
|
+
// during the subagent's chat call, which had been surfacing as
|
|
362
|
+
// "Subagent crashed: 500 Internal Server Error" — easy to read
|
|
363
|
+
// as a tool-denial issue. Now we tag it explicitly.
|
|
364
|
+
const looksLikeUpstream = /\b(5\d\d)\b|upstream|gateway|fetch failed|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|socket hang up|aborted/i.test(msg);
|
|
365
|
+
const tag = looksLikeUpstream
|
|
366
|
+
? 'Subagent failed: upstream/model error (this is NOT a tool-permission issue — the subagent\'s call to the LLM provider failed with a 5xx / network error). You can retry the same task tool call once; if it fails again, fall back to doing the work in the parent agent without delegating.'
|
|
367
|
+
: 'Subagent crashed';
|
|
368
|
+
return { output: `${tag}: ${msg}`, isError: true };
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* `check_task` tool — query the current state of a single background
|
|
375
|
+
* subagent. Returns a friendly status line + the synopsis when the
|
|
376
|
+
* task has completed. The agent rarely needs to call this because the
|
|
377
|
+
* host auto-injects completion events into the next turn, but it's
|
|
378
|
+
* here for explicit "are we there yet" polling and for cases where
|
|
379
|
+
* the agent wants to wait on a specific task before doing the next
|
|
380
|
+
* thing.
|
|
381
|
+
*/
|
|
382
|
+
function buildCheckTaskTool(store) {
|
|
383
|
+
return {
|
|
384
|
+
name: 'check_task',
|
|
385
|
+
description: 'Inspect the current state of a single background subagent task spawned via task(run_in_background="true"). Returns the running/completed/failed status, iteration count, and (when complete) the full synopsis. The output leads with the task\'s short title ("the security review is still running…") so when you narrate back to the user, use the title — not the raw id. Most of the time you do NOT need to call this — completed-task synopses are auto-injected as system messages on the next turn. Use this only when you want to explicitly wait on a specific task before doing the next thing.',
|
|
386
|
+
parameters: [
|
|
387
|
+
{ name: 'task_id', description: 'The id returned from a previous task(run_in_background="true") call.', required: true }
|
|
388
|
+
],
|
|
389
|
+
execute(params) {
|
|
390
|
+
const id = params.task_id?.trim();
|
|
391
|
+
if (!id)
|
|
392
|
+
return Promise.resolve({ output: 'Error: task_id parameter is required.', isError: true });
|
|
393
|
+
const record = store.get(id);
|
|
394
|
+
if (!record)
|
|
395
|
+
return Promise.resolve({ output: `No background task with id "${id}".`, isError: true });
|
|
396
|
+
const seconds = ((record.endedAt ?? Date.now()) - record.startedAt) / 1000;
|
|
397
|
+
const stamp = `${seconds.toFixed(1)}s, ${record.iterations} iter, ${record.toolCalls} tool calls`;
|
|
398
|
+
// Lead with the task's GOAL (short title) so the agent's narration
|
|
399
|
+
// back to the user reads "the security review is still running"
|
|
400
|
+
// instead of "task bg-mpr7i4jb-hths is still running". The raw id
|
|
401
|
+
// stays available in parentheses for explicit re-checks.
|
|
402
|
+
const title = formatTaskTitle(record.goal);
|
|
403
|
+
if (record.status === 'running') {
|
|
404
|
+
return Promise.resolve({ output: `"${title}" — still running (${stamp}). Last tool: ${record.lastTool ?? '—'}. (id: ${id})`, isError: false });
|
|
405
|
+
}
|
|
406
|
+
if (record.status === 'completed') {
|
|
407
|
+
store.markConsumed(id);
|
|
408
|
+
return Promise.resolve({ output: `"${title}" — completed (${stamp}). (id: ${id})\n\n${record.synopsis ?? '(no synopsis)'}`, isError: false });
|
|
409
|
+
}
|
|
410
|
+
if (record.status === 'failed') {
|
|
411
|
+
store.markConsumed(id);
|
|
412
|
+
return Promise.resolve({ output: `"${title}" — failed (${stamp}): ${record.error ?? 'unknown error'} (id: ${id})`, isError: true });
|
|
413
|
+
}
|
|
414
|
+
// cancelled
|
|
415
|
+
store.markConsumed(id);
|
|
416
|
+
return Promise.resolve({ output: `"${title}" — cancelled (${stamp}). (id: ${id})`, isError: false });
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Format a task's goal into a short narratable title. Strips imperative
|
|
422
|
+
* verb scaffolding ("Do a", "Investigate", "Perform a") so the title
|
|
423
|
+
* reads naturally inside a sentence ("the security review is still
|
|
424
|
+
* running" instead of "the do-a-security-review is still running").
|
|
425
|
+
* Caps at 60 chars with an ellipsis so it stays in a single line of
|
|
426
|
+
* the agent's narration.
|
|
427
|
+
*/
|
|
428
|
+
function formatTaskTitle(goal) {
|
|
429
|
+
let title = goal.trim();
|
|
430
|
+
// Strip common imperative openers so the title reads as a noun phrase.
|
|
431
|
+
title = title.replace(/^(do a|do an|perform a|perform an|investigate|investigate the|run a|run an|conduct a|conduct an)\s+/i, '');
|
|
432
|
+
// Trim trailing punctuation that's part of the goal sentence.
|
|
433
|
+
title = title.replace(/[.!?]+$/, '');
|
|
434
|
+
// Single line. Models sometimes wrap goals with newlines; flatten.
|
|
435
|
+
title = title.replace(/\s+/g, ' ');
|
|
436
|
+
if (title.length > 60) {
|
|
437
|
+
title = title.slice(0, 57).trimEnd() + '…';
|
|
438
|
+
}
|
|
439
|
+
return title || goal.slice(0, 60);
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* `list_tasks` tool — list every background subagent task in the
|
|
443
|
+
* current session. Cheap status overview; the agent typically only
|
|
444
|
+
* calls this if the user asks "what's still running" or similar.
|
|
445
|
+
*/
|
|
446
|
+
function buildListTasksTool(store) {
|
|
447
|
+
return {
|
|
448
|
+
name: 'list_tasks',
|
|
449
|
+
description: 'List all background subagent tasks in this session (running and completed). Useful when the user asks "what\'s still running" or "what happened with that earlier task". Each entry leads with the task\'s short title (derived from its goal) — when narrating back to the user, refer to tasks by title ("the security review is still working") rather than by id.',
|
|
450
|
+
parameters: [],
|
|
451
|
+
execute() {
|
|
452
|
+
const tasks = store.list();
|
|
453
|
+
if (tasks.length === 0) {
|
|
454
|
+
return Promise.resolve({ output: 'No background tasks have been spawned in this session.', isError: false });
|
|
455
|
+
}
|
|
456
|
+
const lines = tasks.map((t) => {
|
|
457
|
+
const seconds = ((t.endedAt ?? Date.now()) - t.startedAt) / 1000;
|
|
458
|
+
const status = t.status === 'running' ? `running (${seconds.toFixed(0)}s)` : `${t.status} (${seconds.toFixed(1)}s)`;
|
|
459
|
+
const title = formatTaskTitle(t.goal);
|
|
460
|
+
return `- "${title}" · ${status} · ${t.iterations} iter (id: ${t.id})`;
|
|
461
|
+
});
|
|
462
|
+
return Promise.resolve({ output: lines.join('\n'), isError: false });
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
//# sourceMappingURL=taskTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskTool.js","sourceRoot":"","sources":["../../src/tools/taskTool.ts"],"names":[],"mappings":"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"}
|