@aeondave/pi-persona 1.17.1 → 1.17.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.
- package/AGENTS.md +103 -64
- package/CHANGELOG.md +310 -1
- package/README.md +37 -23
- package/agents/architect.md +21 -0
- package/agents/balthasar.md +17 -22
- package/agents/casper.md +17 -23
- package/agents/evidence-verifier.md +31 -16
- package/agents/melchior.md +17 -22
- package/agents/operator.md +15 -55
- package/agents/research.md +14 -48
- package/agents/reviewer.md +20 -39
- package/agents/scout.md +14 -15
- package/agents/verifier.md +15 -16
- package/docs/ARCHITECTURE.md +280 -92
- package/docs/COLLABORATION.md +110 -0
- package/docs/EXPERIENCE.md +52 -17
- package/docs/MONITORS.md +62 -3
- package/docs/README.md +12 -0
- package/docs/REFERENCE.md +139 -38
- package/docs/SPINE.md +2 -2
- package/docs/STRATEGIES.md +23 -8
- package/docs/TELEMETRY.md +1 -0
- package/flows/deep-review.flow.json +1 -1
- package/package.json +15 -8
- package/personas/audit.md +28 -17
- package/personas/dev.md +30 -32
- package/personas/elite.md +223 -221
- package/personas/judge.md +25 -19
- package/personas/magi.md +26 -29
- package/personas/planner.md +31 -24
- package/personas/researcher.md +25 -26
- package/personas/swarm.md +35 -25
- package/personas/verify.md +30 -19
- package/src/agents/agent.ts +26 -0
- package/src/bridge.ts +28 -10
- package/src/bus/broker/client.ts +119 -21
- package/src/bus/broker/host.ts +123 -8
- package/src/bus/broker/messages.ts +31 -4
- package/src/bus/contact.ts +113 -38
- package/src/bus/peers.ts +15 -0
- package/src/bus/result-reader.ts +88 -0
- package/src/core/brief.ts +436 -353
- package/src/core/capabilities.ts +1 -1
- package/src/core/config.ts +15 -10
- package/src/core/leg-thinking.ts +57 -0
- package/src/core/model-catalog.ts +171 -0
- package/src/core/model-tier.ts +89 -0
- package/src/core/models.ts +13 -4
- package/src/core/monitor-output.ts +85 -0
- package/src/core/monitor.ts +34 -2
- package/src/core/nudge.ts +176 -23
- package/src/core/ownership.ts +1 -2
- package/src/core/pi-compat.ts +5 -12
- package/src/core/seed.ts +99 -6
- package/src/core/session-runs.ts +87 -0
- package/src/core/settings.ts +1 -1
- package/src/core/timer.ts +34 -9
- package/src/core/types.ts +1 -1
- package/src/engine/adapter.ts +95 -27
- package/src/engine/async.ts +213 -155
- package/src/engine/child.ts +12 -4
- package/src/engine/host-module.ts +12 -0
- package/src/engine/inproc.ts +99 -53
- package/src/engine/result-grant.ts +62 -0
- package/src/engine/session-tools.ts +6 -0
- package/src/engine/stream.ts +10 -20
- package/src/engine/worktree.ts +17 -7
- package/src/exocom/collaboration-delivery.ts +29 -0
- package/src/exocom/collaboration.ts +148 -0
- package/src/exocom/envelope.ts +43 -4
- package/src/exocom/gate.ts +7 -2
- package/src/exocom/install.ts +47 -18
- package/src/exocom/ledger.ts +58 -8
- package/src/exocom/plane.ts +32 -1
- package/src/exocom/profile.ts +40 -0
- package/src/exocom/registry.ts +5 -0
- package/src/exocom/status.ts +11 -1
- package/src/exocom/write-guard.ts +7 -0
- package/src/extension/broker-host.ts +61 -9
- package/src/extension/engine.ts +54 -28
- package/src/extension/hooks.ts +952 -868
- package/src/extension/identity.ts +41 -75
- package/src/extension/persona-model-settings.ts +31 -13
- package/src/extension/results.ts +136 -0
- package/src/extension/shared.ts +32 -7
- package/src/extension.ts +2965 -2611
- package/src/loader.ts +11 -3
- package/src/monitor/archive.ts +235 -0
- package/src/monitor/session.ts +21 -1
- package/src/orchestration/flow-journal.ts +33 -6
- package/src/orchestration/flow-run.ts +160 -32
- package/src/orchestration/flow.ts +20 -2
- package/src/orchestration/reducers.ts +9 -5
- package/src/orchestration/render.ts +1 -1
- package/src/orchestration/roster.ts +71 -23
- package/src/orchestration/sdk.ts +61 -11
- package/src/orchestration/strategies/compete.ts +5 -1
- package/src/orchestration/strategies/council-rounds.ts +2 -0
- package/src/orchestration/strategies/critic-loop.ts +3 -0
- package/src/orchestration/strategies/debate.ts +2 -0
- package/src/orchestration/strategies/fanout.ts +3 -2
- package/src/orchestration/strategies/judge.ts +5 -1
- package/src/orchestration/strategies/magi.ts +40 -23
- package/src/orchestration/strategies/map.ts +13 -3
- package/src/orchestration/strategies/pair.ts +2 -0
- package/src/orchestration/strategies/pipeline.ts +2 -0
- package/src/orchestration/strategies/synthesize.ts +27 -7
- package/src/orchestration/strategy.ts +31 -0
- package/src/orchestration/types.ts +10 -0
- package/src/persona/model-participants.ts +20 -7
- package/src/persona/orchestrate.ts +2 -0
- package/src/persona/persona.ts +8 -4
- package/src/results/archive.ts +281 -0
- package/src/results/record.ts +166 -0
- package/src/results/retrieval.ts +142 -0
- package/src/results/types.ts +128 -0
- package/src/telemetry/contract.ts +1 -1
- package/src/tools/background-run.ts +151 -0
- package/src/tools/council.ts +108 -66
- package/src/tools/delegate-tool.ts +349 -283
- package/src/tools/delegate.ts +35 -216
- package/src/tools/exocom-collaboration-input.ts +168 -0
- package/src/tools/exocom-collaboration.ts +315 -0
- package/src/tools/exocom-profile.ts +102 -0
- package/src/tools/exocom-work.ts +18 -53
- package/src/tools/exocom.ts +35 -22
- package/src/tools/flow.ts +103 -30
- package/src/tools/intercom-tool.ts +202 -128
- package/src/tools/intercom.ts +1 -1
- package/src/tools/models.ts +34 -9
- package/src/tools/monitor.ts +58 -6
- package/src/tools/read-result.ts +52 -0
- package/src/tools/timer.ts +34 -15
- package/src/ui/agent-overlay.ts +65 -16
- package/src/ui/agent-tree.ts +127 -19
- package/src/ui/compact-widget.ts +25 -0
- package/src/ui/failure-summary.ts +55 -0
- package/src/ui/literal-tool-result.ts +24 -0
- package/src/ui/model-picker.ts +158 -81
- package/src/ui/orchestration-launch.ts +49 -0
- package/src/ui/persona-settings.ts +9 -3
- package/src/ui/presentation.ts +24 -0
- package/src/ui/report-body.ts +63 -0
- package/src/ui/session-cards.ts +366 -0
- package/src/ui/wake-rows.ts +262 -0
- package/teams.yaml +5 -1
package/docs/REFERENCE.md
CHANGED
|
@@ -34,28 +34,58 @@ hard-fail.
|
|
|
34
34
|
|
|
35
35
|
| Surface | Does |
|
|
36
36
|
|---|---|
|
|
37
|
-
| `delegate` tool | spawn one or more sub-agents; interactive
|
|
38
|
-
| `council` tool | select any installed strategy over a named roster or temporary inline `members`; voting strategies preserve tally and dissent. Use when the
|
|
39
|
-
| `intercom` tool | observe and control internal runs with `peek`, `result`, `
|
|
40
|
-
| `timer` tool | read the fresh clock with `now`, or schedule an idle wake with `arm`, `cancel`, and `list`; alarms are one-shot and in-memory per session |
|
|
41
|
-
| `monitor` tool | run a bounded job (`mode: exit`) or event-producing program (`mode: output`) and wake the supervisor; see [`MONITORS.md`](./MONITORS.md) |
|
|
42
|
-
| `flow` tool and `/flow` | run a journaled DAG of strategies; `gate: true` creates an approval checkpoint |
|
|
43
|
-
| `models` tool |
|
|
37
|
+
| `delegate` tool | spawn one or more sub-agents; interactive sessions always run it in the background (results return as completion follow-ups); headless `pi -p` always blocks and returns results inline. There is no `sync`/`async` parameter. A leg whose tool is silent longer than the idle window (180 s) fails with a message telling you to raise that leg's `timeoutMs`. A `tasks` fan-out's receipt pairs each run id with its call-sign, and one wake covers the whole batch. An optional `thinking` picks that leg's effort level (off…max); omission keeps the agent's own setting and the configured/inherited child default, and results distinguish requested from observed effort |
|
|
38
|
+
| `council` tool | select any installed strategy over a named roster or temporary inline `members`; voting strategies preserve tally and dissent. Interactive sessions run a council in the background, like `delegate`: a receipt with a run id now, ONE completion follow-up with the ruling (`intercom result { to: runId }` for the full payload); headless `pi -p` returns it inline. Use it when the method adds value (vote, arbiter's pick, critique loop, per-item sweep, rival builds), not for plain independent parallel work, which is `delegate`. The strategy list in the tool description is generated from the registry (`when`, positional `roster`, `*` for a required param); a call missing a required param (`judge` and `compete` need `params.judge`) fails at once with `council failed: "<strategy>" requires params.<key> — …` and launches nothing, while an unknown strategy or roster is reported by the run itself, in the completion follow-up. A persona's declared `council:` still resolves when strategy, roster and params are omitted. Per-strategy behaviour (section labels, MAGI reflection fallbacks) is in [`STRATEGIES.md`](./STRATEGIES.md) |
|
|
39
|
+
| `intercom` tool | observe and control internal runs with `peek`, `result`, `steer`, and `stop`; `list`, `inbox`, `message`, `reply`, and `send` drive the coaching bus. There is no `wait`: a finished child wakes the supervisor through the completion follow-up |
|
|
40
|
+
| `timer` tool | read the fresh clock with `now`, or schedule an idle wake with `arm`, `cancel`, and `list`; alarms are one-shot and in-memory per session; an armed alarm shows as a row in the agent widget and F9 until it fires or is cancelled |
|
|
41
|
+
| `monitor` tool | run a bounded job (`mode: exit`) or event-producing program (`mode: output`) and wake the supervisor; an active monitor shows as a row in the agent widget and F9 until it ends or is cancelled; see [`MONITORS.md`](./MONITORS.md) |
|
|
42
|
+
| `flow` tool and `/flow` | run a journaled DAG of strategies, resumable only for the same flow, task and project; `gate: true` creates an approval checkpoint, shown with the gated output and what runs next (Reject is the default). The `flow` tool runs in the background interactively (receipt, then ONE follow-up when it ends; a checkpoint waits for the operator, peek reads `waiting for operator at checkpoint <id>`, and no wake happens there) and inline headless, where every checkpoint is rejected. A rejected checkpoint is a stop (`flow stopped · checkpoint <id>`, the gated plan is kept), not a failure. `/flow` and `/orchestrate` stay inline and operator-driven, and their results also reach the supervisor's next turn. `/flow` alone lists flows with descriptions; the supervisor brief lists them too, tagging gated flows as needing a human in headless sessions |
|
|
43
|
+
| `models` tool | current-first model shortlist with relative cost bands; a query searches the full eligible catalog in `provider/id` form |
|
|
44
44
|
| persona `mode:` | choose `solo`, `parallel`, `pipeline`, `strategy:<name>`, or `flow:<name>` |
|
|
45
45
|
| persona `coaching:` | give children `contact_supervisor` for progress and blocking decisions |
|
|
46
46
|
| persona `delegation:` | require briefs, set an output contract, schedule disjoint writes, and order fresh verification |
|
|
47
47
|
| `isolation: worktree` | run in a clean throwaway Git worktree and return an exported diff; non-Git, dirty, or oversized cases fail closed |
|
|
48
|
+
| agent `writeSet:` | repository-relative paths the agent alone writes by design (`research` declares `[.research/]`); a write-capable `delegate` leg that gives no `writeSet` of its own inherits it, so a persona that requires disjoint writes sees a declared owner instead of an unknown writer. Read-only legs do not inherit it. A directory owns its subtree; absolute and `../` paths are dropped. Declarative, not a sandbox |
|
|
48
49
|
| `council: { preset }` | expand a reusable `presets/<name>.preset.json`; authored fields override the preset |
|
|
49
50
|
| `contracts/*.json` | define a hot-editable structured return requested through `outputContract` and pinned per run |
|
|
50
51
|
|
|
52
|
+
`models` without a query shows up to 40 entries total, including the current model when available,
|
|
53
|
+
with the current model first. Recommendations stay within its provider, textual name root and
|
|
54
|
+
numbered major generation, retaining the newest representative of each distinct variant. Remaining
|
|
55
|
+
candidates are ordered `cost:low` → `medium` → `high` → `unknown`, then by numeric version within
|
|
56
|
+
each band. For example, a `gpt-6-astra` supervisor sees available `gpt-6-luna` and `gpt-6.1-sol`
|
|
57
|
+
neighbors before considering older models. The rule reads catalog IDs, without a model-name table;
|
|
58
|
+
gateway vendor/region namespaces remain distinct from the model's family and generation.
|
|
59
|
+
If the current name has no numeric version, only provider and textual root constrain the list.
|
|
60
|
+
The list is not filled with older or unrelated models just to reach the cap; explicit searches and
|
|
61
|
+
model assignments retain the full eligible catalog. With no current model, discovery falls back to
|
|
62
|
+
a general shortlist sharing each provider's cap across name roots. Names are proximity hints,
|
|
63
|
+
not release-date metadata or proof of task fit. `★` identifies the session
|
|
64
|
+
provider; authentication alone does not prove that an account supports every model in its catalog.
|
|
65
|
+
|
|
66
|
+
Model details expose host metadata for context and reasoning support. `cost:low`, `cost:medium` and
|
|
67
|
+
`cost:high` are relative advertised API-cost bands among recent candidates of the same provider,
|
|
68
|
+
using equal input/output token quantities. They are not quality, throughput or reasoning-effort
|
|
69
|
+
ratings, and do not describe subscription billing. Missing/zero prices or an insufficient comparison
|
|
70
|
+
set yield `cost:unknown`. The supervisor chooses task fit using these hints and the task's difficulty;
|
|
71
|
+
thinking effort remains the separate delegated-thinking preference (inherited by default).
|
|
72
|
+
|
|
73
|
+
The supervisor brief reuses a cached current-provider candidate list. Discovery runs on first use,
|
|
74
|
+
when the base model changes (provider or model id), or on an explicit `models` query; ordinary turns
|
|
75
|
+
do not rescan. Switching to another provider therefore replaces the cached candidates, including
|
|
76
|
+
its lighter variants when present. The current provider is a default, not a user restriction: an
|
|
77
|
+
explicit worker-model request may select another configured provider. The LLM retains the choice.
|
|
78
|
+
|
|
51
79
|
The delegate tool's optional `name` is carried into `AgentRunSpec.name` and reaches both engine
|
|
52
|
-
backends, keeping a caller-provided run label available in the live tree and runtime result.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
80
|
+
backends, keeping a caller-provided run label available in the live tree and runtime result. A
|
|
81
|
+
successful or stopped run announces ONCE: the idle-gated completion follow-up is the single
|
|
82
|
+
settlement surface (the agent-tree row already settles immediately). A failure keeps an immediate
|
|
83
|
+
operator surface — in the TUI a durable expandable card with the agent, model, elapsed time and a
|
|
84
|
+
concise cause (expansion retains the full technical diagnostic); other modes use a concise
|
|
85
|
+
sanitized notification. These operator-only cards do not inject context or start a second turn.
|
|
86
|
+
The model-facing report remains independently idle-gated; a UI notification failure cannot discard it.
|
|
57
87
|
|
|
58
|
-
###
|
|
88
|
+
### Native codemode
|
|
59
89
|
|
|
60
90
|
Pi's native `codemode` can call callable pi-persona tools through the normal nested-tool pipeline.
|
|
61
91
|
Argument validation and persona permission gates still apply to every inner call; scripts do not
|
|
@@ -66,13 +96,13 @@ model, not as a wrapper that prints every result in full. `Promise.allSettled()`
|
|
|
66
96
|
siblings when a call rejects; a fulfilled `bash` call still requires checking `exit_code`.
|
|
67
97
|
Only printed/returned script output reaches the model. Nested results therefore do not contribute
|
|
68
98
|
raw bytes or invisible reminders to pi-persona's context-burn nudges; an actual successful nested
|
|
69
|
-
`delegate`/`council` still resets the hand-off streak.
|
|
99
|
+
`delegate`/`council`/`flow` still resets the hand-off streak.
|
|
70
100
|
|
|
71
101
|
Pi identifies calls made through codemode's `ctx.executeTool` with `parentToolCallId`. If a nested
|
|
72
102
|
delegation report is relayed with `[BLOCKED]` or `FLAG: UNKNOWN`, only the outer model-visible result
|
|
73
103
|
gets the persistence checkpoint and its expandable card. Discarding the report creates no reminder
|
|
74
104
|
and never alters the programmatic inner result. See [the nudge contract](./ARCHITECTURE.md#supervision--the-waiting-model)
|
|
75
|
-
for the differences between
|
|
105
|
+
for the differences between inline (headless) and background reports.
|
|
76
106
|
|
|
77
107
|
The outer code/result card belongs to Pi, not pi-persona's delegate renderer. Keep bulky details
|
|
78
108
|
expandable (`Ctrl+O` by default; `/hotkeys` shows active bindings). `Ctrl+T` toggles thinking blocks
|
|
@@ -94,20 +124,25 @@ a live pending ask on the exact child handle, never inferred from its last activ
|
|
|
94
124
|
|
|
95
125
|
| Surface | Needs | What you get |
|
|
96
126
|
|---|---|---|
|
|
97
|
-
| **Observe and control** | any persona | `peek` inspects async sub-agents; `
|
|
98
|
-
| **Retrieve** | any persona | `result { to }` returns one retained run payload; `message { messageId }` returns one retained bus message. History is bounded to 256 messages and 256,000 body characters, and retrieval never starts a worker |
|
|
99
|
-
| **Message bus** | `coaching: true` | children get `contact_supervisor
|
|
127
|
+
| **Observe and control** | any persona | `peek` inspects async sub-agents; `steer` sends a soft correction; `stop` requests cancellation, and `stop { to: "all" }` cancels every running run, `council` and `flow` included (runs already stopping are skipped, never force-cleared in bulk; a slash or mandated run is stopped at shutdown, not by this). The `f9` overlay provides the same controls (`s`, `x`, `X`). Cancelling a worker does not undo existing changes; an unknown id on `result`, `steer` or `stop` returns a miss text listing the known runs |
|
|
128
|
+
| **Retrieve** | any persona | `result { to }` returns one retained run payload (`offset`/`limit` page a bounded view without collecting it; `collect: true` acknowledges whole-body collection of a live run); `result { ref, offset, limit }` reads a page of a retained terminal result after reload; `results` lists retained terminal results with immutable refs; `message { messageId }` returns one retained bus message. History is bounded to 256 messages and 256,000 body characters, terminal results to 128 entries / 8 MiB per session, and retrieval never starts a worker |
|
|
129
|
+
| **Message bus** | bus allowed; in-process children also require `coaching: true` | broker-connected children and coached in-process children get `contact_supervisor`, subject to explicit empty tool grants and exclusions; progress appears in results and `intercom inbox`, while a blocking `decision` wakes the supervisor for `intercom reply` |
|
|
100
130
|
| **Sibling peer comm** | strategy opt-in | `debate` and `pair` members always get one-way `contact_peer`; `map` and `synthesize` add it with `params: { peers: true }` |
|
|
101
131
|
|
|
102
|
-
|
|
103
|
-
A
|
|
104
|
-
that
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
132
|
+
When supervisor contact is available, an async child's `decision` or `interview` waits for a supervisor reply.
|
|
133
|
+
A headless (inline) child posts the question one-way without waiting: the supervisor is parked
|
|
134
|
+
in that call and cannot answer. The decision/interview remains unresolved; the child may continue
|
|
135
|
+
only independent work already authorized, otherwise it returns a blocked/partial result. A timeout,
|
|
136
|
+
disconnection or failure is never permission to invent an answer. Results expose `outcome` as
|
|
137
|
+
`reported`, `answered`, `unavailable`, `timed-out`, `cancelled` or `failed`; `delivered` means only
|
|
138
|
+
confirmed delivery, not a reply or approval (false can mean unconfirmed). An already-cancelled call
|
|
139
|
+
sends nothing. Progress messages remain one-way.
|
|
140
|
+
|
|
141
|
+
Delegated output is untrusted and is fenced before it reaches the supervisor. Interactive
|
|
142
|
+
delegation always runs in the background: continue independent work, and when only children remain, end the turn for
|
|
143
|
+
automatic completion follow-ups; never sleep, poll, or arm a `timer` to wait for children or monitors.
|
|
144
|
+
Async runs report failures to the supervisor, and a repeated identical failed delegation is stopped by
|
|
145
|
+
the runtime ledger before another child is spawned. A run whose model's provider fails at call time (auth,
|
|
111
146
|
outage, 5xx) may retry the same model id through a compatible fallback provider when its selection
|
|
112
147
|
is unpinned; explicit delegate provider pins remain strict. Strategies and flows instead recover a
|
|
113
148
|
model/provider failure once on the current main model, including unavailable saved or pinned choices.
|
|
@@ -171,18 +206,56 @@ and your own open asks. A claim's `write_set` is advisory, not enforced: a super
|
|
|
171
206
|
coordinate (`exocom_ask`) or claim the path itself; calling the same tool again on the same path is
|
|
172
207
|
then allowed through (one warning per claim + normalized path, not a standing lock).
|
|
173
208
|
|
|
209
|
+
### Exocom collaboration tools
|
|
210
|
+
|
|
211
|
+
The external plane exposes fifteen call-time-gated tools: `exocom_list`, `exocom_send`,
|
|
212
|
+
`exocom_name`, `exocom_claim`, `exocom_ask`, `exocom_answer`, `exocom_decline`, `exocom_wait`,
|
|
213
|
+
`exocom_release`, `exocom_progress`, `exocom_status`, `exocom_task`, `exocom_offer`,
|
|
214
|
+
`exocom_publish`, and `exocom_profile`. Persona denials still apply during an active session; a
|
|
215
|
+
foreign-workspace member does not receive usable `exocom_claim` access.
|
|
216
|
+
|
|
217
|
+
| Tool | Contract |
|
|
218
|
+
|---|---|
|
|
219
|
+
| `exocom_list`, `exocom_send`, `exocom_name` | Discover session-qualified targets, send a one-way postcard, or set this session's display handle. A rename does not change the routing identity. |
|
|
220
|
+
| `exocom_claim`, `exocom_release`, `exocom_progress`, `exocom_status` | Declare advisory repository-relative ownership, release it, add progress, or inspect current ledger state. Claims do not enforce OS-level write access. |
|
|
221
|
+
| `exocom_ask`, `exocom_answer`, `exocom_decline`, `exocom_wait` | Send a targeted question that creates an obligation, settle an incoming ask, or arm a non-blocking wake for an answer. |
|
|
222
|
+
| `exocom_task` | Create a voluntary task (creation does not launch a worker), take it, report progress, finish it as `done` or `abandoned`, or inspect retained tasks. Use `list` then `get` for full details. |
|
|
223
|
+
| `exocom_offer` | Send an optional invitation for an open task to a peer or the pool. It expires after one hour by default and at most 24 hours; it never creates an ask or an obligation to answer. |
|
|
224
|
+
| `exocom_publish` | Share an explicit bounded evidence excerpt for a task, discover titles/message ids by `work_key`, and retrieve one excerpt by `msg_id`. This does not expose an `intercom` terminal-result archive. |
|
|
225
|
+
| `exocom_profile` | Read, set or clear this session's self-reported capability labels and availability. Up to eight labels of 48 characters each; availability is `available`, `busy`, `away` or unknown. It never grants permission or verifies skill. |
|
|
226
|
+
|
|
227
|
+
`exocom_task list` is discovery: omit `work_key` and `task_id`, then use the returned identifiers for
|
|
228
|
+
`get` or a task action. Summary pages default to 10 rows; `detail: true` defaults to 5, and an
|
|
229
|
+
explicit detailed limit above 5 is rejected. `exocom_task create` returns `task_id`, which equals
|
|
230
|
+
the creation message id. Carry it with `work_key` for take/progress/finish, offers and evidence
|
|
231
|
+
publication; the key alone is only a lookup name and can be reused after retention. Write-set pickup
|
|
232
|
+
and claim are committed atomically under the ledger lock. Read-only tasks can be taken from another
|
|
233
|
+
workspace scope. A task whose owner leaves becomes stale and cannot be taken over automatically.
|
|
234
|
+
Detailed paths are available through `exocom_task({ action: "get", work_key, task_id })`;
|
|
235
|
+
paginated list summaries may clip the write set.
|
|
236
|
+
|
|
237
|
+
While an incoming ask is pending, allowed actions are answer/decline, `exocom_name`, status, explicit
|
|
238
|
+
collaboration reads (`exocom_task` list/get, `exocom_publish` read, `exocom_profile` get), and
|
|
239
|
+
read-only filesystem tools. Profile edits and other mutations wait until the ask is settled. Identity
|
|
240
|
+
metadata does not settle it. Task, offer and evidence records are each capped at 64 and share a
|
|
241
|
+
128 KiB state budget; terminal or stale tasks and expired offers are retained for up to an hour,
|
|
242
|
+
while evidence is retained for up to an hour after publication. Active tasks remain while their owner
|
|
243
|
+
lease is live. See the [cross-session collaboration guide](./COLLABORATION.md) for workflows and
|
|
244
|
+
bounded examples.
|
|
245
|
+
|
|
174
246
|
## Configuration and data
|
|
175
247
|
|
|
176
248
|
Personas and agents are Markdown files with YAML frontmatter. Teams, flows, contracts, and presets
|
|
177
249
|
are data files. Discovery precedence is builtin < user `~/.pi/agent/persona` < project `.pi/`.
|
|
178
250
|
Personas and agents are loaded from the user and project agent folders; bundled persona and agent
|
|
179
251
|
files are seed sources. A fresh install has no installed personas until `/persona seed`,
|
|
180
|
-
`/persona restore`, or opt-in first-run seeding installs them.
|
|
252
|
+
`/persona restore`, or opt-in first-run seeding installs them. With none installed, F8, `/doctor` and
|
|
253
|
+
`/persona list` all point to `/persona seed`.
|
|
181
254
|
|
|
182
255
|
| Definition | Location | Purpose |
|
|
183
256
|
|---|---|---|
|
|
184
257
|
| Persona | `personas/*.md` or installed `agents/*.md` with `persona: true` | supervisor prompt, capabilities, delegation, council, orchestration, and coaching |
|
|
185
|
-
| Agent | `agents/*.md` or project `.pi/agents/*.md` | worker prompt, optional tools/model/isolation/MCP |
|
|
258
|
+
| Agent | `agents/*.md` or project `.pi/agents/*.md` | worker prompt, optional tools/model/isolation/MCP/writeSet |
|
|
186
259
|
| Team | `teams.yaml` | named roster of bare agent names or inline `{ agent, role, model, skills }` members |
|
|
187
260
|
| Flow | `flows/*.flow.json` | strategy phases connected by `needs`, optionally gated |
|
|
188
261
|
| Contract | `contracts/*.contract.json` | structured output fields requested by name and pinned per run |
|
|
@@ -268,6 +341,17 @@ Reset removes only that saved key (`null` in a settings patch), revealing lower-
|
|
|
268
341
|
such as a bare agent assignment; inline model pins remain read-only. “Other saved assignments” lets
|
|
269
342
|
you remove keys outside the selected profile without exposing unsafe legacy key text.
|
|
270
343
|
|
|
344
|
+
In the TUI, the picker uses Pi's native editable search field (including paste and cursor movement).
|
|
345
|
+
Search matches model names, IDs and providers; an exact qualified reference takes precedence. The
|
|
346
|
+
participant's current eligible model is selected initially and marked separately from the session
|
|
347
|
+
provider indicator. Editing the query keeps the selected model while it still matches. Rows retain
|
|
348
|
+
the qualified reference and show context, reasoning and vision hints when supplied by the same host
|
|
349
|
+
catalog snapshot; missing metadata is not inferred. Pending settings choices are reflected when a
|
|
350
|
+
picker is reopened, and an unresolved pending reset is not presented as an active model. RPC keeps
|
|
351
|
+
its native selection dialog. These are presentation changes only: eligibility, provider pins,
|
|
352
|
+
refresh policy and the `models` tool's substring search are unchanged. No favorites or recents are
|
|
353
|
+
stored.
|
|
354
|
+
|
|
271
355
|
The existing `/persona models [council-persona]` shortcut remains available for the active caller.
|
|
272
356
|
It refreshes the model catalog before editing, and a named council profile does not change which
|
|
273
357
|
persona owns the saved assignments. Use the Models action in `/persona-settings` when you need to
|
|
@@ -292,7 +376,8 @@ validation, the owning consumer and contract tests—not by adding another setti
|
|
|
292
376
|
Entries are plain tool names or `*` patterns; Pi's `+name`/`-name` default-tool modifier
|
|
293
377
|
syntax is not an allowlist and is rejected. Use the `deny` field to remove tools. Omit `tools` to
|
|
294
378
|
inherit the session tool set. `model`, `isolation: worktree`,
|
|
295
|
-
`mcp: true`,
|
|
379
|
+
`mcp: true`, `writeSet` (a list of repository-relative paths the agent alone writes, inherited by
|
|
380
|
+
write-capable delegate legs that name none), and `purpose` are optional agent metadata. The body is the agent prompt. Inline roster
|
|
296
381
|
members specialise one agent with a role, model, or skills without requiring another agent file.
|
|
297
382
|
|
|
298
383
|
### Multi-agent quick start
|
|
@@ -317,7 +402,8 @@ delegate({
|
|
|
317
402
|
stopConditions: ["Stop after finding the cause or report the missing evidence"]
|
|
318
403
|
}
|
|
319
404
|
})
|
|
320
|
-
|
|
405
|
+
// The call returns a run id at once: end the turn. The completion arrives as a follow-up;
|
|
406
|
+
// `intercom result { to }` fetches a settled run, and peek/steer/stop are for when the user asks.
|
|
321
407
|
```
|
|
322
408
|
|
|
323
409
|
For independent Pi processes, open the same workspace in two terminals with `pi --exocom` and use
|
|
@@ -356,8 +442,9 @@ You research thoroughly. For independent sub-questions, fan out `scout` sub-agen
|
|
|
356
442
|
override it for one call without editing the file:
|
|
357
443
|
|
|
358
444
|
```yaml
|
|
359
|
-
# teams.yaml — one reviewer agent,
|
|
445
|
+
# teams.yaml — one reviewer agent, four lens roles
|
|
360
446
|
review:
|
|
447
|
+
- { agent: reviewer, role: "Focus ONLY on the CORRECTNESS lens" }
|
|
361
448
|
- { agent: reviewer, role: "Focus ONLY on the SECURITY lens" }
|
|
362
449
|
- { agent: reviewer, role: "Focus ONLY on the PERFORMANCE lens" }
|
|
363
450
|
- { agent: reviewer, role: "Focus ONLY on the TESTS lens" }
|
|
@@ -432,6 +519,9 @@ overlapping or missing ownership for parallel writers, and refuses a declared ve
|
|
|
432
519
|
start before or beside a material writer in the same call or while a mutating background run is in
|
|
433
520
|
flight. Only `read`, `grep`, `find`, and `ls` count as read-only; shell-capable, MCP-enabled, and
|
|
434
521
|
unknown toolsets fail closed as writers. `writeSet` is a scheduling contract, not an OS sandbox.
|
|
522
|
+
An agent can declare the area it alone writes (`writeSet: [.research/]` in `research`); a write-capable leg that gives
|
|
523
|
+
no `writeSet` of its own inherits it, so a write-capable but read-in-intent agent is not refused as an
|
|
524
|
+
unknown writer, and a leg that does name one keeps its own. Read-only legs do not inherit defaults.
|
|
435
525
|
|
|
436
526
|
```markdown
|
|
437
527
|
---
|
|
@@ -491,7 +581,7 @@ unsafe-sink risks, secrets/token mishandling, and missing input validation. Cite
|
|
|
491
581
|
```
|
|
492
582
|
|
|
493
583
|
**A flow with a human checkpoint** — phases are journaled and dependents wait for a `gate: true`
|
|
494
|
-
approval. Save as `.pi/flows/gated-build.flow.json`:
|
|
584
|
+
approval. The checkpoint prompt shows the gated phase's output (12 lines) and what runs next, with Reject as the default. A rejection is reported as `flow stopped · checkpoint <id>` and keeps the gated output; it is not a failure, though a mandatory flow still fails closed. Headless sessions always reject checkpoints. Save as `.pi/flows/gated-build.flow.json`:
|
|
495
585
|
|
|
496
586
|
```json
|
|
497
587
|
{
|
|
@@ -536,12 +626,23 @@ test; the data-driven definitions above require no core change.
|
|
|
536
626
|
## Commands, flags, and environment
|
|
537
627
|
|
|
538
628
|
**Keys** — `f8` cycles persona; `f9` or `/agents` opens the agent overlay: ↑↓ navigate, ⏎ open, `x`
|
|
539
|
-
stop, `s` steer, and Esc close.
|
|
629
|
+
stop, `s` steer, and Esc close. `X` (list view) stops every running leaf agent that `x` could stop (armed
|
|
630
|
+
timers and monitors are not agents and are skipped): the first press states the count (`press X again to
|
|
631
|
+
stop N running agents`), any other key or a changed set re-asks. It is offered only for two or more;
|
|
632
|
+
queued or later stages may still start.
|
|
540
633
|
|
|
541
634
|
**Commands** — `/persona [name|off|list|reload|seed|restore|models [council-persona]]` ·
|
|
542
635
|
`/persona-settings [show]` · `/models [query]` · `/orchestrate <task>` · `/flow <name> <task>` ·
|
|
543
636
|
`/peek [id]` · `/exocom` · `/doctor`.
|
|
544
637
|
|
|
638
|
+
`/persona off` is the deactivation command. `/persona restore` force-restores every bundled resource
|
|
639
|
+
into the user persona directory: personas and agents, flows, contracts, presets, `teams.yaml`, and
|
|
640
|
+
the shared prompt pair. Existing bundled destinations are overwritten; additional user files are
|
|
641
|
+
not pruned. For example, custom `agents/pippo.md` (a persona) and `agents/pluto.md` (an agent) survive
|
|
642
|
+
unchanged. Reusing a bundled destination filename means opting into its replacement. This is not a
|
|
643
|
+
reset of `settings.json`, credentials, sessions or project-local overrides. Definitions are reloaded
|
|
644
|
+
afterward, including any preserved custom persona that was active.
|
|
645
|
+
|
|
545
646
|
`/doctor` reports the cross-process broker's lifecycle on one line: `broker: on — endpoint …` once
|
|
546
647
|
the host is listening, `broker: on — (starting…)` mid-attempt, or
|
|
547
648
|
`broker: on — (not started — no child-engine build yet)` before any child-engine build has run. A
|
|
@@ -552,7 +653,7 @@ build retries. A connected broker child's status shows `⇄ <handle>`; if that c
|
|
|
552
653
|
status flips to `⇄ offline` and a fresh ask on it fails fast instead of hanging.
|
|
553
654
|
|
|
554
655
|
`/doctor` also reports the installed host's version against this extension's floor: `pi: <version>
|
|
555
|
-
(requires ≥ 1.
|
|
656
|
+
(requires ≥ 1.4.0)`, with a trailing `— BELOW FLOOR` marker once an installed version fails the
|
|
556
657
|
check (`src/core/pi-compat.ts`). `pi: unknown` means the host's own `package.json` could not be
|
|
557
658
|
resolved (a non-standard install layout) — not a failed check.
|
|
558
659
|
|
|
@@ -567,11 +668,11 @@ from a different cwd. Pi owns `--model <provider/id>`, `--thinking
|
|
|
567
668
|
| `PI_PERSONA_CHILD_THINKING` | inherited | reasoning effort for child-engine sub-agents |
|
|
568
669
|
| `PI_PERSONA_SEED` | off | `on` auto-installs bundled personas on first run |
|
|
569
670
|
| `PI_PERSONA_BROKER` | on | `off` disables the cross-process comm plane for child, worktree, and MCP legs |
|
|
570
|
-
| `PI_PERSONA_PEEK_MS` | 30000 | fast async stall/message
|
|
671
|
+
| `PI_PERSONA_PEEK_MS` | 30000 | fast async stall-card/message tick; `0` disables it |
|
|
571
672
|
| `PI_PERSONA_CHECKIN_MS` | 300000 | durable expandable operator status entry while async children run; does not start a model turn; `0` disables it |
|
|
572
673
|
| `PI_PERSONA_AGENT_MAX_MS` | off | opt-in per-agent hard wall-clock cap; unset leaves healthy work running |
|
|
573
674
|
| `PI_PERSONA_AGENT_STARTUP_MS` | 300000 | startup deadline for a child that makes no progress; `0` disables it. Like the idle window, a leg waiting on a supervisor reply is not idle: the watchdog re-arms while its ask is pending, instead of killing on a blind ceiling |
|
|
574
|
-
| `PI_PERSONA_NUDGE` | on | `off` silences delegation and persistence nudges;
|
|
675
|
+
| `PI_PERSONA_NUDGE` | on | `off` silences delegation and persistence nudges and disables the repeated peek/result and long-sleep guards; inline-result checkpoints stay in model-visible tool results and are mirrored to durable, expandable TUI-only cards |
|
|
575
676
|
| `PI_PERSONA_EXOCOM` | off | `1` joins the current workspace Exocom scope; cross-workspace selection is CLI-only |
|
|
576
677
|
| `PI_PERSONA_SPINE` | off | `on` or a path enables the shared behavioral layer; see [`SPINE.md`](./SPINE.md) |
|
|
577
678
|
| `PI_PERSONA_SPINE_LEGS` | follows `PI_PERSONA_SPINE` | selector for delegated legs, allowing all four spine measurement arms |
|
|
@@ -581,7 +682,7 @@ from a different cwd. Pi owns `--model <provider/id>`, `--thinking
|
|
|
581
682
|
| `PI_PERSONA_KEY` | `f8` | keybinding that cycles installed personas |
|
|
582
683
|
| `PI_PERSONA_PERSIST` | on | `off` stops remembering the last-selected persona across sessions |
|
|
583
684
|
| `PI_PERSONA_DELEGATE_DEFAULT` | allow | `deny` (or an off-word) makes an unlisted delegate target default-deny instead of default-allow |
|
|
584
|
-
| `PI_PERSONA_ASYNC_RETAIN` |
|
|
685
|
+
| `PI_PERSONA_ASYNC_RETAIN` | 64 | how many settled-but-uncollected async runs are retained before FIFO-evicting the oldest (equals the `tasks` cap, so one call can never evict itself) |
|
|
585
686
|
| `PI_PERSONA_LEDGER_V2` | off | `on` widens the delegation-ledger retry-veto key to also include role/tools/isolation, not just agent+model+task |
|
|
586
687
|
| `PI_PERSONA_LEG_CHANGE_REPORT` | on | `off` disables the non-worktree files-changed report (two `git status` spawns per leg) |
|
|
587
688
|
|
package/docs/SPINE.md
CHANGED
|
@@ -10,8 +10,8 @@ two unconditional guidelines: *be concise* and *show file paths clearly* (plus o
|
|
|
10
10
|
bash-usage line, and whatever the caller passes as `promptGuidelines`). It carries no behavioral
|
|
11
11
|
direction beyond that — nothing about scope discipline, verification, irreversibility, or how to
|
|
12
12
|
treat text produced by another agent. Every pi-persona persona has therefore grown its own copy of those rules, and the copies
|
|
13
|
-
drift: `elite.md`
|
|
14
|
-
|
|
13
|
+
drift: `elite.md` still carries its own delegation reflexes and evidence rules, while the other
|
|
14
|
+
bundled personas now share one shape.
|
|
15
15
|
|
|
16
16
|
The spine is that shared layer, written once. It sits between Pi's base prompt and the persona body,
|
|
17
17
|
so a persona can be about *identity and method* instead of restating the same baseline every time.
|
package/docs/STRATEGIES.md
CHANGED
|
@@ -11,7 +11,7 @@ copy-paste recipes see [`REFERENCE.md`](./REFERENCE.md); for the system design s
|
|
|
11
11
|
|
|
12
12
|
## The Strategy SDK
|
|
13
13
|
|
|
14
|
-
A strategy is `{ name, params?, run(input, sdk) }` (`src/orchestration/sdk.ts`). `run` receives the
|
|
14
|
+
A strategy is `{ name, params?, when?, roster?, required?, run(input, sdk) }` (`src/orchestration/sdk.ts`). `run` receives the
|
|
15
15
|
task/roster/params and a constrained `sdk`; it returns one `AgentResult`. The engine is injected, so
|
|
16
16
|
a strategy is backend-agnostic and unit-testable against a stub engine.
|
|
17
17
|
|
|
@@ -47,6 +47,12 @@ worker/verifier waves at splitting and the remaining verifier wave during worker
|
|
|
47
47
|
`critic-loop`, and `council-rounds` reserve their remaining required steps/rounds. Recovery must not
|
|
48
48
|
turn a usable partial panel into a run-fatal child-budget overflow.
|
|
49
49
|
|
|
50
|
+
Who owns which limit: a `council` or `flow` TOOL run takes ONE slot of the delegate launch pool
|
|
51
|
+
(`maxConcurrency`, see [ARCHITECTURE.md](ARCHITECTURE.md#supervision--the-waiting-model)) for its whole life, and
|
|
52
|
+
the SDK's semaphore below gates only the legs INSIDE it, so a strategy's members never contend with delegate
|
|
53
|
+
legs for pool slots. Interactive sessions launch the run in the background (a receipt, then ONE completion
|
|
54
|
+
follow-up); headless sessions join it inline. A strategy needs nothing to opt in.
|
|
55
|
+
|
|
50
56
|
Every `agent()` call in one SDK instance shares a concurrency semaphore, including direct
|
|
51
57
|
`Promise.all` calls and overlapping `parallel()` batches. A requested batch concurrency may lower
|
|
52
58
|
the ceiling, never raise it. Cancellation removes queued legs before they reach an engine.
|
|
@@ -58,7 +64,7 @@ token or billing cap.
|
|
|
58
64
|
|
|
59
65
|
A team member is a bare agent name OR an inline `{ agent, role, model, skills }` map that specialises
|
|
60
66
|
ONE agent (`roster.ts` · `rosterSpec` normalises both). So `review` is one `reviewer` agent run under
|
|
61
|
-
|
|
67
|
+
four lens roles (CORRECTNESS · SECURITY · PERFORMANCE · TESTS), not four files. Every strategy must run members
|
|
62
68
|
through `rosterSpec` to honour the specialisation — **`critic-loop` is the one to watch**: it resolves
|
|
63
69
|
`generator`/`critic` to full specs so a role-carrying roster works, while still accepting a bare-name
|
|
64
70
|
`params.generator`/`critic` override.
|
|
@@ -79,15 +85,15 @@ text, never `role` (or the derived tree key drifts from the seeded one).
|
|
|
79
85
|
|
|
80
86
|
| Strategy | Mechanism | Params (default) | Comm/engine features |
|
|
81
87
|
|---|---|---|---|
|
|
82
|
-
| `fanout` | Every roster agent on the same task in parallel, then `aggregate`. | — | roster-role |
|
|
88
|
+
| `fanout` | Every roster agent on the same task in parallel, then `aggregate`. Sections are labelled by lens (`reviewer · SECURITY`); `structured.results[i].member` carries the label when it differs from the agent name. | — | roster-role |
|
|
83
89
|
| `pipeline` | Roster in SEQUENCE, each builds on the prior output; answer = last step. | — | roster-role |
|
|
84
|
-
| `map` | A splitter breaks the task into a runtime list; a worker runs once per item in parallel, then `aggregate
|
|
90
|
+
| `map` | A splitter breaks the task into a runtime list; a worker runs once per item in parallel, then `aggregate`; sections are labelled `item N: <text>`. | `maxItems` (default AND ceiling: maxChildren − 1 without verification, halved and rounded down with `verify`, minimum 1; the splitter takes a slot; a larger value is clamped and the drop is noted in the output), `peers` (false), `ownership` ("off" — "off"/"declare"/"enforce": ignore, record, or gate on the splitter's per-item `writeSet`; always exposed as `structured.items`, a per-item status ledger), `verify` ("" — agent that re-checks each COMPLETED item read-only; one extra child per completed item, empty = off) | roster-role, opt-in peers |
|
|
85
91
|
| `critic-loop` | Generator proposes, critic attacks; `reject`/`revise` triggers another draft, and only explicit `approve` succeeds. Exhaustion fails closed with the last reviewed draft + unresolved critique (never an unreviewed tail revision). | `generator` (roster[0]), `critic` (roster[1]), `rounds` (positive integer, 3) | roster-role, `outputContract` |
|
|
86
|
-
| `magi` | Parallel INDEPENDENT votes from distinct-persona cores → majority/unanimity, tally + minority report; one anonymised reflection round by default. | `aggregate` ("majority"), `reflect` (true) | vote reducer |
|
|
92
|
+
| `magi` | Parallel INDEPENDENT votes from distinct-persona cores → majority/unanimity, tally + minority report; one anonymised reflection round by default. A core whose reflection leg fails (other than a stop) keeps its round-1 vote; the footer says so, and a reflection skipped for budget is named (`token budget`/`child budget`). | `aggregate` ("majority"), `reflect` (true) | vote reducer |
|
|
87
93
|
| `council-rounds` | Multi-round `magi`, best-of-X: the whole roster re-deliberates carrying the debate forward until a supermajority, else best-by-confidence on the last round. | `rounds` (3), `bestOf` (majority), `aggregate` ("majority") | vote reducer |
|
|
88
94
|
| `debate` | 2+ members work the same task in parallel and exchange positions LIVE via `contact_peer`, then a majority vote settles it. | `bestOf` (majority), `aggregate` ("majority") | **peers always**, vote reducer |
|
|
89
95
|
| `judge` | A panel answers in parallel; one impartial arbiter picks on an anonymised, shuffled ballot. Only a successful arbiter result can select a winner; partial structured output from a failed/aborted arbiter fails closed. | `judge` (required), `contract` (none) | judge reducer |
|
|
90
|
-
| `synthesize` | Parallel gatherers → one synthesiser merges the
|
|
96
|
+
| `synthesize` | Parallel gatherers → one synthesiser merges the findings, labelled by lens like `fanout`, into a single coherent answer (the "reduce" `fanout` lacks). Partial panels explicitly name missing gatherers in the merge input, returned output and coverage metadata. | `synthesizer` (roster[0]), `peers` (false) | roster-role, opt-in peers |
|
|
91
97
|
| `pair` | A driver executes while a navigator inspects the same ground live (risk checklist up front, corrections per milestone, final review attached). | — | **peers always** (both legs) |
|
|
92
98
|
| `compete` | N competitors implement the same task in ISOLATED git worktrees; a successful blind judge picks; the winner is returned as a unified diff for the SUPERVISOR to apply. If judging fails, every valid diff is returned unjudged and the strategy fails closed. | `judge` (required), `ballotDiffChars` (6000) | **`isolation: worktree`**, judge reducer |
|
|
93
99
|
|
|
@@ -189,6 +195,11 @@ Picker preflight reads these declarations instead of guessing participants from
|
|
|
189
195
|
- The **`council` tool** warns (via `ui.notify`, never hard-fails — I2 lenient) when a call passes a
|
|
190
196
|
key the active strategy doesn't declare, e.g. `ignoring unknown param "reflct" for magi (known:
|
|
191
197
|
reflect, aggregate)`. A correct call is behaviourally unchanged.
|
|
198
|
+
- The **`council` tool description** renders one line per strategy from the registry: `name(params, required*)
|
|
199
|
+
— when; roster: positions`. `required` keys (`judge` and `compete` need `params.judge`) are refused at call time
|
|
200
|
+
— `council failed: "<strategy>" requires params.<key> — …` — before any run, tree row or model picker exists
|
|
201
|
+
(`missingRequiredParams`); a persona's own `council:` params count, so the bundled personas are unaffected.
|
|
202
|
+
An unknown strategy or roster is not judged up front: the run reports it in its completion follow-up.
|
|
192
203
|
- **`/doctor`** lists each strategy's params live, so the schema is discoverable and this canonical
|
|
193
204
|
table can't drift from the code.
|
|
194
205
|
|
|
@@ -227,7 +238,8 @@ Correct or remove the field before calling that persona's council, even with per
|
|
|
227
238
|
|
|
228
239
|
The mandatory `orchestration:` path fires pre-turn on the raw user text, so it takes no dynamic
|
|
229
240
|
per-call params (author params are threaded intact) — that is the difference between the two modes:
|
|
230
|
-
`council:` is convened on demand and fully overridable; `orchestration:` runs the shape automatically.
|
|
241
|
+
`council:` is convened on demand and fully overridable; `orchestration:` runs the shape automatically. It stays inline (its result IS the first answer, unlike
|
|
242
|
+
the backgrounded `council` tool) and registers its own run-level abort, so shutdown ends the whole run.
|
|
231
243
|
Its runtime status survives the hand-off into the supervisor turn: only `ok:true` is presented as a
|
|
232
244
|
ruling. A failed, cancelled, or unresolved run is visibly labelled as such, keeps its fenced evidence,
|
|
233
245
|
and must be repaired/re-verified rather than being laundered into a completion claim.
|
|
@@ -235,7 +247,10 @@ and must be repaired/re-verified rather than being laundered into a completion c
|
|
|
235
247
|
## Adding a strategy
|
|
236
248
|
|
|
237
249
|
1. `src/orchestration/strategies/<name>.ts` — export a `Strategy` composing `agent`/`parallel`/
|
|
238
|
-
`reduce.*`. Declare `params` if it reads any
|
|
250
|
+
`reduce.*`. Declare `params` if it reads any, a one-line `when` (which problem class it fits), `roster`
|
|
251
|
+
only where member position matters (`[splitter, worker]`), and `required` for params a call cannot omit.
|
|
252
|
+
The `council` description is generated from these; never hand-write a strategy list. Inject any
|
|
253
|
+
per-member protocol via the TASK text.
|
|
239
254
|
2. Register it in `strategy.ts` `BUILTINS`.
|
|
240
255
|
3. Add a unit test on a stub engine (assert the spec it builds, not a live model).
|
|
241
256
|
4. If it needs a new comm/engine capability rather than composing existing primitives, that is a core
|
package/docs/TELEMETRY.md
CHANGED
|
@@ -15,6 +15,7 @@ broadcast receipts are bounded and omitted mappings remain unknown. Do not repla
|
|
|
15
15
|
`id` with a wire ID, infer a mapping by timestamp/alias, or merge observations from different streams.
|
|
16
16
|
Single delegates publish their terminal progress before tree removal, so a completed worker remains
|
|
17
17
|
`done` in the telemetry instead of being mistaken for a stopped in-flight leg.
|
|
18
|
+
Monitor and timer rows of the local agent tree are not agents and are never published: no `agent.*` event carries a `monitor:` or `timer:` id.
|
|
18
19
|
|
|
19
20
|
The pi-persona producer writes semantic projections under `telemetry/v2/<workspace>/<producerId>/`. `<workspace>` always identifies the Pi process's actual cwd; joining another Exocom scope does not rewrite telemetry identity. It never persists task/prompt text, tool arguments/activity, model output, paths, secrets, or message bodies. Known pi-persona event payloads are allowlisted; an unreviewed producer event retains only its envelope/type (payload `{}`) at the producer and consumer boundary. Future producers must add a reviewed allowlist/schema before publishing data intended for a consumer.
|
|
20
21
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deep-review",
|
|
3
|
-
"description": "Fan security/performance/tests out in parallel and merge them into one verdict, then let the MAGI council rule on what to do — a DAG over strategies.",
|
|
3
|
+
"description": "Fan correctness/security/performance/tests out in parallel and merge them into one verdict, then let the MAGI council rule on what to do — a DAG over strategies.",
|
|
4
4
|
"phases": [
|
|
5
5
|
{ "id": "gather", "strategy": "synthesize", "roster": "review", "params": { "synthesizer": "reviewer" } },
|
|
6
6
|
{ "id": "decide", "strategy": "magi", "roster": "magi", "needs": ["gather"] }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeondave/pi-persona",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Supervised multi-agent orchestration for Pi — async workers, live steering, cross-session collaboration, and switchable personas.",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"docs/README.md",
|
|
43
43
|
"docs/ARCHITECTURE.md",
|
|
44
44
|
"docs/EXPERIENCE.md",
|
|
45
|
+
"docs/COLLABORATION.md",
|
|
45
46
|
"docs/MONITORS.md",
|
|
46
47
|
"docs/REFERENCE.md",
|
|
47
48
|
"docs/SPINE.md",
|
|
@@ -63,7 +64,8 @@
|
|
|
63
64
|
"test": "node --import tsx --import ./test/setup/hermetic-env.ts --test \"test/**/*.test.ts\"",
|
|
64
65
|
"test:unit": "node --import tsx --import ./test/setup/hermetic-env.ts --test \"test/unit/**/*.test.ts\"",
|
|
65
66
|
"drive": "node --import tsx scripts/drive.ts",
|
|
66
|
-
"smoke:exocom": "node --import tsx scripts/exocom-smoke.mjs"
|
|
67
|
+
"smoke:exocom": "node --import tsx scripts/exocom-smoke.mjs",
|
|
68
|
+
"smoke:wake": "node --import tsx scripts/wake-smoke.mjs"
|
|
67
69
|
},
|
|
68
70
|
"peerDependencies": {
|
|
69
71
|
"@earendil-works/pi-agent-core": "*",
|
|
@@ -93,18 +95,23 @@
|
|
|
93
95
|
"node": ">=22.19.0"
|
|
94
96
|
},
|
|
95
97
|
"devDependencies": {
|
|
96
|
-
"@earendil-works/pi-agent-core": "1.
|
|
97
|
-
"@earendil-works/pi-ai": "1.
|
|
98
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
99
|
-
"@earendil-works/pi-tui": "1.
|
|
98
|
+
"@earendil-works/pi-agent-core": "1.4.0",
|
|
99
|
+
"@earendil-works/pi-ai": "1.4.0",
|
|
100
|
+
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
101
|
+
"@earendil-works/pi-tui": "1.4.0",
|
|
100
102
|
"@types/node": "^22.20.4",
|
|
101
103
|
"fast-check": "^4.10.2",
|
|
102
104
|
"tsx": "^4.23.13",
|
|
103
|
-
"typebox": "1.
|
|
105
|
+
"typebox": "1.4.2",
|
|
104
106
|
"typescript": "^7.0.2"
|
|
105
107
|
},
|
|
108
|
+
"overrides": {
|
|
109
|
+
"@earendil-works/pi-coding-agent@1.4.0": {
|
|
110
|
+
"undici": "8.12.3"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
106
113
|
"pi": {
|
|
107
|
-
"image": "https://raw.githubusercontent.com/AeonDave/pi-persona/v1.17.
|
|
114
|
+
"image": "https://raw.githubusercontent.com/AeonDave/pi-persona/v1.17.4/assets/banner.png",
|
|
108
115
|
"video": "https://cdn.jsdelivr.net/gh/AeonDave/pi-persona@6655d281ce7965a75303dd704bd29db73db04070/assets/demo1.mp4",
|
|
109
116
|
"extensions": [
|
|
110
117
|
"./src/extension.ts"
|
package/personas/audit.md
CHANGED
|
@@ -2,28 +2,39 @@
|
|
|
2
2
|
name: audit
|
|
3
3
|
label: "🔬 Audit"
|
|
4
4
|
persona: true
|
|
5
|
+
description: Parallel code and design review. Correctness, security, performance and test lenses run independently and merge into one evidence-backed verdict. Pick it to review a change, file or design without editing it.
|
|
6
|
+
systemPromptMode: append
|
|
7
|
+
delegation:
|
|
8
|
+
requireBrief: true
|
|
5
9
|
council:
|
|
6
10
|
strategy: synthesize
|
|
7
11
|
roster: review
|
|
8
12
|
params: { synthesizer: reviewer, peers: true }
|
|
9
13
|
---
|
|
10
|
-
You are Audit
|
|
11
|
-
request
|
|
12
|
-
|
|
14
|
+
You are Audit, a parallel review supervisor: a panel reads the exact change, file or design the
|
|
15
|
+
request names and you deliver one merged verdict. Use it for "review this"; to build use `dev`, to
|
|
16
|
+
drive a failing suite to green `verify`, to choose between designs `judge` or `magi`.
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
**Method.** Pin the target first: changed paths, diff range, the user's concern. Call `council` with
|
|
19
|
+
just the question: its default panel is yours (correctness, security, performance and tests lenses,
|
|
20
|
+
merged by a `reviewer`). Reviewers have no shell and cannot run `git diff`, so put the changed paths
|
|
21
|
+
and diff hunks in the question. After launching, end your turn: the merged review wakes you
|
|
22
|
+
(headless: the call returns it inline). Fix only on explicit request: delegate one bounded edit per
|
|
23
|
+
finding to `operator` with its own `writeSet`, end your turn, and once the writers have settled
|
|
24
|
+
start a fresh `verifier` against the resulting tree and re-check each fixed finding at its cited
|
|
25
|
+
lines.
|
|
19
26
|
|
|
20
|
-
|
|
21
|
-
confidence
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
**Evidence bar.** A finding stands only with `file:line`, the trigger or precondition, the impact
|
|
28
|
+
and a confidence; a claim about behaviour cites the command or source that showed it. Re-read the
|
|
29
|
+
cited lines of every critical or high finding before calling it confirmed; otherwise it is "reported
|
|
30
|
+
by the panel". A failed lens, a skipped check or an unread area is "not reviewed", never a pass: say
|
|
31
|
+
"no issues" only when every lens returned and you name what was left out.
|
|
25
32
|
|
|
26
|
-
Lead with the verdict
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
**Reporting.** Lead with the verdict: clear, or N issues with the highest severity. Then findings by
|
|
34
|
+
practical risk, each as `file:line`, severity, trigger, impact, confidence and the smallest remedy
|
|
35
|
+
or check; then uncertainty, skipped or failed checks and areas not reviewed; end with the owner's
|
|
36
|
+
next action. If you fixed anything, add what changed and the verifier's result.
|
|
37
|
+
|
|
38
|
+
**Boundaries.** Review only: no edit, fix or relaxed check unless the user asked for fixes. Stay on
|
|
39
|
+
the named target; note out-of-scope observations in one line each, never as findings. When the audit
|
|
40
|
+
exposes a real fork between designs, name it and leave the choice to `judge` or `magi`.
|