@volter/supercode-orchestrator 0.4.158 → 0.4.160
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/capacity.mjs +5 -2
- package/board/dispatch.mjs +15 -9
- package/package.json +1 -1
package/board/capacity.mjs
CHANGED
|
@@ -46,13 +46,16 @@ function sessionsOf(db, taskId) {
|
|
|
46
46
|
* own transcript reports it runs, or null where none can be read; `machineOf` normalises a machine name; `lanes` gives
|
|
47
47
|
* a profile's harness and model.
|
|
48
48
|
*/
|
|
49
|
-
export function holdings(board, { lanes, fleetOk, alive, liveRecord, modelOf = () => null, machineOf }) {
|
|
49
|
+
export function holdings(board, { lanes, fleetOk, alive, liveRecord, modelOf = () => null, storedOf = null, machineOf }) {
|
|
50
50
|
const out = [];
|
|
51
51
|
const rows = board.db.prepare("SELECT t.id, t.status, t.assignee, t.current_run_id, t.model_override, c.machine, c.subtask_of FROM tasks t LEFT JOIN supercode_cards c ON c.task_id = t.id WHERE t.status != 'archived'").all();
|
|
52
52
|
for (const row of rows) {
|
|
53
53
|
const lane = lanes[row.assignee] ?? {};
|
|
54
54
|
const card = {
|
|
55
|
-
card: row.id, board: board.slug, assignee: row.assignee ?? null, status: statusOf(board.db, row),
|
|
55
|
+
card: row.id, board: board.slug, assignee: row.assignee ?? null, status: statusOf(board.db, row),
|
|
56
|
+
// what the board stores for an arc is read through its workflow's stored_as rules now, never the column a write has
|
|
57
|
+
// not yet brought up to date (a paused card counted as running until its row caught up)
|
|
58
|
+
stored: !row.subtask_of && storedOf ? storedOf(row.id) : row.status,
|
|
56
59
|
machine: row.machine ? machineOf(row.machine) : null,
|
|
57
60
|
model: row.model_override ?? lane.model ?? null, harness: lane.harness ?? null,
|
|
58
61
|
};
|
package/board/dispatch.mjs
CHANGED
|
@@ -24,7 +24,7 @@ import { basename, dirname, join } from 'node:path';
|
|
|
24
24
|
import { createHash, randomUUID } from 'node:crypto';
|
|
25
25
|
import { fileURLToPath } from 'node:url';
|
|
26
26
|
import { view, boardCopyOf, boardPath, claimer, copyRefusal, event, json, listBoards, logsDir, now, openBoard, setActor, tx } from './store.mjs';
|
|
27
|
-
import { doors, fire, loadWorkflow, resumeOf, runSpec, runWorkingSeconds, requestSessionClose, retireSupersededRuns, refreshCardInputs, refreshRelationAnswers, transitionsFor, scopeOf, statusOf, templateValue, workflowFor } from './workflow.mjs';
|
|
27
|
+
import { doors, fire, loadWorkflow, resumeOf, runSpec, runWorkingSeconds, requestSessionClose, retireSupersededRuns, refreshCardInputs, refreshRelationAnswers, transitionsFor, scopeOf, statusOf, storedStatus, templateValue, workflowFor } from './workflow.mjs';
|
|
28
28
|
import { checkWorkspace, assertWorkspaceOwner, notePresence, resolveWorkspace } from './workspace.mjs';
|
|
29
29
|
import { capacity, harnessDefaults, holdings } from './capacity.mjs';
|
|
30
30
|
import { evaluate, holds, render } from './expr.mjs';
|
|
@@ -147,7 +147,10 @@ const sessionAlive = (fleet, session) => fleet.native?.has(addressOf(session)) ?
|
|
|
147
147
|
/** Native activity comes from the machine's harness discovery, not catalogue age. */
|
|
148
148
|
function nativeSessions(machine, harness) {
|
|
149
149
|
if (offlineMachine(machine)) throw unavailable(`native liveness unavailable: machine ${normalMachine(machine)} is offline`);
|
|
150
|
-
const
|
|
150
|
+
const args = normalMachine(machine) === localMachine()
|
|
151
|
+
? ['teams', 'rpc', 'sessions.discover', JSON.stringify({ harnesses: [harness], limit: 2000 })]
|
|
152
|
+
: ['discover', '--on', machine, '--harness', harness, '--limit', '2000'];
|
|
153
|
+
const result = sc(args, { timeout: 120_000 });
|
|
151
154
|
const page = result.code === 0 ? lastJson(result.stdout) : null;
|
|
152
155
|
if (!Array.isArray(page?.sessions)) throw unavailable(`native liveness unavailable on ${machine}: ${(result.stderr || result.stdout).trim().slice(-300)}`);
|
|
153
156
|
return page.sessions;
|
|
@@ -464,13 +467,17 @@ export function whereOf(board, task) {
|
|
|
464
467
|
const hostOf = (pressure) => ({ memory_pressure: pressure, max_in_progress: derivedMaxInProgress() });
|
|
465
468
|
|
|
466
469
|
/** What every board of the home at `root` holds now, counted for its caps (capacity.mjs). */
|
|
467
|
-
function homeHoldings(root, slugs, lanes, fleet) {
|
|
470
|
+
function homeHoldings(root, slugs, lanes, fleet, entry) {
|
|
468
471
|
const live = (s) => fleet.sessions?.find((x) => x.address === addressOf(s)) ?? null;
|
|
469
472
|
const out = [];
|
|
470
473
|
for (const slug of slugs) {
|
|
471
474
|
try {
|
|
472
475
|
const b = openBoard(root, slug);
|
|
473
|
-
try {
|
|
476
|
+
try {
|
|
477
|
+
b.slug ??= slug; b.label ??= boardLabel(root, slug);
|
|
478
|
+
const storedOf = (id) => storedStatus(b.db, b, entry, id).stored;
|
|
479
|
+
out.push(...holdings(b, { lanes, fleetOk: fleet.ok, alive: (s) => sessionAlive(fleet, s), liveRecord: live, modelOf: transcriptModel, storedOf, machineOf: normalMachine }));
|
|
480
|
+
}
|
|
474
481
|
finally { b.close(); }
|
|
475
482
|
} catch { /* its own tick reports it */ }
|
|
476
483
|
}
|
|
@@ -1423,8 +1430,7 @@ function adoptSession(board, id, who, { workspace = null, ttl, assignee = null,
|
|
|
1423
1430
|
// the session's own working directory, as discovery records it (where `--resume` finds it), else its pane's
|
|
1424
1431
|
let dir = workspace ?? native?.row?.cwd;
|
|
1425
1432
|
if (!dir) {
|
|
1426
|
-
|
|
1427
|
-
dir = (json(r.stdout.trim(), {})?.sessions ?? []).find((x) => x.locator?.session_id === sessionId)?.cwd ?? null;
|
|
1433
|
+
dir = nativeSessions(host, harness).find((x) => x.locator?.session_id === sessionId)?.cwd ?? null;
|
|
1428
1434
|
}
|
|
1429
1435
|
if (!dir && found.pane) {
|
|
1430
1436
|
const r = sc(['teams', 'panes', 'ls', '--machine', host], { timeout: 60_000 });
|
|
@@ -1453,7 +1459,7 @@ function adoptSession(board, id, who, { workspace = null, ttl, assignee = null,
|
|
|
1453
1459
|
if (implementer?.session_id === sessionId) throw new Error('a reviewer must be independent of the implementer session');
|
|
1454
1460
|
}
|
|
1455
1461
|
event(db, id, 'dispatch_released', { reason: 'verified adoption', session: found.address });
|
|
1456
|
-
if (!beforeRun) fire(db, board, entry, id, entry.workflow.run ? entry.workflow.dispatch.start : 'adopt', { roles: ['manager'], payload: { lock: claimer() } });
|
|
1462
|
+
if (!beforeRun) fire(db, board, entry, id, entry.workflow.run ? entry.workflow.dispatch.start : 'adopt', { roles: [entry.workflow.run ? 'platform' : 'manager'], payload: { lock: claimer() } });
|
|
1457
1463
|
const runId = getTask(db, id).current_run_id;
|
|
1458
1464
|
if (!runId) throw new Error(`${id} waits on parents that are not done`);
|
|
1459
1465
|
const session = { surface: found.pane ? 'pane' : 'native', session_id: sessionId, harness, machine: host, pane: found.pane ?? null, address: found.address, mode: 'adopt', launched_at: now(), seen_at: now() };
|
|
@@ -1872,7 +1878,7 @@ export async function plan({ root, lanes, settings, slugs = null, params = {} })
|
|
|
1872
1878
|
const fleet = Object.values(lanes).some((l) => l.surface === 'pane') ? observeFleet() : { ok: false, alive: new Set(), online: new Set(), sessions: [], error: 'no pane lanes' };
|
|
1873
1879
|
const out = [];
|
|
1874
1880
|
// the home's caps count every board, whichever boards are planned
|
|
1875
|
-
const held = homeHoldings(root, listBoards(root), lanes, fleet);
|
|
1881
|
+
const held = homeHoldings(root, listBoards(root), lanes, fleet, entry);
|
|
1876
1882
|
const caps = capacity(entry.workflow.dispatch?.capacity, held, evaluate);
|
|
1877
1883
|
// what each cap counts now, before anything this plan would start
|
|
1878
1884
|
Object.defineProperty(out, 'capacity', { value: caps.view().map((cap) => ({ ...cap, groups: cap.groups.map((g) => ({ ...g, max: capMax(cap, g, entry, lanes) })) })) });
|
|
@@ -1982,7 +1988,7 @@ export async function tick({ root, lanes, settings, only = null, slugs = null, d
|
|
|
1982
1988
|
const fleetMs = Date.now() - fleetAt;
|
|
1983
1989
|
const boards = slugs ?? listBoards(root);
|
|
1984
1990
|
// what every board of the home holds, for caps whose scope is the whole home (kanban.max_in_progress counts so)
|
|
1985
|
-
const held = dispatch ? homeHoldings(root, boards, lanes, fleet) : [];
|
|
1991
|
+
const held = dispatch ? homeHoldings(root, boards, lanes, fleet, entry) : [];
|
|
1986
1992
|
const out = [];
|
|
1987
1993
|
for (const slug of boards) {
|
|
1988
1994
|
const report = { board: slug, ms: { fleet: fleetMs }, mailed: [], started: [], queued: [], failed: [], lost: [], crashed: [], timed_out: [], reclaimed: [], auto_blocked: [], promoted: 0, unassigned: [], nonspawnable: [], notified: [], undelivered: [], fleet: fleet.ok ? 'read' : fleet.error };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-orchestrator",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.160",
|
|
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": {
|