@tintinweb/pi-subagents 0.3.1 → 0.4.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/CHANGELOG.md CHANGED
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.1] - 2026-03-11
9
+
10
+ ### Fixed
11
+ - **Graceful shutdown in headless mode** — the CLI now waits for all running and queued background agents to complete before exiting (`waitForAll` on `session_shutdown`). Previously, background agents could be silently killed mid-execution when the session ended. Only affects headless/non-interactive mode; interactive sessions already kept the process alive.
12
+
13
+ ### Added
14
+ - `hasRunning()` / `waitForAll()` methods on `AgentManager`.
15
+ - **Cross-package manager access** — agent manager exposed via `Symbol.for("pi-subagents:manager")` on `globalThis` for other extensions to check status or await completion.
16
+
17
+ ## [0.4.0] - 2026-03-11
18
+
19
+ ### Added
20
+ - **XML-delimited prompt sections** — append-mode agents now wrap inherited content in `<inherited_system_prompt>`, `<sub_agent_context>`, and `<agent_instructions>` XML tags, giving the model explicit structure to distinguish inherited rules from sub-agent-specific instructions. Replace mode is unchanged.
21
+ - **Token count in agent results** — foreground agent results, background completion notifications, and `get_subagent_result` now include the token count alongside tool uses and duration (e.g. `Agent completed in 4.2s (12 tool uses, 33.8k token)`).
22
+ - **Widget overflow cap** — the running agents widget now caps at 12 lines. When exceeded, running agents are prioritized over finished ones and an overflow summary line shows hidden counts (e.g. `+3 more (1 running, 2 finished)`).
23
+
24
+ ### Changed - **changing behavior**
25
+ - **General-purpose agent inherits parent prompt** — the default `general-purpose` agent now uses `promptMode: "append"` with an empty system prompt, making it a "parent twin" that inherits the full parent system prompt (including CLAUDE.md rules, project conventions, and safety guardrails). Previously it used a standalone prompt that duplicated a subset of the parent's rules. Explore and Plan are unchanged (standalone prompts). To customize: eject via `/agents` → select `general-purpose` → Eject, then edit the resulting `.md` file. Set `prompt_mode: replace` to go back to a standalone prompt, or keep `prompt_mode: append` and add extra instructions in the body.
26
+ - **Append-mode agents receive parent system prompt** — `buildAgentPrompt` now accepts the parent's system prompt and threads it into append-mode agents (env header + parent prompt + sub-agent context bridge + optional custom instructions). Replace-mode agents are unchanged.
27
+ - **Prompt pipeline simplified** — removed `systemPromptOverride`/`systemPromptAppend` from `SpawnOptions` and `RunOptions`. These were a separate code path where `index.ts` pre-resolved the prompt mode and passed raw strings into the runner, bypassing `buildAgentPrompt`. Now all prompt assembly flows through `buildAgentPrompt` using the agent's `promptMode` config — one code path, no special cases.
28
+
29
+ ### Removed
30
+ - Deprecated backwards-compat aliases: `registerCustomAgents`, `getCustomAgentConfig`, `getCustomAgentNames` (use `registerAgents`, `getAgentConfig`, `getUserAgentNames`).
31
+ - `resolveCustomPrompt()` helper in index.ts — no longer needed now that prompt routing is config-driven.
32
+
8
33
  ## [0.3.1] - 2026-03-09
9
34
 
10
35
  ### Added
@@ -139,7 +164,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
139
164
  ### Added
140
165
  - **Claude Code-style UI rendering** — `renderCall`/`renderResult`/`onUpdate` for live streaming progress
141
166
  - Live activity descriptions: "searching, reading 3 files…"
142
- - Token count display: "33.8k tokens"
167
+ - Token count display: "33.8k token"
143
168
  - Per-agent tool use counter
144
169
  - Expandable completed results (ctrl+o)
145
170
  - Distinct states: running, background, completed, error, aborted
@@ -172,6 +197,9 @@ Initial release.
172
197
  - **Thinking level** — per-agent extended thinking control
173
198
  - **`/agent` and `/agents` commands**
174
199
 
200
+ [0.4.1]: https://github.com/tintinweb/pi-subagents/compare/v0.4.0...v0.4.1
201
+ [0.4.0]: https://github.com/tintinweb/pi-subagents/compare/v0.3.1...v0.4.0
202
+ [0.3.1]: https://github.com/tintinweb/pi-subagents/compare/v0.3.0...v0.3.1
175
203
  [0.3.0]: https://github.com/tintinweb/pi-subagents/compare/v0.2.7...v0.3.0
176
204
  [0.2.7]: https://github.com/tintinweb/pi-subagents/compare/v0.2.6...v0.2.7
177
205
  [0.2.6]: https://github.com/tintinweb/pi-subagents/compare/v0.2.5...v0.2.6
package/README.md CHANGED
@@ -57,9 +57,9 @@ The extension renders a persistent widget above the editor showing all active ag
57
57
 
58
58
  ```
59
59
  ● Agents
60
- ├─ ⠹ Agent Refactor auth module · 5 tool uses · 33.8k tokens · 12.3s
60
+ ├─ ⠹ Agent Refactor auth module · 5 tool uses · 33.8k token · 12.3s
61
61
  │ ⎿ editing 2 files…
62
- ├─ ⠹ Explore Find auth files · 3 tool uses · 12.4k tokens · 4.1s
62
+ ├─ ⠹ Explore Find auth files · 3 tool uses · 12.4k token · 4.1s
63
63
  │ ⎿ searching…
64
64
  └─ 2 queued
65
65
  ```
@@ -68,24 +68,26 @@ Individual agent results render Claude Code-style in the conversation:
68
68
 
69
69
  | State | Example |
70
70
  |-------|---------|
71
- | **Running** | `⠹ 3 tool uses · 12.4k tokens` / `⎿ searching, reading 3 files…` |
72
- | **Completed** | `✓ 5 tool uses · 33.8k tokens · 12.3s` / `⎿ Done` |
73
- | **Wrapped up** | `✓ 50 tool uses · 89.1k tokens · 45.2s` / `⎿ Wrapped up (turn limit)` |
74
- | **Stopped** | `■ 3 tool uses · 12.4k tokens` / `⎿ Stopped` |
75
- | **Error** | `✗ 3 tool uses · 12.4k tokens` / `⎿ Error: timeout` |
76
- | **Aborted** | `✗ 55 tool uses · 102.3k tokens` / `⎿ Aborted (max turns exceeded)` |
71
+ | **Running** | `⠹ 3 tool uses · 12.4k token` / `⎿ searching, reading 3 files…` |
72
+ | **Completed** | `✓ 5 tool uses · 33.8k token · 12.3s` / `⎿ Done` |
73
+ | **Wrapped up** | `✓ 50 tool uses · 89.1k token · 45.2s` / `⎿ Wrapped up (turn limit)` |
74
+ | **Stopped** | `■ 3 tool uses · 12.4k token` / `⎿ Stopped` |
75
+ | **Error** | `✗ 3 tool uses · 12.4k token` / `⎿ Error: timeout` |
76
+ | **Aborted** | `✗ 55 tool uses · 102.3k token` / `⎿ Aborted (max turns exceeded)` |
77
77
 
78
78
  Completed results can be expanded (ctrl+o in pi) to show the full agent output inline.
79
79
 
80
80
  ## Default Agent Types
81
81
 
82
- | Type | Tools | Model | Description |
83
- |------|-------|-------|-------------|
84
- | `general-purpose` | all 7 | inherit | Full read/write access for complex multi-step tasks |
85
- | `Explore` | read, bash, grep, find, ls | haiku (falls back to inherit) | Fast codebase exploration (read-only) |
86
- | `Plan` | read, bash, grep, find, ls | inherit | Software architect for implementation planning (read-only) |
82
+ | Type | Tools | Model | Prompt Mode | Description |
83
+ |------|-------|-------|-------------|-------------|
84
+ | `general-purpose` | all 7 | inherit | `append` (parent twin) | Inherits the parent's full system prompt — same rules, CLAUDE.md, project conventions |
85
+ | `Explore` | read, bash, grep, find, ls | haiku (falls back to inherit) | `replace` (standalone) | Fast codebase exploration (read-only) |
86
+ | `Plan` | read, bash, grep, find, ls | inherit | `replace` (standalone) | Software architect for implementation planning (read-only) |
87
87
 
88
- Default agents can be **overridden** by creating a `.md` file with the same name (e.g. `.pi/agents/Explore.md`), or **disabled** per-project by creating a `.md` file with `enabled: false` frontmatter.
88
+ The `general-purpose` agent is a **parent twin** it receives the parent's entire system prompt plus a sub-agent context bridge, so it follows the same rules the parent does. Explore and Plan use standalone prompts tailored to their read-only roles.
89
+
90
+ Default agents can be **ejected** (`/agents` → select agent → Eject) to export them as `.md` files for customization, **overridden** by creating a `.md` file with the same name (e.g. `.pi/agents/general-purpose.md`), or **disabled** per-project with `enabled: false` frontmatter.
89
91
 
90
92
  ## Custom Agents
91
93
 
@@ -140,7 +142,7 @@ All fields are optional — sensible defaults for everything.
140
142
  | `model` | inherit parent | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`) |
141
143
  | `thinking` | inherit | off, minimal, low, medium, high, xhigh |
142
144
  | `max_turns` | 50 | Max agentic turns before graceful shutdown |
143
- | `prompt_mode` | `replace` | `replace`: body is the full system prompt. `append`: body appended to default prompt |
145
+ | `prompt_mode` | `replace` | `replace`: body is the full system prompt. `append`: body appended to parent's prompt (agent acts as a "parent twin" with optional extra instructions) |
144
146
  | `inherit_context` | `false` | Fork parent conversation into agent |
145
147
  | `run_in_background` | `false` | Run in background by default |
146
148
  | `isolated` | `false` | No extension/MCP tools, only built-in |
@@ -0,0 +1,70 @@
1
+ /**
2
+ * agent-manager.ts — Tracks agents, background execution, resume support.
3
+ *
4
+ * Background agents are subject to a configurable concurrency limit (default: 4).
5
+ * Excess agents are queued and auto-started as running agents complete.
6
+ * Foreground agents bypass the queue (they block the parent anyway).
7
+ */
8
+ import type { ExtensionContext, ExtensionAPI } from "@mariozechner/pi-coding-agent";
9
+ import type { Model } from "@mariozechner/pi-ai";
10
+ import type { AgentSession } from "@mariozechner/pi-coding-agent";
11
+ import { type ToolActivity } from "./agent-runner.js";
12
+ import type { SubagentType, AgentRecord, ThinkingLevel } from "./types.js";
13
+ export type OnAgentComplete = (record: AgentRecord) => void;
14
+ interface SpawnOptions {
15
+ description: string;
16
+ model?: Model<any>;
17
+ maxTurns?: number;
18
+ isolated?: boolean;
19
+ inheritContext?: boolean;
20
+ thinkingLevel?: ThinkingLevel;
21
+ isBackground?: boolean;
22
+ /** Called on tool start/end with activity info (for streaming progress to UI). */
23
+ onToolActivity?: (activity: ToolActivity) => void;
24
+ /** Called on streaming text deltas from the assistant response. */
25
+ onTextDelta?: (delta: string, fullText: string) => void;
26
+ /** Called when the agent session is created (for accessing session stats). */
27
+ onSessionCreated?: (session: AgentSession) => void;
28
+ }
29
+ export declare class AgentManager {
30
+ private agents;
31
+ private cleanupInterval;
32
+ private onComplete?;
33
+ private maxConcurrent;
34
+ /** Queue of background agents waiting to start. */
35
+ private queue;
36
+ /** Number of currently running background agents. */
37
+ private runningBackground;
38
+ constructor(onComplete?: OnAgentComplete, maxConcurrent?: number);
39
+ /** Update the max concurrent background agents limit. */
40
+ setMaxConcurrent(n: number): void;
41
+ getMaxConcurrent(): number;
42
+ /**
43
+ * Spawn an agent and return its ID immediately (for background use).
44
+ * If the concurrency limit is reached, the agent is queued.
45
+ */
46
+ spawn(pi: ExtensionAPI, ctx: ExtensionContext, type: SubagentType, prompt: string, options: SpawnOptions): string;
47
+ /** Actually start an agent (called immediately or from queue drain). */
48
+ private startAgent;
49
+ /** Start queued agents up to the concurrency limit. */
50
+ private drainQueue;
51
+ /**
52
+ * Spawn an agent and wait for completion (foreground use).
53
+ * Foreground agents bypass the concurrency queue.
54
+ */
55
+ spawnAndWait(pi: ExtensionAPI, ctx: ExtensionContext, type: SubagentType, prompt: string, options: Omit<SpawnOptions, "isBackground">): Promise<AgentRecord>;
56
+ /**
57
+ * Resume an existing agent session with a new prompt.
58
+ */
59
+ resume(id: string, prompt: string, signal?: AbortSignal): Promise<AgentRecord | undefined>;
60
+ getRecord(id: string): AgentRecord | undefined;
61
+ listAgents(): AgentRecord[];
62
+ abort(id: string): boolean;
63
+ private cleanup;
64
+ /** Whether any agents are still running or queued. */
65
+ hasRunning(): boolean;
66
+ /** Wait for all running and queued agents to complete (including queued ones). */
67
+ waitForAll(): Promise<void>;
68
+ dispose(): void;
69
+ }
70
+ export {};
@@ -0,0 +1,236 @@
1
+ /**
2
+ * agent-manager.ts — Tracks agents, background execution, resume support.
3
+ *
4
+ * Background agents are subject to a configurable concurrency limit (default: 4).
5
+ * Excess agents are queued and auto-started as running agents complete.
6
+ * Foreground agents bypass the queue (they block the parent anyway).
7
+ */
8
+ import { randomUUID } from "node:crypto";
9
+ import { runAgent, resumeAgent } from "./agent-runner.js";
10
+ /** Default max concurrent background agents. */
11
+ const DEFAULT_MAX_CONCURRENT = 4;
12
+ export class AgentManager {
13
+ agents = new Map();
14
+ cleanupInterval;
15
+ onComplete;
16
+ maxConcurrent;
17
+ /** Queue of background agents waiting to start. */
18
+ queue = [];
19
+ /** Number of currently running background agents. */
20
+ runningBackground = 0;
21
+ constructor(onComplete, maxConcurrent = DEFAULT_MAX_CONCURRENT) {
22
+ this.onComplete = onComplete;
23
+ this.maxConcurrent = maxConcurrent;
24
+ // Cleanup completed agents after 10 minutes (but keep sessions for resume)
25
+ this.cleanupInterval = setInterval(() => this.cleanup(), 60_000);
26
+ }
27
+ /** Update the max concurrent background agents limit. */
28
+ setMaxConcurrent(n) {
29
+ this.maxConcurrent = Math.max(1, n);
30
+ // Start queued agents if the new limit allows
31
+ this.drainQueue();
32
+ }
33
+ getMaxConcurrent() {
34
+ return this.maxConcurrent;
35
+ }
36
+ /**
37
+ * Spawn an agent and return its ID immediately (for background use).
38
+ * If the concurrency limit is reached, the agent is queued.
39
+ */
40
+ spawn(pi, ctx, type, prompt, options) {
41
+ const id = randomUUID().slice(0, 17);
42
+ const abortController = new AbortController();
43
+ const record = {
44
+ id,
45
+ type,
46
+ description: options.description,
47
+ status: options.isBackground ? "queued" : "running",
48
+ toolUses: 0,
49
+ startedAt: Date.now(),
50
+ abortController,
51
+ };
52
+ this.agents.set(id, record);
53
+ const args = { pi, ctx, type, prompt, options };
54
+ if (options.isBackground && this.runningBackground >= this.maxConcurrent) {
55
+ // Queue it — will be started when a running agent completes
56
+ this.queue.push({ id, args });
57
+ return id;
58
+ }
59
+ this.startAgent(id, record, args);
60
+ return id;
61
+ }
62
+ /** Actually start an agent (called immediately or from queue drain). */
63
+ startAgent(id, record, { pi, ctx, type, prompt, options }) {
64
+ record.status = "running";
65
+ record.startedAt = Date.now();
66
+ if (options.isBackground)
67
+ this.runningBackground++;
68
+ const promise = runAgent(ctx, type, prompt, {
69
+ pi,
70
+ model: options.model,
71
+ maxTurns: options.maxTurns,
72
+ isolated: options.isolated,
73
+ inheritContext: options.inheritContext,
74
+ thinkingLevel: options.thinkingLevel,
75
+ signal: record.abortController.signal,
76
+ onToolActivity: (activity) => {
77
+ if (activity.type === "end")
78
+ record.toolUses++;
79
+ options.onToolActivity?.(activity);
80
+ },
81
+ onTextDelta: options.onTextDelta,
82
+ onSessionCreated: (session) => {
83
+ record.session = session;
84
+ options.onSessionCreated?.(session);
85
+ },
86
+ })
87
+ .then(({ responseText, session, aborted, steered }) => {
88
+ // Don't overwrite status if externally stopped via abort()
89
+ if (record.status !== "stopped") {
90
+ record.status = aborted ? "aborted" : steered ? "steered" : "completed";
91
+ }
92
+ record.result = responseText;
93
+ record.session = session;
94
+ record.completedAt ??= Date.now();
95
+ if (options.isBackground) {
96
+ this.runningBackground--;
97
+ this.onComplete?.(record);
98
+ this.drainQueue();
99
+ }
100
+ return responseText;
101
+ })
102
+ .catch((err) => {
103
+ // Don't overwrite status if externally stopped via abort()
104
+ if (record.status !== "stopped") {
105
+ record.status = "error";
106
+ }
107
+ record.error = err instanceof Error ? err.message : String(err);
108
+ record.completedAt ??= Date.now();
109
+ if (options.isBackground) {
110
+ this.runningBackground--;
111
+ this.onComplete?.(record);
112
+ this.drainQueue();
113
+ }
114
+ return "";
115
+ });
116
+ record.promise = promise;
117
+ }
118
+ /** Start queued agents up to the concurrency limit. */
119
+ drainQueue() {
120
+ while (this.queue.length > 0 && this.runningBackground < this.maxConcurrent) {
121
+ const next = this.queue.shift();
122
+ const record = this.agents.get(next.id);
123
+ if (!record || record.status !== "queued")
124
+ continue;
125
+ this.startAgent(next.id, record, next.args);
126
+ }
127
+ }
128
+ /**
129
+ * Spawn an agent and wait for completion (foreground use).
130
+ * Foreground agents bypass the concurrency queue.
131
+ */
132
+ async spawnAndWait(pi, ctx, type, prompt, options) {
133
+ const id = this.spawn(pi, ctx, type, prompt, { ...options, isBackground: false });
134
+ const record = this.agents.get(id);
135
+ await record.promise;
136
+ return record;
137
+ }
138
+ /**
139
+ * Resume an existing agent session with a new prompt.
140
+ */
141
+ async resume(id, prompt, signal) {
142
+ const record = this.agents.get(id);
143
+ if (!record?.session)
144
+ return undefined;
145
+ record.status = "running";
146
+ record.startedAt = Date.now();
147
+ record.completedAt = undefined;
148
+ record.result = undefined;
149
+ record.error = undefined;
150
+ try {
151
+ const responseText = await resumeAgent(record.session, prompt, {
152
+ onToolActivity: (activity) => {
153
+ if (activity.type === "end")
154
+ record.toolUses++;
155
+ },
156
+ signal,
157
+ });
158
+ record.status = "completed";
159
+ record.result = responseText;
160
+ record.completedAt = Date.now();
161
+ }
162
+ catch (err) {
163
+ record.status = "error";
164
+ record.error = err instanceof Error ? err.message : String(err);
165
+ record.completedAt = Date.now();
166
+ }
167
+ return record;
168
+ }
169
+ getRecord(id) {
170
+ return this.agents.get(id);
171
+ }
172
+ listAgents() {
173
+ return [...this.agents.values()].sort((a, b) => b.startedAt - a.startedAt);
174
+ }
175
+ abort(id) {
176
+ const record = this.agents.get(id);
177
+ if (!record)
178
+ return false;
179
+ // Remove from queue if queued
180
+ if (record.status === "queued") {
181
+ this.queue = this.queue.filter(q => q.id !== id);
182
+ record.status = "stopped";
183
+ record.completedAt = Date.now();
184
+ return true;
185
+ }
186
+ if (record.status !== "running")
187
+ return false;
188
+ record.abortController?.abort();
189
+ record.status = "stopped";
190
+ record.completedAt = Date.now();
191
+ return true;
192
+ }
193
+ cleanup() {
194
+ const cutoff = Date.now() - 10 * 60_000;
195
+ for (const [id, record] of this.agents) {
196
+ if (record.status === "running" || record.status === "queued")
197
+ continue;
198
+ if ((record.completedAt ?? 0) >= cutoff)
199
+ continue;
200
+ // Dispose and clear session so memory can be reclaimed
201
+ if (record.session) {
202
+ record.session.dispose();
203
+ record.session = undefined;
204
+ }
205
+ this.agents.delete(id);
206
+ }
207
+ }
208
+ /** Whether any agents are still running or queued. */
209
+ hasRunning() {
210
+ return [...this.agents.values()].some(r => r.status === "running" || r.status === "queued");
211
+ }
212
+ /** Wait for all running and queued agents to complete (including queued ones). */
213
+ async waitForAll() {
214
+ // Loop because drainQueue respects the concurrency limit — as running
215
+ // agents finish they start queued ones, which need awaiting too.
216
+ while (true) {
217
+ this.drainQueue();
218
+ const pending = [...this.agents.values()]
219
+ .filter(r => r.status === "running" || r.status === "queued")
220
+ .map(r => r.promise)
221
+ .filter(Boolean);
222
+ if (pending.length === 0)
223
+ break;
224
+ await Promise.allSettled(pending);
225
+ }
226
+ }
227
+ dispose() {
228
+ clearInterval(this.cleanupInterval);
229
+ // Clear queue
230
+ this.queue = [];
231
+ for (const record of this.agents.values()) {
232
+ record.session?.dispose();
233
+ }
234
+ this.agents.clear();
235
+ }
236
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * agent-runner.ts — Core execution engine: creates sessions, runs agents, collects results.
3
+ */
4
+ import { type AgentSession, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
5
+ import type { ExtensionContext } from "@mariozechner/pi-coding-agent";
6
+ import type { Model } from "@mariozechner/pi-ai";
7
+ import type { SubagentType, ThinkingLevel } from "./types.js";
8
+ /** Get the default max turns value. */
9
+ export declare function getDefaultMaxTurns(): number;
10
+ /** Set the default max turns value (minimum 1). */
11
+ export declare function setDefaultMaxTurns(n: number): void;
12
+ /** Get the grace turns value. */
13
+ export declare function getGraceTurns(): number;
14
+ /** Set the grace turns value (minimum 1). */
15
+ export declare function setGraceTurns(n: number): void;
16
+ /** Info about a tool event in the subagent. */
17
+ export interface ToolActivity {
18
+ type: "start" | "end";
19
+ toolName: string;
20
+ }
21
+ export interface RunOptions {
22
+ /** ExtensionAPI instance — used for pi.exec() instead of execSync. */
23
+ pi: ExtensionAPI;
24
+ model?: Model<any>;
25
+ maxTurns?: number;
26
+ signal?: AbortSignal;
27
+ isolated?: boolean;
28
+ inheritContext?: boolean;
29
+ thinkingLevel?: ThinkingLevel;
30
+ /** Called on tool start/end with activity info. */
31
+ onToolActivity?: (activity: ToolActivity) => void;
32
+ /** Called on streaming text deltas from the assistant response. */
33
+ onTextDelta?: (delta: string, fullText: string) => void;
34
+ onSessionCreated?: (session: AgentSession) => void;
35
+ }
36
+ export interface RunResult {
37
+ responseText: string;
38
+ session: AgentSession;
39
+ /** True if the agent was hard-aborted (max_turns + grace exceeded). */
40
+ aborted: boolean;
41
+ /** True if the agent was steered to wrap up (hit soft turn limit) but finished in time. */
42
+ steered: boolean;
43
+ }
44
+ export declare function runAgent(ctx: ExtensionContext, type: SubagentType, prompt: string, options: RunOptions): Promise<RunResult>;
45
+ /**
46
+ * Send a new prompt to an existing session (resume).
47
+ */
48
+ export declare function resumeAgent(session: AgentSession, prompt: string, options?: {
49
+ onToolActivity?: (activity: ToolActivity) => void;
50
+ signal?: AbortSignal;
51
+ }): Promise<string>;
52
+ /**
53
+ * Send a steering message to a running subagent.
54
+ * The message will interrupt the agent after its current tool execution.
55
+ */
56
+ export declare function steerAgent(session: AgentSession, message: string): Promise<void>;
57
+ /**
58
+ * Get the subagent's conversation messages as formatted text.
59
+ */
60
+ export declare function getAgentConversation(session: AgentSession): string;