pi-multi-agent-skill 0.0.0-stage → 0.2.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.
@@ -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:`. Extensions that have a non-interactive mode run in
78
+ it (see `state.md`), so tool calls that need a person fail without opening a
79
+ dialog. The agent is told not to retry them and to report what it could not
80
+ do in its final message.
81
+
82
+ ## Nesting
83
+
84
+ An agent can start agents of its own. `PI_MULTI_AGENT_DEPTH` counts the depth:
85
+ 0 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
+ `PI_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
+ `PI_MULTI_AGENT_MAX_DEPTH` from the environment of the user's agent.
90
+
91
+ `PI_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.
@@ -0,0 +1,79 @@
1
+ # Profiles
2
+
3
+ A profile sets an agent's system prompt, model, thinking level and tools. It
4
+ is a Markdown file with frontmatter; the body after the frontmatter is the
5
+ profile's prompt.
6
+
7
+ ```markdown
8
+ ---
9
+ description: Reviews a diff for correctness bugs.
10
+ model: anthropic/claude-sonnet-5
11
+ thinking: high
12
+ tools: read, grep, find, ls, bash
13
+ ---
14
+
15
+ You review code changes. Report each bug with its file, line and a failing
16
+ scenario.
17
+ ```
18
+
19
+ ## Where profiles come from
20
+
21
+ Profiles are looked up in three directories, from highest to lowest priority:
22
+
23
+ 1. `<cwd>/.pi/agents/*.md` (project), where `<cwd>` is the agent's working
24
+ directory
25
+ 2. `$PI_CODING_AGENT_DIR/agents/*.md`, default `~/.pi/agent/agents/` (user)
26
+ 3. `profiles/*.md` in this skill's directory (built-in)
27
+
28
+ Names are matched case-insensitively. When several directories define the
29
+ same name, the file from the highest directory is used as a whole; fields are
30
+ never merged across files. To change one field of a built-in profile, copy the
31
+ whole file and edit the copy. A profile with `enabled: false` hides its name,
32
+ including lower profiles of that name.
33
+
34
+ A job keeps the settings it was created with. Editing a profile affects new
35
+ jobs only, not `resume` of an existing one.
36
+
37
+ ## Fields
38
+
39
+ | Field | Default | Effect |
40
+ |---|---|---|
41
+ | `name` | file name without `.md` | Profile name. |
42
+ | `description` | `name` | Shown by `profiles`. |
43
+ | `model` | the caller's model | Passed to `pi --model`. |
44
+ | `thinking` | the caller's thinking level | Passed to `pi --thinking`. |
45
+ | `tools` | pi's default tool selection | Passed to `pi --tools`. |
46
+ | `disallowed_tools` | none | Passed to `pi --exclude-tools`. |
47
+ | `prompt_mode` | `append` | `append` or `replace`; see below. |
48
+ | `enabled` | `true` | `false` hides the profile. |
49
+
50
+ Unknown fields are ignored. The parser reads `key: value` lines, quoted
51
+ strings, `true`/`false` and `[a, b]` lists, and skips comments and indented
52
+ lines; it does not support nested YAML.
53
+
54
+ ## Model and thinking level
55
+
56
+ For each of the two, the first value found wins: the `run` option, the profile
57
+ field, the caller's current setting, then pi's configured default. The
58
+ caller's settings come from the `PI_PROVIDER`, `PI_MODEL` and
59
+ `PI_REASONING_LEVEL` variables that pi sets for the commands it runs.
60
+
61
+ ## Tools
62
+
63
+ `tools` and `disallowed_tools` accept a comma-separated list or `[a, b]`. The
64
+ entries are passed to pi verbatim as `--tools` and `--exclude-tools`; see pi's
65
+ documentation of those options for the patterns they accept and which tools
66
+ they keep.
67
+
68
+ ## System prompt
69
+
70
+ With `prompt_mode: append`, the profile's body is passed to pi with
71
+ `--append-system-prompt`, so it is added to the system prompt pi builds as
72
+ usual. With `prompt_mode: replace`, the body is passed with `--system-prompt`
73
+ and pi also gets `--no-context-files`. Any other value makes `run` fail.
74
+
75
+ Every agent also receives a short block that tells it its job name, that only
76
+ its final message is read, and that no person can approve blocked tool calls.
77
+ This block is passed with `--append-system-prompt` in both modes, so pi does
78
+ not load `APPEND_SYSTEM.md` files for agents; put text that agents need in a
79
+ profile's body.
@@ -0,0 +1,57 @@
1
+ # State
2
+
3
+ ## Locations
4
+
5
+ Job directories are in
6
+ `$XDG_STATE_HOME/pi-multi-agent/<project>/jobs/<name>/` (default
7
+ `~/.local/state`). `<project>` is the project's directory with every character
8
+ other than a letter or digit replaced by `-` and the leading `-` removed, so
9
+ `/home/me/app` becomes `home-me-app`.
10
+
11
+ A running job's runner listens on a Unix socket in
12
+ `$XDG_STATE_HOME/pi-multi-agent/sockets/`, which `steer`, `abort` and `kill`
13
+ connect to. Conversations are pi session files in
14
+ `$PI_CODING_AGENT_DIR/multi-agent-sessions/<project>/` (default
15
+ `~/.pi/agent/`), so they stay out of pi's `/resume` list.
16
+
17
+ ## Job files
18
+
19
+ | File | Content |
20
+ |---|---|
21
+ | `job.json` | Launch settings: profile, pi arguments, cwd, parent job, depth, run mode, timeout. |
22
+ | `prompt.txt` | Prompt of the latest run. |
23
+ | `system-prompt.md` | The profile's prompt, when it replaces pi's system prompt. |
24
+ | `append-prompt.md` | Text added to pi's system prompt: the profile's prompt in append mode, then the multi-agent block. |
25
+ | `status` | Status of the latest run; final once `exit_code` exists. |
26
+ | `lock` | Held by the job's runner for as long as it runs. The job is running exactly while this lock is held. |
27
+ | `started_at`, `ended_at` | UTC timestamps of the latest run. |
28
+ | `runs` | Number of runs. |
29
+ | `exit_code` | Exit code of the latest run, written last. A run without it that is no longer running has `died`. |
30
+ | `output.txt` | Result text of the latest run; empty if that run produced none. |
31
+ | `model` | Model that wrote the latest message. |
32
+ | `stderr.txt` | pi's stderr for the latest run. |
33
+ | `progress.log` | The lines `peek` prints, across runs. |
34
+ | `usage.json` | Token and cost totals across runs. |
35
+ | `runner.log` | Traceback when the runner itself fails. |
36
+
37
+ Starting a run clears the previous run's result, end time and model, so these
38
+ files always describe the latest run.
39
+
40
+ ## Reading a conversation
41
+
42
+ To read a finished job's whole conversation in interactive pi, run the
43
+ `session_cmd` that `status` prints. Do not open it while the job is running,
44
+ because two processes would then write the same session file.
45
+
46
+ ## The agent's environment
47
+
48
+ The script starts the program in `PI_MULTI_AGENT_PI_BIN` (default `pi`). An
49
+ agent inherits the environment of the command that started it, plus:
50
+
51
+ | Variable | Value |
52
+ |---|---|
53
+ | `PI_MULTI_AGENT_JOB` | The agent's job directory. |
54
+ | `PI_MULTI_AGENT_DEPTH` | The agent's nesting depth; see `lifecycle.md`. |
55
+ | `PI_MINIMAL_PERMISSION_SYSTEM_NONINTERACTIVE` | `1`, so that extension never waits for an approval. |
56
+ | `PI_REQUEST_USER_INPUT_NONINTERACTIVE` | `1`, so that extension never asks the user a question. |
57
+ | `PWD` | The agent's working directory. |
@@ -0,0 +1,59 @@
1
+ # Troubleshooting
2
+
3
+ ## Job status
4
+
5
+ - **Status `failed` with `pi exited before the run finished`.** pi stopped
6
+ during start-up or the run. The output holds the end of pi's stderr; the
7
+ whole log is in the job's `stderr.txt`. A model or tool name that pi rejects
8
+ causes this.
9
+ - **Status `failed` with `the runner failed`.** The script itself hit an
10
+ error. The traceback is in the job's `runner.log`.
11
+ - **Status `died`.** The runner was killed without a chance to record a
12
+ result. The agent's pi process exits by itself, usually within a second,
13
+ but commands it started can survive; look for them with `ps` if the agent
14
+ was running a long command. `peek` shows how far it got; `resume`
15
+ continues the conversation. Wait a few seconds before you `resume` a job
16
+ that has just died, so its old pi has exited and does not write the
17
+ conversation at the same time as the new one.
18
+ - **An agent reports that a tool call needs approval.** Agents cannot ask a
19
+ person. Run that step yourself, or tell the user what was blocked.
20
+ - **A job lingers after its caller is gone.** Background jobs outlive their
21
+ caller by design. Stop them with `kill NAME`, or `kill --all` when the user
22
+ asks.
23
+
24
+ ## Command errors
25
+
26
+ - **`job is not running; use resume`.** The run has ended or is ending.
27
+ `resume` the job with a new prompt instead of steering it.
28
+ - **`job NAME already exists in this project`.** Pick another `--name`.
29
+ The error shows the existing job's status and age. Use `resume` or `rm`
30
+ only for a job you started or the user asked about.
31
+ - **`job NAME is running` from `resume` or `rm`.** The job's runner is
32
+ still alive, or another command was starting the job at the same moment.
33
+ `wait` for it, or `kill` it first.
34
+ - **`unknown profile: P (available: ...)`.** No enabled profile has that name
35
+ in the agent's working directory; the message lists the ones that exist.
36
+ - **`--fork needs PI_SESSION_FILE`.** The command does not run inside pi, so
37
+ there is no conversation to copy. Drop `--fork` and write a self-contained
38
+ prompt.
39
+ - **`cannot start an agent: ... PI_MULTI_AGENT_MAX_DEPTH`.** The caller is too
40
+ deep in a chain of agents. Do the work directly.
41
+ - **`the runner of job NAME is not responding`.** The runner did not answer
42
+ `kill` within 10 seconds, or did not exit within 20 seconds after it
43
+ answered. The message ends with a `pkill` command that stops that runner;
44
+ run it, then wait a few seconds before you `resume` the job (see `died`).
45
+ - **`the job's working directory no longer exists`.** `resume` runs the
46
+ agent in the directory the job was started in. Start a new job instead.
47
+ - **`job NAME exists in several projects`.** Run the command from the
48
+ directory where the job was started.
49
+
50
+ ## Environment
51
+
52
+ - **`cannot find the pi program`.** Set `PI_MULTI_AGENT_PI_BIN` to the command
53
+ that starts pi, such as `pi-bolt`, or ask the user which one they use.
54
+ - **`flock does not work on ...`.** The state directory is on a file system
55
+ without working file locks, such as some NFS or SMB mounts. Set
56
+ `XDG_STATE_HOME` to a directory on a local file system.
57
+ - **`the socket path for this job is too long`.** The socket path under
58
+ `XDG_STATE_HOME` exceeds the system's limit for Unix sockets (about 100
59
+ bytes). Set `XDG_STATE_HOME` to a shorter path.