@aeondave/pi-persona 1.17.3 → 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 +44 -36
- package/CHANGELOG.md +76 -1
- package/README.md +23 -13
- package/docs/ARCHITECTURE.md +97 -37
- package/docs/COLLABORATION.md +110 -0
- package/docs/EXPERIENCE.md +33 -8
- package/docs/README.md +12 -0
- package/docs/REFERENCE.md +65 -14
- package/package.json +12 -6
- package/src/agents/agent.ts +6 -0
- package/src/bridge.ts +25 -8
- 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 +14 -4
- package/src/core/capabilities.ts +1 -1
- package/src/core/leg-thinking.ts +57 -0
- package/src/core/ownership.ts +1 -2
- package/src/core/pi-compat.ts +5 -12
- package/src/core/session-runs.ts +1 -1
- package/src/core/types.ts +1 -1
- package/src/engine/adapter.ts +83 -19
- package/src/engine/async.ts +49 -10
- package/src/engine/child.ts +10 -2
- package/src/engine/inproc.ts +87 -46
- package/src/engine/result-grant.ts +62 -0
- package/src/engine/session-tools.ts +6 -0
- package/src/engine/stream.ts +6 -0
- 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 +45 -17
- 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 +20 -21
- package/src/extension/hooks.ts +952 -938
- package/src/extension/identity.ts +41 -75
- package/src/extension/results.ts +136 -0
- package/src/extension/shared.ts +17 -0
- package/src/extension.ts +2963 -2873
- package/src/loader.ts +11 -3
- package/src/orchestration/flow-journal.ts +7 -1
- package/src/orchestration/flow-run.ts +122 -19
- package/src/orchestration/flow.ts +11 -0
- package/src/orchestration/roster.ts +71 -23
- package/src/orchestration/sdk.ts +44 -6
- 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 +1 -1
- 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/council.ts +40 -23
- package/src/tools/delegate-tool.ts +50 -14
- package/src/tools/delegate.ts +13 -6
- 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.ts +20 -3
- package/src/tools/flow.ts +24 -8
- package/src/tools/intercom-tool.ts +98 -14
- package/src/tools/models.ts +15 -0
- package/src/tools/monitor.ts +20 -1
- package/src/tools/read-result.ts +52 -0
- package/src/tools/timer.ts +23 -2
- package/src/ui/agent-overlay.ts +11 -3
- package/src/ui/agent-tree.ts +43 -1
- package/src/ui/literal-tool-result.ts +1 -1
- package/src/ui/model-picker.ts +1 -1
- package/src/ui/orchestration-launch.ts +49 -0
- package/src/ui/session-cards.ts +191 -14
package/AGENTS.md
CHANGED
|
@@ -37,8 +37,13 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
37
37
|
`@earendil-works/pi-*`; never bundle copies.
|
|
38
38
|
- npm publishes as `@aeondave/pi-persona`. Pi supplies the four `@earendil-works/pi-*` packages
|
|
39
39
|
and `typebox`: keep them as `peerDependencies: "*"` with development-only copies, never runtime
|
|
40
|
-
dependencies.
|
|
41
|
-
|
|
40
|
+
dependencies. Target the latest stable Pi only (currently 1.4.0, aligned with `MIN_PI_VERSION`,
|
|
41
|
+
the four development pins and README); do not maintain historical-host compatibility branches.
|
|
42
|
+
**No legacy or deferred cleanup:** remove dead code, obsolete options, superseded implementations
|
|
43
|
+
and compatibility-only aliases with their replacement. Update every caller, fixture and document
|
|
44
|
+
in the same change. A completed feature must not leave temporary scaffolding or cleanup debt.
|
|
45
|
+
Keep a path only when it serves the current host/runtime or a demonstrated current data contract.
|
|
46
|
+
Node.js must be ≥ 22.19 to match that host. Keep the npm
|
|
42
47
|
`files` allowlist explicit for docs/artwork, inspect `npm pack --dry-run`, and never publish drafts.
|
|
43
48
|
- Supply-chain controls: pin every GitHub Action to a verified full commit SHA; keep top-level
|
|
44
49
|
token permissions read-only, grant write permissions only to the reporting job that needs them,
|
|
@@ -175,7 +180,7 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
175
180
|
a live, capability-filtered roster (agents, teams and flows, with descriptions and gated flows tagged in
|
|
176
181
|
headless sessions) + a hand-off default (with one decision-class → method line, checked against the
|
|
177
182
|
registry) to the system-prompt TAIL every turn — discovery that survives context burn.
|
|
178
|
-
- **Sibling peer comm
|
|
183
|
+
- **Sibling peer comm**: a strategy can opt a run into direct sibling messaging
|
|
179
184
|
(`AgentRunSpec.peers` — the `debate` strategy does). The child gets a `contact_peer` tool
|
|
180
185
|
(`bus/peers.ts`): `list`/`send`, ONE-WAY only (blocking stays supervisor-only, so peers can
|
|
181
186
|
never deadlock), peer list scoped per engine instance (never the whole bus), send budget 20,
|
|
@@ -183,7 +188,11 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
183
188
|
Delivery: the in-process engine's bridge steers incoming bus messages into the child session,
|
|
184
189
|
fenced with the sender attributed OUTSIDE the fence — the same bridge delivers the supervisor's
|
|
185
190
|
`intercom send` (previously a dead letter). Gated by `EffectiveCapabilities.canUseBus` (OFF iff
|
|
186
|
-
the persona explicitly denies `intercom`).
|
|
191
|
+
the persona explicitly denies `intercom`). Child-process legs use the broker's engine-scoped
|
|
192
|
+
peer roster; `contact_peer` is installed only when that run opts in and the bus is allowed.
|
|
193
|
+
Granted communication tools join a nonempty child tool allowlist; explicit empty lists and
|
|
194
|
+
tool exclusions still win. In-process supervisor contact additionally requires `coaching`;
|
|
195
|
+
broker-connected children expose it when the bus is allowed.
|
|
187
196
|
Design: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md#the-comm-plane-in-practice) + [`docs/STRATEGIES.md`](docs/STRATEGIES.md).
|
|
188
197
|
On the peer plane: `debate` and `pair` always; `map`/`synthesize` opt-in via `params.peers`.
|
|
189
198
|
`magi`/`judge`/`fanout` stay peer-less BY DESIGN — independence is their bias guard
|
|
@@ -191,38 +200,37 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
191
200
|
this. `compete` runs its competitors with `isolation: worktree` (REQUIRES a clean git repo; missing
|
|
192
201
|
repo/dirty checkout/worktree failure fails closed and never falls back to the real tree) and returns
|
|
193
202
|
the winning diff for the SUPERVISOR to apply.
|
|
194
|
-
- **
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
`
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
`
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
`
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
(`
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
Design: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md#exocom--the-external-plane).
|
|
203
|
+
- **Exocom** (`src/exocom/*`, `src/tools/exocom*.ts`; opt-in `PI_PERSONA_EXOCOM=1` / `--exocom`;
|
|
204
|
+
see [the collaboration guide](docs/COLLABORATION.md)): a flat external plane between independent,
|
|
205
|
+
top-level Pi sessions, separate from one supervisor's internal workers. Bare `--exocom` selects the
|
|
206
|
+
current workspace; exact `--exocom=Ab0T` joins that existing scope from another cwd through a
|
|
207
|
+
persistent, case-sensitive four-character Base62 alias. The scope selects registry, transport,
|
|
208
|
+
ledger and artifacts; each member still advertises its actual home workspace. The code is a
|
|
209
|
+
same-host/same-agent-dir join reference, not authentication.
|
|
210
|
+
`EXOCOM_TOOL_NAMES` contains 15 call-time-gated tools: `exocom_list`, `exocom_send`, `exocom_name`,
|
|
211
|
+
`exocom_claim`, `exocom_ask`, `exocom_answer`, `exocom_decline`, `exocom_wait`, `exocom_release`,
|
|
212
|
+
`exocom_progress`, `exocom_status`, `exocom_task`, `exocom_offer`, `exocom_publish`, and
|
|
213
|
+
`exocom_profile`. A joined foreign-workspace peer cannot use `exocom_claim`; write-set task create
|
|
214
|
+
and pickup also require local scope and callable claim permission. Ledger paths are advisory
|
|
215
|
+
coordination, never filesystem authorization.
|
|
216
|
+
`exocom_task create` declares a voluntary task but does not start work or reserve files. The
|
|
217
|
+
immutable `task_id` is the creation frame's `msg_id`; carry it with `work_key` for take, progress,
|
|
218
|
+
finish, offer and publish so a reused work key cannot select another generation. Write-set pickup
|
|
219
|
+
and its claim are one locked ledger transaction; read-only tasks may be taken from a foreign scope.
|
|
220
|
+
An optional `exocom_offer` expires in at most 24 hours (one hour by default) and creates no answer
|
|
221
|
+
obligation. Use `exocom_ask` for an explicit blocking question. `exocom_publish` shares a bounded,
|
|
222
|
+
explicitly written excerpt, not another session's terminal-result archive. Peer prose is fenced and
|
|
223
|
+
attributed using the registry identity.
|
|
224
|
+
Tasks, offers and evidence are each capped at 64 records and 128 KiB aggregate. Terminal or stale
|
|
225
|
+
task facts and expired offers are retained for up to one hour; evidence is retained for up to one
|
|
226
|
+
hour. `exocom_profile` reports self-described capabilities (up to 8 tags, 48 characters each) and
|
|
227
|
+
optional `available`/`busy`/`away` status; absent status is unknown, and profiles confer no access.
|
|
228
|
+
During a pending ask, only settlement, `exocom_name`, status, explicit collaboration reads and
|
|
229
|
+
read-only filesystem tools remain available: profile `get` is allowed, but `set` and `clear` are not.
|
|
230
|
+
Naming remains metadata and does not answer the ask. Joining requires `canUseBus` plus at least one
|
|
231
|
+
callable ask closer (`exocom_answer` or `exocom_decline`) and is rechecked on persona changes.
|
|
232
|
+
Design: [architecture](docs/ARCHITECTURE.md#exocom--the-external-plane) and
|
|
233
|
+
[collaboration guide](docs/COLLABORATION.md).
|
|
226
234
|
|
|
227
235
|
## Testing
|
|
228
236
|
|
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,82 @@ All notable changes to this project are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project follows the version scheme
|
|
5
5
|
used in its [GitHub releases](https://github.com/AeonDave/pi-persona/releases).
|
|
6
6
|
|
|
7
|
-
## [
|
|
7
|
+
## [1.17.4](https://github.com/AeonDave/pi-persona/releases/tag/v1.17.4) - 2026-10-25
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Voluntary Exocom collaboration: generation-bound shared tasks with atomic pickup/write claims,
|
|
12
|
+
expiring optional invitations, bounded attributed evidence publication and self-reported profiles.
|
|
13
|
+
Stale ownership remains visible without automatic takeover; task/evidence reads are paginated.
|
|
14
|
+
See [the collaboration guide](docs/COLLABORATION.md) for the authority and retention contracts.
|
|
15
|
+
- Uniform operator views across every pi-persona surface: tool cards and commands use compact
|
|
16
|
+
purpose lines with shared-literal expansion (monitor, timer, models, read_result, agent_name,
|
|
17
|
+
contact_supervisor, contact_peer); session cards share the delegate-family frame (`Event · datum`
|
|
18
|
+
titles, indented clipped lines, boilerplate-free compact with drift-guarded projections, full
|
|
19
|
+
payload on expansion); the agent tree and F9 overlay show each leg's effort sigla (`mn l m h xh mx`,
|
|
20
|
+
off renders nothing) with honest requested→observed divergence, and delegate launch cards show the
|
|
21
|
+
full effort level next to the model.
|
|
22
|
+
- Audited all operator notifications: bounded and sanitized toasts, single-surface settlement
|
|
23
|
+
announcements (done/stopped announce once via the follow-up card; failures keep their immediate
|
|
24
|
+
durable surface).
|
|
25
|
+
- Installed-tarball qualification harness (`scripts/qualify-package.mjs`): packs and inspects the
|
|
26
|
+
artifact, installs it into isolated temporary hosts, and exercises real delegation, stop and
|
|
27
|
+
shutdown on both engines with a faux provider, network tripwires and empty credential stores.
|
|
28
|
+
Current policy: latest stable Pi only (1.4.0); historical host versions are rejected.
|
|
29
|
+
- Per-leg thinking/effort: a typed `thinking` level on agents, delegate single/batch calls, roster
|
|
30
|
+
and council members, and auxiliary actors. Precedence is explicit leg/member > agent definition >
|
|
31
|
+
the existing configured/inherited child setting; malformed values fail before launch. Both engines
|
|
32
|
+
report requested and observed Pi effort separately (an observation is Pi's requested effort, never
|
|
33
|
+
a claim about provider cognition); the child engine passes a separate `--thinking` argument and the
|
|
34
|
+
model-suffix synthesis is gone.
|
|
35
|
+
- Bounded durable terminal results: settled delegate/council/flow outcomes are saved as versioned
|
|
36
|
+
session entries with immutable `result:<UUID>` references (count/byte budgets, honest truncation
|
|
37
|
+
and storage receipts). `intercom results` lists them and `intercom result { ref, offset, limit }`
|
|
38
|
+
reads pages after reload — read-only: no respawn, no rebilling, no extra wake. The restore notice
|
|
39
|
+
now distinguishes vanished runtime work from retained terminal reports.
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- Show every council/flow participant's launch model and requested effort, including auxiliary
|
|
44
|
+
judges and repeated roles with distinct inline selections. Persist the receipt for history;
|
|
45
|
+
pending model setup remains explicit. Role hints omit code and technical identifiers rather than
|
|
46
|
+
turning environment-variable names or Git refs into reviewer labels.
|
|
47
|
+
- Treat failed model-availability reads as unavailable rather than advertising the whole catalog.
|
|
48
|
+
Session identity failures remain explicit and cannot reuse a previous owner or synthesize a
|
|
49
|
+
process-based identity; branch recovery restores the persisted name.
|
|
50
|
+
- Admit granted bridge communication tools through Pi 1.4's plain tool allowlist, so a read-only
|
|
51
|
+
worker can still contact its supervisor. Empty grants, explicit exclusions and semantic bus denial
|
|
52
|
+
remain restrictive; sibling contact requires peer opt-in.
|
|
53
|
+
- Refuse incompatible reference-flow journal versions and non-successful archived phases without
|
|
54
|
+
respawning completed work, including unapproved saved checkpoints. Retain truncation provenance
|
|
55
|
+
in resumed previews and final reports.
|
|
56
|
+
- Label compact status usage as cumulative input/output tokens, distinct from context occupancy.
|
|
57
|
+
- Preserve observed model identity after recovery in terminal results and completion views, while
|
|
58
|
+
launch cards retain the original selection. Requested and observed values remain distinguishable.
|
|
59
|
+
- Announce a successful or stopped async run ONCE: the completion follow-up card is the single
|
|
60
|
+
settlement surface (the tree row already settles immediately); the duplicate info toast is gone.
|
|
61
|
+
Failures keep their immediate durable card/sanitized toast.
|
|
62
|
+
- Pin isolated worktree exports to the starting commit, preserving worker commits together with later
|
|
63
|
+
uncommitted changes and new files in the returned patch.
|
|
64
|
+
- Keep unanswered supervisor decisions/interviews unresolved instead of suggesting implicit approval.
|
|
65
|
+
Expose explicit outcomes and suppress bus activity for already-cancelled calls.
|
|
66
|
+
|
|
67
|
+
### Removed
|
|
68
|
+
|
|
69
|
+
- Remove the `/persona none` alias; use `/persona off` to deactivate the current persona.
|
|
70
|
+
- Remove obsolete host API facades, the CJS-only Pi resolver fallback, unused session/notifier
|
|
71
|
+
options, unemitted identity-message aliases and redundant internal re-exports. Callers and test
|
|
72
|
+
fixtures now use the current Pi contracts directly.
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- Clarify and regression-test `/persona restore`: overwrite all bundled defaults without pruning
|
|
77
|
+
additional custom personas, agents or resources. Settings, credentials and sessions are not reset.
|
|
78
|
+
- Target the latest stable Pi only (currently 1.4.0): development pins, `MIN_PI_VERSION`, docs and
|
|
79
|
+
the package-qualification gate move together, and historical host versions are rejected. A scoped
|
|
80
|
+
development override pins `undici` past known advisories inside the Pi 1.4.0 host dependency tree.
|
|
81
|
+
- Align source SDK smoke checks with the canonical settings store and the current interactive vs
|
|
82
|
+
headless execution contract; settings qualification also rejects historical host versions.
|
|
8
83
|
|
|
9
84
|
## [1.17.3](https://github.com/AeonDave/pi-persona/tree/v1.17.3) - 2026-10-23
|
|
10
85
|
|
package/README.md
CHANGED
|
@@ -17,7 +17,8 @@ you can inspect workers, redirect them, or stop a run while it is in progress.
|
|
|
17
17
|
|
|
18
18
|
## Install
|
|
19
19
|
|
|
20
|
-
Requires **Pi
|
|
20
|
+
Requires **the latest stable Pi (currently 1.4.0)**, **Node.js ≥ 22.19**, and **Git**.
|
|
21
|
+
Update Pi together with this plugin; historical Pi releases are not maintained. Configure a model provider in Pi first.
|
|
21
22
|
|
|
22
23
|
Run in your terminal:
|
|
23
24
|
|
|
@@ -39,9 +40,9 @@ your customizations.
|
|
|
39
40
|
| Install option | Command |
|
|
40
41
|
|---|---|
|
|
41
42
|
| This project only | `pi install -l npm:@aeondave/pi-persona` |
|
|
42
|
-
| Pin this release | `pi install npm:@aeondave/pi-persona@1.17.
|
|
43
|
+
| Pin this release | `pi install npm:@aeondave/pi-persona@1.17.4` |
|
|
43
44
|
| Update an unpinned install | `pi update npm:@aeondave/pi-persona` |
|
|
44
|
-
| Git tag 1.17.
|
|
45
|
+
| Git tag 1.17.4 | `pi install git:github.com/AeonDave/pi-persona@v1.17.4` |
|
|
45
46
|
|
|
46
47
|
Restart Pi after updating. For a pinned install, install the new version or tag explicitly.
|
|
47
48
|
If switching from a Git install, remove that source first with
|
|
@@ -52,7 +53,8 @@ then install the npm package. Keep only one source configured to avoid loading t
|
|
|
52
53
|
|
|
53
54
|
| Capability | What you get |
|
|
54
55
|
|---|---|
|
|
55
|
-
| **Async workers** | Specialists with their own roles, skills, and
|
|
56
|
+
| **Async workers** | Specialists with their own roles, skills, models, and thinking levels; results return while the supervisor continues other work |
|
|
57
|
+
| **Retained results** | Bounded reports remain available after reload and can be read in pages without restarting workers |
|
|
56
58
|
| **Live steering** | Inspect a worker, send guidance, or stop a run from the agent panel |
|
|
57
59
|
| **Cross-session collaboration** | Exocom connects independent Pi sessions to exchange findings and coordinate work |
|
|
58
60
|
| **Councils and flows** | Compare perspectives, run repair-and-check loops, or organize work into stages |
|
|
@@ -119,8 +121,9 @@ To enable Exocom, open two terminals in the same workspace and start each with:
|
|
|
119
121
|
pi --exocom --persona dev
|
|
120
122
|
```
|
|
121
123
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
Use `/exocom` to inspect the connection and workspace code. Sessions can exchange one-way messages,
|
|
125
|
+
record a voluntary task, or share a bounded evidence excerpt. Creating a task does not start work in
|
|
126
|
+
the other session; a peer chooses whether to take it.
|
|
124
127
|
|
|
125
128
|
A session in another workspace can join using that exact, case-sensitive code:
|
|
126
129
|
|
|
@@ -129,10 +132,11 @@ pi --exocom=Ab0T --persona researcher
|
|
|
129
132
|
```
|
|
130
133
|
|
|
131
134
|
Replace `Ab0T` with the code shown by `/exocom`. Both sessions must run on the same machine and
|
|
132
|
-
share a Pi agent directory. A peer joining from another workspace can advise
|
|
133
|
-
it cannot claim
|
|
135
|
+
share a Pi agent directory. A peer joining from another workspace can advise, exchange results, and
|
|
136
|
+
take read-only tasks; it cannot claim or take tasks that declare write paths in the joined workspace.
|
|
134
137
|
|
|
135
|
-
See the [collaboration guide](docs/
|
|
138
|
+
See the [cross-session collaboration guide](docs/COLLABORATION.md) for the task, invitation, ask and
|
|
139
|
+
evidence workflows.
|
|
136
140
|
|
|
137
141
|
## Choose a persona
|
|
138
142
|
|
|
@@ -170,8 +174,11 @@ See [the reference](docs/REFERENCE.md) for an inline council example and recover
|
|
|
170
174
|
Edit installed personas and agents in `~/.pi/agent/persona/agents/`, or add project-specific
|
|
171
175
|
overrides in `.pi/agents/`. Run `/persona reload` after editing.
|
|
172
176
|
|
|
173
|
-
`/persona seed` preserves existing files. **`/persona restore`
|
|
174
|
-
|
|
177
|
+
`/persona seed` preserves existing files. **`/persona restore` overwrites all bundled defaults**
|
|
178
|
+
(personas, agents, teams, flows, contracts, presets and shared prompts), discarding customizations
|
|
179
|
+
to those files. It does not delete additional custom files: a persona `pippo.md` or an agent
|
|
180
|
+
`pluto.md` remains untouched. A custom file using the same destination as a bundled default is
|
|
181
|
+
replaced. Settings, credentials, sessions and project-local overrides are not reset.
|
|
175
182
|
|
|
176
183
|
For optional long-term memory, add [pi-persona-mind](https://github.com/AeonDave/pi-persona-mind).
|
|
177
184
|
|
|
@@ -186,6 +193,7 @@ refreshes persona definitions. Model changes apply to future runs. See [configur
|
|
|
186
193
|
| Guide | What's inside |
|
|
187
194
|
|---|---|
|
|
188
195
|
| [Everyday use](docs/EXPERIENCE.md) | Choosing a persona, following work, and reading results |
|
|
196
|
+
| [Cross-session collaboration](docs/COLLABORATION.md) | Voluntary tasks, optional offers, asks, evidence and presence between Pi sessions |
|
|
189
197
|
| [Customization reference](docs/REFERENCE.md) | Tool APIs, configuration, and copyable recipes |
|
|
190
198
|
| [Strategies](docs/STRATEGIES.md) | Teams, councils, flows, and orchestration options |
|
|
191
199
|
| [Timers and monitors](docs/MONITORS.md) | Reminders and programs that wake the supervisor |
|
|
@@ -205,8 +213,10 @@ npm test
|
|
|
205
213
|
```
|
|
206
214
|
|
|
207
215
|
Pi loads the TypeScript extension directly; there is no build step.
|
|
208
|
-
|
|
209
|
-
`node
|
|
216
|
+
Qualify the installed tarball on the current host without provider traffic or your profile with
|
|
217
|
+
`node scripts/qualify-package.mjs --host <absolute-path-to-pi-coding-agent-package>`.
|
|
218
|
+
The narrower source-SDK contract check is
|
|
219
|
+
`node --import tsx scripts/qualify-host.mjs <absolute-path-to-pi-coding-agent-package>`; both reject historical host versions.
|
|
210
220
|
The [CI workflow](https://github.com/AeonDave/pi-persona/actions/workflows/test.yml) runs strict
|
|
211
221
|
typechecking, dependency auditing and the test suite on Linux and Windows. The OpenSSF badge links to the project's
|
|
212
222
|
scored supply-chain checks; it is not a certification that the code is free of vulnerabilities.
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -81,9 +81,10 @@ These are the guardrails a contributor must not violate. They are enforced in co
|
|
|
81
81
|
by the SDK on every `agent()` call and by the engine per child. Concurrency is shared across all
|
|
82
82
|
calls in one SDK instance; token admission uses completed usage and is rechecked after queueing, so
|
|
83
83
|
active legs can overshoot it. Nesting depth is not one of these numeric knobs — it is structural,
|
|
84
|
-
capped at 1:
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
capped at 1: full pi-persona activation short-circuits under `PI_PERSONA_DISABLE=1` (the
|
|
85
|
+
**fork-bomb guard**), so no supervisor orchestration tools (`delegate`/`council`/`flow`) are
|
|
86
|
+
registered. A broker-enabled child instead loads the minimal bridge, which registers only
|
|
87
|
+
granted communication and scoped result-reader tools. On the child engine this is a one-shot env var
|
|
87
88
|
set on each spawned process; the in-process engine instead shares one Node process across
|
|
88
89
|
concurrently-building sub-sessions, so it ref-counts the guard (`inproc.ts`) to keep it set until the
|
|
89
90
|
LAST one finishes. The in-process engine also excludes `ORCHESTRATION_TOOLS` from the child session
|
|
@@ -151,6 +152,12 @@ These are the guardrails a contributor must not violate. They are enforced in co
|
|
|
151
152
|
|
|
152
153
|
## Module layout
|
|
153
154
|
|
|
155
|
+
The supported host is the latest stable Pi (currently 1.4.0). Runtime code uses its public APIs
|
|
156
|
+
directly; obsolete host facades, ignored SDK options and compatibility-only aliases are removed
|
|
157
|
+
with their callers. Genuine host failures remain explicit rather than fabricating session identity
|
|
158
|
+
or model availability. One-way user-data migrations and retained-history readers are separate data
|
|
159
|
+
contracts: they remain only while serving stored user data, not to support an older Pi runtime.
|
|
160
|
+
|
|
154
161
|
Domain dependencies remain downward-only and acyclic: `core ← all`; `engine`/`bus → core`;
|
|
155
162
|
`orchestration → engine + bus + core`; `persona → orchestration + core`; the Exocom transport and
|
|
156
163
|
ledger → `core + bus`; `tools`/`ui → lower layers`. `src/exocom/install.ts` is deliberately the
|
|
@@ -282,9 +289,12 @@ up to 16 names. Same idea, two layers, two caps — see docs/REFERENCE.md's exam
|
|
|
282
289
|
`isolation: worktree` is fail-closed. It requires a clean Git checkout so the detached `HEAD` view
|
|
283
290
|
cannot silently omit staged/unstaged/untracked supervisor work; a non-repository, dirty checkout,
|
|
284
291
|
worktree creation failure, missing diff artifact, or an artifact over the return limit fails the leg —
|
|
285
|
-
the base engine is never invoked against the real tree as a fallback. The
|
|
286
|
-
|
|
287
|
-
|
|
292
|
+
the base engine is never invoked against the real tree as a fallback. The created worktree's initial
|
|
293
|
+
commit is pinned before the worker starts. Export compares the final file state against that immutable
|
|
294
|
+
commit, so worker commits, later unstaged changes and new files are included together. The diff is
|
|
295
|
+
captured before the temporary tree is removed and then returned to the supervisor; commit history is
|
|
296
|
+
not applied to the main checkout. Every git call is asynchronous so the extension host keeps rendering,
|
|
297
|
+
ticking timers, and serving broker sockets while a large checkout runs.
|
|
288
298
|
|
|
289
299
|
Transient retries inside one agent session belong to the host **Pi runtime**'s `retry.*` settings, not
|
|
290
300
|
a persona contract — pi-persona neither parses retry notation nor schedules its own backoff. Both
|
|
@@ -501,12 +511,17 @@ events and cannot route, reply, steer, or otherwise control agents.
|
|
|
501
511
|
## The comm plane in practice
|
|
502
512
|
|
|
503
513
|
- **In-process bus** (`bus/inproc.ts`) — a handle-based mailbox: `send` (one-way), `ask` (blocks for a
|
|
504
|
-
reply), `reply`, `onMessage`. `contact_supervisor` (child→supervisor, gated by `
|
|
514
|
+
reply), `reply`, `onMessage`. `contact_supervisor` (child→supervisor, gated by `canUseBus` and,
|
|
515
|
+
for in-process children, `coaching: on`) and
|
|
505
516
|
`contact_peer` (sibling→sibling) are the child-side tools bound onto it. Each unread inbox holds at
|
|
506
517
|
most 200 messages; overflow evicts an old one-way note first, and an inbox full of live asks rejects
|
|
507
518
|
new delivery rather than stranding a sender. Ask settlement (reply, timeout, abort, departure, or
|
|
508
519
|
failed delivery) releases its timer/listener and unread entry; a previously retained question stays
|
|
509
520
|
readable with `expectsReply: false`, so old questions never advertise an active reply id.
|
|
521
|
+
Tool outcomes distinguish `answered` from unavailable, timed-out, cancelled and failed requests;
|
|
522
|
+
delivery evidence is never approval. Headless questions remain nonblocking and unresolved, allowing
|
|
523
|
+
only independent already-authorized work or a blocked/partial handoff. Pre-aborted calls perform no
|
|
524
|
+
bus action, and replies racing cancellation are not reported as answers.
|
|
510
525
|
- **Sibling peer comm** — a strategy opts a run in via `AgentRunSpec.peers` (gated by `canUseBus`). The
|
|
511
526
|
child gets `contact_peer` (`list`/`send`, ONE-WAY so peers can never deadlock; per-engine-instance
|
|
512
527
|
scoping; a 20-send budget and an 8,000-character body limit, enforced before consuming a send). The
|
|
@@ -529,6 +544,10 @@ events and cannot route, reply, steer, or otherwise control agents.
|
|
|
529
544
|
spawn without a bus endpoint, so they never burn connect backoff against a dead socket), and the next
|
|
530
545
|
build retries; `/doctor` surfaces its state on one line. A dropped client connection flips the
|
|
531
546
|
child-side bridge to `⇄ offline` and fails a fresh ask fast rather than hanging.
|
|
547
|
+
A connected child exposes `contact_supervisor` when `canUseBus` is allowed; `contact_peer` also
|
|
548
|
+
requires the run's peer opt-in. Granted custom tool names join a nonempty plain allowlist so Pi's
|
|
549
|
+
host filter does not hide them. Explicit `tools: []` and exclusions remain restrictive. A denied
|
|
550
|
+
semantic bus does not remove supervisor runtime steering or an independently scoped result reader.
|
|
532
551
|
|
|
533
552
|
### Presentation is a projection, not another comm plane
|
|
534
553
|
|
|
@@ -627,6 +646,21 @@ for the supervisor and for explicit retrieval; the default TUI projection is del
|
|
|
627
646
|
unreadable versions. Session-file deletion owns log deletion; ordinary shutdown saves diagnostics,
|
|
628
647
|
not deletes them. Operator-only expandable log entries do not create model context or extra wakes.
|
|
629
648
|
|
|
649
|
+
**Terminal result archive** (`src/results/`, `src/extension/results.ts`) applies the same
|
|
650
|
+
ownership model to settled agent work: every terminal delegate/council/flow outcome (and each final
|
|
651
|
+
SDK leg result, after any model recovery) is projected — once, idempotently by immutable origin —
|
|
652
|
+
into a versioned session entry with an opaque `result:<UUID>` reference, independent from runtime
|
|
653
|
+
run ids. Budgets: 128 entries, 8 MiB cumulative serialized payload per owning session file, 512 KiB
|
|
654
|
+
per record; bodies cap at 262,144 UTF-16 units with honest truncation metadata. Unknown, malformed
|
|
655
|
+
and duplicate history still consumes quota; unaccountable history disables new persistence instead
|
|
656
|
+
of resetting it. A fork/copy is a new owning file charged only for the entries it actually carries.
|
|
657
|
+
`storage: "session-entry"` means the host accepted the entry — never an fsync guarantee; memory-only
|
|
658
|
+
retention is labelled as such. Retrieval is read-only: `intercom results` lists, `intercom result
|
|
659
|
+
{ ref, offset, limit }` pages (8,000 default / 16,000 max units, surrogate-safe), with no respawn,
|
|
660
|
+
rebilling, collection or extra wake; reading a page never returns the whole run hidden in metadata.
|
|
661
|
+
A saved result is not a live worker: the restore notice says runtime handles are gone while retained
|
|
662
|
+
reports remain readable.
|
|
663
|
+
|
|
630
664
|
This is a UI invariant only: truncating a collapsed card must never be confused with truncating the
|
|
631
665
|
underlying result or changing a strategy's contract.
|
|
632
666
|
|
|
@@ -640,17 +674,22 @@ and message peer-to-peer, with no parent/child relationship. (intercom = interna
|
|
|
640
674
|
external comm.)
|
|
641
675
|
|
|
642
676
|
Exocom supplies fenced one-way postcards and presence; chat `message` never mutates shared work
|
|
643
|
-
state.
|
|
644
|
-
|
|
645
|
-
`
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
677
|
+
state. `src/exocom/ledger.ts` stores claims, questions, answers and progress; `src/exocom/collaboration.ts`
|
|
678
|
+
adds voluntary tasks, optional offers and explicit evidence excerpts. Tool adapters live in
|
|
679
|
+
`src/tools/exocom.ts`, `src/tools/exocom-collaboration.ts`, and `src/tools/exocom-profile.ts`.
|
|
680
|
+
`exocom_ask` resolves its target through the live registry to a raw session id, never a display name.
|
|
681
|
+
Attribution is resolved by `from_session`, never the envelope's self-reported `from_name`.
|
|
682
|
+
|
|
683
|
+
A pending ask gates the participant to `exocom_answer`/`exocom_decline`, `exocom_name` identity
|
|
684
|
+
metadata, `exocom_status`, explicit collaboration reads (`exocom_task` list/get, `exocom_publish`
|
|
685
|
+
read, `exocom_profile` get), and read-only filesystem tools. Profile `set`/`clear` and all other
|
|
686
|
+
mutations remain unavailable until the ask is settled. Naming does not settle an ask. The bounded
|
|
687
|
+
`pendingAskPrompt` explains the outstanding obligation. `exocom_wait` is non-blocking. Clean shutdown
|
|
688
|
+
releases this session's claims/asks; if that best-effort write fails, the vanished owner is pruned on
|
|
689
|
+
the next ledger transaction (live registry sessions are the lease), and `expireWaiters` wakes any
|
|
690
|
+
waiter left behind instead of leaving `exocom_wait` armed forever. This gate is cooperative
|
|
691
|
+
coordination for participating local Pi processes — not filesystem authorization, not isolation from
|
|
692
|
+
another same-user process, and not a delegate/council or task/run replacement.
|
|
654
693
|
|
|
655
694
|
- **Opt-in, OFF by default.** `PI_PERSONA_EXOCOM=1` or bare `--exocom` joins the current workspace;
|
|
656
695
|
`--exocom=Ab0T` joins an existing scope by its exact, case-sensitive four-character Base62 alias
|
|
@@ -677,18 +716,31 @@ replacement.
|
|
|
677
716
|
standing brief, and `/exocom` label a peer as same-workspace or external without exposing its
|
|
678
717
|
absolute `cwd`. External peers are full Pi instances that can inspect files in their own workspace;
|
|
679
718
|
paths are never implicitly shared.
|
|
680
|
-
- **Postcards
|
|
681
|
-
reply is another `exocom_send` with `in_reply_to` set. `target: "*"` broadcasts
|
|
682
|
-
best-effort
|
|
683
|
-
`
|
|
684
|
-
|
|
685
|
-
|
|
719
|
+
- **Postcards, asks and offers have different obligations.** `exocom_send` returns a `msg_id`
|
|
720
|
+
immediately; a reply is another `exocom_send` with `in_reply_to` set. `target: "*"` broadcasts
|
|
721
|
+
postcards best-effort. `exocom_ask` commits a targeted question that must be answered or declined;
|
|
722
|
+
`exocom_wait` arms a bounded idle wake rather than blocking. `exocom_offer` is an optional,
|
|
723
|
+
expiring invitation to consider an open task, targeted to one peer or the pool; it creates no ask,
|
|
724
|
+
no answer obligation and no work authorization. Its default lifetime is one hour, capped at 24 hours.
|
|
725
|
+
Signed immediate-wake frames are signals; the ledger remains authoritative when delivery is deferred.
|
|
726
|
+
- **Task generations and atomic pickup.** `exocom_task create` records a voluntary objective and
|
|
727
|
+
declared write set; creation neither launches work nor claims paths. The task's immutable
|
|
728
|
+
`task_id` is its creation frame's `msg_id`; later take/progress/finish, offer and publish actions
|
|
729
|
+
carry both `work_key` and `task_id`, so reusing a key cannot attach a delayed action to a newer
|
|
730
|
+
task. A write-set task's pickup and overlapping write claim commit together under the ledger lock;
|
|
731
|
+
competing overlapping pickups are rejected. Read-only tasks can be taken by a peer in another
|
|
732
|
+
workspace scope. A task whose owning registry lease disappears becomes stale and cannot be taken
|
|
733
|
+
over automatically. `exocom_task list` is paginated; `get` returns the complete bounded task detail,
|
|
734
|
+
including the exact write set. `exocom_publish` attaches an explicitly authored bounded excerpt to
|
|
735
|
+
one task generation; discovery pages titles and message ids, and the full excerpt is read by id.
|
|
736
|
+
These excerpts do not grant access to a peer's terminal-result archive.
|
|
686
737
|
- **Cross-workspace writes are advisory-only in v1.** A repository-relative claim path has meaning
|
|
687
738
|
only in the workspace that owns the selected scope, so a member whose home workspace differs from
|
|
688
|
-
the scope cannot `exocom_claim` (the tool and
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
unrelated repositories are never compared as
|
|
739
|
+
the scope cannot `exocom_claim` or create/pick up a write-set task (the tool and signed-frame
|
|
740
|
+
transaction both enforce the scope). It can still read shared tasks/evidence, take read-only tasks,
|
|
741
|
+
send postcards, ask, answer/decline, and release its own asks. Multi-repository write coordination
|
|
742
|
+
would need a versioned resource namespace; paths from unrelated repositories are never compared as
|
|
743
|
+
if they named the same files.
|
|
692
744
|
- **Reply routing is session-stable.** `exocom_list` shows human display names (`name`/`name#2`);
|
|
693
745
|
sends and inbound reply hints use `name@<96-bit session hash>`, so a retained qualified target
|
|
694
746
|
stays valid after a rename. Ambiguous suffix matches fail closed rather than guess. The
|
|
@@ -727,15 +779,23 @@ replacement.
|
|
|
727
779
|
double-trigger a turn. An exchange's LENGTH is instead bounded prompt-side: the per-turn peer brief
|
|
728
780
|
(`core/brief.ts`) carries a relevance bound — send only what changes what someone does — deliberately
|
|
729
781
|
not a round count, since a counter can't see whether a round still serves the work.
|
|
730
|
-
- **
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
`
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
and
|
|
737
|
-
|
|
738
|
-
|
|
782
|
+
- **Fifteen tools are lazy and fail closed.** `EXOCOM_TOOL_NAMES` lists `exocom_list`, `exocom_send`,
|
|
783
|
+
`exocom_name`, `exocom_claim`, `exocom_ask`, `exocom_answer`, `exocom_decline`, `exocom_wait`,
|
|
784
|
+
`exocom_release`, `exocom_progress`, `exocom_status`, `exocom_task`, `exocom_offer`,
|
|
785
|
+
`exocom_publish`, and `exocom_profile`. Each tool rechecks effective persona capabilities at call
|
|
786
|
+
time; the live accessor and active-tool set also deny calls once the plane stops, since Pi has no
|
|
787
|
+
dynamic tool-unregister API. A joined foreign-scope peer has no `exocom_claim`. Admission requires
|
|
788
|
+
`canUseBus` and at least one callable ask closer, because every published peer may receive a durable
|
|
789
|
+
ask and must retain a way to settle it.
|
|
790
|
+
- **Collaboration and profile retention are bounded.** The ledger retains at most 64 tasks, 64 offers,
|
|
791
|
+
and 64 evidence excerpts with a 128 KiB aggregate collaboration-state budget. Task descriptions cap
|
|
792
|
+
at 2,048 characters; write sets at 64 paths of 256 characters each; progress/finish notes at 4,096.
|
|
793
|
+
Evidence titles cap at 160 characters and excerpts at 4,096 characters / 8,192 UTF-8 bytes. Finished
|
|
794
|
+
or stale tasks remain for up to one hour; expired offers remain for up to one hour after expiry, and
|
|
795
|
+
evidence for up to one hour after publication. Active tasks remain while their owner lease is live.
|
|
796
|
+
`exocom_profile` contains up to eight self-described capability labels (48 characters each) and
|
|
797
|
+
optional `available`, `busy` or `away` status. Missing status is unknown. Profiles exist only for
|
|
798
|
+
their live Exocom session and never prove skills, permission or availability.
|
|
739
799
|
- **Inbound delivery is bounded without loss.** Each message is injected under the same byte cap
|
|
740
800
|
whether plain text or an artifact descriptor. Bursts stay FIFO-queued; each rate-limited wake drains
|
|
741
801
|
as many whole messages as fit, leaving the rest queued. A presentation cap on the collapsed card
|