@volter/supercode-orchestrator 0.4.30 → 0.4.32
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/board/dispatch.mjs +19 -2
- package/package.json +1 -1
package/board/dispatch.mjs
CHANGED
|
@@ -411,6 +411,17 @@ export async function startCard(board, id, { roles = ['manager'], lanes, setting
|
|
|
411
411
|
* The heartbeat, observed: a running pane session whose last message is a whole tick old is sent `session_idle` with
|
|
412
412
|
* how many times it has been asked this run and whether it worked since the last ask; the workflow decides the rest.
|
|
413
413
|
*/
|
|
414
|
+
/** Panes whose close was asked by their own session's command (see sessionEffect), closed now. */
|
|
415
|
+
function closeRequested(board, report) {
|
|
416
|
+
const rows = board.db.prepare(`SELECT id, task_id, metadata FROM task_runs WHERE metadata LIKE '%"close_requested"%' AND metadata NOT LIKE '%"closed_at"%'`).all();
|
|
417
|
+
for (const row of rows) {
|
|
418
|
+
const session = json(row.metadata, {})?.supercode;
|
|
419
|
+
if (!session?.pane) continue;
|
|
420
|
+
try { stopSession(session); } catch (error) { report.undelivered.push([row.task_id, session.address, `closing it: ${String(error.message).slice(-200)}`]); continue; }
|
|
421
|
+
tx(board, (db) => setRunSession(db, row.id, { ...session, closed_at: now() }));
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
414
425
|
function observeIdle(board, fleet, settings, report, entry, effects) {
|
|
415
426
|
if (!fleet.ok) return;
|
|
416
427
|
for (const { id } of board.db.prepare("SELECT id FROM tasks WHERE status = 'running'").all()) {
|
|
@@ -429,7 +440,10 @@ function observeIdle(board, fleet, settings, report, entry, effects) {
|
|
|
429
440
|
if (session.goal_nudged_at && now() - session.goal_nudged_at < settings.interval * 2) return;
|
|
430
441
|
const worked = Boolean(session.goal_nudged_at) && lastAt >= session.goal_nudged_at + settings.interval;
|
|
431
442
|
try {
|
|
432
|
-
const
|
|
443
|
+
const where = whereOf(board, task);
|
|
444
|
+
// the ask names what the session may do, as its run's prompt did
|
|
445
|
+
const said = doors(entry.workflow, status, session.role ?? entry.workflow.statuses[status]?.run?.role ?? 'implementer', id, where, session.surface === 'pane' ? 'pane' : 'headless');
|
|
446
|
+
const r = fire(db, board, entry, id, 'session_idle', { roles: ['platform'], payload: { turns: Number(session.goal_turns ?? 0), worked }, extra: { where, doors: said } });
|
|
433
447
|
effects.push(...r.effects);
|
|
434
448
|
const after = currentRun(db, id);
|
|
435
449
|
if (after?.id === runRow.id) setRunSession(db, runRow.id, { ...(after.metadata?.supercode ?? session), goal_nudged_at: now() });
|
|
@@ -454,6 +468,9 @@ export async function sessionEffect(board, e) {
|
|
|
454
468
|
for (const row of rows) {
|
|
455
469
|
const session = json(row.metadata, {})?.supercode;
|
|
456
470
|
if ((session?.slot ?? 'worker') !== e.slot || !session?.pane || session.closed_at) continue;
|
|
471
|
+
// the session that sent the event is not closed under its own command: the dispatcher closes it next tick
|
|
472
|
+
const caller = process.env.CLAUDE_CODE_SESSION_ID || process.env.CODEX_THREAD_ID;
|
|
473
|
+
if (caller && caller === session.session_id) { tx(board, (db) => setRunSession(db, row.id, { ...session, close_requested: now() })); return; }
|
|
457
474
|
stopSession(session);
|
|
458
475
|
tx(board, (db) => setRunSession(db, row.id, { ...session, closed_at: now() }));
|
|
459
476
|
return;
|
|
@@ -1077,7 +1094,7 @@ export async function tick({ root, lanes, settings, only = null, slugs = null, d
|
|
|
1077
1094
|
const phase = (name) => { const t = Date.now(); report.ms[name] = t - mark; mark = t; };
|
|
1078
1095
|
readMailbox(board, boardAddress(board.label), report); phase('mailbox');
|
|
1079
1096
|
const effects = [];
|
|
1080
|
-
supervise(board, fleet, settings, report, entry, effects); phase('supervise');
|
|
1097
|
+
supervise(board, fleet, settings, report, entry, effects); closeRequested(board, report); phase('supervise');
|
|
1081
1098
|
report.promoted = recomputeReady(board);
|
|
1082
1099
|
const before = report.started.length;
|
|
1083
1100
|
if (dispatch) startCards(board, fleet, lanes, settings, report, entry, effects, { only, hostRunning });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-orchestrator",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.32",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The orchestrator runtime over the Volter Harness ontology: one typed operational model whose folder is its serialization, read and written through the harness orchestration doors (docs/ORCHESTRATOR-IR.md)",
|
|
6
6
|
"exports": {
|