@narumitw/pi-subagents 0.25.0 → 0.26.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/src/subagents.ts CHANGED
@@ -14,37 +14,33 @@
14
14
 
15
15
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
16
16
  import { registerSubagentConfigCommand } from "./config-ui.js";
17
- import { SubagentParams } from "./params.js";
18
17
  import { executeSubagent } from "./execution.js";
18
+ import { SubagentParams } from "./params.js";
19
19
  import { renderSubagentCall, renderSubagentResult } from "./render.js";
20
20
  import type { SubagentDetails } from "./runner.js";
21
- import { registerStatefulSubagents } from "./stateful.js";
22
21
  import { consumeSubagentSettingsNotice, readSubagentSettings } from "./settings.js";
22
+ import { registerStatefulSubagents } from "./stateful.js";
23
23
 
24
24
  export default function (pi: ExtensionAPI) {
25
25
  pi.registerTool<typeof SubagentParams, SubagentDetails>({
26
26
  name: "subagent",
27
- label: "Subagent",
27
+ label: "Blocking Subagent",
28
28
  description: [
29
- "Delegate tasks to specialized subagents with isolated context.",
29
+ "Run specialized subagents as a blocking operation with isolated contexts.",
30
+ "The call blocks the main agent until every worker and optional aggregator finishes, so queued steering waits.",
30
31
  "Modes: single (agent + task), parallel (tasks array), chain (sequential with {previous} placeholder).",
31
32
  "Parallel mode may include an aggregator fan-in step that receives all task outputs.",
32
33
  'Default agent scope is "user" (from ~/.pi/agent/agents).',
33
34
  'To enable project-local agents in .pi/agents, pass agentScope: "both" (or "project") as a top-level argument for that call.',
34
35
  ].join(" "),
35
36
  promptSnippet:
36
- "Decide whether to spawn 0, 1, or multiple subagents for independent research, review, verification, or multi-step work in isolated Pi processes.",
37
+ "Run blocking isolated subagents only when their outputs are required before the main agent can continue.",
37
38
  promptGuidelines: [
38
39
  "Use subagent only when delegation fits; the main agent should decide how many subagents to spawn from task shape instead of waiting for the user to specify a count.",
39
- "Use no subagent for simple answers, quick targeted edits, latency-sensitive one-step work, tasks requiring frequent user back-and-forth, or critical-path work needed for the main agent's next action.",
40
- "A single blocking subagent call should be used only when independent context, high-volume output isolation, or an external review is worth waiting for; otherwise do the task in the main agent.",
41
- "For one-shot parallel work, use a single subagent call with tasks instead of repeated subagent_spawn calls, even when the user explicitly requests multiple agents.",
42
- "When subagent_spawn is available, use it only for a concrete bounded subtask that can run independently alongside useful main-agent work and has a parallel, isolation, or specialization benefit; otherwise keep the work in the main agent.",
43
- "After subagent_spawn returns, do useful non-overlapping work immediately. Call subagent_wait sparingly, only when the immediate next critical-path step requires the result and is blocked until it arrives; do not wait repeatedly by reflex.",
44
- "Consume and synthesize available subagent_spawn completion messages; interrupt or close agents that are no longer needed.",
45
- "Use subagent parallel mode with 2-4 parallel read-only subagents when work has broad independent branches; prefer scout or reviewer for fan-out and add an aggregator when synthesis helps.",
46
- "Use more than 4 subagent tasks only when clearly justified by distinct independent branches, and stay within the existing hard max 8 parallel tasks.",
47
- "Do not use subagent parallel mode for write-heavy implementation touching the same files or shared state; serialize those changes in the main agent or one worker.",
40
+ "Use no subagent for simple answers, quick targeted edits, latency-sensitive one-step work, tasks requiring frequent user back-and-forth, or critical-path work the main agent can perform directly.",
41
+ "Use the blocking subagent tool only when delegated outputs are required before the main agent's next action and waiting is intentional; the main agent cannot process queued steering until the call returns.",
42
+ "Use a blocking subagent single, parallel, chain, or fan-in call only when synchronous context or output isolation is worth making the main agent unavailable while it runs.",
43
+ "If a blocking parallel subagent call is genuinely required, keep tasks independent, stay within the hard max 8, and avoid write-heavy implementation touching the same files or shared state.",
48
44
  'Do not use subagent with project-local agents unless the user explicitly wants project agents or sets agentScope to "project" or "both"; keep confirmation enabled for untrusted repositories.',
49
45
  "When using subagent, write self-contained tasks with file paths, context, expected output, and whether the subagent may edit files.",
50
46
  ],
@@ -78,18 +74,22 @@ export default function (pi: ExtensionAPI) {
78
74
  if (notice) ctx.ui.notify(notice, "warning");
79
75
  });
80
76
 
81
- registerSubagentConfigCommand(pi);
82
- registerStatefulSubagents(pi);
77
+ const statefulRuntime = registerStatefulSubagents(pi);
78
+ registerSubagentConfigCommand(pi, statefulRuntime);
83
79
  }
80
+ export { parsePositiveInteger } from "./execution.js";
84
81
  export { formatTokens, formatUsageStats } from "./render.js";
85
82
  export { buildPiArgs } from "./runner.js";
86
83
  export {
84
+ inspectCompletionDeliverySettings,
87
85
  normalizeAgentSettings,
88
86
  normalizeSubagentSettings,
89
87
  readSubagentSettings,
90
88
  resolveSubagentThinkingLevel,
91
- saveSubagentConfig,
92
89
  sameToolSet,
90
+ saveSubagentConfig,
91
+ subagentSettingsFilePath,
93
92
  uniqueToolNames,
93
+ updateAgentToolsSetting,
94
+ updateCompletionDeliverySetting,
94
95
  } from "./settings.js";
95
- export { parsePositiveInteger } from "./execution.js";
@@ -1,19 +1,20 @@
1
- import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
- import { discoverAgents } from "./agents.js";
1
+ import { type AgentConfig, discoverAgents, type SubagentThinkingLevel } from "./agents.js";
3
2
  import type { ManagedAgent, TurnOutcome } from "./registry.js";
4
3
  import { getResultFinalOutput, runSingleAgent, type SubagentDetails } from "./runner.js";
5
4
  import { readSubagentSettings, resolveSubagentThinkingLevel } from "./settings.js";
6
- import {
7
- buildStatefulTurnPrompt,
8
- resolveStatefulTurnTimeout,
9
- } from "./stateful-prompt.js";
5
+ import { buildStatefulTurnPrompt, resolveStatefulTurnTimeout } from "./stateful-prompt.js";
10
6
  import type { SubagentTransport } from "./transport.js";
11
7
 
8
+ export function resolveStatefulSubprocessThinkingLevel(
9
+ agents: readonly Pick<AgentConfig, "name" | "thinkingLevel">[],
10
+ record: Pick<ManagedAgent, "agent" | "thinkingLevel">,
11
+ ): SubagentThinkingLevel | undefined {
12
+ return resolveSubagentThinkingLevel(agents, record.agent, record.thinkingLevel);
13
+ }
14
+
12
15
  export class SubprocessTransport implements SubagentTransport {
13
16
  readonly kind = "subprocess" as const;
14
17
 
15
- constructor(private readonly ctx: ExtensionContext) {}
16
-
17
18
  async runTurn(record: ManagedAgent, task: string, signal: AbortSignal): Promise<TurnOutcome> {
18
19
  const settings = readSubagentSettings();
19
20
  const discovery = discoverAgents(record.cwd, record.agentScope ?? "user", settings);
@@ -33,7 +34,7 @@ export class SubprocessTransport implements SubagentTransport {
33
34
  undefined,
34
35
  undefined,
35
36
  signal,
36
- resolveSubagentThinkingLevel(discovery.agents, record.agent),
37
+ resolveStatefulSubprocessThinkingLevel(discovery.agents, record),
37
38
  resolveStatefulTurnTimeout(agent),
38
39
  undefined,
39
40
  makeDetails,