pi-multi-agent-skill 0.0.0-stage → 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Milan Glacier
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,102 @@
1
- # Temporary Holding Version
1
+ # pi-multi-agent-skill
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A minimal, lightweight multi-agent skill and CLI for [pi](https://pi.dev). It
4
+ needs no extension and adds no tools. Your agent starts other agents, runs
5
+ them in parallel or in the background, and waits for, steers, stops or
6
+ resumes them. Any harness or agent that has a shell can use it.
7
+
8
+ ## Features
9
+
10
+ - **Small token cost.** A subagent extension adds its tool definitions to
11
+ every request, whether or not your agent delegates anything. With this
12
+ skill, your agent's context holds only the skill's description, a few
13
+ dozen tokens, until it decides to delegate. Then it loads SKILL.md, which
14
+ is about 1.2K tokens and is all it needs for a fully working multi-agent
15
+ setup. The details of each command stay in separate references that it
16
+ reads only when needed.
17
+ - **Everything a subagent tool does, without the tool.** Your agent gets the
18
+ same controls a dedicated extension would give it: start agents, wait for
19
+ them, `steer` one with a correction, `abort` it and keep what it has so
20
+ far, `resume` a finished job with a follow-up task, and see what each job
21
+ is doing. You can run the same commands yourself from a terminal.
22
+ - **Parallel and background agents.** Run a quick question in the
23
+ foreground, or start several jobs at once and collect their results later.
24
+ - **Stops when you stop.** A foreground agent ends when the command that
25
+ started it ends: press Esc, cancel the tool call or close the session, and
26
+ the agent and the commands it was running stop with it, at every level of
27
+ nesting. Background jobs keep running until they finish or time out.
28
+ - **Your full pi setup.** Each agent loads the same extensions, MCP servers,
29
+ skills and settings as an interactive pi, and uses your model unless its
30
+ profile picks another.
31
+ - **Profiles.** They work as in other subagent tools: each one sets an
32
+ agent's system prompt, model, thinking level and tools.
33
+ - **Fork your conversation.** `--fork` hands the agent everything you have
34
+ discussed so far, for tasks that need that context.
35
+ - **Works outside pi.** Claude Code, Codex or any other agent with a shell
36
+ can run the same commands to delegate work to pi agents.
37
+
38
+ ## Install
39
+
40
+ Install the skill as a pi package from npm:
41
+
42
+ ```bash
43
+ pi install npm:pi-multi-agent-skill
44
+ ```
45
+
46
+ Or install directly from GitHub:
47
+
48
+ ```bash
49
+ pi install git:github.com/milanglacier/pi-multi-agent-skill
50
+ ```
51
+
52
+ You can also install the skill with the open skills CLI:
53
+
54
+ ```bash
55
+ npx skills install milanglacier/pi-multi-agent-skill --global --agent pi
56
+ ```
57
+
58
+ The CLI copies the skill to `~/.agents/skills/multi-agent`, which pi reads.
59
+ You can also link it into pi's skills directory yourself:
60
+
61
+ ```bash
62
+ ln -s "$PWD/skills/multi-agent" ~/.pi/agent/skills/multi-agent
63
+ ```
64
+
65
+ Requirements: pi and Python 3.9 or later. Nothing else to install.
66
+
67
+ ## Usage
68
+
69
+ Your agent drives the skill on its own, but the commands also work by hand:
70
+
71
+ ```bash
72
+ multi_agent.py run --profile Explore "Where is the retry policy defined?"
73
+ multi_agent.py run --background --name review "Review the error handling in src/server/"
74
+ multi_agent.py wait review --timeout 120
75
+ multi_agent.py steer review "Skip generated files"
76
+ multi_agent.py resume review "Now check the client side"
77
+ multi_agent.py list
78
+ ```
79
+
80
+ See [`skills/multi-agent/references/`](skills/multi-agent/references/) for
81
+ every command and option, how jobs start and stop, the profile format, where
82
+ state is kept and troubleshooting.
83
+
84
+ ## Tests
85
+
86
+ ```bash
87
+ python3 -m unittest discover tests
88
+ ```
89
+
90
+ The tests use an offline stand-in for pi, so they call no model.
91
+
92
+ ## Releases
93
+
94
+ Set the version in `package.json`, commit it, and push a matching tag such
95
+ as `v0.1.1`. The GitHub workflow runs the tests and publishes to npm.
96
+ Prerelease versions use the `next` npm tag; stable versions use `latest`.
97
+ The npm trusted publisher is `milanglacier/pi-multi-agent-skill` with the
98
+ workflow filename `publish.yml` and permission to publish directly.
99
+
100
+ ## License
101
+
102
+ MIT
package/package.json CHANGED
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "name": "pi-multi-agent-skill",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "A minimal multi-agent skill+cli for pi. It adds no extension or tools, so it uses only a few dozen tokens of the context window until the main agent delegates, yet it gives the same controls as a subagent extension. Background agents keep running after the session closes, and any later session can collect their results.",
5
+ "license": "MIT",
6
+ "author": "Milan Glacier",
7
+ "homepage": "https://github.com/milanglacier/pi-multi-agent-skill#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/milanglacier/pi-multi-agent-skill.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/milanglacier/pi-multi-agent-skill/issues"
14
+ },
15
+ "keywords": [
16
+ "pi-package",
17
+ "pi",
18
+ "agent-skill",
19
+ "multi-agent"
20
+ ],
21
+ "files": [
22
+ "skills/multi-agent/SKILL.md",
23
+ "skills/multi-agent/profiles/*.md",
24
+ "skills/multi-agent/references/*.md",
25
+ "skills/multi-agent/scripts/*.py",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
29
+ "pi": {
30
+ "skills": ["./skills"]
31
+ }
32
+ }
@@ -0,0 +1,140 @@
1
+ ---
2
+ name: multi-agent
3
+ description: Start other pi agents and delegate work to them. Use it when a task benefits from a multi-agent workflow, such as splitting work across agents, running it in parallel or in the background, or keeping a side task out of your own context.
4
+ ---
5
+
6
+ # Multi-agent
7
+
8
+ This skill starts other agents and manages each one as a named job. An agent
9
+ does not see your conversation unless you start it with `--fork`, and you see
10
+ only its final message.
11
+
12
+ `SKILL_DIR` below is the directory that contains this SKILL.md. Every command
13
+ has the form:
14
+
15
+ ```bash
16
+ python3 "$SKILL_DIR/scripts/multi_agent.py" <command> ...
17
+ ```
18
+
19
+ ## Pick a profile
20
+
21
+ A profile sets an agent's system prompt, model, thinking level and tools. Run
22
+ this once per session to see the available profiles:
23
+
24
+ ```bash
25
+ python3 "$SKILL_DIR/scripts/multi_agent.py" profiles
26
+ ```
27
+
28
+ There are two built-in profiles. `general-purpose` (the default) has your
29
+ tools and settings. `Explore` is a read-only search agent. Pass a profile
30
+ with `--profile NAME`.
31
+
32
+ ## Run an agent
33
+
34
+ For a short single task, run it in the foreground. The command blocks until
35
+ the agent finishes and prints its result:
36
+
37
+ ```bash
38
+ python3 "$SKILL_DIR/scripts/multi_agent.py" run --profile Explore "Where is the retry policy for HTTP calls defined?"
39
+ ```
40
+
41
+ Pass a prompt longer than one line through `-` and a heredoc:
42
+
43
+ ```bash
44
+ python3 "$SKILL_DIR/scripts/multi_agent.py" run --name auth-review - <<'EOF'
45
+ Read src/auth/ and list every place that ...
46
+ EOF
47
+ ```
48
+
49
+ Write prompts that are self-contained: give the goal, the relevant paths and
50
+ what the answer should contain. When the task builds on your conversation so
51
+ far, add `--fork` instead: the agent starts from a copy of it.
52
+
53
+ For a long task, or several tasks in parallel:
54
+
55
+ - If your harness has a tool that runs a shell command in the background, run
56
+ the foreground `run` command with it. The job then stops when your session
57
+ ends. The command prints `multi-agent: started job NAME` first; use that
58
+ name for `steer` and `abort`. If the tool can wake you on each output line,
59
+ turn that off and wait for the command to exit. If the tool has its own
60
+ timeout, see "Timeouts" below.
61
+ - Otherwise, or when the work must continue after your session ends, add
62
+ `--background`. The command prints the job name and returns at once. A
63
+ background job runs until it finishes or reaches its timeout (one hour by
64
+ default). Tell the user the job's name.
65
+ - Never put the command in the background with `&`; use `--background`.
66
+
67
+ Run only as many jobs at once as the task needs.
68
+
69
+ ## Timeouts
70
+
71
+ - A foreground `run` or `resume` has no timeout unless you pass
72
+ `--timeout S`. It stops when the agent finishes or when the command ends,
73
+ for example when your tool call is cancelled or your session ends.
74
+ - A `--background` job stops after one hour unless you pass `--timeout S`.
75
+ `--timeout 0` removes the limit.
76
+ - When a background tool of your harness runs the foreground command and the
77
+ tool has its own timeout, pass a shorter `--timeout`, leaving a grace
78
+ period so the job stops the agent and records its result before the tool
79
+ kills it. If you disable the tool's timeout instead, the job runs until
80
+ the agent finishes or your session ends.
81
+
82
+ ## Wait for a result
83
+
84
+ ```bash
85
+ python3 "$SKILL_DIR/scripts/multi_agent.py" wait NAME --timeout 120
86
+ ```
87
+
88
+ Exit code 2 means the job is still running; run the same command again in a
89
+ new tool call. Wait for one job per tool call and do not chain several `wait`
90
+ commands in one call: a message that steers you arrives only after your
91
+ current tool call returns.
92
+
93
+ The output is the agent's final message followed by a `--- multi-agent ---`
94
+ footer. The footer is for you. Report the agent's findings to the user in your
95
+ own words.
96
+
97
+ Exit code 0 means the job ended with status `done`; 1 means it ended another
98
+ way (`failed`, `aborted`, `timeout`, `killed`, `died`), and the output says
99
+ why.
100
+
101
+ ## Correct or continue a job
102
+
103
+ ```bash
104
+ python3 "$SKILL_DIR/scripts/multi_agent.py" steer NAME "Skip the tests directory"
105
+ python3 "$SKILL_DIR/scripts/multi_agent.py" abort NAME
106
+ python3 "$SKILL_DIR/scripts/multi_agent.py" kill NAME
107
+ python3 "$SKILL_DIR/scripts/multi_agent.py" resume NAME "Now check the callers too"
108
+ ```
109
+
110
+ - `steer` adds a message that the agent reads before its next step.
111
+ - `abort` stops the agent and keeps its last message as the result.
112
+ - `kill` stops a job that does not respond to `abort`.
113
+ - `resume` continues a finished job's conversation with a new prompt.
114
+
115
+ `kill --all` stops every running job of the current project. Use it only when
116
+ the user asks.
117
+
118
+ ## Inspect jobs
119
+
120
+ ```bash
121
+ python3 "$SKILL_DIR/scripts/multi_agent.py" list
122
+ python3 "$SKILL_DIR/scripts/multi_agent.py" status NAME
123
+ python3 "$SKILL_DIR/scripts/multi_agent.py" peek NAME
124
+ ```
125
+
126
+ `peek` shows the job's recent tool calls.
127
+
128
+ ## References
129
+
130
+ The `references/` directory next to this file has the details. Read a file
131
+ only when you need it:
132
+
133
+ - `commands.md`: every command and option, output formats and exit codes.
134
+ - `lifecycle.md`: statuses, how a run stops, foreground and background
135
+ lifetime, timeouts, dialogs and nesting.
136
+ - `profiles.md`: writing a profile, where profiles are looked up, and how the
137
+ model, tools and system prompt are chosen.
138
+ - `state.md`: where jobs and conversations are stored, and the agent's
139
+ environment.
140
+ - `troubleshooting.md`: error messages and what to do about them.
@@ -0,0 +1,34 @@
1
+ ---
2
+ description: "Fast read-only search agent for locating code. Use it to find files by pattern (eg. \"src/components/**/*.tsx\"), grep for symbols or keywords (eg. \"API endpoints\"), or answer \"where is X defined / which files reference Y.\" Do NOT use it for code review, design-doc auditing, cross-file consistency checks, or open-ended analysis — it reads excerpts rather than whole files and will miss content past its read window. When calling, specify search breadth: \"quick\" for a single targeted lookup, \"medium\" for moderate exploration, or \"very thorough\" to search across multiple locations and naming conventions."
3
+ tools: read, bash, grep, find, ls
4
+ prompt_mode: replace
5
+ ---
6
+
7
+ # CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS
8
+ You are a file search specialist. You excel at thoroughly navigating and exploring codebases.
9
+ Your role is EXCLUSIVELY to search and analyze existing code. You do NOT have access to file editing tools.
10
+
11
+ You are STRICTLY PROHIBITED from:
12
+ - Creating new files
13
+ - Modifying existing files
14
+ - Deleting files
15
+ - Moving or copying files
16
+ - Creating temporary files anywhere, including /tmp
17
+ - Using redirect operators (>, >>, |) or heredocs to write to files
18
+ - Running ANY commands that change system state
19
+
20
+ Use Bash ONLY for read-only operations: ls, git status, git log, git diff, find, cat, head, tail.
21
+
22
+ # Tool Usage
23
+ - Use the find tool for file pattern matching (NOT the bash find command)
24
+ - Use the grep tool for content search (NOT bash grep/rg command)
25
+ - Use the read tool for reading files (NOT bash cat/head/tail)
26
+ - Use Bash ONLY for read-only operations
27
+ - Make independent tool calls in parallel for efficiency
28
+ - Adapt search approach based on thoroughness level specified
29
+
30
+ # Output
31
+ - Use absolute file paths in all references
32
+ - Report findings as regular messages
33
+ - Do not use emojis
34
+ - Be thorough and precise
@@ -0,0 +1,3 @@
1
+ ---
2
+ description: General-purpose agent for research, broad searches and multi-step tasks. It has the caller's tools and settings.
3
+ ---
@@ -0,0 +1,214 @@
1
+ # Commands
2
+
3
+ Every command runs as `python3 "$SKILL_DIR/scripts/multi_agent.py" <command>`.
4
+ A PROMPT or MESSAGE of `-` is read from stdin, without its trailing newlines.
5
+ An empty prompt or message is a usage error. `--help` prints a usage summary.
6
+
7
+ | Command | What it does |
8
+ |---|---|
9
+ | `run [options] (PROMPT \| -)` | Start a new job. |
10
+ | `resume NAME [--background] [--timeout S] (PROMPT \| -)` | Start a new run of a finished job, in the same conversation. |
11
+ | `wait NAME [--timeout S]` | Block until the job is no longer running, then print its result. |
12
+ | `result NAME` | Print the result of a job that is not running. |
13
+ | `steer NAME (MESSAGE \| -)` | Give a running agent a message to read before its next step. |
14
+ | `abort NAME` | Ask a running agent to stop, keeping its last message as the result. |
15
+ | `kill NAME` / `kill --all` | Stop one job, or every running job of the current project. |
16
+ | `status NAME` | Print the job's settings and state. |
17
+ | `peek NAME [-n N]` | Print the last N lines (default 20) of the job's progress log. |
18
+ | `list [--all]` | List the jobs of the current project. |
19
+ | `profiles` | List the available profiles. |
20
+ | `rm NAME` | Delete a job that is not running, with its conversation. |
21
+
22
+ ## Projects and job names
23
+
24
+ A job belongs to the project of the directory where `run` was called. `run`,
25
+ `list` and `kill --all` work on the current directory's project only.
26
+
27
+ The other commands look for NAME in the current project first. If the project
28
+ has no job of that name, they search every project and use the job when
29
+ exactly one project has it, so they also work from another directory. When
30
+ several projects have a job of that name, the command fails and lists them;
31
+ run it from the job's project.
32
+
33
+ ## run
34
+
35
+ | Option | Meaning |
36
+ |---|---|
37
+ | `--profile P` | Profile name, matched case-insensitively. Default `general-purpose`. |
38
+ | `--name N` | Job name. Default: the profile name in lowercase, `-`, and 4 hex digits, such as `explore-3f9a`. |
39
+ | `--background` | Return as soon as the job has started. |
40
+ | `--timeout S` | Wall-clock limit for the run in seconds. Default 3600 for a background run and no limit for a foreground run. `0` means no limit. |
41
+ | `--fork` | Start the agent from a copy of the caller's conversation. |
42
+ | `--model M` | Model pattern passed to `pi --model`. |
43
+ | `--thinking L` | Thinking level passed to `pi --thinking`. |
44
+ | `--cwd DIR` | Working directory for the agent, relative to the current directory. Default: the current directory. |
45
+
46
+ A job name contains letters, digits, `.`, `_` and `-`, starts and ends with a
47
+ letter or digit, and has at most 64 characters. `run` refuses a name that
48
+ already exists in the project; `resume` that job, pick another name, or `rm`
49
+ the old job first.
50
+
51
+ `--cwd` changes where the agent works and where project profiles are looked
52
+ up (`DIR/.pi/agents/`). The job still belongs to the current directory's
53
+ project.
54
+
55
+ `--fork` copies the conversation in `$PI_SESSION_FILE`, which pi sets for the
56
+ commands it runs. It fails when that variable is unset or the file does not
57
+ exist. Only the job's first run starts from the copy; later runs continue the
58
+ job's own conversation.
59
+
60
+ When `--model` and `--thinking` are omitted, the profile and then the caller's
61
+ settings decide; see `profiles.md`.
62
+
63
+ A foreground `run` writes `multi-agent: started job NAME` to stderr as soon as
64
+ the job starts, then blocks and prints the result when the run ends. If the
65
+ command receives SIGINT, SIGTERM or SIGHUP, the job stops with status `killed`
66
+ and the command still prints the result. A second signal ends the command at
67
+ once.
68
+
69
+ A background `run` prints the following and exits with code 0. `timeout_s`
70
+ is `none` when the run has no limit.
71
+
72
+ ```
73
+ job: explore-3f9a
74
+ status: running
75
+ timeout_s: 3600
76
+ ```
77
+
78
+ ## resume
79
+
80
+ `resume` starts a new run of a job that is not running. The agent continues
81
+ the job's conversation, with the profile, model, thinking level, tools, system
82
+ prompt and working directory that the job was created with. Editing the
83
+ profile afterwards does not change an existing job.
84
+
85
+ Only `--background` and `--timeout` can be given. They apply to the new run
86
+ alone and have the same defaults as for `run`, so a resumed run does not
87
+ inherit the previous run's timeout. Output is the same as for `run`.
88
+
89
+ The job's status, result and duration always describe its latest run. If the
90
+ job has no saved conversation, for example because pi failed during start-up,
91
+ `resume` prints a note to stderr and the agent starts a new conversation.
92
+
93
+ ## wait and result
94
+
95
+ `wait` blocks until the job is no longer running and prints its result.
96
+ Without `--timeout` it waits as long as the job runs. When `--timeout`
97
+ expires first, it prints the following and exits with code 2; the
98
+ `last_progress` line is missing when the progress log is empty.
99
+
100
+ ```
101
+ job: explore-3f9a
102
+ status: running
103
+ waited_s: 120
104
+ last_progress: 14:02:11 grep retry policy
105
+ ```
106
+
107
+ `result` prints the result of a job that is not running and fails with `job
108
+ NAME is still running; use wait` otherwise.
109
+
110
+ `run` in the foreground, `wait` and `result` print the result as the agent's
111
+ final message followed by a footer:
112
+
113
+ ```
114
+ <final assistant text>
115
+
116
+ --- multi-agent ---
117
+ name: explore-3f9a
118
+ status: done
119
+ profile: Explore
120
+ model: anthropic/claude-sonnet-5
121
+ duration_s: 84
122
+ ```
123
+
124
+ The text is `(no output)` when the run produced none. For a `failed` run it
125
+ ends with an `error:` line. `model` is the model that wrote the latest
126
+ message, or the requested model when none did, or `(pi default)` when no
127
+ model was requested. `duration_s` covers the latest run. `lifecycle.md`
128
+ explains what the text holds for each status.
129
+
130
+ ## steer
131
+
132
+ `steer` sends a message to the running agent, which reads it before its next
133
+ step. It prints `job: NAME` and `steer: queued` once pi has accepted the
134
+ message, and the message appears in the progress log. It fails with `job is
135
+ not running; use resume` when the run has ended or is ending.
136
+
137
+ ## abort
138
+
139
+ `abort` asks the agent to stop and prints `job: NAME` and `abort: requested`
140
+ without waiting for it. Steering messages that the agent has not read yet are
141
+ discarded. The run ends with status `aborted`; use `wait` to get the result.
142
+ `abort` fails with `job is not running; use resume` when the run has ended or
143
+ is ending.
144
+
145
+ ## kill
146
+
147
+ `kill NAME` stops the run at once and returns after the job's runner has
148
+ exited, which takes at most about 20 seconds. It prints the job name and the
149
+ status the run ended with:
150
+
151
+ ```
152
+ job: explore-3f9a
153
+ status: killed
154
+ ```
155
+
156
+ When the run had already ended, or was ending on its own, `kill` changes
157
+ nothing, prints that status followed by `(not running)`, and exits with code
158
+ 0.
159
+
160
+ `kill --all` stops every running job of the current project in parallel and
161
+ prints one such block per job. For a job it could not stop, the block has an
162
+ `error:` line instead of the status, and the command exits with code 1. With
163
+ no running job it prints `no running jobs in this project`.
164
+
165
+ ## status
166
+
167
+ `status` prints `key: value` lines: `name`, `status`, `mode` (`foreground` or
168
+ `background`), `profile`, `model`, `parent`, `cwd`, `started_at`, `ended_at`,
169
+ `runs`, `exit_code`, `output_file`, `session_file` and `session_cmd`. A `-`
170
+ marks a missing value. Timestamps are UTC and describe the latest run.
171
+
172
+ `session_cmd` opens the job's conversation in interactive pi. While the job
173
+ runs, `status` adds a `note:` line as a reminder not to open it yet, because
174
+ two processes would then write the same conversation file.
175
+
176
+ ## peek
177
+
178
+ `peek` prints the last N lines of the job's progress log, which spans all of
179
+ its runs. Each line starts with the local time. The log records each run's
180
+ start and end, every tool call with a short excerpt of its main argument,
181
+ retries, compactions, cancelled dialogs (`denied:`), steering messages, abort
182
+ requests and timeouts. It does not hold the agent's text; read that with
183
+ `wait` or `result`.
184
+
185
+ ## list
186
+
187
+ `list` prints a table with the columns `NAME`, `STATUS`, `MODE`, `PARENT` and
188
+ `AGE`, oldest first. It shows running jobs and jobs that ended in the last 24
189
+ hours; `--all` shows every job of the project. `AGE` is the time since the
190
+ run started for a running job and since it ended otherwise. `PARENT` is the
191
+ job that started this one, or `-`.
192
+
193
+ ## profiles
194
+
195
+ `profiles` lists each enabled profile with its description and source file.
196
+ It looks up project profiles in the current directory.
197
+
198
+ ## rm
199
+
200
+ `rm` deletes a job that is not running: its state directory and its
201
+ conversation file. It prints `removed: NAME` and fails with `job NAME is
202
+ running; kill it first` while the job runs.
203
+
204
+ ## Exit codes
205
+
206
+ | Code | Meaning |
207
+ |---|---|
208
+ | 0 | The job ended with status `done`, or the command succeeded. |
209
+ | 1 | The job ended with another status, or the command failed. |
210
+ | 2 | `wait` timed out and the job is still running. |
211
+ | 64 | Usage error, such as an unknown option or a missing prompt. |
212
+
213
+ The job's status decides the exit code of a foreground `run` or `resume`, of
214
+ `wait` and of `result`. The other commands exit with 0 when they succeed.
@@ -0,0 +1,92 @@
1
+ # Job lifecycle
2
+
3
+ A job is a named agent and its conversation. `run` creates the job and starts
4
+ its first run; each `resume` starts another run in the same conversation. A
5
+ job has at most one run at a time, and its status describes the latest run.
6
+
7
+ ## Statuses
8
+
9
+ | Status | Meaning | Result text |
10
+ |---|---|---|
11
+ | `running` | The agent is working. | — |
12
+ | `done` | The agent finished its turn. | Its final message. |
13
+ | `failed` | The run could not finish; see below. | The agent's last message, if any, then an `error:` line. |
14
+ | `aborted` | `abort` stopped the agent, or something else aborted its turn. | Its last message. |
15
+ | `timeout` | The run reached its `--timeout`. | Its last message. |
16
+ | `killed` | `kill`, a signal to the job's runner, or the end of a foreground command stopped the run. | Its last message. |
17
+ | `died` | The job's runner ended without recording a result, for example after a SIGKILL. | None; the result reads `(no output)`. |
18
+
19
+ A run ends as `failed` when the model returns an error after pi's own retries,
20
+ pi rejects the prompt, pi cannot start, or pi exits during the run. In the
21
+ last case the result holds the end of pi's stderr. A model or tool name that
22
+ pi rejects is a common cause.
23
+
24
+ "Last message" is the text of the agent's latest message in this run. It is
25
+ empty when that message had only tool calls, or when the run stopped before
26
+ the agent wrote anything; the result then reads `(no output)`. A message cut
27
+ short by an abort keeps the text written before it.
28
+
29
+ A prompt that pi handles by itself without starting the agent, such as an
30
+ extension command, ends the run at once as `done` with no output.
31
+
32
+ ## How a run stops
33
+
34
+ - **The agent finishes.** The status is `done`, or `failed` if its last
35
+ message was an error.
36
+ - **`abort`.** Steering messages that the agent has not read are discarded and
37
+ pi is asked to abort the current turn. The agent gets 30 seconds to wind
38
+ down; after that the run is stopped anyway. The status is `aborted`.
39
+ - **Timeout.** The limit counts from the start of the run. When it is
40
+ reached, the run is aborted as above and ends as `timeout`.
41
+ - **`kill`, a signal, or the end of a foreground command.** The run stops at
42
+ once without the 30-second wind-down. The status is `killed`.
43
+
44
+ In every case pi is shut down cleanly: it gets 10 seconds to exit, then
45
+ SIGTERM, then SIGKILL 5 seconds later. A run that hits its timeout can
46
+ therefore take up to 45 seconds to end. `steer` and `abort` fail with `job is
47
+ not running; use resume` as soon as the run has started to end.
48
+
49
+ ## Foreground and background runs
50
+
51
+ Every run is driven by its own runner process, detached from the caller's
52
+ terminal and process group.
53
+
54
+ - A foreground run is tied to the command that started it. Whatever ends that
55
+ command, SIGKILL included, stops the agent and the commands it was running.
56
+ On SIGINT, SIGTERM or SIGHUP the command waits for the run to stop and
57
+ prints its result; a second signal ends it at once. A foreground run started
58
+ by another agent is tied to that agent's command in the same way, so a chain
59
+ of foreground runs stops together.
60
+ - A background run keeps going after its caller ends, until it finishes,
61
+ reaches its timeout, or is stopped with `kill`.
62
+ - If a runner is killed with SIGKILL, its job's status becomes `died` at once.
63
+ The agent's pi process usually exits within a second, but commands the agent
64
+ was running may keep running.
65
+
66
+ ## Timeouts
67
+
68
+ A timeout applies to one run. `run` and `resume` default to 3600 seconds in
69
+ the background and to no limit in the foreground; `--timeout 0` removes the
70
+ limit, and fractional seconds are allowed. A timeout does not carry over to
71
+ the next run.
72
+
73
+ ## Dialogs and approvals
74
+
75
+ No person watches an agent. When an extension inside the agent opens a dialog
76
+ (select, confirm, input or editor), it is cancelled at once and logged in the
77
+ progress log as `denied:`. The pi-minimal-permission-system extension, if
78
+ installed, runs in its non-interactive mode, so tool calls that need approval
79
+ are blocked. The agent is told not to retry them and to report what it could not do in its final
80
+ message.
81
+
82
+ ## Nesting
83
+
84
+ An agent can start agents of its own. `MULTI_AGENT_DEPTH` counts the depth: 0
85
+ or unset for the user's agent, 1 for an agent it started, and so on. `run` and
86
+ `resume` refuse to start when the caller's depth is at least
87
+ `MULTI_AGENT_MAX_DEPTH` (default 2), so by default the user's agent and its
88
+ agents can delegate, and their agents cannot. Agents inherit
89
+ `MULTI_AGENT_MAX_DEPTH` from the environment of the user's agent.
90
+
91
+ `MULTI_AGENT_JOB` holds the job directory of the agent that is running.
92
+ `status` and `list` use it to show the job that started each job.