@llblab/pi-actors 0.29.2 → 0.30.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 +16 -1
- package/BACKLOG.md +89 -206
- package/CHANGELOG.md +9 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +71 -315
- package/dist/lib/actor-inspector-tui.d.ts +35 -0
- package/dist/lib/actor-inspector-tui.js +159 -1
- package/dist/lib/observability.d.ts +34 -0
- package/dist/lib/observability.js +103 -1
- package/dist/lib/paths.d.ts +9 -0
- package/dist/lib/paths.js +15 -0
- package/dist/lib/pi.d.ts +19 -0
- package/dist/lib/pi.js +21 -0
- package/dist/lib/runtime.d.ts +5 -0
- package/dist/lib/runtime.js +48 -0
- package/dist/lib/tools.d.ts +9 -0
- package/dist/lib/tools.js +58 -8
- package/dist/skills/actors/SKILL.md +10 -116
- package/dist/skills/swarm/SKILL.md +20 -1
- package/docs/README.md +1 -0
- package/docs/actors-deep-reference.md +66 -0
- package/index.ts +99 -379
- package/lib/actor-inspector-tui.ts +221 -1
- package/lib/observability.ts +194 -34
- package/lib/paths.ts +27 -0
- package/lib/pi.ts +47 -0
- package/lib/runtime.ts +55 -0
- package/lib/tools.ts +119 -24
- package/package.json +1 -1
- package/skills/actors/SKILL.md +10 -116
- package/skills/swarm/SKILL.md +20 -1
package/dist/index.js
CHANGED
|
@@ -4,59 +4,24 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Wraps command templates as callable pi tools, stores durable user tools as recipe files, and exposes actor orchestration across reloads and sessions.
|
|
6
6
|
*/
|
|
7
|
-
import { existsSync, readdirSync, watch } from "node:fs";
|
|
8
|
-
import { dirname, join } from "node:path";
|
|
9
|
-
import { fileURLToPath } from "node:url";
|
|
10
7
|
import * as ActorInspectorTui from "./lib/actor-inspector-tui.js";
|
|
11
8
|
import * as AsyncRuns from "./lib/async-runs.js";
|
|
12
9
|
import * as CommandTemplates from "./lib/command-templates.js";
|
|
13
10
|
import * as Observability from "./lib/observability.js";
|
|
14
11
|
import * as Paths from "./lib/paths.js";
|
|
12
|
+
import * as Pi from "./lib/pi.js";
|
|
15
13
|
import * as Prompts from "./lib/prompts.js";
|
|
16
14
|
import * as Runtime from "./lib/runtime.js";
|
|
17
15
|
import * as Temp from "./lib/temp.js";
|
|
18
16
|
import * as Tools from "./lib/tools.js";
|
|
19
|
-
const EXTENSION_DIR = dirname(fileURLToPath(import.meta.url));
|
|
20
|
-
const EXTENSION_SKILLS_DIR = join(EXTENSION_DIR, "skills");
|
|
21
|
-
const CONFIG_PATH = Paths.getConfigPath();
|
|
22
|
-
const TEMP_DIR = Paths.getExtensionTmpDir();
|
|
23
|
-
const RUN_STATE_ROOT = Paths.getRunStateRoot();
|
|
24
|
-
const RESERVED_TOOL_NAMES = new Set([
|
|
25
|
-
"read",
|
|
26
|
-
"write",
|
|
27
|
-
"edit",
|
|
28
|
-
"bash",
|
|
29
|
-
"find",
|
|
30
|
-
"grep",
|
|
31
|
-
"ls",
|
|
32
|
-
"register_tool",
|
|
33
|
-
"message",
|
|
34
|
-
"spawn",
|
|
35
|
-
"inspect",
|
|
36
|
-
]);
|
|
37
17
|
export default function toolRegistryExtension(pi) {
|
|
38
18
|
let runsAnimationInterval;
|
|
39
19
|
let runsNotifyTimeout;
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
let stateRootWatcher;
|
|
43
|
-
const runDirWatchers = new Map();
|
|
44
|
-
const observedRuns = new Map();
|
|
45
|
-
const observedRunEventLines = new Map();
|
|
46
|
-
const observedRunOutboxEventIds = new Map();
|
|
20
|
+
let activeRunContext;
|
|
21
|
+
const runUi = Observability.createRunUiObservationState();
|
|
47
22
|
const retirementAttempts = new Set();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let actorInspectorRows = 12;
|
|
51
|
-
let actorInspectorChannels;
|
|
52
|
-
let actorInspectorMention;
|
|
53
|
-
let actorInspectorBranch;
|
|
54
|
-
let actorInspectorUnreadOnly = false;
|
|
55
|
-
let actorInspectorRoomLimitPerRun = 12;
|
|
56
|
-
let selectedInspectorSequence;
|
|
57
|
-
const actorInspectorReadKeys = new Set();
|
|
58
|
-
let recipeWatcherFailureNotified = false;
|
|
59
|
-
const getRunOwnerId = (ctx) => ctx.sessionManager.getSessionId();
|
|
23
|
+
const actorInspector = ActorInspectorTui.createActorInspectorControllerState();
|
|
24
|
+
const getRunOwnerId = Pi.getSessionId;
|
|
60
25
|
const retireCandidateRuns = (ctx, summary) => {
|
|
61
26
|
void Observability.executeRunRetirements(summary, {
|
|
62
27
|
attempted: retirementAttempts,
|
|
@@ -67,88 +32,40 @@ export default function toolRegistryExtension(pi) {
|
|
|
67
32
|
};
|
|
68
33
|
const updateRunUi = (ctx, notify = false) => {
|
|
69
34
|
const ownerId = getRunOwnerId(ctx);
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
ctx.ui.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
readKeys: actorInspectorReadKeys,
|
|
94
|
-
roomLimitPerRun: actorInspectorRoomLimitPerRun,
|
|
95
|
-
unreadOnly: actorInspectorUnreadOnly,
|
|
96
|
-
});
|
|
97
|
-
const rows = (selectedInspectorSequence !== undefined
|
|
98
|
-
? ActorInspectorTui.renderInspectorItemView(previews, width, style, { sequence: selectedInspectorSequence })
|
|
99
|
-
: ActorInspectorTui.renderInspectorWidget(previews, width, style)) ?? [];
|
|
100
|
-
const run = previews[0]?.run;
|
|
101
|
-
const roster = selectedInspectorSequence === undefined && run
|
|
102
|
-
? ActorInspectorTui.renderInspectorRosterPanel(ActorInspectorTui.readActorInspectorRoster(RUN_STATE_ROOT, run), width, style)
|
|
103
|
-
: undefined;
|
|
104
|
-
return roster ? [...roster, ...rows] : rows;
|
|
105
|
-
},
|
|
106
|
-
};
|
|
107
|
-
}
|
|
35
|
+
const snapshot = Observability.readRunUiSnapshot(runUi, ownerId);
|
|
36
|
+
ctx.ui.setStatus("zz-pi-actors-runs", snapshot.status ? ctx.ui.theme.fg("dim", snapshot.status) : undefined);
|
|
37
|
+
ctx.ui.setWidget("zz-pi-actors-comms", actorInspector.visible
|
|
38
|
+
? () => ({
|
|
39
|
+
invalidate() { },
|
|
40
|
+
render(width) {
|
|
41
|
+
return ActorInspectorTui.renderActorInspectorPanel({
|
|
42
|
+
stateRoot: Paths.EXTENSION_RUNTIME_PATHS.runStateRoot,
|
|
43
|
+
state: actorInspector,
|
|
44
|
+
ownerId,
|
|
45
|
+
width,
|
|
46
|
+
style: {
|
|
47
|
+
actor: (text) => ctx.ui.theme.fg("accent", text),
|
|
48
|
+
muted: (text) => ctx.ui.theme.fg("dim", text),
|
|
49
|
+
preview: (text) => ctx.ui.theme.fg("text", text),
|
|
50
|
+
stripe: (text) => text,
|
|
51
|
+
stripeAlt: (text) => ctx.ui.theme.bg("customMessageBg", text),
|
|
52
|
+
target: (text) => ctx.ui.theme.fg("success", text),
|
|
53
|
+
type: (text) => ctx.ui.theme.fg("warning", text),
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
})
|
|
108
58
|
: undefined, { placement: "belowEditor" });
|
|
109
|
-
const transitions = Observability.detectRunTransitions(observedRuns, summary);
|
|
110
|
-
const outboxEvents = Observability.detectRunOutboxEvents(observedRunEventLines, summary, observedRunOutboxEventIds);
|
|
111
59
|
if (!notify)
|
|
112
60
|
return;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const notificationType = Observability.getRunTransitionNotificationType(transition);
|
|
119
|
-
ctx.ui.notify(text, notificationType);
|
|
120
|
-
if (!Observability.shouldSendRunTransitionFollowUp(transition))
|
|
121
|
-
continue;
|
|
122
|
-
pi.sendMessage({
|
|
123
|
-
customType: "pi-actors-run",
|
|
124
|
-
content: text,
|
|
125
|
-
display: true,
|
|
126
|
-
details: transition,
|
|
127
|
-
}, { deliverAs: "followUp", triggerTurn: true });
|
|
128
|
-
}
|
|
129
|
-
Observability.pruneRunObservationState(observedRuns, observedRunEventLines, summary, transitions.map((transition) => transition.stateDir ?? transition.run), observedRunOutboxEventIds);
|
|
130
|
-
for (const event of outboxEvents) {
|
|
131
|
-
if (!Observability.shouldNotifyRunOutboxEvent(event))
|
|
132
|
-
continue;
|
|
133
|
-
const text = Observability.formatRunOutboxMessage(event);
|
|
134
|
-
const notificationType = Observability.getRunOutboxNotificationType(event);
|
|
135
|
-
ctx.ui.notify(text, notificationType);
|
|
136
|
-
if (!Observability.shouldSendRunOutboxFollowUp(event))
|
|
137
|
-
continue;
|
|
138
|
-
pi.sendMessage({
|
|
139
|
-
customType: "pi-actors-run-message",
|
|
140
|
-
content: text,
|
|
141
|
-
display: true,
|
|
142
|
-
details: event,
|
|
143
|
-
}, { deliverAs: "followUp", triggerTurn: true });
|
|
144
|
-
}
|
|
61
|
+
const notificationSink = Pi.createNotificationSink(pi, ctx);
|
|
62
|
+
retireCandidateRuns(ctx, snapshot.summary);
|
|
63
|
+
Observability.deliverRunTransitionNotifications(snapshot.transitions, notificationSink);
|
|
64
|
+
Observability.pruneRunUiObservationState(runUi, snapshot);
|
|
65
|
+
Observability.deliverRunOutboxNotifications(snapshot.outboxEvents, notificationSink);
|
|
145
66
|
};
|
|
146
67
|
const closeRunWatchers = () => {
|
|
147
|
-
|
|
148
|
-
stateRootWatcher = undefined;
|
|
149
|
-
for (const watcher of runDirWatchers.values())
|
|
150
|
-
watcher.close();
|
|
151
|
-
runDirWatchers.clear();
|
|
68
|
+
runWatcher.close();
|
|
152
69
|
if (runsNotifyTimeout)
|
|
153
70
|
clearTimeout(runsNotifyTimeout);
|
|
154
71
|
runsNotifyTimeout = undefined;
|
|
@@ -157,89 +74,18 @@ export default function toolRegistryExtension(pi) {
|
|
|
157
74
|
if (runsNotifyTimeout)
|
|
158
75
|
clearTimeout(runsNotifyTimeout);
|
|
159
76
|
runsNotifyTimeout = setTimeout(() => {
|
|
160
|
-
|
|
77
|
+
runWatcher.refresh();
|
|
161
78
|
updateRunUi(ctx, true);
|
|
162
79
|
}, 50);
|
|
163
80
|
runsNotifyTimeout.unref?.();
|
|
164
81
|
};
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const watcher = watch(stateDir, () => scheduleRunEventUpdate(ctx));
|
|
170
|
-
watcher.on("error", () => {
|
|
171
|
-
watcher.close();
|
|
172
|
-
runDirWatchers.delete(stateDir);
|
|
173
|
-
});
|
|
174
|
-
runDirWatchers.set(stateDir, watcher);
|
|
175
|
-
}
|
|
176
|
-
catch {
|
|
177
|
-
// Watching is best-effort; explicit inspect remains available.
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
function refreshRunWatchers(ctx) {
|
|
181
|
-
if (!existsSync(RUN_STATE_ROOT))
|
|
182
|
-
return;
|
|
183
|
-
if (!stateRootWatcher) {
|
|
184
|
-
try {
|
|
185
|
-
stateRootWatcher = watch(RUN_STATE_ROOT, () => scheduleRunEventUpdate(ctx));
|
|
186
|
-
stateRootWatcher.on("error", () => {
|
|
187
|
-
stateRootWatcher?.close();
|
|
188
|
-
stateRootWatcher = undefined;
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
catch {
|
|
192
|
-
// Watching is best-effort; explicit inspect remains available.
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
for (const entry of readdirSync(RUN_STATE_ROOT, { withFileTypes: true })) {
|
|
196
|
-
if (!entry.isDirectory())
|
|
197
|
-
continue;
|
|
198
|
-
watchRunDir(ctx, `${RUN_STATE_ROOT}/${entry.name}`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
const closeRecipeWatcher = () => {
|
|
202
|
-
recipeRootWatcher?.close();
|
|
203
|
-
recipeRootWatcher = undefined;
|
|
204
|
-
if (recipeReloadTimeout)
|
|
205
|
-
clearTimeout(recipeReloadTimeout);
|
|
206
|
-
recipeReloadTimeout = undefined;
|
|
207
|
-
};
|
|
208
|
-
const notifyRecipeWatcherFailure = (ctx) => {
|
|
209
|
-
if (recipeWatcherFailureNotified)
|
|
210
|
-
return;
|
|
211
|
-
recipeWatcherFailureNotified = true;
|
|
212
|
-
ctx.ui.notify("Recipe live reload watcher failed; restart the session or use register_tool again to refresh recipe tools.", "warning");
|
|
213
|
-
};
|
|
214
|
-
const scheduleRecipeReload = (ctx) => {
|
|
215
|
-
recipeWatcherFailureNotified = false;
|
|
216
|
-
if (recipeReloadTimeout)
|
|
217
|
-
clearTimeout(recipeReloadTimeout);
|
|
218
|
-
recipeReloadTimeout = setTimeout(() => {
|
|
219
|
-
runtime.loadTools(ctx);
|
|
220
|
-
ctx.ui.notify("Recipe tools refreshed from ~/.pi/agent/recipes", "info");
|
|
221
|
-
}, 150);
|
|
222
|
-
recipeReloadTimeout.unref?.();
|
|
223
|
-
};
|
|
224
|
-
const watchRecipeRoot = (ctx) => {
|
|
225
|
-
const recipeRoot = Paths.getRecipeRoot();
|
|
226
|
-
if (recipeRootWatcher || !existsSync(recipeRoot))
|
|
227
|
-
return;
|
|
228
|
-
try {
|
|
229
|
-
recipeRootWatcher = watch(recipeRoot, () => scheduleRecipeReload(ctx));
|
|
230
|
-
recipeRootWatcher.on("error", () => {
|
|
231
|
-
recipeRootWatcher?.close();
|
|
232
|
-
recipeRootWatcher = undefined;
|
|
233
|
-
notifyRecipeWatcherFailure(ctx);
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
catch {
|
|
237
|
-
notifyRecipeWatcherFailure(ctx);
|
|
238
|
-
}
|
|
239
|
-
};
|
|
82
|
+
const runWatcher = Observability.createRunStateWatcher({
|
|
83
|
+
stateRoot: Paths.EXTENSION_RUNTIME_PATHS.runStateRoot,
|
|
84
|
+
onChange: () => activeRunContext && scheduleRunEventUpdate(activeRunContext),
|
|
85
|
+
});
|
|
240
86
|
const actorToolDefinitions = new Map();
|
|
241
87
|
const runtime = Runtime.createAutoToolsRuntime({
|
|
242
|
-
configPath:
|
|
88
|
+
configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
|
|
243
89
|
exec: CommandTemplates.execCommandTemplate,
|
|
244
90
|
getActiveTools: () => pi.getActiveTools(),
|
|
245
91
|
getAllTools: () => pi.getAllTools(),
|
|
@@ -247,22 +93,25 @@ export default function toolRegistryExtension(pi) {
|
|
|
247
93
|
actorToolDefinitions.set(definition.name, definition);
|
|
248
94
|
pi.registerTool(definition);
|
|
249
95
|
},
|
|
250
|
-
reservedToolNames: RESERVED_TOOL_NAMES,
|
|
96
|
+
reservedToolNames: Tools.RESERVED_TOOL_NAMES,
|
|
251
97
|
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
|
252
98
|
});
|
|
99
|
+
const recipeReload = Runtime.createRecipeToolReloadWatcher(runtime);
|
|
253
100
|
pi.on("resources_discover", async () => {
|
|
254
|
-
|
|
101
|
+
const skillPaths = Paths.getExistingExtensionSkillPaths(import.meta.url);
|
|
102
|
+
if (skillPaths.length === 0)
|
|
255
103
|
return;
|
|
256
|
-
return { skillPaths
|
|
104
|
+
return { skillPaths };
|
|
257
105
|
});
|
|
258
106
|
pi.on("session_start", async (_event, ctx) => {
|
|
259
|
-
|
|
107
|
+
activeRunContext = ctx;
|
|
108
|
+
await Temp.prepareExtensionTempDir(Paths.EXTENSION_RUNTIME_PATHS.tempDir);
|
|
260
109
|
runtime.loadTools(ctx);
|
|
261
110
|
updateRunUi(ctx);
|
|
262
111
|
closeRunWatchers();
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
112
|
+
recipeReload.close();
|
|
113
|
+
runWatcher.refresh();
|
|
114
|
+
recipeReload.watch(ctx);
|
|
266
115
|
if (runsAnimationInterval)
|
|
267
116
|
clearInterval(runsAnimationInterval);
|
|
268
117
|
runsAnimationInterval = setInterval(() => updateRunUi(ctx, false), 1000);
|
|
@@ -272,139 +121,46 @@ export default function toolRegistryExtension(pi) {
|
|
|
272
121
|
if (runsAnimationInterval)
|
|
273
122
|
clearInterval(runsAnimationInterval);
|
|
274
123
|
runsAnimationInterval = undefined;
|
|
124
|
+
activeRunContext = undefined;
|
|
275
125
|
closeRunWatchers();
|
|
276
|
-
|
|
126
|
+
recipeReload.close();
|
|
277
127
|
});
|
|
278
128
|
pi.registerCommand("actors-inspector-toggle", {
|
|
279
|
-
description:
|
|
129
|
+
description: ActorInspectorTui.ACTOR_INSPECTOR_COMMAND_DESCRIPTIONS.toggle,
|
|
280
130
|
handler: async (args, ctx) => {
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
-
const rows = Number.parseInt(String(raw), 10);
|
|
284
|
-
if (!Number.isFinite(rows) || rows <= 0) {
|
|
285
|
-
ctx.ui.notify("Usage: /actors-inspector-toggle [rows] where rows > 0", "warning");
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
actorInspectorRows = rows;
|
|
289
|
-
actorInspectorRoomLimitPerRun = rows;
|
|
290
|
-
selectedInspectorSequence = undefined;
|
|
291
|
-
communicationWidgetVisible = true;
|
|
131
|
+
const result = ActorInspectorTui.handleActorInspectorToggle(actorInspector, args);
|
|
132
|
+
if (result.update)
|
|
292
133
|
updateRunUi(ctx);
|
|
293
|
-
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
if (selectedInspectorSequence !== undefined) {
|
|
297
|
-
selectedInspectorSequence = undefined;
|
|
298
|
-
communicationWidgetVisible = true;
|
|
299
|
-
updateRunUi(ctx);
|
|
300
|
-
ctx.ui.notify("Actor inspector table", "info");
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
if (communicationWidgetVisible) {
|
|
304
|
-
communicationWidgetVisible = false;
|
|
305
|
-
}
|
|
306
|
-
else {
|
|
307
|
-
actorInspectorRows = 12;
|
|
308
|
-
actorInspectorRoomLimitPerRun = 12;
|
|
309
|
-
communicationWidgetVisible = true;
|
|
310
|
-
}
|
|
311
|
-
updateRunUi(ctx);
|
|
312
|
-
ctx.ui.notify(`Actor inspector ${communicationWidgetVisible ? "shown" : "hidden"}`, "info");
|
|
134
|
+
ctx.ui.notify(result.notify, result.type);
|
|
313
135
|
},
|
|
314
136
|
});
|
|
315
137
|
pi.registerCommand("actors-inspector-filter", {
|
|
316
|
-
description:
|
|
138
|
+
description: ActorInspectorTui.ACTOR_INSPECTOR_COMMAND_DESCRIPTIONS.filter,
|
|
317
139
|
handler: async (args, ctx) => {
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (!mode || mode === "all" || mode === "clear") {
|
|
323
|
-
actorInspectorChannels = undefined;
|
|
324
|
-
actorInspectorMention = undefined;
|
|
325
|
-
actorInspectorBranch = undefined;
|
|
326
|
-
actorInspectorUnreadOnly = false;
|
|
327
|
-
}
|
|
328
|
-
else if (mode === "room" || mode === "direct" || mode === "broadcast") {
|
|
329
|
-
actorInspectorChannels = [mode];
|
|
330
|
-
actorInspectorMention = undefined;
|
|
331
|
-
}
|
|
332
|
-
else if (mode === "unread") {
|
|
333
|
-
actorInspectorUnreadOnly = true;
|
|
334
|
-
}
|
|
335
|
-
else if (mode === "branch" || mode === "current-branch") {
|
|
336
|
-
const branch = parts.slice(1).join(" ").trim();
|
|
337
|
-
if (!branch) {
|
|
338
|
-
ctx.ui.notify(`Usage: /actors-inspector-filter ${mode} <branch-name>`, "warning");
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
actorInspectorBranch = branch;
|
|
342
|
-
}
|
|
343
|
-
else if (mode === "mention") {
|
|
344
|
-
const mention = parts.slice(1).join(" ").trim();
|
|
345
|
-
if (!mention) {
|
|
346
|
-
ctx.ui.notify("Usage: /actors-inspector-filter mention <text>", "warning");
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
actorInspectorChannels = undefined;
|
|
350
|
-
actorInspectorMention = mention;
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
ctx.ui.notify("Usage: /actors-inspector-filter all|room|direct|broadcast|unread|branch <name>|mention <text>", "warning");
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
selectedInspectorSequence = undefined;
|
|
357
|
-
communicationWidgetVisible = true;
|
|
358
|
-
updateRunUi(ctx);
|
|
359
|
-
ctx.ui.notify(`Actor inspector filter ${mode || "all"}`, "info");
|
|
140
|
+
const result = ActorInspectorTui.handleActorInspectorFilter(actorInspector, args);
|
|
141
|
+
if (result.update)
|
|
142
|
+
updateRunUi(ctx);
|
|
143
|
+
ctx.ui.notify(result.notify, result.type);
|
|
360
144
|
},
|
|
361
145
|
});
|
|
362
146
|
pi.registerCommand("actors-inspect", {
|
|
363
|
-
description:
|
|
147
|
+
description: ActorInspectorTui.ACTOR_INSPECTOR_COMMAND_DESCRIPTIONS.inspect,
|
|
364
148
|
handler: async (args, ctx) => {
|
|
365
|
-
const
|
|
366
|
-
const
|
|
367
|
-
if (
|
|
368
|
-
ctx
|
|
369
|
-
|
|
370
|
-
}
|
|
371
|
-
const previews = ActorInspectorTui.readActorInspectorPreviews(RUN_STATE_ROOT, actorInspectorRows, {
|
|
372
|
-
channels: actorInspectorChannels,
|
|
373
|
-
currentRunOnly: true,
|
|
374
|
-
branch: actorInspectorBranch,
|
|
375
|
-
mention: actorInspectorMention,
|
|
376
|
-
ownerId: getRunOwnerId(ctx),
|
|
377
|
-
readKeys: actorInspectorReadKeys,
|
|
378
|
-
roomLimitPerRun: actorInspectorRoomLimitPerRun,
|
|
379
|
-
unreadOnly: actorInspectorUnreadOnly,
|
|
380
|
-
});
|
|
381
|
-
const preview = previews.find((item) => item.sequence === sequence);
|
|
382
|
-
if (preview)
|
|
383
|
-
actorInspectorReadKeys.add(ActorInspectorTui.inspectorPreviewReadKey(preview));
|
|
384
|
-
selectedInspectorSequence = sequence;
|
|
385
|
-
communicationWidgetVisible = true;
|
|
386
|
-
updateRunUi(ctx);
|
|
387
|
-
ctx.ui.notify(`Actor inspect item ${sequence}`, "info");
|
|
149
|
+
const previews = ActorInspectorTui.readActorInspectorPreviews(Paths.EXTENSION_RUNTIME_PATHS.runStateRoot, actorInspector.rows, ActorInspectorTui.getActorInspectorPreviewOptions(actorInspector, getRunOwnerId(ctx)));
|
|
150
|
+
const result = ActorInspectorTui.handleActorInspectorInspect(actorInspector, args, previews);
|
|
151
|
+
if (result.update)
|
|
152
|
+
updateRunUi(ctx);
|
|
153
|
+
ctx.ui.notify(result.notify, result.type);
|
|
388
154
|
},
|
|
389
155
|
});
|
|
390
156
|
pi.on("before_agent_start", async (event) => ({
|
|
391
157
|
systemPrompt: `${event.systemPrompt}\n\n${Prompts.ONBOARDING_SYSTEM_PROMPT}`,
|
|
392
158
|
}));
|
|
393
|
-
|
|
394
|
-
configPath:
|
|
159
|
+
Pi.registerToolDefinitions(pi, Tools.createCoreActorToolDefinitions({
|
|
160
|
+
configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
|
|
395
161
|
getActiveTools: () => pi.getActiveTools(),
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
notify: runtime.notify,
|
|
399
|
-
registerRuntimeTool: runtime.registerRuntimeTool,
|
|
400
|
-
reservedToolNames: RESERVED_TOOL_NAMES,
|
|
162
|
+
getRuntimeTool: (name) => actorToolDefinitions.get(name),
|
|
163
|
+
registryRuntime: runtime,
|
|
401
164
|
setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
|
|
402
165
|
}));
|
|
403
|
-
pi.registerTool(Tools.createSpawnToolDefinition());
|
|
404
|
-
pi.registerTool(Tools.createActorMessageToolDefinition({
|
|
405
|
-
getTool: (name) => actorToolDefinitions.get(name),
|
|
406
|
-
}));
|
|
407
|
-
pi.registerTool(Tools.createInspectToolDefinition({
|
|
408
|
-
getTool: (name) => actorToolDefinitions.get(name),
|
|
409
|
-
}));
|
|
410
166
|
}
|
|
@@ -50,6 +50,41 @@ export interface ActorInspectorPreviewReadOptions {
|
|
|
50
50
|
roomLimitPerRun?: number;
|
|
51
51
|
unreadOnly?: boolean;
|
|
52
52
|
}
|
|
53
|
+
export interface ActorInspectorControllerState {
|
|
54
|
+
branch?: string;
|
|
55
|
+
channels?: ActorInspectorPreview["channel"][];
|
|
56
|
+
mention?: string;
|
|
57
|
+
readKeys: Set<string>;
|
|
58
|
+
roomLimitPerRun: number;
|
|
59
|
+
rows: number;
|
|
60
|
+
selectedSequence?: number;
|
|
61
|
+
unreadOnly: boolean;
|
|
62
|
+
visible: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface ActorInspectorCommandResult {
|
|
65
|
+
notify: string;
|
|
66
|
+
type: "info" | "warning";
|
|
67
|
+
update: boolean;
|
|
68
|
+
}
|
|
69
|
+
export declare const DEFAULT_ACTOR_INSPECTOR_ROWS = 12;
|
|
70
|
+
export declare const ACTOR_INSPECTOR_COMMAND_DESCRIPTIONS: {
|
|
71
|
+
filter: string;
|
|
72
|
+
inspect: string;
|
|
73
|
+
toggle: string;
|
|
74
|
+
};
|
|
75
|
+
export declare function createActorInspectorControllerState(): ActorInspectorControllerState;
|
|
76
|
+
export declare function getActorInspectorPreviewOptions(state: ActorInspectorControllerState, ownerId: string): ActorInspectorPreviewReadOptions;
|
|
77
|
+
export declare function handleActorInspectorToggle(state: ActorInspectorControllerState, args: unknown): ActorInspectorCommandResult;
|
|
78
|
+
export declare function handleActorInspectorFilter(state: ActorInspectorControllerState, args: unknown): ActorInspectorCommandResult;
|
|
79
|
+
export declare function handleActorInspectorInspect(state: ActorInspectorControllerState, args: unknown, previews: ActorInspectorPreview[]): ActorInspectorCommandResult;
|
|
80
|
+
export declare function selectActorInspectorSequence(state: ActorInspectorControllerState, sequence: number, previews: ActorInspectorPreview[]): ActorInspectorCommandResult;
|
|
81
|
+
export declare function renderActorInspectorPanel(input: {
|
|
82
|
+
stateRoot: string;
|
|
83
|
+
state: ActorInspectorControllerState;
|
|
84
|
+
ownerId: string;
|
|
85
|
+
width: number;
|
|
86
|
+
style: ActorInspectorWidgetStyle;
|
|
87
|
+
}): string[];
|
|
53
88
|
export declare function inspectorPreviewReadKey(preview: ActorInspectorPreview): string;
|
|
54
89
|
export declare function readActorInspectorPreviews(stateRoot?: string, limit?: number, options?: ActorInspectorPreviewReadOptions): ActorInspectorPreview[];
|
|
55
90
|
export declare function readActorInspectorRoster(stateRoot: string | undefined, run: string, room?: string): ActorInspectorRosterMember[];
|