@tduyng/pi-subagent 0.0.3 → 0.0.4

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.
Files changed (2) hide show
  1. package/README.md +50 -65
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,48 +1,20 @@
1
1
  # @tduyng/pi-subagent
2
2
 
3
- A subagent that stays small on purpose. It reads docs, logs, and source with a cheap model, returns one answer, and none of that reading lands in your context.
3
+ A subagent that stays small on purpose. It reads docs, logs and source on a cheap model, returns one answer, and leaves none of that reading in the parent's context.
4
4
 
5
- ## What it costs
5
+ A session spends most of its tokens reading. A question about which files build a retry policy has a paragraph for an answer and 40 KB of source behind it, and the parent carries that 40 KB into every later turn. The child's context dies with the task, so the cost of a delegation is bounded by its answer.
6
6
 
7
- One tool, `subagent`, at 379 tokens a request. The bulk-read guard and the log reducer are event handlers, so they add no schema and no prompt text.
7
+ Fanning four edit-capable children over one change is the case this is not for. Every child builds its own system prompt and tool list, and their edits still have to be reconciled.
8
8
 
9
- The child is a separate session with its own context that dies with the task. A parent that would have carried 40 KB of file dumps carries one paragraph and a file list instead, and every later turn of the parent pays for the paragraph rather than the dumps.
9
+ 379 tokens a request for the tool. The bulk-read guard and the log reducer are event handlers, so they add no schema and no prompt text.
10
10
 
11
- ## What it is for
12
-
13
- Not parallel implementation. Fanning four edit-capable children out over one change costs more than doing it in the parent: every child builds its own system prompt and tool list, and their edits still have to be reconciled.
14
-
15
- The cheap and safe case is reading: search twenty files, trace one call path, read a build log, summarize a doc. That is where a session spends its turns and its tokens, and it is the work a cheap model does as well as a frontier one.
11
+ ## The tool
16
12
 
17
13
  ```text
18
- subagent(task: "Which files construct the retry policy? Return path:line for each.",
19
- agent: "scout")
14
+ subagent(task: "Which files construct the retry policy? Return path:line for each.", agent: "scout")
20
15
  ```
21
16
 
22
- ## Scout ships with it
23
-
24
- `agents/scout.md` is bundled, so `agent: "scout"` works with no setup and no profile of your own. The default when you omit `agent` is scout, so the cheap read-only child is what you get by typing less.
25
-
26
- Scout carries `tools: read, grep, find, ls`, `inheritSkills: false`, and `thinking: low`. It never edits, never runs a command, never reaches the network, and answers in a fixed `STATUS / FINDING / NEXT` shape with file:line evidence.
27
-
28
- Override it by dropping your own copy in `~/.pi/agent/agents/scout.md` or `.pi/agents/scout.md`. A project file shadows a user file, and both shadow the bundled one. Copy the [bundled profile](agents/scout.md) as the starting point.
29
-
30
- ## Point the child at a cheap model
31
-
32
- The child inherits the parent's model unless you say otherwise, and inheriting defeats the point. Set it once:
33
-
34
- ```json
35
- {
36
- "model": "claude/claude-haiku-5-5",
37
- "thinking": "low"
38
- }
39
- ```
40
-
41
- `~/.pi/agent/subagent.json` sets the default, `.pi/subagent.json` overrides either field per project. Both fields are optional. `thinking` is one of `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, default `medium`. A `model` on the profile wins over the file.
42
-
43
- ## Tasks
44
-
45
- The `subagent` tool takes one task or up to 8, with at most 4 running at once. Each child sees one prompt and returns one message.
17
+ One task or up to 8, at most 4 running at once.
46
18
 
47
19
  | Field | Meaning |
48
20
  | --- | --- |
@@ -54,47 +26,56 @@ The `subagent` tool takes one task or up to 8, with at most 4 running at once. E
54
26
  | `context` | `fork` to replay the parent's history into the child |
55
27
  | `resume` | Task id, or `all`, to continue a stopped child |
56
28
 
57
- `label`, `thinking`, `model`, `timeoutMs`, and `maxTurns` are profile policy rather than model choices. A scripted caller can still pass them, and they still work.
29
+ ## Scout
30
+
31
+ `agents/scout.md` is bundled, so `agent: "scout"` works with no setup and no profile. It is also the default when no agent is named, so the cheap read-only child is what a plain call gets.
32
+
33
+ Scout carries `tools: read, grep, find, ls`, `inheritSkills: false`, and `thinking: low`. It never edits, never runs a command, never reaches the network, and answers in a fixed `STATUS / FINDING / NEXT` shape with file:line evidence.
34
+
35
+ Override it with a copy in `~/.pi/agent/agents/scout.md` or `.pi/agents/scout.md`. A project file shadows a user file, and both shadow the bundled one.
58
36
 
59
- ### Resume instead of re-reading
37
+ The child inherits the parent's model unless told otherwise, which defeats the point. Set it once in `~/.pi/agent/subagent.json`:
60
38
 
61
- A child that hits its turn budget is told to wrap up and gets a fresh budget in the same session, so a cap never turns work into a failure. If it still stops early its last text comes back marked `[partial answer]`, and salvage walks the whole transcript for it, so a child stopped mid tool-burst still returns what it wrote.
39
+ ```json
40
+ {
41
+ "model": "claude/claude-haiku-5-5",
42
+ "thinking": "low"
43
+ }
44
+ ```
62
45
 
63
- Every failed task prints a `resume:` id. Pass it back to continue where the child stopped instead of paying for the investigation again. An optional `task` alongside `resume` steers the continuation. Failed sessions are kept 30 minutes, completed ones 5.
46
+ `.pi/subagent.json` overrides either field per project. A `model` on the profile wins over the file, so a judgment role such as `verifier` can opt out and ask for a strong model.
64
47
 
65
- A deadline is reported as a timeout, not a cancellation: pi keeps any final text produced before it and marks it partial.
48
+ ## A stopped child is resumable
66
49
 
67
- Every run also writes `run.json` under `<agent-dir>/subagents/<session-id>/<run-id>/` with the task prompt, model, tools, and the path to each child session, rewritten after each transition. Reopening the session reads it back: a child interrupted less than ten minutes ago is resumed from its saved session and its answer arrives as a `subagent-durable` message, and older interruptions are listed with their resume ids. `resume` therefore works after a restart, not only inside the process that started the child.
50
+ A child that hits its turn budget is told to wrap up and gets a fresh budget in the same session, so a cap never turns work into a failure. If it still stops early, its last text comes back marked `[partial answer]`, recovered by walking the whole transcript, so a child stopped mid tool-burst still returns what it wrote.
68
51
 
69
- ### Worktree isolation
52
+ Every failed task prints a `resume:` id. Passing it back continues where the child stopped instead of paying for the investigation again. Failed sessions are kept 30 minutes and completed ones 5.
70
53
 
71
- With `isolation: "worktree"` each child runs in its own git worktree on a branch named `pi-task-<id>`, so concurrent children never edit the same checkout and a commit the child makes outlives it. The result names the branch. This is also the answer to two sessions committing in one repo, which no path reservation can cover.
54
+ Every run writes `run.json` under `<agent-dir>/subagents/<session-id>/<run-id>/` with the task, model, tools and the path to each child session. Reopening the session reads it back: a child interrupted less than ten minutes ago is resumed from its saved session and its answer arrives as a `subagent-durable` message, and older interruptions are listed with their resume ids. `resume` therefore works after a restart.
72
55
 
73
- ### Structured output
56
+ ## Worktrees, schemas, forks
74
57
 
75
- Pass `schema` to ask the child to call `structured_output` exactly once. The parsed payload comes back in the task result. A child that finishes without calling it is re-prompted in the same session up to three times, so the investigation is not paid for twice. If it still refuses, the text answer stands and the task completes marked partial. If a provider rejects the schema tool, the extension removes it and retries once as plain text.
58
+ `isolation: "worktree"` runs each child in its own git worktree on a branch named `pi-task-<id>`, so concurrent children never edit the same checkout and a commit the child makes outlives it. The result names the branch. This is also the answer to two sessions committing in one repository, which no path reservation covers.
76
59
 
77
- ### Fork context
60
+ `schema` asks the child to call `structured_output` exactly once, and the parsed payload comes back in the task result. A child that finishes without calling it is re-prompted in the same session up to three times, so the investigation is not paid for twice. If it still refuses, the text answer stands and the task completes marked partial. If a provider rejects the schema tool, the extension removes it and retries once as plain text.
78
61
 
79
62
  `context: "fork"` replays the parent's conversation history into the child as context entries.
80
63
 
81
- ## Profiles
82
-
83
- A profile is a markdown file with YAML frontmatter in `~/.pi/agent/agents/`, in `.pi/agents/`, or bundled. It sets the tool list, model, thinking level, limits, and an optional color for the widget, plus `inheritProjectContext` and `inheritSkills` to decide what the child picks up from the parent, and `systemPromptMode: replace` to swap the default system prompt instead of appending to it.
64
+ ## Two guards on the parent
84
65
 
85
- `/agents` lists them. The `subagent` widget shows up to 8 running and recently finished children with a status summary line: Down and Up to move, Enter to open a live transcript, d or x to dismiss.
66
+ **Bulk read.** The guard blocks a read of a file above `BULK_READ_MIN_LINES` lines (default 350), and blocks `cat`, `less` or `more` that would dump a large file. The block names `outline` first, so the model fetches a map of declarations rather than the text. The second call for the same path passes, and so does a read that returns fewer lines than the threshold, whether from a `limit`, an `offset`, a small file, or `head` and `tail` on their 10-line default.
86
67
 
87
- Children cannot spawn their own subagents.
68
+ **Log reducer.** The reducer replaces a build or test log above 4,096 bytes from a diagnostic command with a short receipt of quoted lines. It verifies every quote byte for byte against the archived original, and if validation fails the full log reaches the model untouched. It runs on `tool_result`, so the swap happens before the result enters history, and the raw log is archived next to the session.
88
69
 
89
- ## Bulk-read guard
70
+ Both are what stop a delegation from being undone by the next `cat`.
90
71
 
91
- A read of a file above `BULK_READ_MIN_LINES` lines (default 350) is blocked, and so is `cat`, `less`, or `more` that would dump a large file. The block names `outline` first, so the model fetches a map of declarations rather than the text.
72
+ ## Profiles and the widget
92
73
 
93
- The second call for the same path passes through, so the file stays reachable and a model with a reason to read it can. A read passes when it returns fewer lines than the threshold, whether from a `limit`, an `offset`, a small file, or `head` and `tail` on their 10-line default, and so does a piped command.
74
+ A profile is a markdown file with YAML frontmatter in `~/.pi/agent/agents/`, `.pi/agents/`, or bundled. It sets the tool list, model, thinking level, limits, an optional color, `inheritProjectContext` and `inheritSkills`, and `systemPromptMode: replace` to swap the default system prompt rather than append to it.
94
75
 
95
- ## Log reducer
76
+ `/agents` lists them with their tools, model and limits. The roster rarely changes mid-task, so it is a command, not a model tool.
96
77
 
97
- A build or test log above 4,096 bytes, from a diagnostic command pattern, is replaced with a short receipt of quoted lines. Every quote is verified byte for byte against the archived original, and if validation fails the full log reaches the model untouched. The reducer runs on `tool_result`, so the swap happens before the result enters history, and the raw log is archived next to the session.
78
+ A persistent widget lists running and recently finished children. Down on an empty prompt highlights the roster, Up and Down move, Escape clears, Enter opens a live conversation viewer with thinking, tool calls and results.
98
79
 
99
80
  ## Install
100
81
 
@@ -104,15 +85,19 @@ pi install npm:@tduyng/pi-subagent
104
85
 
105
86
  Local checkout: `pi install /path/to/dotfiles/pi/agent/extensions/pi-subagent`
106
87
 
107
- ## Configure
88
+ Worktree isolation needs `git` on PATH, and the bulk-read hint names `rg`.
108
89
 
109
- - `subagent.json` in the agent dir sets the child model and thinking. Shape: `{ "model": "provider/model-id", "thinking": "medium" }`, both optional.
110
- - `BULK_READ=0` disables the guard. `BULK_READ_MIN_LINES` sets the line threshold.
111
- - `PI_LOG_REDUCER=0` disables the reducer. `PI_LOG_REDUCER_TIMEOUT_MS` sets its deadline, default 15 seconds, maximum 60.
90
+ | Setting | Default | Meaning |
91
+ | --- | --- | --- |
92
+ | `BULK_READ` | `1` | `0` disables the read guard |
93
+ | `BULK_READ_MIN_LINES` | `350` | Line threshold for a blocked read |
94
+ | `PI_LOG_REDUCER` | `1` | `0` disables the log reducer |
95
+ | `PI_LOG_REDUCER_TIMEOUT_MS` | `15000` | Reducer deadline, 60,000 at most |
112
96
 
113
- ## Design notes
97
+ ## Limits
114
98
 
115
- - Child deadlines default to 30 minutes. A shorter `timeoutMs` or profile `maxExecutionTimeMs` is raised to it, and longer values pass through. A profile deadline past the 32-bit setTimeout ceiling clamps to the ceiling, because Node rounds a larger delay down to 1 ms and would kill the child instantly.
116
- - Child thinking resolves from the task, then the profile, then `subagent.json`, then `medium`. It does not inherit the parent's.
117
- - Read-only scouts run in parallel. A write-capable child is never run alongside another one, and a call whose tasks normalize to the same request is refused.
118
- - The registry holds at most 50 tasks, the widget 8 rows, the `touched` list per task 12 entries, and progress updates emit at most every 250ms.
99
+ - Eight tasks per call, four running at once. A fifth concurrent write-capable child is refused rather than queued.
100
+ - Child deadlines default to 30 minutes. A profile deadline past the 32-bit `setTimeout` ceiling clamps to it, because Node rounds a larger delay down to 1 ms and would kill the child instantly.
101
+ - A child cannot spawn its own subagent, so delegation stays one level deep.
102
+ - Read-only children run in parallel. A write-capable child never runs alongside another one, and two tasks that normalize to the same request are refused.
103
+ - The registry holds 50 tasks, the widget 8 rows, and the touched list 12 entries per task.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tduyng/pi-subagent",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Cheap delegation: a child session reads docs, logs, and source, returns one answer, and its context is thrown away. Scout profile bundled.",
5
5
  "keywords": [
6
6
  "pi",