@aeondave/pi-persona 1.16.0 → 1.16.1
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 +2 -0
- package/CHANGELOG.md +15 -0
- package/README.md +2 -2
- package/docs/TELEMETRY.md +6 -0
- package/package.json +9 -4
- package/src/extension.ts +24 -8
- package/src/telemetry/contract.ts +1 -1
package/AGENTS.md
CHANGED
|
@@ -198,6 +198,8 @@ the shared behavioral prompt layer: [`docs/SPINE.md`](docs/SPINE.md).
|
|
|
198
198
|
|
|
199
199
|
## Testing
|
|
200
200
|
|
|
201
|
+
- Offline SDK harnesses must await `session_shutdown` before SDK `dispose()` and temporary-profile
|
|
202
|
+
deletion. `dispose()` disconnects SDK listeners; it does not join extension-owned writers.
|
|
201
203
|
- TDD: write the failing test first for `core/*` and any behavior change; watch it fail, then fix.
|
|
202
204
|
- Done = `npm run typecheck` clean **and** full suite green. The suite has **two** intentional skips,
|
|
203
205
|
both Windows-only — the runner reports `skipped 2` on Windows and `skipped 0` elsewhere (see
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,21 @@ used in its [GitHub releases](https://github.com/AeonDave/pi-persona/releases).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.16.1](https://github.com/AeonDave/pi-persona/releases/tag/v1.16.1) - 2026-10-06
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Publish the real pending-supervisor-ask state as `agent.updated` telemetry for Flow. Refresh it on
|
|
14
|
+
ask delivery and reply/timeout/cancellation settlement, without duplicate events or text-based
|
|
15
|
+
guesses; queued and terminal state remain authoritative.
|
|
16
|
+
- Make the native offline codemode harness await extension shutdown before deleting its temporary
|
|
17
|
+
profile; SDK `dispose()` alone does not flush the extension's telemetry writer.
|
|
18
|
+
|
|
19
|
+
### Packaging
|
|
20
|
+
|
|
21
|
+
- Add the npm author and focused Pi gallery keywords; align the banner preview and pinned install
|
|
22
|
+
examples with this release.
|
|
23
|
+
|
|
9
24
|
## [1.16.0](https://github.com/AeonDave/pi-persona/releases/tag/v1.16.0) - 2026-10-03
|
|
10
25
|
|
|
11
26
|
### Compatibility
|
package/README.md
CHANGED
|
@@ -39,9 +39,9 @@ your customizations.
|
|
|
39
39
|
| Install option | Command |
|
|
40
40
|
|---|---|
|
|
41
41
|
| This project only | `pi install -l npm:@aeondave/pi-persona` |
|
|
42
|
-
| Pin this release | `pi install npm:@aeondave/pi-persona@1.16.
|
|
42
|
+
| Pin this release | `pi install npm:@aeondave/pi-persona@1.16.1` |
|
|
43
43
|
| Update an unpinned install | `pi update npm:@aeondave/pi-persona` |
|
|
44
|
-
| Git alternative | `pi install git:github.com/AeonDave/pi-persona@v1.16.
|
|
44
|
+
| Git alternative | `pi install git:github.com/AeonDave/pi-persona@v1.16.1` |
|
|
45
45
|
|
|
46
46
|
Restart Pi after updating. For a pinned install, install the new version or tag explicitly.
|
|
47
47
|
If switching from a Git install, remove that source first with
|
package/docs/TELEMETRY.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Telemetry wire contract
|
|
2
2
|
|
|
3
|
+
Agent `waiting` is an explicit projection of a pending supervisor ask, read through the live
|
|
4
|
+
engine steer handle. Ask delivery and settlement (reply, timeout or cancellation) refresh the
|
|
5
|
+
projection; overlapping asks keep it waiting until the last one settles. Queued and terminal
|
|
6
|
+
statuses retain precedence. The producer deduplicates unchanged projections and never infers
|
|
7
|
+
waiting from tool arguments, output text or a quiet clock.
|
|
8
|
+
|
|
3
9
|
Telemetry is a vendor-neutral v2 envelope. `producerId` and `producerVersion` identify the emitting plugin; `version` identifies the wire schema. `seq` is monotonic only within `(producerId, sessionId)`, and `id` is deduplicated within that same scope.
|
|
4
10
|
|
|
5
11
|
The pi-persona producer writes semantic projections under `telemetry/v2/<workspace>/<producerId>/`. `<workspace>` always identifies the Pi process's actual cwd; joining another Exocom scope does not rewrite telemetry identity. It never persists task/prompt text, tool arguments/activity, model output, paths, secrets, or message bodies. Known pi-persona event payloads are allowlisted; an unreviewed producer event retains only its envelope/type (payload `{}`) at the producer and consumer boundary. Future producers must add a reviewed allowlist/schema before publishing data intended for a consumer.
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeondave/pi-persona",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Supervised multi-agent orchestration for Pi — async workers, live steering, cross-session collaboration, and switchable personas.",
|
|
7
|
+
"author": "AeonDave",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
10
|
"url": "git+https://github.com/AeonDave/pi-persona.git"
|
|
@@ -18,12 +19,16 @@
|
|
|
18
19
|
"keywords": [
|
|
19
20
|
"pi-package",
|
|
20
21
|
"pi-extension",
|
|
22
|
+
"pi-coding-agent",
|
|
21
23
|
"pi",
|
|
22
|
-
"persona",
|
|
23
24
|
"subagents",
|
|
24
25
|
"orchestration",
|
|
25
26
|
"multi-agent",
|
|
26
|
-
"supervisor"
|
|
27
|
+
"supervisor",
|
|
28
|
+
"async-agents",
|
|
29
|
+
"live-steering",
|
|
30
|
+
"cross-session",
|
|
31
|
+
"persona"
|
|
27
32
|
],
|
|
28
33
|
"license": "MIT",
|
|
29
34
|
"files": [
|
|
@@ -99,7 +104,7 @@
|
|
|
99
104
|
"typescript": "^7.0.2"
|
|
100
105
|
},
|
|
101
106
|
"pi": {
|
|
102
|
-
"image": "https://raw.githubusercontent.com/AeonDave/pi-persona/v1.16.
|
|
107
|
+
"image": "https://raw.githubusercontent.com/AeonDave/pi-persona/v1.16.1/assets/banner.png",
|
|
103
108
|
"video": "https://cdn.jsdelivr.net/gh/AeonDave/pi-persona@6655d281ce7965a75303dd704bd29db73db04070/assets/demo1.mp4",
|
|
104
109
|
"extensions": [
|
|
105
110
|
"./src/extension.ts"
|
package/src/extension.ts
CHANGED
|
@@ -535,6 +535,8 @@ export default function piPersona(pi: ExtensionAPI, options: PiPersonaOptions =
|
|
|
535
535
|
// left hanging when Pi resolves a call as "immediate" and never reaches a result.
|
|
536
536
|
type PendingIntercomTelemetry = { kind: string; to: string; size: number; replyTo?: string };
|
|
537
537
|
const telemetryIntercomPending = new Map<string, PendingIntercomTelemetry>();
|
|
538
|
+
// node id → steer that one agent (in-process engine only): inject a live user message.
|
|
539
|
+
const steerRegistry = new Map<string, SteerFn>();
|
|
538
540
|
function telemetryKind(node: AgentNode): TelemetryAgentKind {
|
|
539
541
|
if (node.kind) return node.kind;
|
|
540
542
|
if (node.id.startsWith("flow:")) return "flow";
|
|
@@ -547,9 +549,10 @@ export default function piPersona(pi: ExtensionAPI, options: PiPersonaOptions =
|
|
|
547
549
|
// "queued" is a marker WE set (the seeded roster / a launched async run), so it is a real
|
|
548
550
|
// state. Nothing ever sets `detail` to a waiting state — it is a usage string, an error, or
|
|
549
551
|
// `toolActivity(name, args)`, which splices the tool's own argument text — so a substring
|
|
550
|
-
// test for "waiting" could only ever fire on a leg that is running normally.
|
|
552
|
+
// test for "waiting" could only ever fire on a leg that is running normally. A live in-process
|
|
553
|
+
// steer handle has the authoritative bus predicate for a supervisor ask.
|
|
551
554
|
if (isQueuedMarker(node.detail)) return "queued";
|
|
552
|
-
return "running";
|
|
555
|
+
return steerRegistry.get(node.id)?.isWaitingForSupervisor?.() === true ? "waiting" : "running";
|
|
553
556
|
}
|
|
554
557
|
function telemetryAgent(node: AgentNode): TelemetryAgentInput {
|
|
555
558
|
return {
|
|
@@ -585,6 +588,22 @@ export default function piPersona(pi: ExtensionAPI, options: PiPersonaOptions =
|
|
|
585
588
|
// unfiltered publish appends one byte-identical duplicate per chunk: a 5k-chunk leg writes
|
|
586
589
|
// ~1.5MB of them and evicts genuine history from the producer's file budget.
|
|
587
590
|
const lastAgentProjection = new Map<string, string>();
|
|
591
|
+
function publishAgentProjection(node: AgentNode): void {
|
|
592
|
+
const producer = telemetry;
|
|
593
|
+
if (!producer) return;
|
|
594
|
+
const agent = telemetryAgent(node);
|
|
595
|
+
const projection = JSON.stringify(agent);
|
|
596
|
+
if (lastAgentProjection.get(node.id) === projection) return;
|
|
597
|
+
lastAgentProjection.set(node.id, projection);
|
|
598
|
+
producer.publishAgentUpdated(node.id, agent);
|
|
599
|
+
}
|
|
600
|
+
function refreshSteeredAgentTelemetry(): void {
|
|
601
|
+
if (!telemetry || steerRegistry.size === 0) return;
|
|
602
|
+
const steeredIds = new Set(steerRegistry.keys());
|
|
603
|
+
for (const node of agentTree.snapshot()) {
|
|
604
|
+
if (steeredIds.has(node.id)) publishAgentProjection(node);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
588
607
|
function publishAgentTreeChange(change: AgentTreeChange): void {
|
|
589
608
|
const producer = telemetry;
|
|
590
609
|
if (!producer) return;
|
|
@@ -594,10 +613,7 @@ export default function piPersona(pi: ExtensionAPI, options: PiPersonaOptions =
|
|
|
594
613
|
return;
|
|
595
614
|
}
|
|
596
615
|
if (change.type === "updated") {
|
|
597
|
-
|
|
598
|
-
if (lastAgentProjection.get(change.node.id) === projection) return;
|
|
599
|
-
lastAgentProjection.set(change.node.id, projection);
|
|
600
|
-
producer.publishAgentUpdated(change.node.id, telemetryAgent(change.node));
|
|
616
|
+
publishAgentProjection(change.node);
|
|
601
617
|
return;
|
|
602
618
|
}
|
|
603
619
|
if (change.type === "removed") {
|
|
@@ -644,8 +660,6 @@ export default function piPersona(pi: ExtensionAPI, options: PiPersonaOptions =
|
|
|
644
660
|
return true;
|
|
645
661
|
}
|
|
646
662
|
|
|
647
|
-
// node id → steer that one agent (in-process engine only): inject a live user message.
|
|
648
|
-
const steerRegistry = new Map<string, SteerFn>();
|
|
649
663
|
function waitingTreeIds(nodes: readonly AgentNode[] = agentTree.snapshot()): Set<string> {
|
|
650
664
|
return deriveWaitingNodeIds(nodes, (id) => steerRegistry.get(id)?.isWaitingForSupervisor?.() === true);
|
|
651
665
|
}
|
|
@@ -1063,6 +1077,7 @@ export default function piPersona(pi: ExtensionAPI, options: PiPersonaOptions =
|
|
|
1063
1077
|
bus.onAskSettled(({ id }) => {
|
|
1064
1078
|
intercomNotifier.discard((ask) => ask.askId === id);
|
|
1065
1079
|
telemetryAskSenders.delete(id);
|
|
1080
|
+
if (!disposed) refreshSteeredAgentTelemetry();
|
|
1066
1081
|
});
|
|
1067
1082
|
// Supervisor-armable alarms: when a timer expires it WAKES the session by routing the fire
|
|
1068
1083
|
// through the same idle-delivery path (an idle delivery starts a fresh turn, so the supervisor
|
|
@@ -1144,6 +1159,7 @@ export default function piPersona(pi: ExtensionAPI, options: PiPersonaOptions =
|
|
|
1144
1159
|
expectsReply: env.expectsReply,
|
|
1145
1160
|
size: Buffer.byteLength(env.text, "utf8"),
|
|
1146
1161
|
});
|
|
1162
|
+
if (!disposed && env.expectsReply) refreshSteeredAgentTelemetry();
|
|
1147
1163
|
if (disposed || env.to !== SUPERVISOR || !env.expectsReply) return;
|
|
1148
1164
|
// Only an ask can be replied to, so only an ask needs its sender remembered. Oldest first
|
|
1149
1165
|
// out: a long session must not grow this without bound.
|
|
@@ -4,7 +4,7 @@ export const TELEMETRY_EVENT_NAME = "pi:telemetry" as const;
|
|
|
4
4
|
export const LEGACY_TELEMETRY_EVENT_NAME = "pi-persona:telemetry" as const;
|
|
5
5
|
export const LEGACY_TELEMETRY_VERSION = 1 as const;
|
|
6
6
|
export const TELEMETRY_PRODUCER_ID = "pi-persona" as const;
|
|
7
|
-
export const TELEMETRY_PRODUCER_VERSION = "1.16.
|
|
7
|
+
export const TELEMETRY_PRODUCER_VERSION = "1.16.1" as const;
|
|
8
8
|
|
|
9
9
|
export type InstanceStatus = "active" | "idle" | "stopped" | "stale" | (string & {});
|
|
10
10
|
export type AgentKind = "subagent" | "delegate" | "council" | "flow" | "phase" | (string & {});
|