@aeondave/pi-persona 1.15.2 → 1.16.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/AGENTS.md +30 -6
- package/CHANGELOG.md +82 -0
- package/README.md +27 -8
- package/SECURITY.md +42 -0
- package/docs/ARCHITECTURE.md +52 -7
- package/docs/EXPERIENCE.md +21 -5
- package/docs/README.md +2 -0
- package/docs/REFERENCE.md +84 -14
- package/docs/STRATEGIES.md +58 -31
- package/docs/TELEMETRY.md +8 -0
- package/package.json +11 -9
- package/src/bus/broker/paths.ts +3 -2
- package/src/core/brief.ts +1 -1
- package/src/core/nudge.ts +3 -4
- package/src/core/pi-compat.ts +3 -3
- package/src/engine/adapter.ts +11 -6
- package/src/engine/async.ts +12 -6
- package/src/engine/inproc.ts +14 -6
- package/src/extension/engine.ts +25 -4
- package/src/extension/hooks.ts +68 -21
- package/src/extension.ts +209 -49
- package/src/orchestration/model-retry.ts +32 -61
- package/src/orchestration/params.ts +27 -1
- package/src/orchestration/roster.ts +80 -3
- package/src/orchestration/sdk.ts +150 -36
- package/src/orchestration/strategies/compete.ts +14 -8
- package/src/orchestration/strategies/council-rounds.ts +8 -1
- package/src/orchestration/strategies/critic-loop.ts +25 -11
- package/src/orchestration/strategies/judge.ts +18 -9
- package/src/orchestration/strategies/magi.ts +42 -93
- package/src/orchestration/strategies/map.ts +41 -19
- package/src/orchestration/strategies/pipeline.ts +2 -2
- package/src/orchestration/strategies/synthesize.ts +18 -11
- package/src/orchestration/types.ts +15 -0
- package/src/persona/model-participants.ts +240 -0
- package/src/persona/orchestrate.ts +44 -2
- package/src/persona/persona.ts +86 -14
- package/src/telemetry/contract.ts +1 -1
- package/src/telemetry/producer.ts +241 -8
- package/src/tools/council.ts +36 -8
- package/src/tools/delegate-tool.ts +162 -24
- package/src/tools/intercom-tool.ts +119 -32
- package/src/ui/agent-overlay.ts +15 -6
- package/src/ui/agent-tree.ts +39 -2
package/AGENTS.md
CHANGED
|
@@ -30,8 +30,18 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
30
30
|
`@earendil-works/pi-*`; never bundle copies.
|
|
31
31
|
- npm publishes as `@aeondave/pi-persona`. Pi supplies the four `@earendil-works/pi-*` packages
|
|
32
32
|
and `typebox`: keep them as `peerDependencies: "*"` with development-only copies, never runtime
|
|
33
|
-
dependencies. The supported host floor
|
|
33
|
+
dependencies. The supported host floor is Pi ≥ 1.0.0 (`MIN_PI_VERSION` and the README); Node.js
|
|
34
|
+
must be ≥ 22.19 to match that host. Keep the npm
|
|
34
35
|
`files` allowlist explicit for docs/artwork, inspect `npm pack --dry-run`, and never publish drafts.
|
|
36
|
+
- Supply-chain controls: pin every GitHub Action to a verified full commit SHA; keep top-level
|
|
37
|
+
token permissions read-only, grant write permissions only to the reporting job that needs them,
|
|
38
|
+
and disable persisted checkout credentials. Dependabot proposes updates; it does not auto-merge.
|
|
39
|
+
Keep the four Pi development packages in one update group so their APIs stay aligned.
|
|
40
|
+
Match `@types/node` to the oldest supported Node major, including in CI; upgrade them together.
|
|
41
|
+
Keep security overrides scoped to the affected development dependency and version; remove them
|
|
42
|
+
when upgrading Pi if the new dependency graph no longer needs them.
|
|
43
|
+
Run the full dependency audit (including development dependencies), tests and typecheck after
|
|
44
|
+
lockfile updates. A development override does not patch a user's installed Pi host.
|
|
35
45
|
- **Cross-OS**: use Pi's spawn/kill/path/temp helpers (`getPiInvocation`, `killProcessTree`), not raw
|
|
36
46
|
`child_process`. Windows kill goes straight to `taskkill /F /T`; always attach an `error` listener.
|
|
37
47
|
- Two engines behind the `StrategyEngine` seam: **InProcessEngine** (`engine/inproc`,
|
|
@@ -78,6 +88,11 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
78
88
|
policy (OpenAI-family → OpenAI providers; Claude-family → the native Claude provider). A caller may
|
|
79
89
|
explicitly opt a pinned run into cross-provider recovery. Only `failureKind === "provider"` reroutes;
|
|
80
90
|
abort/timeout/contract/unknown/agent are terminal.
|
|
91
|
+
Strategy/council/flow runs disable that provider search and use SDK-level main-only recovery:
|
|
92
|
+
`provider`/`unknown-model` may retry ONCE on the current supervisor model, including a saved or
|
|
93
|
+
inline-pinned choice (explicit user-authorized exception). Never borrow a peer model, never restart
|
|
94
|
+
a stopped/timed-out/contract-failed leg, and charge each attempt to child/token limits and usage.
|
|
95
|
+
Ordinary delegate pins remain strict. Recovery must remain visible in metadata/UI and MAGI rulings.
|
|
81
96
|
Engines classify the cause on the `AgentResult` (`failureKind` + resolved `modelUsed`); keep those
|
|
82
97
|
set when you touch `inproc.ts`/`adapter.ts` or the fallback silently stops working.
|
|
83
98
|
- **Fork-bomb guard**: children run with env `PI_PERSONA_DISABLE=1` so pi-persona self-disables inside
|
|
@@ -93,11 +108,13 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
93
108
|
blind retry loops are stopped by the runtime `DelegationLedger` (an identical agent+model+task
|
|
94
109
|
delegation that failed twice is vetoed before it spawns).
|
|
95
110
|
- Dynamic sub-agents: `delegate` shapes an on-the-fly specialist with `role` (extra system prompt,
|
|
96
|
-
appended to the agent's own) + `skills` — prompt-level only, capabilities stay the gate.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
appended to the agent's own) + `skills` — prompt-level only, capabilities stay the gate. Intercom
|
|
112
|
+
`wait` snapshots already-settled reports by default in interactive/RPC sessions; `sync: true` opts
|
|
113
|
+
into a bounded join (≤ the bus-ask timeout). Headless waits default to joining; `sync: false` takes
|
|
114
|
+
a snapshot. Collected reports are discarded from the pending completion follow-up so they are
|
|
115
|
+
never double-reported; snapshots leave running children active. In interactive sessions `delegate`
|
|
116
|
+
is background-by-default (`sync: true` opts a call out; headless `pi -p` defaults to sync so the
|
|
117
|
+
single turn carries the result). An explicit `async` flag takes precedence over `sync` and the default.
|
|
101
118
|
Message ids and run ids are separate: `intercom message { messageId }` retrieves retained bus
|
|
102
119
|
text, `intercom result { to: runId }` retrieves a settled run. Both explicit and automatic inbox
|
|
103
120
|
drains retain bounded history (256 messages / 256,000 body characters). Ask settlement clears
|
|
@@ -120,6 +137,10 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
120
137
|
fills with every leg's body, failures included), while `renderCompletion` scans only `status: "done"`
|
|
121
138
|
runs. A background leg that FAILED while emitting `[BLOCKED]` therefore gets the failure block but no
|
|
122
139
|
persistence note — deliberate (see the `renderCompletion` doc comment), not a bug to "fix" silently.
|
|
140
|
+
Nested reports from codemode's `ctx.executeTool` retain bounded provenance through Pi's explicit
|
|
141
|
+
`parentToolCallId`; never infer nesting from the call-id string. Only an outer result that relays
|
|
142
|
+
the surrender marker gets the note/card. Nested programmatic data is never patched with a reminder,
|
|
143
|
+
and discarded reports never generate an invisible one. Relay state clears at turn/session settlement.
|
|
123
144
|
`config.nudge` (`PI_PERSONA_NUDGE=off`) silences all of it: the `tool_result` hook (the by-hand
|
|
124
145
|
reminder and the sync-result persistence one) and both `renderCompletion` call sites, which take
|
|
125
146
|
their `scan` through the same gate — so a background/`intercom wait` report carries no note either.
|
|
@@ -190,6 +211,9 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
190
211
|
persistence; `src/extension/identity.ts` registers `agent_name` and the pre-name context bootstrap.
|
|
191
212
|
Exocom uses that same state. A delegate's optional `AgentRunSpec.name` is leader-assigned
|
|
192
213
|
display identity, propagated to both engines without changing routing ids.
|
|
214
|
+
Async launch/control cards use that alias, with persisted tool-result snapshots for history.
|
|
215
|
+
Keep run IDs for routing/diagnostics, not primary display identity; disambiguate duplicate aliases.
|
|
216
|
+
Steering cards preview the accepted message and expose all of it with Pi's expand-key binding.
|
|
193
217
|
Runtime metadata guidance belongs in the stable supervisor system prompt, not a new user-like
|
|
194
218
|
acknowledgement message. Keep initial setup/actionable asks working, preserve user-visible history,
|
|
195
219
|
and never re-inject a chosen identity. Progress `tokens` is cumulative input/output usage, not live
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,88 @@ used in its [GitHub releases](https://github.com/AeonDave/pi-persona/releases).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.16.0](https://github.com/AeonDave/pi-persona/releases/tag/v1.16.0) - 2026-10-03
|
|
10
|
+
|
|
11
|
+
### Compatibility
|
|
12
|
+
|
|
13
|
+
- Require Pi ≥ 1.0.0 and Node.js ≥ 22.19. Update the development cohort to Pi 1.0's four coordinated
|
|
14
|
+
host-package pins and qualify its SDK and tool lifecycle. Pre-1.0 Pi hosts are no longer supported;
|
|
15
|
+
the host packages and TypeBox remain wildcard peers supplied by Pi, not bundled runtime copies.
|
|
16
|
+
- Update the live control harness to use Pi 1.0's session `modelRuntime` through the public
|
|
17
|
+
`ModelRegistry` facade instead of the removed session registry property.
|
|
18
|
+
- An authored `council.members` field is now validated. Older malformed fields that were ignored
|
|
19
|
+
must be corrected or removed; council calls fail with the field diagnostic instead of selecting
|
|
20
|
+
an unrelated fallback panel.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Reserve mandatory downstream child slots before optional model recovery in `map`, `pipeline`,
|
|
25
|
+
`critic-loop`, and `council-rounds`. Provider outages no longer spend the slots needed by later
|
|
26
|
+
workers, verifiers, steps, or rounds and turn completed work into a run-fatal admission error.
|
|
27
|
+
- Pass live supervisor-ask state to the `intercom peek` tool, including untargeted peeks; a child
|
|
28
|
+
waiting for its supervisor is not reported as stuck. Collapsed steer receipts identify the run.
|
|
29
|
+
- Honor members-only council profiles for active and explicitly selected personas, including their
|
|
30
|
+
params when MAGI is selected explicitly as the same default strategy. Evaluate each configured
|
|
31
|
+
agent-model lookup once.
|
|
32
|
+
- Carry persistence checkpoints through nested codemode reports when their `[BLOCKED]`/`FLAG:
|
|
33
|
+
UNKNOWN` marker is relayed to the model. Suppressed nested output stays unchanged; only the outer
|
|
34
|
+
visible result receives the checkpoint and its expandable card.
|
|
35
|
+
- Surface telemetry cleanup/write diagnostics without requiring debug mode; diagnostics remain
|
|
36
|
+
non-fatal. Failed admission removes only the empty directories created by that attempt.
|
|
37
|
+
- Release a telemetry writer lease after its terminal writes finish without waiting for the shared
|
|
38
|
+
retention sweep over unrelated sessions; explicit maintenance joins remain available.
|
|
39
|
+
- Harden the exported council-preset expansion boundary with normalized strategy names and the
|
|
40
|
+
same strategy/roster/params allowlist as the JSON loader; validated authored members remain intact.
|
|
41
|
+
- Resolve live tree and telemetry model labels for auxiliary actors through the same role-specific
|
|
42
|
+
participants as the picker, including inline model pins and repeated SDK keys. Ambiguous short
|
|
43
|
+
role hints omit an uncertain model rather than attributing a different participant's choice.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Make general council guidance proportionate while preserving MAGI and Judge's specialized focus;
|
|
48
|
+
all eleven strategies remain available through the same tool. Add ephemeral inline council members
|
|
49
|
+
and specialized external actors without creating persona/team files.
|
|
50
|
+
- Include role-specific members and external arbiters in model selection; respect configured models
|
|
51
|
+
and remember prompts per participant rather than suppressing later teams for the whole persona.
|
|
52
|
+
- Recover model/provider failures across strategies and flows once on the supervisor's current model,
|
|
53
|
+
including unavailable saved or pinned choices. Remove MAGI's peer-model substitution; report the
|
|
54
|
+
switch, account both attempts, and preserve child/token limits and cancellation.
|
|
55
|
+
- Use worker aliases in async launch cards and targeted Intercom call headers, matching the live tree.
|
|
56
|
+
Persist display identity in tool results so history remains readable after reload or tracker eviction;
|
|
57
|
+
routing still uses run IDs, with a secondary ID shown when aliases collide.
|
|
58
|
+
- Show the accepted steering message as a compact preview, with Pi's expand-key hint for the full
|
|
59
|
+
message and diagnostic run ID. Replace repetitive soft-request/cancellation boilerplate with a
|
|
60
|
+
concise queued receipt; steering remains a request, not proof of execution or cancellation.
|
|
61
|
+
- Make context-burn checkpoints aware of Pi's nested-tool metadata: raw inner results do not
|
|
62
|
+
consume the model-visible output budget or receive invisible reminders. Permission gates,
|
|
63
|
+
telemetry and genuine successful hand-off resets still apply inside codemode.
|
|
64
|
+
- Show an immediate async completion banner with the worker's display name, including successful
|
|
65
|
+
runs. The semantic report still arrives once through the idle-gated completion path, and a failed
|
|
66
|
+
UI notification cannot swallow it.
|
|
67
|
+
- Replace the child watchdog test's load-sensitive kill-latency assertion with an observed blocked →
|
|
68
|
+
released → idle-timeout barrier; preserve the two intentional Windows-only skips.
|
|
69
|
+
- Clarify that automatic background completion follow-ups and end-turn guidance are the intended
|
|
70
|
+
async default: continue independent work, and do not monitor or join all workers when they are the
|
|
71
|
+
only remaining work. `intercom wait` now snapshots without blocking by default in interactive/RPC
|
|
72
|
+
sessions; `sync: true` opts into its bounded join, while headless remains blocking by default and
|
|
73
|
+
`sync: false` opts out. Snapshots collect only already-settled reports, leaving running work active.
|
|
74
|
+
Queued steering does not preempt an explicitly blocking join. A real Pi 1.0 SDK test with a local faux provider characterizes steering becoming
|
|
75
|
+
dormant when delayed input hooks outlast the active run. No unsafe input-triggered join abort ships.
|
|
76
|
+
- A council call that switches strategy no longer inherits unrelated profile params; params continue
|
|
77
|
+
to merge when the selected strategy is unchanged, and unknown explicit keys still warn.
|
|
78
|
+
- Show live supervisor asks as `waiting for supervisor`, rather than stalled, in the tree, F9 and
|
|
79
|
+
peek; refresh council parent clocks on child progress. A waiting worker becomes eligible for
|
|
80
|
+
stall detection again when its ask settles. Steering an already-settled run points to its result.
|
|
81
|
+
- Add age-based telemetry cleanup with a 30-day default; see
|
|
82
|
+
[`docs/TELEMETRY.md`](docs/TELEMETRY.md) for the retention contract.
|
|
83
|
+
- Reuse one tree snapshot per F9 list redraw for rows, selection and waiting state; remove an
|
|
84
|
+
unreachable delegate-title branch and distinguish event liveness from proof of useful progress.
|
|
85
|
+
- Align the README and technical guides on async snapshots/joins, steering delivery, model-selection
|
|
86
|
+
precedence, members-only councils, and automatic `map` verifier headroom.
|
|
87
|
+
|
|
88
|
+
After updating, let active workers settle and restart Pi (or use `/reload`). `/persona reload`
|
|
89
|
+
refreshes definitions, not extension code. Existing custom personas and provider pins are preserved.
|
|
90
|
+
|
|
9
91
|
## [1.15.2](https://github.com/AeonDave/pi-persona/releases/tag/v1.15.2) - 2026-09-28
|
|
10
92
|
|
|
11
93
|
### Distribution
|
package/README.md
CHANGED
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
<img src="assets/banner.png" alt="pi-persona — supervised multi-agent orchestration for Pi">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
+
[](https://github.com/AeonDave/pi-persona/actions/workflows/test.yml) [](https://scorecard.dev/viewer/?uri=github.com/AeonDave/pi-persona) [](https://www.npmjs.com/package/@aeondave/pi-persona) [](LICENSE)
|
|
8
|
+
|
|
7
9
|
**Give Pi a supervised team.**
|
|
8
|
-
`pi-persona`
|
|
9
|
-
async workers, live steering, cross-session collaboration, and switchable personas.
|
|
10
|
+
`pi-persona` adds supervised multi-agent orchestration to [Pi](https://github.com/earendil-works/pi):
|
|
11
|
+
async workers, live steering, cross-session collaboration, and switchable personas. It builds on
|
|
12
|
+
Pi's native SDK and tool hooks; the extension adds worker supervision and coordination.
|
|
10
13
|
Describe the outcome. A supervisor delegates work, gathers results, and checks the outcome;
|
|
11
14
|
you can inspect workers, redirect them, or stop a run while it is in progress.
|
|
12
15
|
|
|
@@ -14,7 +17,7 @@ you can inspect workers, redirect them, or stop a run while it is in progress.
|
|
|
14
17
|
|
|
15
18
|
## Install
|
|
16
19
|
|
|
17
|
-
Requires **Pi ≥ 0.
|
|
20
|
+
Requires **Pi ≥ 1.0.0**, **Node.js ≥ 22.19**, and **Git**. Configure a model provider in Pi first.
|
|
18
21
|
|
|
19
22
|
Run in your terminal:
|
|
20
23
|
|
|
@@ -36,9 +39,9 @@ your customizations.
|
|
|
36
39
|
| Install option | Command |
|
|
37
40
|
|---|---|
|
|
38
41
|
| This project only | `pi install -l npm:@aeondave/pi-persona` |
|
|
39
|
-
| Pin this release | `pi install npm:@aeondave/pi-persona@1.
|
|
42
|
+
| Pin this release | `pi install npm:@aeondave/pi-persona@1.16.0` |
|
|
40
43
|
| Update an unpinned install | `pi update npm:@aeondave/pi-persona` |
|
|
41
|
-
| Git alternative | `pi install git:github.com/AeonDave/pi-persona@v1.
|
|
44
|
+
| Git alternative | `pi install git:github.com/AeonDave/pi-persona@v1.16.0` |
|
|
42
45
|
|
|
43
46
|
Restart Pi after updating. For a pinned install, install the new version or tag explicitly.
|
|
44
47
|
If switching from a Git install, remove that source first with
|
|
@@ -69,8 +72,12 @@ For example, specialists can investigate code paths, tests, and the API contract
|
|
|
69
72
|
Their findings return to the **same supervisor**, which integrates them, verifies the fix, and reports
|
|
70
73
|
the outcome. This is one possible workflow, not a fixed pipeline; dependent steps run in order.
|
|
71
74
|
|
|
72
|
-
Interactive delegation runs in the background by default.
|
|
73
|
-
|
|
75
|
+
Interactive delegation runs in the background by default. Results return automatically when the
|
|
76
|
+
supervisor is free; you can inspect or redirect a worker at any point.
|
|
77
|
+
|
|
78
|
+
Launch and control cards show the worker's name. Steering receipts preview the message sent;
|
|
79
|
+
expand with `Ctrl+O` (the default binding) to read it in full. A queued message is not proof that
|
|
80
|
+
the worker has acted on it.
|
|
74
81
|
|
|
75
82
|
| Key or command | Action |
|
|
76
83
|
|---|---|
|
|
@@ -135,6 +142,13 @@ everyday coding, or choose one for the work ahead.
|
|
|
135
142
|
These are editable starting points. Browse the bundled [personas](personas) and [worker agents](agents),
|
|
136
143
|
or read the [practical guide](docs/EXPERIENCE.md) for help choosing a workflow.
|
|
137
144
|
|
|
145
|
+
Strategies are not restricted to the similarly named persona: `council` can select `judge`, `magi`,
|
|
146
|
+
`debate`, `critic-loop`, or another installed shape when it adds value. Temporary `members` allow
|
|
147
|
+
custom role-based groups without team files. Model selection includes external arbiters. In councils
|
|
148
|
+
and flows, a provider failure or unavailable model can recover once on the supervisor's model, with
|
|
149
|
+
the switch visible and both attempts accounted; ordinary delegates keep explicit provider pins strict.
|
|
150
|
+
See [the reference](docs/REFERENCE.md) for an inline council example and recovery limits.
|
|
151
|
+
|
|
138
152
|
## Make it yours
|
|
139
153
|
|
|
140
154
|
Edit installed personas and agents in `~/.pi/agent/persona/agents/`, or add project-specific
|
|
@@ -169,4 +183,9 @@ npm test
|
|
|
169
183
|
```
|
|
170
184
|
|
|
171
185
|
Pi loads the TypeScript extension directly; there is no build step.
|
|
172
|
-
|
|
186
|
+
The [CI workflow](https://github.com/AeonDave/pi-persona/actions/workflows/test.yml) runs strict
|
|
187
|
+
typechecking, dependency auditing and the test suite on Linux and Windows. The OpenSSF badge links to the project's
|
|
188
|
+
scored supply-chain checks; it is not a certification that the code is free of vulnerabilities.
|
|
189
|
+
|
|
190
|
+
See [AGENTS.md](AGENTS.md) for contribution conventions and the [security policy](SECURITY.md)
|
|
191
|
+
for private vulnerability reporting. Licensed under [MIT](LICENSE).
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Security fixes target the latest published version of
|
|
6
|
+
[`@aeondave/pi-persona`](https://www.npmjs.com/package/@aeondave/pi-persona).
|
|
7
|
+
Older versions do not have a guaranteed backport policy. Check the
|
|
8
|
+
[release notes](https://github.com/AeonDave/pi-persona/releases) for fixes and
|
|
9
|
+
upgrade instructions. Keep your Pi host and Node.js runtime updated as well.
|
|
10
|
+
|
|
11
|
+
## Reporting a vulnerability
|
|
12
|
+
|
|
13
|
+
Use [GitHub private vulnerability reporting](https://github.com/AeonDave/pi-persona/security/advisories/new).
|
|
14
|
+
Do not open a public issue with exploit details, credentials, private session
|
|
15
|
+
logs, or other sensitive material. Ordinary bugs can use the public issue tracker.
|
|
16
|
+
|
|
17
|
+
Include the affected package version or commit, Pi and Node.js versions, operating
|
|
18
|
+
system, relevant configuration, expected security boundary, actual behavior, and
|
|
19
|
+
a minimal reproduction with synthetic data. Explain the impact and any safe
|
|
20
|
+
workaround you have verified. Do not test against other users' sessions or systems
|
|
21
|
+
without their permission.
|
|
22
|
+
|
|
23
|
+
Follow-up and disclosure coordination happen in the private advisory. This is a
|
|
24
|
+
maintainer-run project, with no guaranteed response or remediation deadline and
|
|
25
|
+
no paid bug bounty. Agree on public disclosure after triage so users can receive
|
|
26
|
+
a fix or mitigation before exploit details are published.
|
|
27
|
+
|
|
28
|
+
## Security boundaries
|
|
29
|
+
|
|
30
|
+
Pi extensions and installed persona/agent definitions are trusted local code and
|
|
31
|
+
configuration, not an OS sandbox. Capability checks and Exocom's cooperative file
|
|
32
|
+
claims do not isolate a malicious local process. A workspace join code is a
|
|
33
|
+
same-host routing reference, not an authentication secret. See the
|
|
34
|
+
[architecture](docs/ARCHITECTURE.md) for the actual trust boundaries.
|
|
35
|
+
|
|
36
|
+
Reports of capability bypasses, broker/Exocom trust violations, unsafe handling of
|
|
37
|
+
untrusted worker output, or unintended disclosure of session data are welcome.
|
|
38
|
+
Use synthetic credentials and payloads in reproductions.
|
|
39
|
+
|
|
40
|
+
The npm package uses Pi-provided peer dependencies rather than shipping another
|
|
41
|
+
Pi runtime. Development lockfile fixes do not update an installed user's host;
|
|
42
|
+
host vulnerabilities must also be addressed by updating Pi itself.
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -54,6 +54,10 @@ rejected with the run id to wait on, so a later call cannot slip past the in-bat
|
|
|
54
54
|
- **L3 — flow file.** `flows/<name>.flow.json` composes strategies into a resumable DAG.
|
|
55
55
|
|
|
56
56
|
You climb only when you want determinism, structure, or reuse. Nothing forces the higher tiers.
|
|
57
|
+
The `council` tool is a gateway to all installed strategies, not a universal instruction to vote on
|
|
58
|
+
routine work. Choose a strategy when its topology adds value; MAGI and Judge retain their specialized
|
|
59
|
+
persona focus. A caller can supply ephemeral `members` with inline roles/models/skills instead of a
|
|
60
|
+
named team, without persisting a team or switching personas.
|
|
57
61
|
|
|
58
62
|
## Binding invariants (I1–I7)
|
|
59
63
|
|
|
@@ -193,7 +197,8 @@ engine, telemetry, UI, and tool surfaces; it is not part of the transport/domain
|
|
|
193
197
|
constrained-turn allowlist), `install.ts` (the feature's composition adapter: session-scoped plane +
|
|
194
198
|
ledger + wait/tool/hook wiring).
|
|
195
199
|
- **`src/telemetry/`** — a generic, versioned observer/export contract for future plugins: projected
|
|
196
|
-
lifecycle metadata only, never an agent-message router or control surface.
|
|
200
|
+
lifecycle metadata only, never an agent-message router or control surface. See
|
|
201
|
+
[`TELEMETRY.md`](./TELEMETRY.md) for privacy, retention, writer leases, and shutdown behavior.
|
|
197
202
|
- **`src/persona/`** — identity: `persona.ts` (parse + `expandCouncilPreset` + `composeSystemPrompt`),
|
|
198
203
|
`controller.ts`, `gating.ts`, `orchestrate.ts`, `config-store.ts`, `state.ts` (last-selected persona),
|
|
199
204
|
`spine.ts` (the shared behavioral layer's SOURCE resolution — docs/SPINE.md; composition sits in
|
|
@@ -282,6 +287,19 @@ prevents an explicitly selected OpenAI or native Claude leg from silently moving
|
|
|
282
287
|
provider. (`"verification"` is a further terminal value that never appears on an `AgentResult` — see
|
|
283
288
|
`map`'s `verify` param in [`docs/STRATEGIES.md`](./STRATEGIES.md).)
|
|
284
289
|
|
|
290
|
+
Strategy/council/flow runs use a different, explicitly authorized recovery policy: the selected model
|
|
291
|
+
is tried first without arbitrary provider reroutes, then `makeSDK` may retry a `provider` or
|
|
292
|
+
`unknown-model` failure ONCE on the supervisor's current model. This main-only exception also applies
|
|
293
|
+
to saved and inline-pinned assignments; ordinary delegate provider pins remain strict. Missing main
|
|
294
|
+
models, repeated same-model attempts, stop/timeout/contract/agent/infrastructure failures, and exhausted
|
|
295
|
+
child/token budgets do not recover. Both attempts are accounted, and a warning plus result metadata
|
|
296
|
+
identify the switch. A per-role model assignment can supplement the legacy per-agent assignment;
|
|
297
|
+
preflight model selection includes external arbiters and other declared agent-valued parameters.
|
|
298
|
+
Live tree and telemetry labels use those participant identities for auxiliary actors too, with
|
|
299
|
+
inline model pins taking precedence. If distinct full roles share a short display hint, the display
|
|
300
|
+
keeps the hint (with `#N` suffixes for repeated node keys) but omits the uncertain model label rather
|
|
301
|
+
than borrowing another role's choice. Routing still resolves the full role key, not the display hint.
|
|
302
|
+
|
|
285
303
|
### MCP (and other `session_start`-scoped extensions) in sub-agents
|
|
286
304
|
|
|
287
305
|
**A sub-agent does NOT share the supervisor's MCP session, and an in-process sub-agent gets NO MCP at
|
|
@@ -403,7 +421,9 @@ never simultaneously a telemetry event, a routed message, and a UI source of tru
|
|
|
403
421
|
- **ProgressView** — a derived, read-only UI view computed *from* EngineEvents. Never authored, never
|
|
404
422
|
a source of truth. The `f9` agent tree and `peek` digest are ProgressViews.
|
|
405
423
|
|
|
406
|
-
Steering is
|
|
424
|
+
Steering is a supervisor-to-child control action, distinct from semantic Bus messages; requesting
|
|
425
|
+
steering does not establish that an active blocking join has been interrupted. The peek digest is
|
|
426
|
+
always a read-only ProgressView.
|
|
407
427
|
|
|
408
428
|
External telemetry is not a fourth communication plane: it is a generic observer/export contract that
|
|
409
429
|
future plugins may consume or produce, not an exclusive pi-persona protocol. It observes projected
|
|
@@ -459,6 +479,12 @@ for the supervisor and for explicit retrieval; the default TUI projection is del
|
|
|
459
479
|
failed legs first, a failed council/flow card leads with the cause in its title, and an
|
|
460
480
|
`intercom wait` card leads with the `N settled — X done, Y failed` tally (per-leg causes sit in the
|
|
461
481
|
body, below the preview cut, so `wait`'s own success doesn't get a `failed` prefix);
|
|
482
|
+
- async launch cards and targeted Intercom call headers use the worker's canonical alias/model,
|
|
483
|
+
matching the tree rather than promoting its routing ID to display identity. Launch/control receipts
|
|
484
|
+
persist identity snapshots for history rendering; aliases never become routing keys. Colliding
|
|
485
|
+
aliases carry a secondary ID, and legacy receipts without a recoverable name retain their ID fallback.
|
|
486
|
+
Accepted steering receipts retain the exact sent message: collapsed cards preview it, expansion
|
|
487
|
+
shows all sanitized text and the diagnostic ID. A queued receipt does not prove the worker acted;
|
|
462
488
|
- follow-up cards (`pi-persona`, exocom) retain their complete semantic content but render a bounded
|
|
463
489
|
preview until expanded; terminal escape/control sequences are removed from the visible projection;
|
|
464
490
|
- the sticky agent and exocom widgets have fixed row budgets — F9/`/agents` and paginated
|
|
@@ -606,15 +632,29 @@ a local process able to modify that directory is already inside the trust bounda
|
|
|
606
632
|
|
|
607
633
|
- **sync** — the supervisor actively blocks on the delegate/strategy call (results still stream); no
|
|
608
634
|
idle/peek/steer.
|
|
609
|
-
- **async** —
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
635
|
+
- **async** — interactive delegation is background-first; headless execution remains synchronous
|
|
636
|
+
by default. The prompt/runtime guidance is to continue independent work and, when only background
|
|
637
|
+
children remain, end the turn for automatic completion follow-ups rather than monitor or join the
|
|
638
|
+
whole batch. `intercom wait` collects a snapshot without blocking by default in interactive/RPC
|
|
639
|
+
sessions; settled results are reported and running children continue. Use `sync: true` for an
|
|
640
|
+
intentional bounded join. Headless sessions preserve the blocking default; `sync: false` requests a
|
|
641
|
+
snapshot. A snapshot does not wait, start timers/input hooks, or cancel children. Queued steering
|
|
642
|
+
does not release an explicitly active join. Input-triggered join interruption is
|
|
643
|
+
deliberately not implemented: a real Pi 1.0 SDK characterization shows steering can remain dormant
|
|
644
|
+
if delayed input hooks outlast the active run; no supported post-admission ordering guarantee
|
|
645
|
+
has been established. The supervisor otherwise returns control and
|
|
646
|
+
goes idle until a wake; the **peek watchdog** fires while async children run but stays SILENT unless
|
|
647
|
+
there is something to act on — a healthy background run should not interrupt. It surfaces on two independent
|
|
613
648
|
signals: a **fast** wakeup (`PI_PERSONA_PEEK_MS`, ~30s, `0` disables) when a child NEWLY crosses the
|
|
614
649
|
`STALL_FLAG_MS` (90s) stall window (a focused *possibly stuck* alert, framed patience-first — ask the
|
|
615
650
|
leg, don't probe its environment) or messages the supervisor; and a **slow routine check-in**
|
|
616
651
|
(`PI_PERSONA_CHECKIN_MS`, ~5 min, `0` disables) delivering the compact ProgressView digest — never
|
|
617
|
-
full transcripts — so the supervisor can catch a leg going off-track early.
|
|
652
|
+
full transcripts — so the supervisor can catch a leg going off-track early. Live supervisor asks
|
|
653
|
+
are derived from the exact engine handle's optional `isWaitingForSupervisor` predicate: tree/F9/peek
|
|
654
|
+
show waiting, and the watchdog suppresses false stalls until the ask settles. Parent clocks advance
|
|
655
|
+
with child engine events (liveness, not proof of useful work); parents are waiting only when every
|
|
656
|
+
live descendant branch is waiting.
|
|
657
|
+
Both let an idle
|
|
618
658
|
supervisor steer/stop a wedged or drifting child even with NO completion fired; the enforcing
|
|
619
659
|
backstop is the engines' hard wall-clock cap (above). The full digest is also on demand via `/peek`.
|
|
620
660
|
Progress tokens are labelled **cumulative input/output**, not context occupancy; cache-read/write
|
|
@@ -649,6 +689,11 @@ a persona directive lives at the TOP of the prompt and its pull decays as recent
|
|
|
649
689
|
only `status === "done"` runs by design — a failed background/`wait` leg already gets a failure
|
|
650
690
|
block, so a `[BLOCKED]` marker there doesn't also get the persistence note. Same marker, same leg,
|
|
651
691
|
different counterweight depending on how it was collected.
|
|
692
|
+
Nested calls through codemode's `ctx.executeTool` leave their programmatic result untouched.
|
|
693
|
+
Pi's explicit `parentToolCallId` supplies the parent identity; call-id string shapes are never
|
|
694
|
+
used to infer nesting. A bounded set of parent call ids carries report provenance through wrappers
|
|
695
|
+
only while their output relays a surrender marker; the outer model-visible result alone gets the
|
|
696
|
+
note/card. Suppressed reports produce neither, and turn/session settlement clears abandoned relay state.
|
|
652
697
|
- **The off switch covers every path.** `PI_PERSONA_NUDGE=off` silences DelegationNudge entirely and
|
|
653
698
|
PersistenceNudge on every collection path (sync result, background notifier, `intercom wait`).
|
|
654
699
|
|
package/docs/EXPERIENCE.md
CHANGED
|
@@ -40,20 +40,36 @@ ask for a monitor. Pi runs a small event-producing program and brings the result
|
|
|
40
40
|
supervisor is free. Keep the session open, and cancel a watch when its purpose ends. See
|
|
41
41
|
[time and event wakes](MONITORS.md) for examples and limits.
|
|
42
42
|
|
|
43
|
-
- **F9** opens the agent tree.
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
- **F9** opens the agent tree. Queued rows have not started their clocks. Live supervisor asks show
|
|
44
|
+
`waiting for supervisor`, not a stall; running rows otherwise show elapsed time and switch to
|
|
45
|
+
`⚠ stalled <duration>` after 90 seconds without progress — a suspicion, not proof of a deadlock.
|
|
46
|
+
Council parent clocks refresh on child engine events; that indicates liveness, not useful work.
|
|
47
|
+
A parent is waiting only when all its live descendant branches are waiting. Enter opens a selectable worker's output; `s` sends a course correction;
|
|
46
48
|
`x` requests cancellation and appears only when the run can actually be stopped, marking the row
|
|
47
49
|
`stopping…` at once; a stop that can't be applied says so instead of doing nothing. Escape goes
|
|
48
50
|
back or closes the panel.
|
|
49
51
|
- **`/peek`** gives a compact progress view. A quiet worker is a reason to inspect its last
|
|
50
52
|
progress and current activity, not to launch a duplicate immediately.
|
|
51
53
|
- **Background results arrive automatically.** A supervisor can continue independent work while
|
|
52
|
-
they run.
|
|
54
|
+
they run. When only background workers remain, end the turn and let completion follow-ups return
|
|
55
|
+
their results; do not monitor or poll healthy workers or automatically join the whole batch.
|
|
56
|
+
`intercom wait` snapshots immediately by default in interactive/RPC sessions; use `sync: true` for
|
|
57
|
+
an intentional bounded join when the next step depends on those results. Headless waits remain
|
|
58
|
+
blocking by default; pass `sync: false` for a snapshot.
|
|
53
59
|
- **Answer a waiting worker before joining it.** A coaching worker may need a decision from its
|
|
54
60
|
supervisor before it can finish. An unanswered question is actionable work.
|
|
55
61
|
- **Steering is a request.** Check the subsequent output to see whether the worker incorporated
|
|
56
|
-
it.
|
|
62
|
+
it. In-process workers can receive guidance mid-run; child-engine workers (including MCP/worktree
|
|
63
|
+
runs) receive it as a queued follow-up. Neither promises to interrupt arbitrary tool work, and
|
|
64
|
+
steering does not preempt an explicitly blocking `intercom wait`. End the supervisor turn rather
|
|
65
|
+
than join merely to idle. Check the terminal result after requesting cancellation; changes already
|
|
66
|
+
made are not undone.
|
|
67
|
+
|
|
68
|
+
Launch cards and targeted Intercom calls show the same worker alias as the live tree. A steering
|
|
69
|
+
receipt previews the message that was actually queued; expand it (`Ctrl+O` by default, or your
|
|
70
|
+
configured key) to read the full message and diagnostic run ID. Aliases are display names, not
|
|
71
|
+
addresses: tools still route by run ID, and duplicate aliases show a secondary ID to distinguish them.
|
|
72
|
+
Saved launch/control receipts keep their display names even after the runtime tracker is gone.
|
|
57
73
|
|
|
58
74
|
A truncated message includes a message id. The supervisor can retrieve its retained body with
|
|
59
75
|
`intercom { action: "message", messageId: "m1" }`. A worker's final report has a run id instead:
|
package/docs/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# pi-persona documentation
|
|
2
2
|
|
|
3
3
|
This folder contains the long-form documentation that defines how the project is designed and run.
|
|
4
|
+
It follows the current checkout; consult the [changelog](../CHANGELOG.md) for the release that
|
|
5
|
+
introduced a behavior. An `Unreleased` entry is not yet part of a published release.
|
|
4
6
|
|
|
5
7
|
## Canonical docs
|
|
6
8
|
|
package/docs/REFERENCE.md
CHANGED
|
@@ -16,7 +16,7 @@ plus a file that calls `parallel` and `reduce.vote`.
|
|
|
16
16
|
|
|
17
17
|
| Primitive | Does |
|
|
18
18
|
|---|---|
|
|
19
|
-
| `agent(spec)` | run one sub-agent and return a structured `AgentResult`; `spec` may carry `name`, model, tools, skills, or `outputContract
|
|
19
|
+
| `agent(spec, { reserveChildren? }?)` | run one sub-agent and return a structured `AgentResult`; `spec` may carry `name`, model, tools, skills, or `outputContract`; optional reservations protect mandatory later legs from model recovery |
|
|
20
20
|
| `parallel(thunks, {concurrency})` | run many at once, bounded by the run limits; this also provides the basis of `map` |
|
|
21
21
|
| `reduce.aggregate(results)` | merge N results into one, used by fan-out |
|
|
22
22
|
| `reduce.vote(candidates, opts)` | tally the candidates' own votes and preserve `winner`, `tie`, `no_consensus`, `invalid_outputs`, and dissent |
|
|
@@ -35,8 +35,8 @@ hard-fail.
|
|
|
35
35
|
| Surface | Does |
|
|
36
36
|
|---|---|
|
|
37
37
|
| `delegate` tool | spawn one or more sub-agents; interactive calls are background-first, while `sync: true` blocks the turn |
|
|
38
|
-
| `council` tool |
|
|
39
|
-
| `intercom` tool | observe and control internal runs with `peek`, `result`, `wait`, `steer`, and `stop`; `list`, `inbox`, `message`, `reply`, and `send` drive the coaching bus |
|
|
38
|
+
| `council` tool | select any installed strategy over a named roster or temporary inline `members`; voting strategies preserve tally and dissent. Use when the topology adds value, not for routine work |
|
|
39
|
+
| `intercom` tool | observe and control internal runs with `peek`, `result`, `wait`, `steer`, and `stop`; `list`, `inbox`, `message`, `reply`, and `send` drive the coaching bus. `wait` snapshots without blocking by default with UI; `sync: true` opts into a bounded blocking join (headless defaults to blocking; use `sync: false` for a snapshot); queued steering does not preempt an explicit join |
|
|
40
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
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
42
|
| `flow` tool and `/flow` | run a journaled DAG of strategies; `gate: true` creates an approval checkpoint |
|
|
@@ -49,30 +49,70 @@ hard-fail.
|
|
|
49
49
|
| `contracts/*.json` | define a hot-editable structured return requested through `outputContract` and pinned per run |
|
|
50
50
|
|
|
51
51
|
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.
|
|
52
|
+
backends, keeping a caller-provided run label available in the live tree and runtime result. Every
|
|
53
|
+
settled async run also emits an immediate UI banner with that name and its terminal outcome. The
|
|
54
|
+
model-facing report remains independently idle-gated; a UI notification failure cannot discard it.
|
|
55
|
+
An explicit `delegate` `async` flag overrides both `sync` and the session default: `async: true`
|
|
56
|
+
forces background execution; `async: false` forces synchronous execution.
|
|
57
|
+
|
|
58
|
+
### Pi 1.0 codemode
|
|
59
|
+
|
|
60
|
+
Pi's native `codemode` can call callable pi-persona tools through the normal nested-tool pipeline.
|
|
61
|
+
Argument validation and persona permission gates still apply to every inner call; scripts do not
|
|
62
|
+
turn a denied tool into an allowed one. Native `model-only` and `hidden` tools are not callable.
|
|
63
|
+
|
|
64
|
+
Use scripts for independent batches or for filtering large results before returning them to the
|
|
65
|
+
model, not as a wrapper that prints every result in full. `Promise.allSettled()` preserves successful
|
|
66
|
+
siblings when a call rejects; a fulfilled `bash` call still requires checking `exit_code`.
|
|
67
|
+
Only printed/returned script output reaches the model. Nested results therefore do not contribute
|
|
68
|
+
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.
|
|
70
|
+
|
|
71
|
+
Pi identifies calls made through codemode's `ctx.executeTool` with `parentToolCallId`. If a nested
|
|
72
|
+
delegation report is relayed with `[BLOCKED]` or `FLAG: UNKNOWN`, only the outer model-visible result
|
|
73
|
+
gets the persistence checkpoint and its expandable card. Discarding the report creates no reminder
|
|
74
|
+
and never alters the programmatic inner result. See [the nudge contract](./ARCHITECTURE.md#supervision--the-waiting-model)
|
|
75
|
+
for the differences between synchronous and background reports.
|
|
76
|
+
|
|
77
|
+
The outer code/result card belongs to Pi, not pi-persona's delegate renderer. Keep bulky details
|
|
78
|
+
expandable (`Ctrl+O` by default; `/hotkeys` shows active bindings). `Ctrl+T` toggles thinking blocks
|
|
79
|
+
separately. A smaller script output also reduces model context; merely collapsing its card does not.
|
|
80
|
+
No replacement sandbox or renderer is required for this integration.
|
|
53
81
|
|
|
54
82
|
`outputContract` takes a contract **name**, not an inline shape — `/doctor` lists what's installed
|
|
55
|
-
(the
|
|
83
|
+
(the built-in `default` and bundled `finding` are available without custom files). Naming one that
|
|
84
|
+
isn't installed is rejected before any worker
|
|
56
85
|
spawns, checked across every task in a parallel batch: `delegate: unknown output contract(s) "x" —
|
|
57
86
|
nothing was spawned. Installed contracts: default, finding` (the list is capped at 16 names; a
|
|
58
87
|
`, …` marker is appended only when more than 16 are installed).
|
|
59
88
|
|
|
60
89
|
### Supervising running sub-agents — the `intercom` plane
|
|
61
90
|
|
|
62
|
-
The supervisor's internal communication with children
|
|
91
|
+
The supervisor's internal communication with children exposes these surfaces. Tree/F9/peek distinguish
|
|
92
|
+
queued, running, waiting for supervisor, suspected stalled and terminal runs. Waiting is derived from
|
|
93
|
+
a live pending ask on the exact child handle, never inferred from its last activity text:
|
|
63
94
|
|
|
64
|
-
|
|
|
95
|
+
| Surface | Needs | What you get |
|
|
65
96
|
|---|---|---|
|
|
66
|
-
| **Observe and control** | any persona | `peek`
|
|
97
|
+
| **Observe and control** | any persona | `peek` inspects async sub-agents; `wait` is nonblocking by default with UI (`sync: true` joins; headless defaults to joining, with `sync: false` for snapshots); `steer` sends a soft correction; `stop` requests cancellation. The `f9` overlay provides the same controls (`s`, `x`). Queued steering does not preempt an active join. Cancelling a worker does not undo existing changes |
|
|
67
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 |
|
|
68
99
|
| **Message bus** | `coaching: true` | children get `contact_supervisor`; progress appears in results and `intercom inbox`, while a blocking `decision` wakes the supervisor for `intercom reply` |
|
|
69
100
|
| **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 }` |
|
|
70
101
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
102
|
+
With coaching enabled, an async child's `decision` or `interview` waits for a supervisor reply.
|
|
103
|
+
A synchronous child posts the question one-way and continues instead: the supervisor is holding
|
|
104
|
+
that turn and cannot answer a blocking ask. Progress messages are always one-way.
|
|
105
|
+
|
|
106
|
+
Delegated output is untrusted and is fenced before it reaches the supervisor. Interactive async
|
|
107
|
+
work is background-first: continue independent work, and when only children remain, end the turn for
|
|
108
|
+
automatic completion follow-ups rather than monitoring or joining all children. Use `wait` only when
|
|
109
|
+
the next step depends on results. Async runs report failures to the supervisor, and a repeated
|
|
110
|
+
identical failed delegation is stopped by the runtime ledger before another child is spawned. A run whose model's provider fails at call time (auth,
|
|
111
|
+
outage, 5xx) may retry the same model id through a compatible fallback provider when its selection
|
|
112
|
+
is unpinned; explicit delegate provider pins remain strict. Strategies and flows instead recover a
|
|
113
|
+
model/provider failure once on the current main model, including unavailable saved or pinned choices.
|
|
114
|
+
They never substitute a peer's model or search arbitrary providers. Each recovery is visible and both
|
|
115
|
+
attempts consume usage/child budget; stop, timeout, contract and infrastructure failures do not retry.
|
|
76
116
|
|
|
77
117
|
Any leg that does NOT run in `isolation: worktree` shares the real checkout, so its result gets a
|
|
78
118
|
"what changed" block appended: `--- FILES CHANGED DURING THIS LEG (shared checkout; parallel legs
|
|
@@ -235,6 +275,36 @@ Convene the council before sign-off, then apply its merged findings yourself.
|
|
|
235
275
|
council({ question: "cache this or recompute?", strategy: "debate", roster: "review", params: { bestOf: 2 } })
|
|
236
276
|
```
|
|
237
277
|
|
|
278
|
+
A one-off group can be composed without editing a team file. The external arbiter is also an
|
|
279
|
+
agent specification, independent of the panel:
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
council({
|
|
283
|
+
question: "Choose between these designs; prioritize correctness and operational cost.",
|
|
284
|
+
strategy: "judge",
|
|
285
|
+
members: [
|
|
286
|
+
{ agent: "reviewer", role: "Evaluate correctness and failure boundaries." },
|
|
287
|
+
{ agent: "reviewer", role: "Evaluate operating cost and maintainability." }
|
|
288
|
+
],
|
|
289
|
+
params: { judge: { agent: "reviewer", role: "Choose impartially from the anonymised options." } }
|
|
290
|
+
})
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
`members` overrides the named roster for this invocation only. Roles/skills do not grant tools or
|
|
294
|
+
bypass capability gates. Model selection covers roster members and declared auxiliary actors such
|
|
295
|
+
as `judge` and `synthesizer`; supported agent-valued params accept inline member specs too. Model
|
|
296
|
+
precedence is inline `model`, saved role assignment, saved agent assignment, agent frontmatter,
|
|
297
|
+
then the session model (`src/persona/model-participants.ts`).
|
|
298
|
+
|
|
299
|
+
With an active persona, UI, and at least two configured models, unassigned participants can be
|
|
300
|
+
picked and saved for the active persona, even when borrowing another persona's council profile.
|
|
301
|
+
Dismissing a picker suppresses another prompt for that participant during the session, not for
|
|
302
|
+
later teams with different participants. Headless runs never prompt.
|
|
303
|
+
An unavailable choice is not overwritten: a provider or unknown-model failure may recover once
|
|
304
|
+
on the main model, with the switch reported and both attempts accounted. This does not relax
|
|
305
|
+
ordinary delegate provider pins. The MAGI persona retains its canonical core team; the Judge
|
|
306
|
+
persona retains impartial arbitration. Other personas choose whichever strategy fits the task.
|
|
307
|
+
|
|
238
308
|
**A delegation policy on any persona** — fields are generic and are never keyed to a persona name.
|
|
239
309
|
The runtime rejects incomplete briefs before a model call, supplies a missing contract, rejects
|
|
240
310
|
overlapping or missing ownership for parallel writers, and refuses a declared verifier that would
|
|
@@ -360,7 +430,7 @@ build retries. A connected broker child's status shows `⇄ <handle>`; if that c
|
|
|
360
430
|
status flips to `⇄ offline` and a fresh ask on it fails fast instead of hanging.
|
|
361
431
|
|
|
362
432
|
`/doctor` also reports the installed host's version against this extension's floor: `pi: <version>
|
|
363
|
-
(requires ≥ 0.
|
|
433
|
+
(requires ≥ 1.0.0)`, with a trailing `— BELOW FLOOR` marker once an installed version fails the
|
|
364
434
|
check (`src/core/pi-compat.ts`). `pi: unknown` means the host's own `package.json` could not be
|
|
365
435
|
resolved (a non-standard install layout) — not a failed check.
|
|
366
436
|
|