@dougbots/avenor-pi 0.3.5 → 0.3.7
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.d.ts +2 -1
- package/dist/index.js +105 -28
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
|
|
3
3
|
//#region src/index.d.ts
|
|
4
|
+
declare function statusSupervisorId(requestedSupervisorId: string | undefined, spawnedSupervisorId: string): string | undefined;
|
|
4
5
|
declare function export_default(pi: ExtensionAPI): Promise<void>;
|
|
5
6
|
//#endregion
|
|
6
|
-
export { export_default as default };
|
|
7
|
+
export { export_default as default, statusSupervisorId };
|
package/dist/index.js
CHANGED
|
@@ -80,6 +80,9 @@ function formatRunLine(entry) {
|
|
|
80
80
|
//#endregion
|
|
81
81
|
//#region src/index.ts
|
|
82
82
|
const POLL_INTERVAL_MS = 3e3;
|
|
83
|
+
function statusSupervisorId(requestedSupervisorId, spawnedSupervisorId) {
|
|
84
|
+
return requestedSupervisorId ? spawnedSupervisorId : void 0;
|
|
85
|
+
}
|
|
83
86
|
function sleep(ms) {
|
|
84
87
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
85
88
|
}
|
|
@@ -108,31 +111,79 @@ function summarizeEvent(evt) {
|
|
|
108
111
|
async function src_default(pi) {
|
|
109
112
|
const trackedRuns = /* @__PURE__ */ new Map();
|
|
110
113
|
let pollingActive = false;
|
|
114
|
+
let pollingGeneration = 0;
|
|
115
|
+
let pollInFlight = null;
|
|
111
116
|
let sessionCtx = null;
|
|
112
117
|
async function pollRuns() {
|
|
113
|
-
|
|
118
|
+
const liveMap = /* @__PURE__ */ new Map();
|
|
114
119
|
try {
|
|
115
|
-
|
|
120
|
+
const allLive = await statusTool({});
|
|
121
|
+
const liveList = Array.isArray(allLive) ? allLive : [allLive];
|
|
122
|
+
for (const result of liveList) liveMap.set(result.run_id, result);
|
|
116
123
|
} catch (err) {
|
|
117
|
-
console.error("avenor pollRuns:
|
|
118
|
-
return [];
|
|
124
|
+
console.error("avenor pollRuns: failed to list singleton runs", err);
|
|
119
125
|
}
|
|
120
|
-
const results = Array.isArray(raw) ? raw : [raw];
|
|
121
126
|
const entries = [];
|
|
122
|
-
for (const
|
|
123
|
-
const
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
for (const run of trackedRuns.values()) {
|
|
128
|
+
const live = liveMap.get(run.runId);
|
|
129
|
+
if (live) {
|
|
130
|
+
liveMap.delete(live.run_id);
|
|
131
|
+
run.lastStatus = live;
|
|
132
|
+
entries.push({
|
|
133
|
+
runId: run.runId,
|
|
134
|
+
label: run.label,
|
|
135
|
+
status: live.status,
|
|
136
|
+
phase: live.phase,
|
|
137
|
+
phaseLabel: live.phase_label,
|
|
138
|
+
agent: run.agent,
|
|
139
|
+
pendingPermission: !!live.pending_permission,
|
|
140
|
+
permissionDescription: live.pending_permission?.description
|
|
141
|
+
});
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const raw = await statusTool({
|
|
146
|
+
runId: run.runId,
|
|
147
|
+
supervisorId: run.supervisorId
|
|
148
|
+
});
|
|
149
|
+
const result = Array.isArray(raw) ? raw[0] : raw;
|
|
150
|
+
if (!result) throw new Error("status response was empty");
|
|
151
|
+
run.lastStatus = result;
|
|
152
|
+
entries.push({
|
|
153
|
+
runId: run.runId,
|
|
154
|
+
label: run.label,
|
|
155
|
+
status: result.status,
|
|
156
|
+
phase: result.phase,
|
|
157
|
+
phaseLabel: result.phase_label,
|
|
158
|
+
agent: run.agent,
|
|
159
|
+
pendingPermission: !!result.pending_permission,
|
|
160
|
+
permissionDescription: result.pending_permission?.description
|
|
161
|
+
});
|
|
162
|
+
} catch (err) {
|
|
163
|
+
console.error(`avenor pollRuns: statusTool failed for ${run.runId}`, err);
|
|
164
|
+
const previous = run.lastStatus;
|
|
165
|
+
entries.push({
|
|
166
|
+
runId: run.runId,
|
|
167
|
+
label: run.label,
|
|
168
|
+
status: previous?.status ?? "unavailable",
|
|
169
|
+
phase: previous?.phase,
|
|
170
|
+
phaseLabel: previous?.phase_label,
|
|
171
|
+
agent: run.agent,
|
|
172
|
+
pendingPermission: !!previous?.pending_permission,
|
|
173
|
+
permissionDescription: previous?.pending_permission?.description
|
|
174
|
+
});
|
|
175
|
+
}
|
|
135
176
|
}
|
|
177
|
+
for (const live of liveMap.values()) entries.push({
|
|
178
|
+
runId: live.run_id,
|
|
179
|
+
label: live.label,
|
|
180
|
+
status: live.status,
|
|
181
|
+
phase: live.phase,
|
|
182
|
+
phaseLabel: live.phase_label,
|
|
183
|
+
agent: "unknown",
|
|
184
|
+
pendingPermission: !!live.pending_permission,
|
|
185
|
+
permissionDescription: live.pending_permission?.description
|
|
186
|
+
});
|
|
136
187
|
return entries;
|
|
137
188
|
}
|
|
138
189
|
function renderStatusLines(entries) {
|
|
@@ -160,17 +211,24 @@ async function src_default(pi) {
|
|
|
160
211
|
function startPolling() {
|
|
161
212
|
if (pollingActive) return;
|
|
162
213
|
pollingActive = true;
|
|
214
|
+
const generation = ++pollingGeneration;
|
|
163
215
|
const tick = async () => {
|
|
216
|
+
if (!pollingActive || generation !== pollingGeneration) return;
|
|
164
217
|
const prevStatuses = /* @__PURE__ */ new Map();
|
|
165
218
|
for (const [id, run] of trackedRuns) prevStatuses.set(id, run.lastStatus?.status);
|
|
166
|
-
const
|
|
219
|
+
const currentPoll = pollRuns();
|
|
220
|
+
pollInFlight = currentPoll;
|
|
221
|
+
const entries = await currentPoll.finally(() => {
|
|
222
|
+
if (pollInFlight === currentPoll) pollInFlight = null;
|
|
223
|
+
});
|
|
224
|
+
if (!pollingActive || generation !== pollingGeneration) return;
|
|
167
225
|
updateWidget(entries);
|
|
168
226
|
for (const entry of entries) {
|
|
169
227
|
const run = trackedRuns.get(entry.runId);
|
|
170
228
|
if (!run) continue;
|
|
171
229
|
if (TERMINAL_STATUSES.has(entry.status)) {
|
|
172
230
|
const prevStatus = prevStatuses.get(entry.runId);
|
|
173
|
-
if (prevStatus
|
|
231
|
+
if (!prevStatus || !TERMINAL_STATUSES.has(prevStatus)) {
|
|
174
232
|
sessionCtx?.ui.notify(`Sub-agent "${entry.label}" finished: ${entry.status}`, entry.status === "done" ? "info" : "warning");
|
|
175
233
|
if (!run.blocking) try {
|
|
176
234
|
pi.sendUserMessage(buildCompletionText({
|
|
@@ -195,20 +253,35 @@ async function src_default(pi) {
|
|
|
195
253
|
}
|
|
196
254
|
} else if (!entry.pendingPermission && run.permissionNotified) run.permissionNotified = false;
|
|
197
255
|
}
|
|
198
|
-
if (entries.some((e) => !TERMINAL_STATUSES.has(e.status))) setTimeout(
|
|
256
|
+
if (entries.some((e) => !TERMINAL_STATUSES.has(e.status)) && pollingActive && generation === pollingGeneration) setTimeout(() => {
|
|
257
|
+
tick().catch((err) => {
|
|
258
|
+
pollingActive = false;
|
|
259
|
+
console.error("avenor polling loop failed", err);
|
|
260
|
+
});
|
|
261
|
+
}, POLL_INTERVAL_MS);
|
|
199
262
|
else {
|
|
200
263
|
pollingActive = false;
|
|
201
264
|
sessionCtx?.ui.setStatus("avenor", "");
|
|
202
265
|
sessionCtx?.ui.setWidget("avenor-status", void 0);
|
|
203
266
|
}
|
|
204
267
|
};
|
|
205
|
-
tick()
|
|
268
|
+
tick().catch((err) => {
|
|
269
|
+
pollingActive = false;
|
|
270
|
+
console.error("avenor polling loop failed", err);
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
async function stopPolling() {
|
|
274
|
+
pollingActive = false;
|
|
275
|
+
pollingGeneration++;
|
|
276
|
+
await pollInFlight?.catch(() => {});
|
|
277
|
+
sessionCtx?.ui.setStatus("avenor", "");
|
|
278
|
+
sessionCtx?.ui.setWidget("avenor-status", void 0);
|
|
206
279
|
}
|
|
207
280
|
pi.on("session_start", async (_event, ctx) => {
|
|
208
281
|
sessionCtx = ctx;
|
|
209
282
|
});
|
|
210
283
|
pi.on("session_shutdown", async (_event, _ctx) => {
|
|
211
|
-
|
|
284
|
+
await stopPolling();
|
|
212
285
|
sessionCtx = null;
|
|
213
286
|
});
|
|
214
287
|
pi.on("before_agent_start", async (event, _ctx) => {
|
|
@@ -280,11 +353,13 @@ async function src_default(pi) {
|
|
|
280
353
|
serverUrl: params.server_url,
|
|
281
354
|
supervisorId: params.supervisor_id
|
|
282
355
|
});
|
|
356
|
+
const supervisorId = statusSupervisorId(params.supervisor_id, result.supervisor_id);
|
|
283
357
|
trackedRuns.set(result.run_id, {
|
|
284
358
|
runId: result.run_id,
|
|
285
359
|
agent: params.agent,
|
|
286
360
|
label,
|
|
287
|
-
supervisorId
|
|
361
|
+
supervisorId,
|
|
362
|
+
runtimeId: result.runtime_id,
|
|
288
363
|
startTime: Date.now(),
|
|
289
364
|
blocking: wait
|
|
290
365
|
});
|
|
@@ -317,7 +392,7 @@ async function src_default(pi) {
|
|
|
317
392
|
try {
|
|
318
393
|
raw = await statusTool({
|
|
319
394
|
runId: result.run_id,
|
|
320
|
-
supervisorId
|
|
395
|
+
supervisorId
|
|
321
396
|
});
|
|
322
397
|
} catch (err) {
|
|
323
398
|
console.error("avenor spawn poll: statusTool failed", err);
|
|
@@ -337,7 +412,7 @@ async function src_default(pi) {
|
|
|
337
412
|
});
|
|
338
413
|
else {
|
|
339
414
|
let lastAction = "";
|
|
340
|
-
if (!
|
|
415
|
+
if (!params.supervisor_id) try {
|
|
341
416
|
const eventsResult = await eventsTool({
|
|
342
417
|
runId: result.run_id,
|
|
343
418
|
limit: 3
|
|
@@ -537,6 +612,8 @@ async function src_default(pi) {
|
|
|
537
612
|
force: Type.Optional(Type.Boolean({ description: "Force shutdown instead of graceful" }))
|
|
538
613
|
}),
|
|
539
614
|
async execute(_toolCallId, params) {
|
|
615
|
+
await stopPolling();
|
|
616
|
+
trackedRuns.clear();
|
|
540
617
|
const result = await shutdownTool({
|
|
541
618
|
supervisorId: params.supervisor_id,
|
|
542
619
|
force: params.force
|
|
@@ -658,7 +735,7 @@ async function src_default(pi) {
|
|
|
658
735
|
if (!await ctx.ui.confirm("Cancel run", `Cancel "${label}" (${runId.slice(0, 8)})?`)) return;
|
|
659
736
|
try {
|
|
660
737
|
const { Supervisor } = await import("@dougbots/avenor-core");
|
|
661
|
-
await (await Supervisor.get()).getClient().cancel(run?.lastStatus?.runtime_id ?? runId);
|
|
738
|
+
await (await Supervisor.get()).getClient().cancel(run?.lastStatus?.runtime_id ?? run?.runtimeId ?? runId);
|
|
662
739
|
ctx.ui.notify(`Cancelled "${label}"`, "info");
|
|
663
740
|
} catch (err) {
|
|
664
741
|
ctx.ui.notify(`Failed to cancel: ${err instanceof Error ? err.message : String(err)}`, "error");
|
|
@@ -667,4 +744,4 @@ async function src_default(pi) {
|
|
|
667
744
|
});
|
|
668
745
|
}
|
|
669
746
|
//#endregion
|
|
670
|
-
export { src_default as default };
|
|
747
|
+
export { src_default as default, statusSupervisorId };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dougbots/avenor-pi",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
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.7"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@earendil-works/pi-coding-agent": "*",
|