@dougbots/avenor-pi 0.3.5 → 0.3.6
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/dist/index.js +98 -25
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -108,31 +108,79 @@ function summarizeEvent(evt) {
|
|
|
108
108
|
async function src_default(pi) {
|
|
109
109
|
const trackedRuns = /* @__PURE__ */ new Map();
|
|
110
110
|
let pollingActive = false;
|
|
111
|
+
let pollingGeneration = 0;
|
|
112
|
+
let pollInFlight = null;
|
|
111
113
|
let sessionCtx = null;
|
|
112
114
|
async function pollRuns() {
|
|
113
|
-
|
|
115
|
+
const liveMap = /* @__PURE__ */ new Map();
|
|
114
116
|
try {
|
|
115
|
-
|
|
117
|
+
const allLive = await statusTool({});
|
|
118
|
+
const liveList = Array.isArray(allLive) ? allLive : [allLive];
|
|
119
|
+
for (const result of liveList) liveMap.set(result.run_id, result);
|
|
116
120
|
} catch (err) {
|
|
117
|
-
console.error("avenor pollRuns:
|
|
118
|
-
return [];
|
|
121
|
+
console.error("avenor pollRuns: failed to list singleton runs", err);
|
|
119
122
|
}
|
|
120
|
-
const results = Array.isArray(raw) ? raw : [raw];
|
|
121
123
|
const entries = [];
|
|
122
|
-
for (const
|
|
123
|
-
const
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
124
|
+
for (const run of trackedRuns.values()) {
|
|
125
|
+
const live = liveMap.get(run.runId);
|
|
126
|
+
if (live) {
|
|
127
|
+
liveMap.delete(live.run_id);
|
|
128
|
+
run.lastStatus = live;
|
|
129
|
+
entries.push({
|
|
130
|
+
runId: run.runId,
|
|
131
|
+
label: run.label,
|
|
132
|
+
status: live.status,
|
|
133
|
+
phase: live.phase,
|
|
134
|
+
phaseLabel: live.phase_label,
|
|
135
|
+
agent: run.agent,
|
|
136
|
+
pendingPermission: !!live.pending_permission,
|
|
137
|
+
permissionDescription: live.pending_permission?.description
|
|
138
|
+
});
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const raw = await statusTool({
|
|
143
|
+
runId: run.runId,
|
|
144
|
+
supervisorId: run.supervisorId
|
|
145
|
+
});
|
|
146
|
+
const result = Array.isArray(raw) ? raw[0] : raw;
|
|
147
|
+
if (!result) throw new Error("status response was empty");
|
|
148
|
+
run.lastStatus = result;
|
|
149
|
+
entries.push({
|
|
150
|
+
runId: run.runId,
|
|
151
|
+
label: run.label,
|
|
152
|
+
status: result.status,
|
|
153
|
+
phase: result.phase,
|
|
154
|
+
phaseLabel: result.phase_label,
|
|
155
|
+
agent: run.agent,
|
|
156
|
+
pendingPermission: !!result.pending_permission,
|
|
157
|
+
permissionDescription: result.pending_permission?.description
|
|
158
|
+
});
|
|
159
|
+
} catch (err) {
|
|
160
|
+
console.error(`avenor pollRuns: statusTool failed for ${run.runId}`, err);
|
|
161
|
+
const previous = run.lastStatus;
|
|
162
|
+
entries.push({
|
|
163
|
+
runId: run.runId,
|
|
164
|
+
label: run.label,
|
|
165
|
+
status: previous?.status ?? "unavailable",
|
|
166
|
+
phase: previous?.phase,
|
|
167
|
+
phaseLabel: previous?.phase_label,
|
|
168
|
+
agent: run.agent,
|
|
169
|
+
pendingPermission: !!previous?.pending_permission,
|
|
170
|
+
permissionDescription: previous?.pending_permission?.description
|
|
171
|
+
});
|
|
172
|
+
}
|
|
135
173
|
}
|
|
174
|
+
for (const live of liveMap.values()) entries.push({
|
|
175
|
+
runId: live.run_id,
|
|
176
|
+
label: live.label,
|
|
177
|
+
status: live.status,
|
|
178
|
+
phase: live.phase,
|
|
179
|
+
phaseLabel: live.phase_label,
|
|
180
|
+
agent: "unknown",
|
|
181
|
+
pendingPermission: !!live.pending_permission,
|
|
182
|
+
permissionDescription: live.pending_permission?.description
|
|
183
|
+
});
|
|
136
184
|
return entries;
|
|
137
185
|
}
|
|
138
186
|
function renderStatusLines(entries) {
|
|
@@ -160,17 +208,24 @@ async function src_default(pi) {
|
|
|
160
208
|
function startPolling() {
|
|
161
209
|
if (pollingActive) return;
|
|
162
210
|
pollingActive = true;
|
|
211
|
+
const generation = ++pollingGeneration;
|
|
163
212
|
const tick = async () => {
|
|
213
|
+
if (!pollingActive || generation !== pollingGeneration) return;
|
|
164
214
|
const prevStatuses = /* @__PURE__ */ new Map();
|
|
165
215
|
for (const [id, run] of trackedRuns) prevStatuses.set(id, run.lastStatus?.status);
|
|
166
|
-
const
|
|
216
|
+
const currentPoll = pollRuns();
|
|
217
|
+
pollInFlight = currentPoll;
|
|
218
|
+
const entries = await currentPoll.finally(() => {
|
|
219
|
+
if (pollInFlight === currentPoll) pollInFlight = null;
|
|
220
|
+
});
|
|
221
|
+
if (!pollingActive || generation !== pollingGeneration) return;
|
|
167
222
|
updateWidget(entries);
|
|
168
223
|
for (const entry of entries) {
|
|
169
224
|
const run = trackedRuns.get(entry.runId);
|
|
170
225
|
if (!run) continue;
|
|
171
226
|
if (TERMINAL_STATUSES.has(entry.status)) {
|
|
172
227
|
const prevStatus = prevStatuses.get(entry.runId);
|
|
173
|
-
if (prevStatus
|
|
228
|
+
if (!prevStatus || !TERMINAL_STATUSES.has(prevStatus)) {
|
|
174
229
|
sessionCtx?.ui.notify(`Sub-agent "${entry.label}" finished: ${entry.status}`, entry.status === "done" ? "info" : "warning");
|
|
175
230
|
if (!run.blocking) try {
|
|
176
231
|
pi.sendUserMessage(buildCompletionText({
|
|
@@ -195,20 +250,35 @@ async function src_default(pi) {
|
|
|
195
250
|
}
|
|
196
251
|
} else if (!entry.pendingPermission && run.permissionNotified) run.permissionNotified = false;
|
|
197
252
|
}
|
|
198
|
-
if (entries.some((e) => !TERMINAL_STATUSES.has(e.status))) setTimeout(
|
|
253
|
+
if (entries.some((e) => !TERMINAL_STATUSES.has(e.status)) && pollingActive && generation === pollingGeneration) setTimeout(() => {
|
|
254
|
+
tick().catch((err) => {
|
|
255
|
+
pollingActive = false;
|
|
256
|
+
console.error("avenor polling loop failed", err);
|
|
257
|
+
});
|
|
258
|
+
}, POLL_INTERVAL_MS);
|
|
199
259
|
else {
|
|
200
260
|
pollingActive = false;
|
|
201
261
|
sessionCtx?.ui.setStatus("avenor", "");
|
|
202
262
|
sessionCtx?.ui.setWidget("avenor-status", void 0);
|
|
203
263
|
}
|
|
204
264
|
};
|
|
205
|
-
tick()
|
|
265
|
+
tick().catch((err) => {
|
|
266
|
+
pollingActive = false;
|
|
267
|
+
console.error("avenor polling loop failed", err);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
async function stopPolling() {
|
|
271
|
+
pollingActive = false;
|
|
272
|
+
pollingGeneration++;
|
|
273
|
+
await pollInFlight?.catch(() => {});
|
|
274
|
+
sessionCtx?.ui.setStatus("avenor", "");
|
|
275
|
+
sessionCtx?.ui.setWidget("avenor-status", void 0);
|
|
206
276
|
}
|
|
207
277
|
pi.on("session_start", async (_event, ctx) => {
|
|
208
278
|
sessionCtx = ctx;
|
|
209
279
|
});
|
|
210
280
|
pi.on("session_shutdown", async (_event, _ctx) => {
|
|
211
|
-
|
|
281
|
+
await stopPolling();
|
|
212
282
|
sessionCtx = null;
|
|
213
283
|
});
|
|
214
284
|
pi.on("before_agent_start", async (event, _ctx) => {
|
|
@@ -285,6 +355,7 @@ async function src_default(pi) {
|
|
|
285
355
|
agent: params.agent,
|
|
286
356
|
label,
|
|
287
357
|
supervisorId: result.supervisor_id,
|
|
358
|
+
runtimeId: result.runtime_id,
|
|
288
359
|
startTime: Date.now(),
|
|
289
360
|
blocking: wait
|
|
290
361
|
});
|
|
@@ -337,7 +408,7 @@ async function src_default(pi) {
|
|
|
337
408
|
});
|
|
338
409
|
else {
|
|
339
410
|
let lastAction = "";
|
|
340
|
-
if (!
|
|
411
|
+
if (!params.supervisor_id) try {
|
|
341
412
|
const eventsResult = await eventsTool({
|
|
342
413
|
runId: result.run_id,
|
|
343
414
|
limit: 3
|
|
@@ -537,6 +608,8 @@ async function src_default(pi) {
|
|
|
537
608
|
force: Type.Optional(Type.Boolean({ description: "Force shutdown instead of graceful" }))
|
|
538
609
|
}),
|
|
539
610
|
async execute(_toolCallId, params) {
|
|
611
|
+
await stopPolling();
|
|
612
|
+
trackedRuns.clear();
|
|
540
613
|
const result = await shutdownTool({
|
|
541
614
|
supervisorId: params.supervisor_id,
|
|
542
615
|
force: params.force
|
|
@@ -658,7 +731,7 @@ async function src_default(pi) {
|
|
|
658
731
|
if (!await ctx.ui.confirm("Cancel run", `Cancel "${label}" (${runId.slice(0, 8)})?`)) return;
|
|
659
732
|
try {
|
|
660
733
|
const { Supervisor } = await import("@dougbots/avenor-core");
|
|
661
|
-
await (await Supervisor.get()).getClient().cancel(run?.lastStatus?.runtime_id ?? runId);
|
|
734
|
+
await (await Supervisor.get()).getClient().cancel(run?.lastStatus?.runtime_id ?? run?.runtimeId ?? runId);
|
|
662
735
|
ctx.ui.notify(`Cancelled "${label}"`, "info");
|
|
663
736
|
} catch (err) {
|
|
664
737
|
ctx.ui.notify(`Failed to cancel: ${err instanceof Error ? err.message : String(err)}`, "error");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dougbots/avenor-pi",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dev": "tsdown --watch"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@dougbots/avenor-core": "^0.3.
|
|
38
|
+
"@dougbots/avenor-core": "^0.3.6"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@earendil-works/pi-coding-agent": "*",
|