@volter/supercode-orchestrator 0.5.114 → 0.5.115
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 +22 -9
- package/package.json +2 -2
package/board/dispatch.mjs
CHANGED
|
@@ -1786,14 +1786,13 @@ async function launchPane(board, task, runId, lane, fleet, { input = null, slot
|
|
|
1786
1786
|
let session = null;
|
|
1787
1787
|
let replaced = null;
|
|
1788
1788
|
// A session in no pane is read on its machine before anything replaces it. One the board released (an adopted
|
|
1789
|
-
// session it did not launch, left running at its run's end) is
|
|
1790
|
-
//
|
|
1789
|
+
// session it did not launch, left running at its run's end) is never resumed beside itself: while it runs it is kept,
|
|
1790
|
+
// and the card's next run is delivered into it, as into any kept session.
|
|
1791
1791
|
if (prev?.surface === 'native' && !prev.pane && (!prev.close_confirmed_at || prev.released)) {
|
|
1792
1792
|
const reading = nativeReading(await readNative(prev.machine, prev.harness, prev.session_id), prev);
|
|
1793
1793
|
if (reading.alive == null) throw unavailable(`cannot establish native continuation liveness for ${addressOf(prev)}`);
|
|
1794
1794
|
fleet.native ??= new Map(); fleet.native.set(addressOf(prev), reading);
|
|
1795
|
-
if (reading.alive && prev.released) throw unavailable(`
|
|
1796
|
-
if (reading.alive && (prev.closed_at || prev.close_requested || prev.forgotten)) throw unavailable(`native session ${addressOf(prev)} is still live; its close must finish before replacement`);
|
|
1795
|
+
if (reading.alive && !prev.released && (prev.closed_at || prev.close_requested || prev.forgotten)) throw unavailable(`native session ${addressOf(prev)} is still live; its close must finish before replacement`);
|
|
1797
1796
|
}
|
|
1798
1797
|
if (prev?.forgotten) {
|
|
1799
1798
|
if (!prev.close_confirmed_at && prev.pane && await panePresent(prev.machine, prev.pane)) throw new Error(`forgotten session ${prev.session_id} still has live pane ${prev.pane}; close it before replacement`);
|
|
@@ -1807,11 +1806,11 @@ async function launchPane(board, task, runId, lane, fleet, { input = null, slot
|
|
|
1807
1806
|
} else if (prev && prev.machine === machine) {
|
|
1808
1807
|
// a session the board closed, or one whose close its own command asked for (the next tick's sweep closes that
|
|
1809
1808
|
// run's pane), is not kept, whatever a fleet reading taken before the close still lists
|
|
1810
|
-
const
|
|
1811
|
-
if (
|
|
1812
|
-
if (
|
|
1809
|
+
const next = continuationOf(prev, prev.pane ? await panePresent(prev.machine, prev.pane) : sessionAlive(fleet, prev));
|
|
1810
|
+
if (next === 'refuse') throw new Error(`session ${prev.session_id} still has live pane ${prev.pane}; cannot resume or replace it`);
|
|
1811
|
+
if (next === 'keep') {
|
|
1813
1812
|
// the session is kept; the heartbeat's count belongs to the run that ended, so the new run starts it again
|
|
1814
|
-
const { missing_since: _m, goal_turns: _t, goal_nudged_at: _n, idle_since: _is, unknown_since: _us, unknown_notice: _un, work_progress: _wp, idle_observation: _io, idle_below_threshold: _ib, idle_eligible: _ie, close_requested: _q, closed_at: _c, close_confirmed_at: _cc, close_error: _ce, close_attempts: _ca, close_attempted_at: _ct, monitor_held: _mh, ...kept } = prev;
|
|
1813
|
+
const { missing_since: _m, goal_turns: _t, goal_nudged_at: _n, idle_since: _is, unknown_since: _us, unknown_notice: _un, work_progress: _wp, idle_observation: _io, idle_below_threshold: _ib, idle_eligible: _ie, close_requested: _q, closed_at: _c, close_confirmed_at: _cc, close_error: _ce, close_attempts: _ca, close_attempted_at: _ct, monitor_held: _mh, released: _rl, ...kept } = prev;
|
|
1815
1814
|
session = { ...kept, mode: 'adopt', launched_at: now(), seen_at: now() };
|
|
1816
1815
|
// a kept session is told what this run is for (its card came back to it, with what happened since), only while
|
|
1817
1816
|
// this run is still the card's current one (its pane and native reads were awaited)
|
|
@@ -1885,6 +1884,18 @@ async function launchPane(board, task, runId, lane, fleet, { input = null, slot
|
|
|
1885
1884
|
return session;
|
|
1886
1885
|
}
|
|
1887
1886
|
|
|
1887
|
+
/**
|
|
1888
|
+
* What a slot's last session on the card's machine is to the card's next run, given whether it is live (its pane, else
|
|
1889
|
+
* its native process): an open session that is live is kept, and the run is delivered into it; a live pane holding a
|
|
1890
|
+
* session the board closed refuses the launch; anything else is resumed. A released session is open: its release only
|
|
1891
|
+
* freed the slot, and the session was left running.
|
|
1892
|
+
*/
|
|
1893
|
+
export function continuationOf(prev, live) {
|
|
1894
|
+
const open = Boolean(prev.released) || (!prev.closed_at && !prev.close_requested);
|
|
1895
|
+
if (open) return live ? 'keep' : 'resume';
|
|
1896
|
+
return live && prev.pane ? 'refuse' : 'resume';
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1888
1899
|
/** A machine reading, not a missing catalog entry, establishes whether a pane is alive. */
|
|
1889
1900
|
async function panePresent(machine, pane) {
|
|
1890
1901
|
const r = await doorOn(machine, 'harness.v1.panes.list',{}, { timeout: 60_000 });
|
|
@@ -2136,7 +2147,9 @@ async function adoptSession(board, id, who, { request = null, open = request, pr
|
|
|
2136
2147
|
if (beforeRun && assignee && assignee !== task.assignee) throw new Error('rebinding a session does not reassign its active run');
|
|
2137
2148
|
if (task.machine && normalMachine(task.machine) !== host) throw new Error(`${id} runs on ${task.machine}, and ${found.address} is on ${host}; move the card first`);
|
|
2138
2149
|
const was = lastSession(db, id);
|
|
2139
|
-
|
|
2150
|
+
// a session whose close the board confirmed is not live, whatever a fleet reading still lists (a released one was
|
|
2151
|
+
// left running, and is read)
|
|
2152
|
+
if (was && was.session_id !== sessionId && !(was.close_confirmed_at && !was.released) && sessionAlive(fleet, was)) throw new Error(`${id} already has a live session, ${was.address}`);
|
|
2140
2153
|
if (!task.machine) db.prepare('INSERT INTO supercode_cards (task_id, machine) VALUES (?, ?) ON CONFLICT(task_id) DO UPDATE SET machine = excluded.machine').run(id, host);
|
|
2141
2154
|
// the lane that resumes it if it is lost, set in the same transaction (assigning first would let a tick start another)
|
|
2142
2155
|
if (assignee && assignee !== task.assignee) { db.prepare('UPDATE tasks SET assignee = ? WHERE id = ?').run(assignee, id); event(db, id, 'assigned', { assignee }); }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-orchestrator",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.115",
|
|
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.47",
|
|
29
29
|
"@volter/ztrack": "^2.4.23",
|
|
30
30
|
"yaml": "^2.9.0"
|
|
31
31
|
},
|