@h-rig/pi-rig 0.0.6-alpha.6 → 0.0.6-alpha.60
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/src/client.js +28 -2
- package/dist/src/commands.js +33 -3
- package/dist/src/index.js +173 -12
- package/package.json +2 -2
package/dist/src/client.js
CHANGED
|
@@ -79,8 +79,9 @@ function createRigContextFromEnv(env = process.env) {
|
|
|
79
79
|
const discovered = discoverRigContext(env);
|
|
80
80
|
const serverUrl = env.RIG_SERVER_URL ?? env.RIG_SERVER_BASE_URL ?? discovered.serverUrl;
|
|
81
81
|
const projectRoot = env.RIG_PROJECT_ROOT ?? env.PROJECT_RIG_ROOT ?? discovered.projectRoot;
|
|
82
|
-
const authToken = env.RIG_AUTH_TOKEN ?? env.
|
|
82
|
+
const authToken = env.RIG_AUTH_TOKEN ?? env.RIG_SERVER_AUTH_TOKEN ?? discovered.authToken;
|
|
83
83
|
const steeringPollMs = cleanNonNegativeInteger(env.RIG_STEERING_POLL_MS);
|
|
84
|
+
const operatorSession = env.RIG_PI_OPERATOR_SESSION === "1" || env.RIG_PI_OPERATOR_SESSION === "true";
|
|
84
85
|
const active = Boolean(runId || taskId || serverUrl || projectRoot);
|
|
85
86
|
if (!active)
|
|
86
87
|
return { active: false };
|
|
@@ -91,7 +92,8 @@ function createRigContextFromEnv(env = process.env) {
|
|
|
91
92
|
...serverUrl ? { serverUrl } : {},
|
|
92
93
|
...projectRoot ? { projectRoot } : {},
|
|
93
94
|
...authToken ? { authToken } : {},
|
|
94
|
-
...steeringPollMs !== null ? { steeringPollMs } : {}
|
|
95
|
+
...steeringPollMs !== null ? { steeringPollMs } : {},
|
|
96
|
+
...operatorSession ? { operatorSession } : {}
|
|
95
97
|
};
|
|
96
98
|
}
|
|
97
99
|
function joinUrl(baseUrl, pathname) {
|
|
@@ -157,6 +159,20 @@ class RigBridgeClient {
|
|
|
157
159
|
const payload = await this.request(`/api/runs/${encodeURIComponent(runId)}`);
|
|
158
160
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { runId };
|
|
159
161
|
}
|
|
162
|
+
async runLogs(runId = this.context.runId, limit = 20) {
|
|
163
|
+
if (!runId)
|
|
164
|
+
throw new Error("runId is required");
|
|
165
|
+
const payload = await this.request(`/api/runs/${encodeURIComponent(runId)}/logs?limit=${encodeURIComponent(String(limit))}`);
|
|
166
|
+
const entries = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.entries : null;
|
|
167
|
+
return Array.isArray(entries) ? entries.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
|
|
168
|
+
}
|
|
169
|
+
async runTimeline(runId = this.context.runId, limit = 20) {
|
|
170
|
+
if (!runId)
|
|
171
|
+
throw new Error("runId is required");
|
|
172
|
+
const payload = await this.request(`/api/runs/${encodeURIComponent(runId)}/timeline?limit=${encodeURIComponent(String(limit))}`);
|
|
173
|
+
const entries = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.entries : null;
|
|
174
|
+
return Array.isArray(entries) ? entries.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
|
|
175
|
+
}
|
|
160
176
|
async steer(message, runId = this.context.runId) {
|
|
161
177
|
if (!runId)
|
|
162
178
|
throw new Error("runId is required");
|
|
@@ -167,6 +183,16 @@ class RigBridgeClient {
|
|
|
167
183
|
});
|
|
168
184
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true };
|
|
169
185
|
}
|
|
186
|
+
async stop(runId = this.context.runId) {
|
|
187
|
+
if (!runId)
|
|
188
|
+
throw new Error("runId is required");
|
|
189
|
+
const payload = await this.request("/api/runs/stop", {
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: { "content-type": "application/json" },
|
|
192
|
+
body: JSON.stringify({ runId })
|
|
193
|
+
});
|
|
194
|
+
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true, runId };
|
|
195
|
+
}
|
|
170
196
|
async pollSteering(runId = this.context.runId) {
|
|
171
197
|
if (!runId)
|
|
172
198
|
return [];
|
package/dist/src/commands.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/pi-rig/src/commands.ts
|
|
3
|
+
function runRecordFromPayload(payload) {
|
|
4
|
+
return payload.run && typeof payload.run === "object" && !Array.isArray(payload.run) ? payload.run : payload;
|
|
5
|
+
}
|
|
6
|
+
function formatEntry(entry) {
|
|
7
|
+
const type = String(entry.type ?? entry.title ?? "event");
|
|
8
|
+
const text = typeof entry.text === "string" ? entry.text : typeof entry.detail === "string" ? entry.detail : typeof entry.message === "string" ? entry.message : JSON.stringify(entry);
|
|
9
|
+
return `${type}: ${text}`;
|
|
10
|
+
}
|
|
3
11
|
function createRigSlashCommands(input) {
|
|
4
12
|
const notify = input.notify ?? (() => {});
|
|
5
13
|
async function handleRig(args) {
|
|
@@ -28,18 +36,40 @@ function createRigSlashCommands(input) {
|
|
|
28
36
|
}
|
|
29
37
|
if (first === "attach") {
|
|
30
38
|
const run = await input.client.attach(second);
|
|
31
|
-
const runRecord = run
|
|
39
|
+
const runRecord = runRecordFromPayload(run);
|
|
32
40
|
notify(`Attached to ${String(runRecord.runId ?? second ?? input.context.runId ?? "run")}: ${String(runRecord.status ?? "unknown")}`, "info");
|
|
33
41
|
return;
|
|
34
42
|
}
|
|
35
|
-
|
|
43
|
+
if (first === "timeline" || first === "logs") {
|
|
44
|
+
const runId = second || input.context.runId;
|
|
45
|
+
const entries = first === "timeline" ? await input.client.runTimeline(runId, 20) : await input.client.runLogs(runId, 20);
|
|
46
|
+
notify(entries.length > 0 ? entries.slice(-10).map(formatEntry).join(`
|
|
47
|
+
`) : `No ${first} entries for ${runId ?? "run"}.`, "info");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (first === "steer") {
|
|
51
|
+
const message = args.trim().slice("steer".length).trim();
|
|
52
|
+
if (!message) {
|
|
53
|
+
notify("Usage: /rig steer <message>", "error");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
await input.client.steer(message);
|
|
57
|
+
notify("Rig steering message queued.", "info");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (first === "stop") {
|
|
61
|
+
await input.client.stop(second || input.context.runId);
|
|
62
|
+
notify("Rig stop requested.", "info");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
notify("Usage: /rig status | /rig task list | /rig task run [id] | /rig attach [run-id] | /rig timeline [run-id] | /rig logs [run-id] | /rig steer <message> | /rig stop [run-id]", "error");
|
|
36
66
|
} catch (error) {
|
|
37
67
|
notify(error instanceof Error ? error.message : String(error), "error");
|
|
38
68
|
}
|
|
39
69
|
}
|
|
40
70
|
return {
|
|
41
71
|
rig: {
|
|
42
|
-
description: "Rig control-plane commands: status, task list, task run, attach",
|
|
72
|
+
description: "Rig control-plane commands: status, task list, task run, attach, timeline, logs, steer, stop",
|
|
43
73
|
handler: handleRig
|
|
44
74
|
}
|
|
45
75
|
};
|
package/dist/src/index.js
CHANGED
|
@@ -79,8 +79,9 @@ function createRigContextFromEnv(env = process.env) {
|
|
|
79
79
|
const discovered = discoverRigContext(env);
|
|
80
80
|
const serverUrl = env.RIG_SERVER_URL ?? env.RIG_SERVER_BASE_URL ?? discovered.serverUrl;
|
|
81
81
|
const projectRoot = env.RIG_PROJECT_ROOT ?? env.PROJECT_RIG_ROOT ?? discovered.projectRoot;
|
|
82
|
-
const authToken = env.RIG_AUTH_TOKEN ?? env.
|
|
82
|
+
const authToken = env.RIG_AUTH_TOKEN ?? env.RIG_SERVER_AUTH_TOKEN ?? discovered.authToken;
|
|
83
83
|
const steeringPollMs = cleanNonNegativeInteger(env.RIG_STEERING_POLL_MS);
|
|
84
|
+
const operatorSession = env.RIG_PI_OPERATOR_SESSION === "1" || env.RIG_PI_OPERATOR_SESSION === "true";
|
|
84
85
|
const active = Boolean(runId || taskId || serverUrl || projectRoot);
|
|
85
86
|
if (!active)
|
|
86
87
|
return { active: false };
|
|
@@ -91,7 +92,8 @@ function createRigContextFromEnv(env = process.env) {
|
|
|
91
92
|
...serverUrl ? { serverUrl } : {},
|
|
92
93
|
...projectRoot ? { projectRoot } : {},
|
|
93
94
|
...authToken ? { authToken } : {},
|
|
94
|
-
...steeringPollMs !== null ? { steeringPollMs } : {}
|
|
95
|
+
...steeringPollMs !== null ? { steeringPollMs } : {},
|
|
96
|
+
...operatorSession ? { operatorSession } : {}
|
|
95
97
|
};
|
|
96
98
|
}
|
|
97
99
|
function joinUrl(baseUrl, pathname) {
|
|
@@ -157,6 +159,20 @@ class RigBridgeClient {
|
|
|
157
159
|
const payload = await this.request(`/api/runs/${encodeURIComponent(runId)}`);
|
|
158
160
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { runId };
|
|
159
161
|
}
|
|
162
|
+
async runLogs(runId = this.context.runId, limit = 20) {
|
|
163
|
+
if (!runId)
|
|
164
|
+
throw new Error("runId is required");
|
|
165
|
+
const payload = await this.request(`/api/runs/${encodeURIComponent(runId)}/logs?limit=${encodeURIComponent(String(limit))}`);
|
|
166
|
+
const entries = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.entries : null;
|
|
167
|
+
return Array.isArray(entries) ? entries.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
|
|
168
|
+
}
|
|
169
|
+
async runTimeline(runId = this.context.runId, limit = 20) {
|
|
170
|
+
if (!runId)
|
|
171
|
+
throw new Error("runId is required");
|
|
172
|
+
const payload = await this.request(`/api/runs/${encodeURIComponent(runId)}/timeline?limit=${encodeURIComponent(String(limit))}`);
|
|
173
|
+
const entries = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.entries : null;
|
|
174
|
+
return Array.isArray(entries) ? entries.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
|
|
175
|
+
}
|
|
160
176
|
async steer(message, runId = this.context.runId) {
|
|
161
177
|
if (!runId)
|
|
162
178
|
throw new Error("runId is required");
|
|
@@ -167,6 +183,16 @@ class RigBridgeClient {
|
|
|
167
183
|
});
|
|
168
184
|
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true };
|
|
169
185
|
}
|
|
186
|
+
async stop(runId = this.context.runId) {
|
|
187
|
+
if (!runId)
|
|
188
|
+
throw new Error("runId is required");
|
|
189
|
+
const payload = await this.request("/api/runs/stop", {
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: { "content-type": "application/json" },
|
|
192
|
+
body: JSON.stringify({ runId })
|
|
193
|
+
});
|
|
194
|
+
return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : { ok: true, runId };
|
|
195
|
+
}
|
|
170
196
|
async pollSteering(runId = this.context.runId) {
|
|
171
197
|
if (!runId)
|
|
172
198
|
return [];
|
|
@@ -201,6 +227,14 @@ class RigBridgeClient {
|
|
|
201
227
|
}
|
|
202
228
|
|
|
203
229
|
// packages/pi-rig/src/commands.ts
|
|
230
|
+
function runRecordFromPayload(payload) {
|
|
231
|
+
return payload.run && typeof payload.run === "object" && !Array.isArray(payload.run) ? payload.run : payload;
|
|
232
|
+
}
|
|
233
|
+
function formatEntry(entry) {
|
|
234
|
+
const type = String(entry.type ?? entry.title ?? "event");
|
|
235
|
+
const text = typeof entry.text === "string" ? entry.text : typeof entry.detail === "string" ? entry.detail : typeof entry.message === "string" ? entry.message : JSON.stringify(entry);
|
|
236
|
+
return `${type}: ${text}`;
|
|
237
|
+
}
|
|
204
238
|
function createRigSlashCommands(input) {
|
|
205
239
|
const notify = input.notify ?? (() => {});
|
|
206
240
|
async function handleRig(args) {
|
|
@@ -229,18 +263,40 @@ function createRigSlashCommands(input) {
|
|
|
229
263
|
}
|
|
230
264
|
if (first === "attach") {
|
|
231
265
|
const run = await input.client.attach(second);
|
|
232
|
-
const runRecord = run
|
|
266
|
+
const runRecord = runRecordFromPayload(run);
|
|
233
267
|
notify(`Attached to ${String(runRecord.runId ?? second ?? input.context.runId ?? "run")}: ${String(runRecord.status ?? "unknown")}`, "info");
|
|
234
268
|
return;
|
|
235
269
|
}
|
|
236
|
-
|
|
270
|
+
if (first === "timeline" || first === "logs") {
|
|
271
|
+
const runId = second || input.context.runId;
|
|
272
|
+
const entries = first === "timeline" ? await input.client.runTimeline(runId, 20) : await input.client.runLogs(runId, 20);
|
|
273
|
+
notify(entries.length > 0 ? entries.slice(-10).map(formatEntry).join(`
|
|
274
|
+
`) : `No ${first} entries for ${runId ?? "run"}.`, "info");
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (first === "steer") {
|
|
278
|
+
const message = args.trim().slice("steer".length).trim();
|
|
279
|
+
if (!message) {
|
|
280
|
+
notify("Usage: /rig steer <message>", "error");
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
await input.client.steer(message);
|
|
284
|
+
notify("Rig steering message queued.", "info");
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (first === "stop") {
|
|
288
|
+
await input.client.stop(second || input.context.runId);
|
|
289
|
+
notify("Rig stop requested.", "info");
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
notify("Usage: /rig status | /rig task list | /rig task run [id] | /rig attach [run-id] | /rig timeline [run-id] | /rig logs [run-id] | /rig steer <message> | /rig stop [run-id]", "error");
|
|
237
293
|
} catch (error) {
|
|
238
294
|
notify(error instanceof Error ? error.message : String(error), "error");
|
|
239
295
|
}
|
|
240
296
|
}
|
|
241
297
|
return {
|
|
242
298
|
rig: {
|
|
243
|
-
description: "Rig control-plane commands: status, task list, task run, attach",
|
|
299
|
+
description: "Rig control-plane commands: status, task list, task run, attach, timeline, logs, steer, stop",
|
|
244
300
|
handler: handleRig
|
|
245
301
|
}
|
|
246
302
|
};
|
|
@@ -318,6 +374,35 @@ function notify(ctx, message, level = "info") {
|
|
|
318
374
|
notifyFn.call(ui, message, level);
|
|
319
375
|
}
|
|
320
376
|
}
|
|
377
|
+
function setWidget(ctx, id, lines) {
|
|
378
|
+
const ui = ctx && typeof ctx === "object" ? ctx.ui : null;
|
|
379
|
+
const setWidgetFn = ui && typeof ui === "object" ? ui.setWidget : null;
|
|
380
|
+
if (typeof setWidgetFn === "function") {
|
|
381
|
+
setWidgetFn.call(ui, id, lines);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function setStatus(ctx, id, text) {
|
|
385
|
+
const ui = ctx && typeof ctx === "object" ? ctx.ui : null;
|
|
386
|
+
const setStatusFn = ui && typeof ui === "object" ? ui.setStatus : null;
|
|
387
|
+
if (typeof setStatusFn === "function") {
|
|
388
|
+
setStatusFn.call(ui, id, text);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function setFooter(ctx, line) {
|
|
392
|
+
const ui = ctx && typeof ctx === "object" ? ctx.ui : null;
|
|
393
|
+
const setFooterFn = ui && typeof ui === "object" ? ui.setFooter : null;
|
|
394
|
+
if (typeof setFooterFn !== "function")
|
|
395
|
+
return;
|
|
396
|
+
setFooterFn.call(ui, () => ({
|
|
397
|
+
render(width) {
|
|
398
|
+
const max = Math.max(0, Math.trunc(width));
|
|
399
|
+
if (max === 0)
|
|
400
|
+
return [""];
|
|
401
|
+
return [line.length > max ? `${line.slice(0, Math.max(0, max - 1))}\u2026` : line];
|
|
402
|
+
},
|
|
403
|
+
invalidate() {}
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
321
406
|
function steeringText(message) {
|
|
322
407
|
const text = typeof message.message === "string" ? message.message.trim() : "";
|
|
323
408
|
if (!text)
|
|
@@ -327,7 +412,7 @@ function steeringText(message) {
|
|
|
327
412
|
${text}`;
|
|
328
413
|
}
|
|
329
414
|
async function consumeQueuedSteering(pi, state, ctx) {
|
|
330
|
-
if (!state.active || !state.runId || typeof pi.sendUserMessage !== "function")
|
|
415
|
+
if (state.operatorSession || !state.active || !state.runId || typeof pi.sendUserMessage !== "function")
|
|
331
416
|
return;
|
|
332
417
|
try {
|
|
333
418
|
const messages = await state.client.consumeSteering(state.runId);
|
|
@@ -344,8 +429,86 @@ async function consumeQueuedSteering(pi, state, ctx) {
|
|
|
344
429
|
notify(ctx, `Rig steering sync failed: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
345
430
|
}
|
|
346
431
|
}
|
|
432
|
+
function inputText(event) {
|
|
433
|
+
if (!event || typeof event !== "object" || Array.isArray(event))
|
|
434
|
+
return null;
|
|
435
|
+
const text = event.text;
|
|
436
|
+
return typeof text === "string" && text.trim() ? text.trim() : null;
|
|
437
|
+
}
|
|
438
|
+
async function handleOperatorInput(event, state, ctx) {
|
|
439
|
+
if (!state.operatorSession || !state.active || !state.runId)
|
|
440
|
+
return;
|
|
441
|
+
const text = inputText(event);
|
|
442
|
+
if (!text || text.startsWith("/"))
|
|
443
|
+
return;
|
|
444
|
+
try {
|
|
445
|
+
await state.client.steer(text, state.runId);
|
|
446
|
+
notify(ctx, "Rig steering message queued.");
|
|
447
|
+
} catch (error) {
|
|
448
|
+
notify(ctx, `Rig steering failed: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
449
|
+
}
|
|
450
|
+
return { action: "handled" };
|
|
451
|
+
}
|
|
452
|
+
function shortEntry(entry) {
|
|
453
|
+
const type = String(entry.type ?? entry.title ?? "event");
|
|
454
|
+
const text = typeof entry.text === "string" ? entry.text : typeof entry.detail === "string" ? entry.detail : typeof entry.message === "string" ? entry.message : "";
|
|
455
|
+
return `${type}: ${text}`.slice(0, 160);
|
|
456
|
+
}
|
|
457
|
+
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
458
|
+
function runLocation(run) {
|
|
459
|
+
const worktree = typeof run.worktreePath === "string" && run.worktreePath.trim() ? run.worktreePath.trim() : null;
|
|
460
|
+
const projectRoot = typeof run.projectRoot === "string" && run.projectRoot.trim() ? run.projectRoot.trim() : null;
|
|
461
|
+
return worktree ?? projectRoot ?? "remote/local worker workspace";
|
|
462
|
+
}
|
|
463
|
+
function runPayload(payload) {
|
|
464
|
+
return payload.run && typeof payload.run === "object" && !Array.isArray(payload.run) ? payload.run : payload;
|
|
465
|
+
}
|
|
466
|
+
function startOperatorRunWidget(state, ctx) {
|
|
467
|
+
if (!state.operatorSession || !state.active || !state.runId)
|
|
468
|
+
return;
|
|
469
|
+
let inFlight = false;
|
|
470
|
+
let frame = 0;
|
|
471
|
+
const refresh = async () => {
|
|
472
|
+
if (inFlight)
|
|
473
|
+
return;
|
|
474
|
+
inFlight = true;
|
|
475
|
+
const spinner = SPINNER_FRAMES[frame++ % SPINNER_FRAMES.length] ?? "\u2022";
|
|
476
|
+
try {
|
|
477
|
+
const [runPayloadRecord, timeline] = await Promise.all([
|
|
478
|
+
state.client.attach(state.runId),
|
|
479
|
+
state.client.runTimeline(state.runId, 8).catch(() => [])
|
|
480
|
+
]);
|
|
481
|
+
const run = runPayload(runPayloadRecord);
|
|
482
|
+
const status = String(run.status ?? "unknown");
|
|
483
|
+
const header = `${spinner} Rig ${String(run.runId ?? state.runId)} \xB7 ${status}`;
|
|
484
|
+
const location = runLocation(run);
|
|
485
|
+
const detail = typeof run.statusDetail === "string" && run.statusDetail.trim() ? run.statusDetail.trim() : String(run.title ?? run.taskId ?? "");
|
|
486
|
+
const lines = [
|
|
487
|
+
header,
|
|
488
|
+
`worker: ${location}`.slice(0, 200),
|
|
489
|
+
...detail ? [detail.slice(0, 160)] : [],
|
|
490
|
+
...timeline.slice(-5).map(shortEntry)
|
|
491
|
+
];
|
|
492
|
+
setStatus(ctx, "rig", `${spinner} Rig ${status}`);
|
|
493
|
+
setFooter(ctx, `${spinner} Rig ${String(run.runId ?? state.runId)} \xB7 ${status} \xB7 worker ${location}`);
|
|
494
|
+
setWidget(ctx, "rig-run", lines);
|
|
495
|
+
} catch (error) {
|
|
496
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
497
|
+
setStatus(ctx, "rig", `${spinner} Rig unavailable`);
|
|
498
|
+
setFooter(ctx, `${spinner} Rig ${state.runId} \xB7 unavailable \xB7 ${message}`);
|
|
499
|
+
setWidget(ctx, "rig-run", [`${spinner} Rig ${state.runId} \xB7 unavailable`, message]);
|
|
500
|
+
} finally {
|
|
501
|
+
inFlight = false;
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
refresh();
|
|
505
|
+
const timer = setInterval(() => void refresh(), 1000);
|
|
506
|
+
if (typeof timer.unref === "function") {
|
|
507
|
+
timer.unref();
|
|
508
|
+
}
|
|
509
|
+
}
|
|
347
510
|
function startLiveSteeringPoll(pi, state, ctx) {
|
|
348
|
-
if (!state.active || !state.runId || typeof pi.sendUserMessage !== "function")
|
|
511
|
+
if (state.operatorSession || !state.active || !state.runId || typeof pi.sendUserMessage !== "function")
|
|
349
512
|
return;
|
|
350
513
|
const intervalMs = state.steeringPollMs ?? 1000;
|
|
351
514
|
if (intervalMs <= 0)
|
|
@@ -389,14 +552,12 @@ function createPiRigExtension(pi, options = {}) {
|
|
|
389
552
|
}
|
|
390
553
|
startLiveSteeringPoll(pi, state, globalThis);
|
|
391
554
|
}
|
|
555
|
+
pi.on?.("input", async (event, ctx) => handleOperatorInput(event, state, ctx));
|
|
392
556
|
pi.on?.("session_start", async (_event, ctx) => {
|
|
393
557
|
if (!state.active || !state.runId)
|
|
394
558
|
return;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (typeof setStatus === "function") {
|
|
398
|
-
setStatus.call(ui, "rig", `Rig ${state.runId}`);
|
|
399
|
-
}
|
|
559
|
+
setStatus(ctx, "rig", `Rig ${state.runId}`);
|
|
560
|
+
startOperatorRunWidget(state, ctx);
|
|
400
561
|
await consumeQueuedSteering(pi, state, ctx);
|
|
401
562
|
});
|
|
402
563
|
pi.on?.("turn_end", async (_event, ctx) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h-rig/pi-rig",
|
|
3
|
-
"version": "0.0.6-alpha.
|
|
3
|
+
"version": "0.0.6-alpha.60",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Rig package",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
]
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@earendil-works/pi-coding-agent": "
|
|
36
|
+
"@earendil-works/pi-coding-agent": "npm:@h-rig/pi-coding-agent@0.0.6-alpha.60",
|
|
37
37
|
"typebox": "*"
|
|
38
38
|
}
|
|
39
39
|
}
|