@volter/supercode-orchestrator 0.5.148 → 0.5.150

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.
Files changed (2) hide show
  1. package/board/dispatch.mjs +31 -3
  2. package/package.json +2 -2
@@ -187,9 +187,36 @@ const paneInRecord = (fleet, session) => session?.surface !== 'headless' && sess
187
187
  const sessionAlive = (fleet, session) => fleet.native?.has(addressOf(session)) ? fleet.native.get(addressOf(session)).alive : paneInRecord(fleet, session) ?? unpublishedAlive(session);
188
188
  /** A subscriber's address as the session it names, for sessionAlive (its machine, harness and native id). */
189
189
  const sessionAt = (address) => { const m = /^sc:([^:]+):([^:]+):(.+)$/.exec(String(address)); return m && HARNESSES[m[2]] ? { address, machine: normalMachine(m[1]), harness: m[2], session_id: m[3] } : null; };
190
- /** A subscriber's liveness, read first (readBefore): true, false, or null when it could not be read (unknown, never dead). */
190
+ /** An agent's address (`sc:<machine>:agent:<name>`) as its machine and name, or null. */
191
+ const agentAt = (address) => { const m = /^sc:([^:\s]+):agent:([^:\s]+)$/.exec(String(address)); return m ? { machine: normalMachine(m[1]), name: m[2] } : null; };
192
+ const agentMains = new Map();
193
+ /**
194
+ * An agent's main session, where mail to its address goes (ADR 0008), asked of its machine's daemon, which keeps the
195
+ * agent's record (one reading serves READING_MS): its address, false when that machine declares no such agent, or null
196
+ * when the daemon did not answer.
197
+ */
198
+ async function agentMain(address) {
199
+ const held = agentMains.get(address);
200
+ if (held && Date.now() - held.at <= READING_MS) return held.main;
201
+ const { machine, name } = agentAt(address);
202
+ const local = machine === localMachine();
203
+ const r = await doorOn(machine, 'harness.v1.agent.show', { name, ...(local ? { claim: { pid: process.pid, ppid: process.ppid, session: null, named: null, owner: null } } : {}) }, { timeout: 5_000 });
204
+ const answer = r.code === 0 ? lastJson(r.stdout) : null;
205
+ const main = answer?.agents?.[0]?.main_session;
206
+ const read = { at: Date.now(), main: typeof main === 'string' && main ? main : answer && Number.isInteger(answer.code) && answer.code !== 0 ? false : null };
207
+ agentMains.set(address, read);
208
+ return read.main;
209
+ }
210
+ /**
211
+ * A subscriber's liveness, read first (readBefore): true, false, or null when it could not be read (unknown, never dead).
212
+ * An agent's address is as live as its main session.
213
+ */
191
214
  async function subscriberAlive(fleet, address) {
192
215
  if (fleet.alive.has(address)) return true;
216
+ if (agentAt(address)) {
217
+ const main = await agentMain(address);
218
+ return main && sessionAt(main) ? subscriberAlive(fleet, main) : main === null ? null : false;
219
+ }
193
220
  const session = sessionAt(address);
194
221
  if (!session) return false;
195
222
  await readBefore(fleet, session);
@@ -2750,8 +2777,9 @@ async function notify(board, fleet, report, entry) {
2750
2777
  // the card as the workflow names it (its status the workflow's: triaging, reviewing, stopped; `stored_as` kanban.db's)
2751
2778
  const task = view(board, (db) => { const t = getTask(db, sub.task_id); return t ? { ...t, status: statusOf(db, t), stored_as: t.status } : t; });
2752
2779
  // a worker whose run has ended is not woken by a notice (a second session would start working the card beside
2753
- // the one the next run gets): the notice is filed for its next turn
2754
- const working = role !== 'worker' || view(board, (db) => addressOf(currentRun(db, sub.task_id)?.metadata?.supercode) === sub.chat_id);
2780
+ // the one the next run gets): the notice is filed for its next turn, and the next run's brief carries the card's
2781
+ // thread. A subtask has no run of its own: its worker works in its arc's run.
2782
+ const working = role !== 'worker' || view(board, (db) => addressOf(currentRun(db, task?.subtask_of ?? sub.task_id)?.metadata?.supercode) === sub.chat_id);
2755
2783
  // a Claude session always starts a turn when mail reaches it, so its mail is always delivered now
2756
2784
  const wake = String(sub.chat_id).includes(':claude-code:') || (working && !(!entry.workflow.run && sub.delivery_mode === 'notify'));
2757
2785
  const where = "WHERE task_id = ? AND platform = 'supercode' AND chat_id = ? AND thread_id = ?";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-orchestrator",
3
- "version": "0.5.148",
3
+ "version": "0.5.150",
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.91",
28
- "@volter/teams": "0.2.60",
28
+ "@volter/teams": "0.2.61",
29
29
  "@volter/ztrack": "^2.4.23",
30
30
  "yaml": "^2.9.0"
31
31
  },