@arhen/pi-core-subagent 1.3.50 → 1.3.51

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arhen/pi-core-subagent",
3
- "version": "1.3.50",
3
+ "version": "1.3.51",
4
4
  "type": "module",
5
5
  "description": "pi extension: fast in-process subagents with a dependency-graph scheduler (needs edges gate tasks and carry upstream output into dependent prompts), plus background runs, intercom and agent-to-agent mailbox. Leader defines agents inline.",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -128,21 +128,18 @@ export default function (pi: ExtensionAPI) {
128
128
  label: "Subagent",
129
129
 
130
130
  description:
131
- "Run isolated subagents (own context, own session). You invent each agent: name, optional system prompt, toolset (read-only default, write:true to edit). Use `agent`+`task` for one, `tasks` for many. `needs` declares dependency edges: a task waits for its needs and receives their outputs prepended to its prompt. If a user agent file in `.agents/agents`, `.claude/agents`, or `.pi/agents` (project dirs, then home) has a `description` matching the spawn goal (name + task), that file is authoritative: body = system prompt, frontmatter `model`/`tools` apply and inline prompt/model are ignored — except explicit per-call `tools`/`write`, which override the file's tools. No match → the inline definition stands. Write agents run in an isolated git worktree: on completion the result reports the branch + changed files — review, then merge with `git merge --no-ff <branch>` (merged branches are cleaned automatically). Every run is background: the call returns a runId immediately and completion notifies you — do NOT park waiting on it. If you have no other work, end your turn; the completion notice wakes you with the results. Set autoAwait:true only when the very next step in the SAME turn consumes the result. Children always carry talk tools: they can ask you questions, notify you, and message siblings.",
131
+ "Run isolated subagents (own context, own session) in the background: returns a runId immediately, completion notifies you. One call = one agent (`agent`+`task`) or many (`tasks`, or `chain` with `{previous}`). `needs` edges gate tasks and prepend upstream outputs to their prompts. A user agent file (`.agents/agents`, `.claude/agents`, `.pi/agents`; project dirs, then home) whose `description` matches the goal is authoritative: body = system prompt, frontmatter `model`/`tools` apply, but explicit per-call `tools`/`write` override the file's tools. Write agents get an isolated git worktree; the result reports the branch. Children always carry talk tools (ask/notify the leader, message siblings).",
132
132
  promptSnippet: "Define and delegate work to specialized subagents.",
133
133
  promptGuidelines: [
134
134
  "Use subagent when independent review, testing, research, or parallel analysis improves quality.",
135
- "Put every sub-task in ONE call: subagent({ tasks: [...] }). Never make multiple parallel subagent calls — one call, one run, N tasks.",
136
- "Order comes from `needs`, not from separate calls: give tasks an `id`, list the ids each depends on. Tasks with no unmet needs run in parallel; dependents receive their upstream outputs automatically — do not restate them.",
137
- "Prefer flat `tasks` (plain parallel) unless a real dependency exists — only add `needs` edges when ordering genuinely matters.",
138
- "End each task with a runnable check, e.g. 'Verify: npx tsc --noEmit && bun test'. A subagent's claim of success is not evidence.",
139
- "For write agents (write:true) in a git repo, the child works in an isolated worktree and its changes are committed to a branch — the result reports branch + changed files. Review the diff, then merge with `git merge --no-ff <branch>`; merged branches are cleaned up automatically. Never leave a worktree branch unmerged at the end of the task.",
140
- "Define each agent yourself: invented name, focused system prompt, and read-only (default) or write:true. Prefer read-only. A user agent file (`.agents/agents`, `.claude/agents`, `.pi/agents` — project first, then home) whose `description` matches the spawn goal (name + task) takes over: its body is the system prompt, frontmatter `model`/`tools` apply and are validated against the model registry — explicit per-call `tools`/`write` still override the file's tools. Matching is by description, not name — name the agent whatever fits the goal.",
141
- "Right after a background spawn, call subagent_status(runId) ONCE before any other work — confirm each task is running (or already progressing), not stuck queued or failed at startup. A child that dies on spawn otherwise stays invisible until far later.",
142
- "If that first status shows a task failed or never started, fix or respawn immediately; do not move on assuming it runs.",
143
- "Never block with nothing to do: if you have no work left after spawning, end your turn. Task completion notifies you and wakes a fresh turn with the results — await_subagent/autoAwait in that situation only burns time and tokens.",
144
- "autoAwait:true only when the same turn must consume the result immediately (e.g. you spawn a reviewer and then must act on its verdict before replying). Otherwise spawn background and read results from the completion notice, or subagent_result when you come back.",
145
- "await_subagent is for the rare case where you have parallel work of your own and need to sync at a specific point — not the default follow-up to a spawn.",
135
+ "Batch every sub-task in ONE call: subagent({ tasks: [...] }) — never multiple parallel subagent calls.",
136
+ "Declare ordering with `needs` edges on the tasks, never by splitting into separate calls; dependents receive upstream outputs automatically — do not restate them. Prefer flat `tasks` (plain parallel); add `needs` only when ordering genuinely matters.",
137
+ "End each task with a runnable check, e.g. 'Verify: bun test'. A subagent's claim of success is not evidence.",
138
+ "Write agents work in an isolated git worktree; their changes land on a branch — review the diff, then merge with `git merge --no-ff <branch>`. Never leave a worktree branch unmerged at the end of the task.",
139
+ "Define each agent inline: invented name, focused system prompt, read-only by default (write:true to edit). A matched agent file takes over (see description); matching is by description, not name — name the agent whatever fits the goal.",
140
+ "Right after spawning, call subagent_status(runId) ONCE before any other work — a child that died on spawn (or never started) is invisible until far later otherwise. If it shows a task failed/never started, fix or respawn immediately.",
141
+ "Never block with nothing to do: if you have no work left after spawning, end your turn — completion notifies you and wakes a fresh turn with the results. await_subagent/autoAwait while idle only burns time and tokens.",
142
+ "autoAwait:true only when this SAME turn must consume the result immediately. await_subagent is for syncing with your own parallel work — not the default follow-up to a spawn.",
146
143
  ],
147
144
  parameters: SubagentParams,
148
145
  executionMode: "parallel",
@@ -263,11 +260,8 @@ export default function (pi: ExtensionAPI) {
263
260
  name: "subagent_status",
264
261
  label: "Subagent Status",
265
262
  description:
266
- "Live status of a subagent run (non-blocking): per-task state, plus each child's session file path (JSONL) so you can tail it from outside — e.g. in a terminal multiplexer pane. Call this once right after spawning to verify the children actually started.",
263
+ "Live per-task status of a subagent run (non-blocking), incl. each child's session file path (JSONL) to `tail -f` from outside. Call once right after spawning to verify children actually started.",
267
264
  promptSnippet: "Check progress of a subagent run; use right after spawn as a health check.",
268
- promptGuidelines: [
269
- "Health-check every background spawn with one subagent_status(runId) before continuing — catch dead-on-arrival children early instead of at completion time.",
270
- ],
271
265
  parameters: RunIdParam,
272
266
  async execute(_id, params) {
273
267
  const { runId } = params as { runId: string };
@@ -313,10 +307,7 @@ export default function (pi: ExtensionAPI) {
313
307
  name: "await_subagent",
314
308
  label: "Await Subagent",
315
309
  description:
316
- "Block until a run finishes (or timeoutMs elapses). Use ONLY when you have work of your own to sync with; if you have nothing else to do, end your turn instead — completion notifies you and wakes a new turn with the results. While parked, child→leader messages (asks, notifies, completions) wake the wait and arrive INSIDE the result.",
317
- promptGuidelines: [
318
- "Do not call await_subagent right after spawning with no other work pending — end the turn and let the completion notice wake you.",
319
- ],
310
+ "Block until a run finishes (or timeoutMs elapses). Only when you have your own work to sync — otherwise end your turn; completion notifies you. While parked, child→leader messages (asks, notifies, completions) wake the wait and arrive inside the result.",
320
311
  parameters: AwaitParam,
321
312
  async execute(_id, params) {
322
313
  const { runId, timeoutMs } = params as { runId: string; timeoutMs?: number };
package/src/schemas.ts CHANGED
@@ -5,23 +5,17 @@ import { DEFAULT_CONCURRENCY, MAX_CONCURRENCY } from "./manager.ts";
5
5
  const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
6
6
  const TaskItem = Type.Object({
7
7
  id: Type.Optional(Type.String({ description: "Optional stable task id" })),
8
- agent: Type.String({
9
- minLength: 1,
10
- description:
11
- "Agent name you invent. Always define the agent inline: prompt (system prompt) + toolset (write: true for write access). Never create agent files.",
12
- }),
8
+ agent: Type.String({ minLength: 1, description: "Agent name you invent (defined inline via `prompt`)" }),
13
9
  task: Type.String({ minLength: 1, description: "Task for this agent" }),
14
- prompt: Type.Optional(
15
- Type.String({ description: "System prompt defining this agent's behavior. Optional — a minimal default is used." }),
16
- ),
10
+ prompt: Type.Optional(Type.String({ description: "System prompt defining this agent's behavior" })),
17
11
  write: Type.Optional(
18
12
  Type.Boolean({
19
- description: "true = write toolset (read, bash, edit, write); default false = read-only (read, grep, find, ls)",
13
+ description: "true = write toolset (adds bash, edit, write); default false = read-only (read, grep, find, ls)",
20
14
  }),
21
15
  ),
22
16
  model: Type.Optional(Type.String({ description: "Model override (provider/model-id)" })),
23
17
  thinking: Type.Optional(StringEnum(THINKING_LEVELS, { description: "Thinking level override" })),
24
- cwd: Type.Optional(Type.String({ description: "Working directory for this task. Default: current project." })),
18
+ cwd: Type.Optional(Type.String({ description: "Working directory (default: current project)" })),
25
19
  tools: Type.Optional(Type.Array(Type.String(), { description: "Explicit tool allowlist (overrides the toolset)" })),
26
20
  maxRuntimeMs: Type.Optional(Type.Number({ description: "Per-task timeout (ms)" })),
27
21
  needs: Type.Optional(
@@ -50,13 +44,12 @@ export const SubagentParams = Type.Object({
50
44
  maxRuntimeMs: Type.Optional(
51
45
  Type.Number({
52
46
  description:
53
- "Per-task timeout, ms. Omit unless a hard bound is genuinely required — a safety ceiling always applies (6 h, or 1 h with `/subagents auto-limit on`).",
47
+ "Per-task timeout, ms. Omit unless a hard bound is genuinely required — a ceiling always applies (6 h, or 1 h with `/subagents auto-limit on`).",
54
48
  }),
55
49
  ),
56
50
  autoAwait: Type.Optional(
57
51
  Type.Boolean({
58
- description:
59
- "Start the run in the background, then park this tool call until it finishes and return the final result inline (runId + summary in one response). Default false.",
52
+ description: "Park this call until the run finishes and return the result inline. Default false.",
60
53
  }),
61
54
  ),
62
55
  notifyPerTask: Type.Optional(