@llblab/pi-actors 0.41.0 → 0.41.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 -2
- package/BACKLOG.md +0 -19
- package/CHANGELOG.md +7 -0
- package/dist/index.js +51 -8
- package/dist/lib/inspector-overlay.d.ts +11 -0
- package/dist/lib/inspector-overlay.js +321 -75
- package/dist/lib/inspector.js +4 -1
- package/dist/lib/observability.d.ts +38 -3
- package/dist/lib/observability.js +151 -33
- package/dist/lib/tools-response.d.ts +1 -1
- package/dist/lib/tools-response.js +5 -7
- package/dist/skills/actors/SKILL.md +3 -7
- package/dist/skills/swarm/SKILL.md +1 -1
- package/docs/actor-inspector.md +18 -13
- package/docs/async-runs.md +1 -1
- package/index.ts +49 -8
- package/lib/inspector-overlay.ts +418 -82
- package/lib/inspector.ts +6 -3
- package/lib/observability.ts +205 -39
- package/lib/tools-response.ts +5 -6
- package/package.json +1 -1
- package/skills/actors/SKILL.md +3 -7
- package/skills/swarm/SKILL.md +1 -1
package/AGENTS.md
CHANGED
|
@@ -70,7 +70,7 @@ Pi host
|
|
|
70
70
|
|
|
71
71
|
- Prefer explicit operator action over silent user-config rewrites.
|
|
72
72
|
- Keep published documentation portable: use `~`, `<repo>`, or relative paths instead of machine-local absolute paths.
|
|
73
|
-
- Preserve runtime output discipline because tool output flows directly into agent context.
|
|
73
|
+
- Preserve runtime output discipline because tool output flows directly into agent context. Tool result/error text contributes exactly one leading line break; Pi's renderer contributes the other break after the call header, producing one empty separator row without doubled gaps.
|
|
74
74
|
- Optimize every actor-facing surface for signal over volume: prefer compact state-backed hints and fewer concepts over broad explanatory prose or speculative guidance.
|
|
75
75
|
- Split broad domains proactively when the current name becomes a generic bucket. Prefer concise domain names that match actual ownership. `tools.ts` is the public tool family owner; decomposed tool subdomains use `tools-<part>.ts` (`tools-message.ts`, `tools-inspect.ts`, `tools-spawn.ts`) under that family. Keep only genuinely cross-family domains unprefixed (`schema.ts`); tool-only helpers stay under `tools-*`. If a `tools-*` helper becomes reused by non-tools domains, remove the `tools-` prefix in the same slice and update ownership comments/imports so the name matches its broader responsibility. Avoid redundant internal `actor-` file prefixes in this actor-scoped package unless the file is deliberately tied to a public actor-named recipe/script/docs surface.
|
|
76
76
|
- Until a stable release greater than `1.x.x`, favor context compression over compatibility shims: do not preserve legacy actor-facing names, aliases, fields, env vars, paths, or docs solely for backward compatibility when a clearer current term exists. Remove compatibility layers in the same slice that renames a concept, and record the break in `CHANGELOG.md`.
|
|
@@ -107,7 +107,7 @@ Pi host
|
|
|
107
107
|
- Preserve node controls: `when`, positive `timeout`, `delay`, bounded `retry`, `failure`, and `recover` cleanup.
|
|
108
108
|
- Persist every async command's complete byte-exact stdout/stderr under command- and retry-specific run-state paths while keeping returned tails bounded and pipeline stdin complete.
|
|
109
109
|
- Keep async run state under `~/.pi/agent/tmp/pi-actors/runs` with injected `{run_id}` and `{state_dir}` values.
|
|
110
|
-
- Preserve event-driven observability: durable retrying terminal follow-up notifications,
|
|
110
|
+
- Preserve event-driven observability with bounded reconciliation: file watchers accelerate durable retrying terminal follow-up notifications, while a conservative terminal-only interval recovers missed watcher activity, rearms degraded watchers, and never replays outbox traffic. Queue coordinator context through Pi follow-up delivery rather than steering so current work finishes before async results arrive and host follow-up batching policy can combine concurrent completions. Terminal delivery is at-least-once across the unavoidable send/handled-marker crash window; watch-triggered and periodic delivery share one live-runtime in-flight guard.
|
|
111
111
|
- When a deferred actor result gates the next step, wait for its terminal follow-up. Do not schedule continuation loops, repeatedly inspect, or mutate its reviewed scope while it runs; inspect early only on operator request, meaningful actor event, or diagnosis of an overdue/stuck run.
|
|
112
112
|
- Do not restore busy-polling examples, duplicate terminal notifications, or duplicate notifications for handled `cancel`, `kill`, or control-stop actions.
|
|
113
113
|
|
package/BACKLOG.md
CHANGED
|
@@ -43,25 +43,6 @@ Non-goals:
|
|
|
43
43
|
|
|
44
44
|
- [ ] Add a manually invoked command that launches an agent-led consolidation cycle over `~/.pi/agent/recipes/drafts`. The cycle must inventory and classify every draft, propose a complete `promote`, `merge`, or `discard` plan, require explicit operator confirmation before mutations, normalize approved reusable capabilities into active recipe-backed tools under `~/.pi/agent/recipes`, and remove every handled source so the drafts directory finishes empty. It must never run automatically or promote tools silently; preserve evidence for each decision and add regressions for plan-only, confirmation, promotion, merge, discard, failure recovery, and empty-directory completion.
|
|
45
45
|
|
|
46
|
-
### Overlay actor inspector
|
|
47
|
-
|
|
48
|
-
- [ ] Replace the command-driven inspector workflow with one large keyboard-driven overlay while preserving the compact striped information design. Stop conditions: `/actors-inspector-toggle` only toggles the overlay; an operator can select an owned run and subagent, switch `Messages` / `Turns` tabs, navigate rows, open/close detail, scroll bounded content, and understand keys/current scope without entering subcommands.
|
|
49
|
-
- [x] Close the dogfood security prerequisites: reset selection across Pi sessions, revalidate ownership before every selected-run read, contain session evidence beneath the owned run state, broaden structured/text redaction, and add regressions.
|
|
50
|
-
- [x] Build the centered responsive overlay shell with bordered header/footer, tabs, owned-run/subagent selector, active-scope summary, empty/loading/error states, and Escape close.
|
|
51
|
-
- [x] Move compact striped Messages rows, filters, unread filtering/attention markers, roster context, and row detail into keyboard navigation.
|
|
52
|
-
- [x] Move Turns rows and full bounded provenance/tool detail into keyboard navigation with scrolling and explicit persisted/unavailable reasoning labels.
|
|
53
|
-
- [x] Remove the subcommand grammar and below-editor widget lifecycle, retain only the toggle command, and document discoverable key hints plus responsive behavior.
|
|
54
|
-
- [ ] Run full package, conformance, and context validation, then close this item. Component input/render/width/scroll/tab/ownership/live-refresh regressions and iterative manual TUI dogfood now cover the accepted visual interaction contract.
|
|
55
|
-
|
|
56
|
-
### Inspector execution observability
|
|
57
|
-
|
|
58
|
-
- [x] Consolidate the actor inspector into one manually opened, navigable operator surface for communication and execution evidence. Stop conditions: an operator can choose an owned run/subagent, switch between communication and turn timelines, open one bounded detail view, and inspect every persisted user/assistant/tool-result turn in source order without exposing another session or claiming unavailable hidden reasoning.
|
|
59
|
-
- [x] Persist deterministic Pi session provenance for each child `pi -p` command under its owned run state, without overriding an explicitly supplied session policy; record the session path in command evidence and tolerate commands that never create a session.
|
|
60
|
-
- [x] Add a resilient, bounded session-evidence reader that follows the active JSONL entry branch, groups assistant responses with correlated tool calls/results into turns, preserves model/usage/error metadata, redacts sensitive argument/content fields, and reports malformed or incomplete evidence honestly.
|
|
61
|
-
- [x] Replace communication-specific inspector controller state with a shared navigation model: run selector → `communication` or `turns` timeline → numbered detail, with stable back/toggle/filter behavior and useful empty states for actors that never send messages.
|
|
62
|
-
- [x] Render compact turn rows and bounded manual detail views for effective prompt/context references, assistant text, host-exposed thinking blocks, tool arguments/results, model/usage, and source-file provenance; label missing reasoning as unavailable rather than inferred.
|
|
63
|
-
- [x] Add ownership, truncation, redaction, malformed JSONL, active-branch ordering, tool correlation, parallel tool completion, terminal run, coordinator-launched subagent, and communication-navigation regressions; update the Actors skill and inspector documentation after the interaction contract stabilizes.
|
|
64
|
-
|
|
65
46
|
## Backlog Curation Rules
|
|
66
47
|
|
|
67
48
|
- Completed work belongs in `CHANGELOG.md`, not in `BACKLOG.md`.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.41.1: Actor Inspector and Delivery Hotfix
|
|
6
|
+
|
|
7
|
+
- `Terminal Delivery`: Added bounded ten-second terminal reconciliation and watcher rearm so owned terminal follow-ups converge without reload when file watching misses or fails. Delivery still uses Pi follow-ups with owner filtering, `triggerTurn`, no historical outbox replay, and the existing at-least-once handled-marker contract; routine run-directory removal stays quiet while real watcher degradation remains diagnostic.
|
|
8
|
+
- `Actor Inspector`: Finished the 0.41 overlay line around a compact meaning-first workflow. `/actors-inspector` now opens the latest numbered Run; Run, Message, and Turn lists show newest evidence first; bounded menus remain usable on short terminals; and humanized Turn rows lead into wrapped Evidence and a metadata-free readable transcript. Turn content now prioritizes User, Thinking, Assistant, and tool actions before Execution and Provenance, strips prompt transport wrappers in readable mode, keeps logical sections on one stripe, and removes false wraps, clipped values, redundant labels/separators, and blank rows.
|
|
9
|
+
- `Tool Output`: Normalized successful results and errors to contribute exactly one leading line break, preserving one empty separator row beneath Pi's rendered tool-call header without occasional double gaps.
|
|
10
|
+
- `Agent Guidance`: Kept Inspector behavior in user documentation and removed it from the bundled Actors skill, leaving that skill focused on agent-operational `spawn`, `message`, `inspect`, recipes, and lifecycle guidance.
|
|
11
|
+
|
|
5
12
|
## 0.41.0: Actor Inspector Overlay and Execution Observability
|
|
6
13
|
|
|
7
14
|
- `[Inspector Menu Alignment]` Shifted value submenus one cell left so adjacent levels share a border, aligned Run and tab labels to one vertical grid, and made the Run dropdown begin immediately below Run by overlaying the tab row. Impact: nested menus read as one connected hierarchy and every top-level control follows the same anchored dropdown rhythm.
|
package/dist/index.js
CHANGED
|
@@ -19,8 +19,10 @@ export default function toolRegistryExtension(pi) {
|
|
|
19
19
|
let runsAnimationInterval;
|
|
20
20
|
let runsNotifyTimeout;
|
|
21
21
|
let activeRunContext;
|
|
22
|
+
let lastRunWatcherDiagnosticId = 0;
|
|
22
23
|
const runUi = Observability.createRunUiObservationState();
|
|
23
24
|
const retirementAttempts = new Set();
|
|
25
|
+
const terminalNotificationsInFlight = new Set();
|
|
24
26
|
const getRunOwnerId = Pi.getSessionId;
|
|
25
27
|
const retireCandidateRuns = (ctx, summary) => {
|
|
26
28
|
void Observability.executeRunRetirements(summary, {
|
|
@@ -38,7 +40,7 @@ export default function toolRegistryExtension(pi) {
|
|
|
38
40
|
return;
|
|
39
41
|
const notificationSink = Pi.createNotificationSink(pi, ctx);
|
|
40
42
|
retireCandidateRuns(ctx, snapshot.summary);
|
|
41
|
-
Observability.deliverRunTransitionNotifications(snapshot.transitions, notificationSink);
|
|
43
|
+
Observability.deliverRunTransitionNotifications(snapshot.transitions, notificationSink, terminalNotificationsInFlight);
|
|
42
44
|
Observability.pruneRunUiObservationState(runUi, snapshot);
|
|
43
45
|
if (!terminalOnly) {
|
|
44
46
|
Observability.deliverRunOutboxNotifications(snapshot.outboxEvents, notificationSink);
|
|
@@ -46,22 +48,57 @@ export default function toolRegistryExtension(pi) {
|
|
|
46
48
|
};
|
|
47
49
|
const closeRunWatchers = () => {
|
|
48
50
|
runWatcher.close();
|
|
51
|
+
terminalReconciliation.close();
|
|
49
52
|
if (runsNotifyTimeout)
|
|
50
53
|
clearTimeout(runsNotifyTimeout);
|
|
51
54
|
runsNotifyTimeout = undefined;
|
|
52
55
|
};
|
|
53
|
-
const
|
|
56
|
+
const reportRunWatcherDiagnostics = (ctx) => {
|
|
57
|
+
for (const diagnostic of runWatcher.getDiagnostics()) {
|
|
58
|
+
if (diagnostic.id <= lastRunWatcherDiagnosticId)
|
|
59
|
+
continue;
|
|
60
|
+
lastRunWatcherDiagnosticId = diagnostic.id;
|
|
61
|
+
ctx.ui.notify(diagnostic.message, diagnostic.code === "rearmed" ? "info" : "warning");
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const scheduleRunEventUpdate = () => {
|
|
54
65
|
if (runsNotifyTimeout)
|
|
55
66
|
clearTimeout(runsNotifyTimeout);
|
|
56
67
|
runsNotifyTimeout = setTimeout(() => {
|
|
68
|
+
const ctx = activeRunContext;
|
|
69
|
+
if (!ctx)
|
|
70
|
+
return;
|
|
57
71
|
runWatcher.refresh();
|
|
58
72
|
updateRunUi(ctx, true);
|
|
73
|
+
reportRunWatcherDiagnostics(ctx);
|
|
59
74
|
}, 50);
|
|
60
75
|
runsNotifyTimeout.unref?.();
|
|
61
76
|
};
|
|
62
77
|
const runWatcher = Observability.createRunStateWatcher({
|
|
63
78
|
stateRoot: Paths.EXTENSION_RUNTIME_PATHS.runStateRoot,
|
|
64
|
-
onChange:
|
|
79
|
+
onChange: scheduleRunEventUpdate,
|
|
80
|
+
});
|
|
81
|
+
const terminalReconciliation = Observability.createRunTerminalReconciliationLoop({
|
|
82
|
+
onError: (error) => {
|
|
83
|
+
const ctx = activeRunContext;
|
|
84
|
+
if (!ctx)
|
|
85
|
+
return;
|
|
86
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
87
|
+
ctx.ui.notify(`Actor terminal reconciliation failed: ${message}`, "error");
|
|
88
|
+
},
|
|
89
|
+
reconcile: () => {
|
|
90
|
+
const ctx = activeRunContext;
|
|
91
|
+
if (!ctx)
|
|
92
|
+
return;
|
|
93
|
+
Observability.reconcileRunTerminalNotifications({
|
|
94
|
+
inFlight: terminalNotificationsInFlight,
|
|
95
|
+
ownerId: getRunOwnerId(ctx),
|
|
96
|
+
sink: Pi.createNotificationSink(pi, ctx),
|
|
97
|
+
state: runUi,
|
|
98
|
+
});
|
|
99
|
+
reportRunWatcherDiagnostics(ctx);
|
|
100
|
+
},
|
|
101
|
+
refreshWatcher: () => runWatcher.refresh(),
|
|
65
102
|
});
|
|
66
103
|
const actorToolDefinitions = new Map();
|
|
67
104
|
const withCurrentThinkingContext = (definition) => {
|
|
@@ -111,16 +148,22 @@ export default function toolRegistryExtension(pi) {
|
|
|
111
148
|
// Clear the pre-overlay widget after hot reloads from older pi-actors builds.
|
|
112
149
|
ctx.ui.setWidget("zz-pi-actors-comms", undefined);
|
|
113
150
|
activeRunContext = ctx;
|
|
151
|
+
closeRunWatchers();
|
|
152
|
+
recipeReload.close();
|
|
114
153
|
await Temp.prepareExtensionTempDir(Paths.EXTENSION_RUNTIME_PATHS.tempDir);
|
|
154
|
+
if (activeRunContext !== ctx)
|
|
155
|
+
return;
|
|
115
156
|
runtime.loadTools(ctx);
|
|
116
157
|
updateRunUi(ctx, true, true);
|
|
117
|
-
closeRunWatchers();
|
|
118
|
-
recipeReload.close();
|
|
119
158
|
runWatcher.refresh();
|
|
159
|
+
terminalReconciliation.start();
|
|
120
160
|
recipeReload.watch(ctx);
|
|
121
161
|
if (runsAnimationInterval)
|
|
122
162
|
clearInterval(runsAnimationInterval);
|
|
123
|
-
runsAnimationInterval = setInterval(() =>
|
|
163
|
+
runsAnimationInterval = setInterval(() => {
|
|
164
|
+
if (activeRunContext === ctx)
|
|
165
|
+
updateRunUi(ctx, false);
|
|
166
|
+
}, 1000);
|
|
124
167
|
runsAnimationInterval.unref?.();
|
|
125
168
|
});
|
|
126
169
|
pi.on("session_shutdown", async () => {
|
|
@@ -131,8 +174,8 @@ export default function toolRegistryExtension(pi) {
|
|
|
131
174
|
closeRunWatchers();
|
|
132
175
|
recipeReload.close();
|
|
133
176
|
});
|
|
134
|
-
pi.registerCommand("actors-inspector
|
|
135
|
-
description: "
|
|
177
|
+
pi.registerCommand("actors-inspector", {
|
|
178
|
+
description: "Open the keyboard-driven actor inspector overlay",
|
|
136
179
|
handler: async (_args, ctx) => {
|
|
137
180
|
ctx.ui.setWidget("zz-pi-actors-comms", undefined);
|
|
138
181
|
await ctx.ui.custom((tui, theme, _keybindings, done) => new InspectorOverlay.ActorInspectorOverlay({
|
|
@@ -29,6 +29,7 @@ export declare class ActorInspectorOverlay {
|
|
|
29
29
|
private detailOpen;
|
|
30
30
|
private detailScroll;
|
|
31
31
|
private detailTurn?;
|
|
32
|
+
private detailView;
|
|
32
33
|
private readonly readKeys;
|
|
33
34
|
private focus;
|
|
34
35
|
private filterControlIndex;
|
|
@@ -45,6 +46,9 @@ export declare class ActorInspectorOverlay {
|
|
|
45
46
|
dispose(): void;
|
|
46
47
|
private runs;
|
|
47
48
|
private ensureSelectedRun;
|
|
49
|
+
private contentViewportRows;
|
|
50
|
+
private selectRun;
|
|
51
|
+
private cycleRun;
|
|
48
52
|
private listItemCount;
|
|
49
53
|
private selectorAnchor;
|
|
50
54
|
private renderKeyHints;
|
|
@@ -58,6 +62,12 @@ export declare class ActorInspectorOverlay {
|
|
|
58
62
|
private communicationFromOptions;
|
|
59
63
|
private communicationRows;
|
|
60
64
|
private renderDetail;
|
|
65
|
+
private wrapDetailLines;
|
|
66
|
+
private detailSection;
|
|
67
|
+
private readableValueLines;
|
|
68
|
+
private turnEvidenceLines;
|
|
69
|
+
private readablePromptText;
|
|
70
|
+
private turnTranscriptLines;
|
|
61
71
|
private turnItems;
|
|
62
72
|
private turnRows;
|
|
63
73
|
private subagents;
|
|
@@ -73,6 +83,7 @@ export declare class ActorInspectorOverlay {
|
|
|
73
83
|
private renderMenuBox;
|
|
74
84
|
private renderFilterMenus;
|
|
75
85
|
private openDetail;
|
|
86
|
+
private backDetail;
|
|
76
87
|
private closeDetail;
|
|
77
88
|
private border;
|
|
78
89
|
private stripeBackground;
|