@volter/supercode-orchestrator 0.5.79 → 0.5.81
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/machine-fleet.mjs +29 -34
- package/package.json +2 -2
package/board/machine-fleet.mjs
CHANGED
|
@@ -1,46 +1,41 @@
|
|
|
1
|
-
// The fleet as each machine the board works on
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// is for viewers; dispatch never waits on it (D137, D138).
|
|
1
|
+
// The fleet as each machine the board works on keeps it: its panes, the harness session beneath each live pane's
|
|
2
|
+
// process, and what a board launch needs of it (`capabilities`: its board process guard's harnesses, and whether it has
|
|
3
|
+
// the keyed launch door). Each machine pushes this as its record (order 3 PR 3, @volter/teams machine-records): this
|
|
4
|
+
// machine's daemon holds every record it follows, with how current each is, and the owner reads them all in one local
|
|
5
|
+
// call. No machine is asked at call time. Teams' session feed is for viewers; dispatch never waits on it (D137, D138).
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// not linked (`machine_offline`): then it is offline. This machine's door not answering is no reading at all.
|
|
7
|
+
// A machine whose record is current is `online`. One whose record is out of date (its stream closed, its panes or the
|
|
8
|
+
// sessions under them not read) or was never read is `unknown` (its runs are kept, as an unread machine's always were), unless its record says it was unlinked from the
|
|
9
|
+
// team: then it is offline. This machine's own record not being given is no reading at all.
|
|
11
10
|
import { noteStep } from '@volter/supercode-harness-sdk/slow-log';
|
|
12
11
|
import { machineCall } from './doors.mjs';
|
|
13
|
-
|
|
14
12
|
const DEADLINE_MS = 10_000;
|
|
15
13
|
const within = (promise, ms) => Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject(Object.assign(new Error(`no answer within ${ms} ms`), { code: 'timeout' })), ms).unref?.())]);
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
try { activities = (await machineCall(at, 'harness.v1.sessions.activity_under', { pids: live.map((pane) => pane.pid) }))?.activities ?? []; }
|
|
32
|
-
catch (error) { sessionsUnread = String(error?.message ?? error).slice(0, 200); }
|
|
33
|
-
}
|
|
34
|
-
return { machine: name, panes, activities, capabilities, sessionsUnread };
|
|
14
|
+
// One machine's reading, from its held record: its panes, what a board launch needs of it, and the session under each
|
|
15
|
+
// live pane.
|
|
16
|
+
function readOne(name, held) {
|
|
17
|
+
if (!held) return { machine: name, error: 'this machine follows no record of it (not linked to the team, or not yet read)', code: 'unavailable' };
|
|
18
|
+
if (held.stream === 'unlinked') return { machine: name, error: held.why ?? 'unlinked from the team', code: 'machine_offline' };
|
|
19
|
+
if (!held.record) return { machine: name, error: `its record was never read: ${held.why ?? 'no reason given'}`, code: 'unavailable' };
|
|
20
|
+
if (held.stream !== 'open' && held.stream !== 'self') return { machine: name, error: `its record may be out of date: its stream is ${held.stream} since ${held.since ? new Date(held.since).toISOString() : 'unknown'} (${held.why ?? 'no reason given'})`, code: 'stale' };
|
|
21
|
+
const record = held.record;
|
|
22
|
+
// panes not read, or read without the sessions under them (or while the session index is lost), are no reading of
|
|
23
|
+
// what runs there: the machine is unknown, never one whose panes or sessions are absent (refused is not absent)
|
|
24
|
+
const notCurrent = record.unread?.panes ?? record.unread?.sessions_index ?? record.unread?.sessions_index_parts ?? record.unread?.claude_registry_watch ?? record.unread?.pane_exits_watch ?? record.panes?.activities_omitted ?? record.panes?.sessions_unread ?? (record.panes ? null : 'its record holds no pane list');
|
|
25
|
+
if (notCurrent) return { machine: name, error: `its panes are not current: ${notCurrent}`, code: 'stale' };
|
|
26
|
+
const panes = record.panes?.panes ?? [];
|
|
27
|
+
const capabilities = record.capabilities ?? { guard: [], launches: false };
|
|
28
|
+
return { machine: name, panes, activities: record.panes?.activities ?? [], capabilities: { guard: capabilities.guard ?? [], launches: Boolean(capabilities.launches), launchesRefused: capabilities.launches ? null : 'its record names no keyed launch door' } };
|
|
35
29
|
}
|
|
36
|
-
|
|
37
|
-
/** One reading of `machines` (normalized names) and this machine, `local`: every machine at once, each bounded. */
|
|
30
|
+
/** One reading of `machines` (normalized names) and this machine, `local`: every record, from this machine's daemon. */
|
|
38
31
|
export async function readMachineFleet(machines, local) {
|
|
39
32
|
const names = [...new Set([local, ...machines])];
|
|
40
33
|
const started = performance.now();
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
let held = null, heldError = null;
|
|
35
|
+
try { held = (await within(machineCall(null, 'harness.v1.machine.records', {}), DEADLINE_MS))?.records ?? {}; }
|
|
36
|
+
catch (error) { heldError = String(error?.message ?? error).slice(0, 300); }
|
|
37
|
+
const rows = names.map((name) => heldError ? { machine: name, error: `this machine's daemon did not give the records it holds: ${heldError}`, code: 'unavailable' } : readOne(name, held[name]));
|
|
38
|
+
noteStep(`fleet reading (${names.length} machine${names.length === 1 ? '' : 's'}, held records)`, performance.now() - started);
|
|
44
39
|
// `panes`: each answering machine's live pane ids, whether or not a session was read in them
|
|
45
40
|
const online = new Set(), unknown = new Set(), alive = new Set(), native = new Map(), sessions = [], capabilities = new Map(), panes = new Map();
|
|
46
41
|
let localError = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-orchestrator",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.81",
|
|
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": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@volter/supercode-harness-sdk": "^0.3.60",
|
|
28
|
-
"@volter/teams": "0.2.
|
|
28
|
+
"@volter/teams": "0.2.30",
|
|
29
29
|
"@volter/ztrack": "^2.4.23",
|
|
30
30
|
"yaml": "^2.9.0"
|
|
31
31
|
},
|