@volter/supercode-orchestrator 0.4.65 → 0.4.66
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 +20 -5
- package/board/workflow.mjs +4 -3
- package/package.json +1 -1
package/board/dispatch.mjs
CHANGED
|
@@ -500,11 +500,6 @@ function observeIdle(board, fleet, settings, report, entry, effects) {
|
|
|
500
500
|
|
|
501
501
|
/** A session effect a committed move asked for: a message to the card's current actor, or closing a slot's pane. */
|
|
502
502
|
export async function sessionEffect(board, e) {
|
|
503
|
-
if (e.kind === 'tell') {
|
|
504
|
-
// an ask is sent under the id the card's block waits on
|
|
505
|
-
await send(boardAddress(board.label), board.label, e.to, e.text, e.messageId ?? `board-tell-${e.id}-${now()}`, { ask: Boolean(e.messageId) });
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
503
|
if (e.kind === 'send_to_actor') {
|
|
509
504
|
const run = tx(board, (db) => currentRun(db, e.id));
|
|
510
505
|
const session = run?.metadata?.supercode;
|
|
@@ -854,6 +849,25 @@ async function send(from, label, to, body, key, { queue = false, ask = false } =
|
|
|
854
849
|
if (answer.code !== 0) throw new Error((answer.text || r.stderr || `no answer (exit ${r.code})`).trim().slice(-300));
|
|
855
850
|
}
|
|
856
851
|
|
|
852
|
+
/**
|
|
853
|
+
* The messages the workflow has the board send (`tell`, `ask`: board_message events) that it has not sent yet, sent now
|
|
854
|
+
* and marked board_message_sent. A question goes under the id its card waits on; a resend of a sent one is a no-op
|
|
855
|
+
* (the id is the send's idempotency key). One that fails is tried again next tick.
|
|
856
|
+
*/
|
|
857
|
+
async function sendBoardMessages(board, report) {
|
|
858
|
+
const rows = tx(board, (db) => db.prepare(`SELECT id, task_id, payload FROM task_events e WHERE kind = 'board_message' AND NOT EXISTS
|
|
859
|
+
(SELECT 1 FROM task_events s WHERE s.kind = 'board_message_sent' AND s.task_id = e.task_id AND json_extract(s.payload, '$.event') = e.id) ORDER BY id`).all());
|
|
860
|
+
for (const row of rows) {
|
|
861
|
+
const m = json(row.payload, {}) ?? {};
|
|
862
|
+
try {
|
|
863
|
+
await send(boardAddress(board.label), board.label, m.to, m.text, m.message_id ?? `board-message-${row.id}`, { ask: Boolean(m.message_id) });
|
|
864
|
+
tx(board, (db) => event(db, row.task_id, 'board_message_sent', { event: row.id, to: m.to, ...(m.message_id ? { message_id: m.message_id } : {}) }));
|
|
865
|
+
} catch (error) {
|
|
866
|
+
report.undelivered.push([row.task_id, m.to, String(error.message).slice(-200)]);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
857
871
|
/** The board's own address: where its notices come from and where card updates are mailed. */
|
|
858
872
|
export const boardAddress = (label) => `sc:${localMachine()}:board:${label.replace(/[^A-Za-z0-9_.-]/g, '-')}`;
|
|
859
873
|
|
|
@@ -1216,6 +1230,7 @@ export async function tick({ root, lanes, settings, only = null, slugs = null, d
|
|
|
1216
1230
|
supervise(board, fleet, settings, report, entry, effects); closeRequested(board, report); phase('supervise');
|
|
1217
1231
|
report.unsettled = [];
|
|
1218
1232
|
report.promoted = recomputeReady(board, effects, report.unsettled);
|
|
1233
|
+
await sendBoardMessages(board, report);
|
|
1219
1234
|
const before = report.started.length;
|
|
1220
1235
|
if (dispatch) startCards(board, fleet, lanes, settings, report, entry, effects, { only, hostRunning });
|
|
1221
1236
|
hostRunning += report.started.length - before; phase('start');
|
package/board/workflow.mjs
CHANGED
|
@@ -534,15 +534,16 @@ const ACTIONS = {
|
|
|
534
534
|
return;
|
|
535
535
|
}
|
|
536
536
|
},
|
|
537
|
-
// a message from the board to a session (`to`: its address)
|
|
538
|
-
|
|
537
|
+
// a message from the board to a session (`to`: its address), kept on the card as a board_message event until the
|
|
538
|
+
// dispatcher has sent it: a move settled by any verb (a list settles too) is never lost with its effects
|
|
539
|
+
tell(ctx, { to, text }) { if (to) record(ctx.db, ctx.id, 'board_message', { to: String(to), text: String(text ?? '') }, null); },
|
|
539
540
|
// a question from the board to a session, sent under a message id chosen now: `{{asked}}` in the actions after it is
|
|
540
541
|
// that id (what a block waits on), and the answer to it lands in the board's mailbox
|
|
541
542
|
ask(ctx, { to, text }) {
|
|
542
543
|
if (!to) throw new Error(`the workflow asks nobody about ${ctx.id} (ask.to is empty)`);
|
|
543
544
|
const id = `m-${randomBytes(12).toString('hex')}`;
|
|
544
545
|
ctx.scope.asked = id;
|
|
545
|
-
ctx.
|
|
546
|
+
record(ctx.db, ctx.id, 'board_message', { to: String(to), text: `${String(text ?? '')}\n\nAnswer with reply_to ${id}.`, message_id: id }, null);
|
|
546
547
|
},
|
|
547
548
|
send_to_actor(ctx, text) { ctx.effects.push({ kind: 'send_to_actor', id: ctx.id, text }); },
|
|
548
549
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-orchestrator",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.66",
|
|
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": {
|