@jungjaehoon/mama-os 0.78.0 → 0.79.0
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/CHANGELOG.md +311 -0
- package/README.md +38 -24
- package/db/migrations/002-model-runs-parent-index.sql +11 -0
- package/db/migrations/003-upkeep-settled.sql +15 -0
- package/dist/api/google-read-actions.d.ts +30 -0
- package/dist/api/google-read-actions.d.ts.map +1 -0
- package/dist/api/google-read-actions.js +256 -0
- package/dist/api/google-read-actions.js.map +1 -0
- package/dist/api/record-actions.d.ts.map +1 -1
- package/dist/api/record-actions.js +23 -5
- package/dist/api/record-actions.js.map +1 -1
- package/dist/api/report-handler.d.ts +0 -6
- package/dist/api/report-handler.d.ts.map +1 -1
- package/dist/api/report-handler.js +0 -54
- package/dist/api/report-handler.js.map +1 -1
- package/dist/api/security-events.d.ts +1 -1
- package/dist/api/security-events.d.ts.map +1 -1
- package/dist/api/security-events.js.map +1 -1
- package/dist/api/source-actions.d.ts +9 -0
- package/dist/api/source-actions.d.ts.map +1 -1
- package/dist/api/source-actions.js +49 -0
- package/dist/api/source-actions.js.map +1 -1
- package/dist/api/viewer-request-security.d.ts +14 -1
- package/dist/api/viewer-request-security.d.ts.map +1 -1
- package/dist/api/viewer-request-security.js +26 -3
- package/dist/api/viewer-request-security.js.map +1 -1
- package/dist/api/viewer-server.d.ts +7 -0
- package/dist/api/viewer-server.d.ts.map +1 -1
- package/dist/api/viewer-server.js +32 -0
- package/dist/api/viewer-server.js.map +1 -1
- package/dist/api/work-actions.d.ts +19 -2
- package/dist/api/work-actions.d.ts.map +1 -1
- package/dist/api/work-actions.js +15 -0
- package/dist/api/work-actions.js.map +1 -1
- package/dist/cli/commands/backup.d.ts +7 -6
- package/dist/cli/commands/backup.d.ts.map +1 -1
- package/dist/cli/commands/backup.js +44 -7
- package/dist/cli/commands/backup.js.map +1 -1
- package/dist/cli/commands/control.d.ts +22 -4
- package/dist/cli/commands/control.d.ts.map +1 -1
- package/dist/cli/commands/control.js +172 -11
- package/dist/cli/commands/control.js.map +1 -1
- package/dist/cli/commands/daemon.d.ts +13 -2
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/daemon.js +211 -5
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/cli/commands/init-questions.d.ts +98 -0
- package/dist/cli/commands/init-questions.d.ts.map +1 -0
- package/dist/cli/commands/init-questions.js +420 -0
- package/dist/cli/commands/init-questions.js.map +1 -0
- package/dist/cli/commands/init-section.d.ts +13 -0
- package/dist/cli/commands/init-section.d.ts.map +1 -0
- package/dist/cli/commands/init-section.js +375 -0
- package/dist/cli/commands/init-section.js.map +1 -0
- package/dist/cli/commands/init.d.ts +56 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +562 -351
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/node-move.d.ts +20 -0
- package/dist/cli/commands/node-move.d.ts.map +1 -0
- package/dist/cli/commands/node-move.js +289 -0
- package/dist/cli/commands/node-move.js.map +1 -0
- package/dist/cli/commands/register-owner.d.ts +3 -0
- package/dist/cli/commands/register-owner.d.ts.map +1 -1
- package/dist/cli/commands/register-owner.js +2 -0
- package/dist/cli/commands/register-owner.js.map +1 -1
- package/dist/cli/commands/restore.d.ts +2 -0
- package/dist/cli/commands/restore.d.ts.map +1 -1
- package/dist/cli/commands/restore.js +7 -0
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/service.d.ts +16 -0
- package/dist/cli/commands/service.d.ts.map +1 -1
- package/dist/cli/commands/service.js +36 -8
- package/dist/cli/commands/service.js.map +1 -1
- package/dist/cli/commands/tools.d.ts +1 -1
- package/dist/cli/commands/tools.d.ts.map +1 -1
- package/dist/cli/commands/tools.js +8 -3
- package/dist/cli/commands/tools.js.map +1 -1
- package/dist/cli/commands/uninstall.d.ts.map +1 -1
- package/dist/cli/commands/uninstall.js +78 -5
- package/dist/cli/commands/uninstall.js.map +1 -1
- package/dist/cli/commands/update.d.ts +59 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +948 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.js +8 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/launch-files.d.ts +36 -0
- package/dist/cli/launch-files.d.ts.map +1 -1
- package/dist/cli/launch-files.js +94 -1
- package/dist/cli/launch-files.js.map +1 -1
- package/dist/cli/prompt.d.ts +2 -1
- package/dist/cli/prompt.d.ts.map +1 -1
- package/dist/cli/prompt.js +5 -2
- package/dist/cli/prompt.js.map +1 -1
- package/dist/cli/runtime/backup.d.ts +17 -1
- package/dist/cli/runtime/backup.d.ts.map +1 -1
- package/dist/cli/runtime/backup.js +32 -4
- package/dist/cli/runtime/backup.js.map +1 -1
- package/dist/cli/runtime/daemon-control.d.ts +92 -7
- package/dist/cli/runtime/daemon-control.d.ts.map +1 -1
- package/dist/cli/runtime/daemon-control.js +183 -8
- package/dist/cli/runtime/daemon-control.js.map +1 -1
- package/dist/cli/runtime/default-roots.d.ts +27 -0
- package/dist/cli/runtime/default-roots.d.ts.map +1 -0
- package/dist/cli/runtime/default-roots.js +61 -0
- package/dist/cli/runtime/default-roots.js.map +1 -0
- package/dist/cli/runtime/diagnostics.d.ts +25 -0
- package/dist/cli/runtime/diagnostics.d.ts.map +1 -1
- package/dist/cli/runtime/diagnostics.js +249 -63
- package/dist/cli/runtime/diagnostics.js.map +1 -1
- package/dist/cli/runtime/init-state.d.ts +20 -0
- package/dist/cli/runtime/init-state.d.ts.map +1 -0
- package/dist/cli/runtime/init-state.js +51 -0
- package/dist/cli/runtime/init-state.js.map +1 -0
- package/dist/cli/runtime/install-kind.d.ts +54 -0
- package/dist/cli/runtime/install-kind.d.ts.map +1 -0
- package/dist/cli/runtime/install-kind.js +164 -0
- package/dist/cli/runtime/install-kind.js.map +1 -0
- package/dist/cli/runtime/node-move-journal.d.ts +44 -0
- package/dist/cli/runtime/node-move-journal.d.ts.map +1 -0
- package/dist/cli/runtime/node-move-journal.js +48 -0
- package/dist/cli/runtime/node-move-journal.js.map +1 -0
- package/dist/cli/runtime/release-check.d.ts +94 -0
- package/dist/cli/runtime/release-check.d.ts.map +1 -0
- package/dist/cli/runtime/release-check.js +316 -0
- package/dist/cli/runtime/release-check.js.map +1 -0
- package/dist/cli/runtime/setup-page.d.ts +57 -0
- package/dist/cli/runtime/setup-page.d.ts.map +1 -0
- package/dist/cli/runtime/setup-page.js +266 -0
- package/dist/cli/runtime/setup-page.js.map +1 -0
- package/dist/cli/runtime/source-tools.d.ts +60 -0
- package/dist/cli/runtime/source-tools.d.ts.map +1 -0
- package/dist/cli/runtime/source-tools.js +170 -0
- package/dist/cli/runtime/source-tools.js.map +1 -0
- package/dist/cli/runtime/telegram-pairing.d.ts +73 -0
- package/dist/cli/runtime/telegram-pairing.d.ts.map +1 -0
- package/dist/cli/runtime/telegram-pairing.js +184 -0
- package/dist/cli/runtime/telegram-pairing.js.map +1 -0
- package/dist/cli/runtime/update-journal.d.ts +135 -0
- package/dist/cli/runtime/update-journal.d.ts.map +1 -0
- package/dist/cli/runtime/update-journal.js +144 -0
- package/dist/cli/runtime/update-journal.js.map +1 -0
- package/dist/cli/runtime/update-progress.d.ts +95 -0
- package/dist/cli/runtime/update-progress.d.ts.map +1 -0
- package/dist/cli/runtime/update-progress.js +154 -0
- package/dist/cli/runtime/update-progress.js.map +1 -0
- package/dist/cli/runtime/update-request.d.ts +58 -0
- package/dist/cli/runtime/update-request.d.ts.map +1 -0
- package/dist/cli/runtime/update-request.js +172 -0
- package/dist/cli/runtime/update-request.js.map +1 -0
- package/dist/connectors/calendar/index.d.ts +5 -1
- package/dist/connectors/calendar/index.d.ts.map +1 -1
- package/dist/connectors/calendar/index.js +19 -28
- package/dist/connectors/calendar/index.js.map +1 -1
- package/dist/connectors/chatwork/index.d.ts.map +1 -1
- package/dist/connectors/chatwork/index.js +7 -3
- package/dist/connectors/chatwork/index.js.map +1 -1
- package/dist/connectors/config-loader.d.ts +5 -0
- package/dist/connectors/config-loader.d.ts.map +1 -1
- package/dist/connectors/config-loader.js +8 -0
- package/dist/connectors/config-loader.js.map +1 -1
- package/dist/connectors/discord/index.d.ts.map +1 -1
- package/dist/connectors/discord/index.js +4 -3
- package/dist/connectors/discord/index.js.map +1 -1
- package/dist/connectors/drive/index.d.ts.map +1 -1
- package/dist/connectors/drive/index.js +15 -13
- package/dist/connectors/drive/index.js.map +1 -1
- package/dist/connectors/framework/gws-utils.d.ts +62 -0
- package/dist/connectors/framework/gws-utils.d.ts.map +1 -1
- package/dist/connectors/framework/gws-utils.js +133 -3
- package/dist/connectors/framework/gws-utils.js.map +1 -1
- package/dist/connectors/framework/types.d.ts +24 -0
- package/dist/connectors/framework/types.d.ts.map +1 -1
- package/dist/connectors/framework/types.js +9 -0
- package/dist/connectors/framework/types.js.map +1 -1
- package/dist/connectors/gmail/index.d.ts.map +1 -1
- package/dist/connectors/gmail/index.js +14 -13
- package/dist/connectors/gmail/index.js.map +1 -1
- package/dist/connectors/index.d.ts +4 -4
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +4 -10
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/notion/index.d.ts.map +1 -1
- package/dist/connectors/notion/index.js +5 -3
- package/dist/connectors/notion/index.js.map +1 -1
- package/dist/connectors/sheets/index.d.ts.map +1 -1
- package/dist/connectors/sheets/index.js +17 -12
- package/dist/connectors/sheets/index.js.map +1 -1
- package/dist/connectors/slack/index.d.ts.map +1 -1
- package/dist/connectors/slack/index.js +9 -3
- package/dist/connectors/slack/index.js.map +1 -1
- package/dist/connectors/telegram/index.d.ts.map +1 -1
- package/dist/connectors/telegram/index.js +4 -3
- package/dist/connectors/telegram/index.js.map +1 -1
- package/dist/connectors/trello/index.d.ts +1 -1
- package/dist/connectors/trello/index.d.ts.map +1 -1
- package/dist/connectors/trello/index.js +10 -5
- package/dist/connectors/trello/index.js.map +1 -1
- package/dist/gateways/discord.d.ts +6 -0
- package/dist/gateways/discord.d.ts.map +1 -1
- package/dist/gateways/discord.js +38 -27
- package/dist/gateways/discord.js.map +1 -1
- package/dist/gateways/slack.d.ts +6 -0
- package/dist/gateways/slack.d.ts.map +1 -1
- package/dist/gateways/slack.js +38 -27
- package/dist/gateways/slack.js.map +1 -1
- package/dist/gateways/telegram-commands.d.ts +124 -0
- package/dist/gateways/telegram-commands.d.ts.map +1 -0
- package/dist/gateways/telegram-commands.js +131 -0
- package/dist/gateways/telegram-commands.js.map +1 -0
- package/dist/gateways/telegram.d.ts +20 -0
- package/dist/gateways/telegram.d.ts.map +1 -1
- package/dist/gateways/telegram.js +138 -34
- package/dist/gateways/telegram.js.map +1 -1
- package/dist/gateways/turn-contract.d.ts +11 -0
- package/dist/gateways/turn-contract.d.ts.map +1 -1
- package/dist/runtime/action-surface.d.ts +1 -1
- package/dist/runtime/action-surface.d.ts.map +1 -1
- package/dist/runtime/action-surface.js +10 -0
- package/dist/runtime/action-surface.js.map +1 -1
- package/dist/runtime/backend-security.d.ts +23 -2
- package/dist/runtime/backend-security.d.ts.map +1 -1
- package/dist/runtime/backend-security.js +50 -5
- package/dist/runtime/backend-security.js.map +1 -1
- package/dist/runtime/member-paths.d.ts +15 -7
- package/dist/runtime/member-paths.d.ts.map +1 -1
- package/dist/runtime/member-paths.js +64 -12
- package/dist/runtime/member-paths.js.map +1 -1
- package/dist/runtime/member-session.d.ts +4 -0
- package/dist/runtime/member-session.d.ts.map +1 -1
- package/dist/runtime/member-session.js +23 -2
- package/dist/runtime/member-session.js.map +1 -1
- package/dist/runtime/native-session.d.ts +2 -0
- package/dist/runtime/native-session.d.ts.map +1 -1
- package/dist/runtime/native-session.js +1 -0
- package/dist/runtime/native-session.js.map +1 -1
- package/dist/runtime/owner-runtime.d.ts +63 -1
- package/dist/runtime/owner-runtime.d.ts.map +1 -1
- package/dist/runtime/owner-runtime.js +180 -3
- package/dist/runtime/owner-runtime.js.map +1 -1
- package/dist/runtime/owner-system-prompt.d.ts.map +1 -1
- package/dist/runtime/owner-system-prompt.js +0 -1
- package/dist/runtime/owner-system-prompt.js.map +1 -1
- package/dist/runtime/principal-access.d.ts +2 -0
- package/dist/runtime/principal-access.d.ts.map +1 -1
- package/dist/runtime/principal-access.js +7 -0
- package/dist/runtime/principal-access.js.map +1 -1
- package/dist/runtime/principal-sessions.d.ts.map +1 -1
- package/dist/runtime/principal-sessions.js +8 -1
- package/dist/runtime/principal-sessions.js.map +1 -1
- package/dist/runtime/record-orders.d.ts.map +1 -1
- package/dist/runtime/record-orders.js +3 -29
- package/dist/runtime/record-orders.js.map +1 -1
- package/dist/runtime/report-scheduler.d.ts +9 -2
- package/dist/runtime/report-scheduler.d.ts.map +1 -1
- package/dist/runtime/report-scheduler.js +37 -10
- package/dist/runtime/report-scheduler.js.map +1 -1
- package/dist/runtime/stimulus-delivery.d.ts +3 -0
- package/dist/runtime/stimulus-delivery.d.ts.map +1 -1
- package/dist/runtime/stimulus-delivery.js +19 -3
- package/dist/runtime/stimulus-delivery.js.map +1 -1
- package/dist/runtime/tools-paths.d.ts +7 -0
- package/dist/runtime/tools-paths.d.ts.map +1 -1
- package/dist/runtime/tools-paths.js +11 -5
- package/dist/runtime/tools-paths.js.map +1 -1
- package/dist/runtime/upkeep-close.d.ts +17 -0
- package/dist/runtime/upkeep-close.d.ts.map +1 -0
- package/dist/runtime/upkeep-close.js +127 -0
- package/dist/runtime/upkeep-close.js.map +1 -0
- package/dist/runtime/upkeep-orders.d.ts +124 -0
- package/dist/runtime/upkeep-orders.d.ts.map +1 -0
- package/dist/runtime/upkeep-orders.js +310 -0
- package/dist/runtime/upkeep-orders.js.map +1 -0
- package/dist/runtime/upkeep-reconcile.d.ts +25 -0
- package/dist/runtime/upkeep-reconcile.d.ts.map +1 -0
- package/dist/runtime/upkeep-reconcile.js +231 -0
- package/dist/runtime/upkeep-reconcile.js.map +1 -0
- package/dist/runtime/upkeep-writeback.d.ts +22 -0
- package/dist/runtime/upkeep-writeback.d.ts.map +1 -0
- package/dist/runtime/upkeep-writeback.js +203 -0
- package/dist/runtime/upkeep-writeback.js.map +1 -0
- package/dist/utils/untrusted-content.d.ts.map +1 -1
- package/dist/utils/untrusted-content.js +8 -1
- package/dist/utils/untrusted-content.js.map +1 -1
- package/install/install.sh +457 -0
- package/install/node.json +9 -0
- package/package.json +3 -4
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UPKEEP_SCAN_PAGE = exports.UPKEEP_WINDOW_MS = exports.UPKEEP_MAX_ATTEMPTS = void 0;
|
|
4
|
+
exports.upkeepOrderIdPrefix = upkeepOrderIdPrefix;
|
|
5
|
+
exports.parseUpkeepOrder = parseUpkeepOrder;
|
|
6
|
+
exports.orderRunIds = orderRunIds;
|
|
7
|
+
exports.noUpdateCites = noUpdateCites;
|
|
8
|
+
exports.runningChildren = runningChildren;
|
|
9
|
+
exports.createUpkeepOrders = createUpkeepOrders;
|
|
10
|
+
const node_crypto_1 = require("node:crypto");
|
|
11
|
+
/**
|
|
12
|
+
* Ledger upkeep orders (docs/development/work/ledger-upkeep.md). The host chooses the subjects,
|
|
13
|
+
* the agent judges and writes in the common session, and the host checks each subject when the
|
|
14
|
+
* order's run ends. Record orders (record-orders.ts) stay a separate lane: they follow live deltas
|
|
15
|
+
* and carry batches; upkeep follows the ledger's own state.
|
|
16
|
+
*
|
|
17
|
+
* tick(kind) ── scan ──> subjects not checked, not in an open order, under the attempt limit
|
|
18
|
+
* │ │
|
|
19
|
+
* │ accept(order on kind.channel)
|
|
20
|
+
* ▼ ▼
|
|
21
|
+
* onResult / onLost ──> per subject: checked │ waiting (picked by the next tick) │ lost
|
|
22
|
+
*
|
|
23
|
+
* Checked and lost subjects are also written to upkeep_settled: the mailbox deletes acked order
|
|
24
|
+
* rows after seven days, and a settled subject must never be ordered again.
|
|
25
|
+
*/
|
|
26
|
+
/** A subject is ordered at most this many times; then it is reported lost and left alone. */
|
|
27
|
+
exports.UPKEEP_MAX_ATTEMPTS = 3;
|
|
28
|
+
/** How far back stored orders are read to count a subject's attempts. */
|
|
29
|
+
exports.UPKEEP_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
|
|
30
|
+
/** Candidates per scan page. */
|
|
31
|
+
exports.UPKEEP_SCAN_PAGE = 200;
|
|
32
|
+
/** Every order of a kind has an id with this prefix; its runs carry it as sourceMessageRef. */
|
|
33
|
+
function upkeepOrderIdPrefix(kindName) {
|
|
34
|
+
return `upkeep:${kindName}:`;
|
|
35
|
+
}
|
|
36
|
+
function parseUpkeepOrder(payload) {
|
|
37
|
+
const value = payload;
|
|
38
|
+
if (!value ||
|
|
39
|
+
value.order !== 'upkeep' ||
|
|
40
|
+
typeof value.kind !== 'string' ||
|
|
41
|
+
!Array.isArray(value.subjects) ||
|
|
42
|
+
value.subjects.length === 0 ||
|
|
43
|
+
value.subjects.some((subject) => typeof subject?.key !== 'string' || subject.key === ''))
|
|
44
|
+
throw new Error('Upkeep order requires { order: upkeep, kind, subjects: [{ key }] }');
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
/** The runs an order produced: its own turn and the child runs that turn started. */
|
|
48
|
+
function orderRunIds(adapter, orderIds) {
|
|
49
|
+
if (orderIds.length === 0)
|
|
50
|
+
return [];
|
|
51
|
+
const marks = orderIds.map(() => '?').join(',');
|
|
52
|
+
return adapter
|
|
53
|
+
.prepare(`SELECT r.model_run_id AS id FROM model_runs r
|
|
54
|
+
WHERE json_extract(r.input_refs_json, '$.sourceMessageRef') IN (${marks})
|
|
55
|
+
UNION
|
|
56
|
+
SELECT c.model_run_id FROM model_runs c JOIN model_runs p ON c.parent_model_run_id = p.model_run_id
|
|
57
|
+
WHERE json_extract(p.input_refs_json, '$.sourceMessageRef') IN (${marks})`)
|
|
58
|
+
.all(...orderIds, ...orderIds).map((row) => row.id);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A completed work.no_update in these runs. With `cites`, the no-update must name one of the
|
|
62
|
+
* values in that input field (`commitmentIds` for a work item, `observationRefs` for a source);
|
|
63
|
+
* with `cites` null, any no-update in the runs counts. The field name is a fixed union, never
|
|
64
|
+
* caller text, so it interpolates into the json path safely.
|
|
65
|
+
*/
|
|
66
|
+
function noUpdateCites(adapter, runIds, cites) {
|
|
67
|
+
if (runIds.length === 0)
|
|
68
|
+
return false;
|
|
69
|
+
if (cites !== null && cites.values.length === 0)
|
|
70
|
+
return false;
|
|
71
|
+
const citing = cites === null
|
|
72
|
+
? ''
|
|
73
|
+
: `AND EXISTS (
|
|
74
|
+
SELECT 1 FROM json_each(CASE WHEN json_valid(t.input_summary)
|
|
75
|
+
THEN json_extract(t.input_summary, '$.${cites.field}') END) ref
|
|
76
|
+
WHERE ref.value IN (${cites.values.map(() => '?').join(',')}))`;
|
|
77
|
+
return (adapter
|
|
78
|
+
.prepare(`SELECT 1 FROM tool_traces t
|
|
79
|
+
WHERE t.tool_name = 'work.no_update' AND t.execution_status = 'completed'
|
|
80
|
+
AND t.model_run_id IN (${runIds.map(() => '?').join(',')})
|
|
81
|
+
${citing}
|
|
82
|
+
LIMIT 1`)
|
|
83
|
+
.get(...runIds, ...(cites?.values ?? [])) !== undefined);
|
|
84
|
+
}
|
|
85
|
+
/** The kind's subjects as its stored orders of the last week show them. */
|
|
86
|
+
function storedSubjects(adapter, kind, now) {
|
|
87
|
+
const rows = adapter
|
|
88
|
+
.prepare(`SELECT m.stimulus_id, m.payload_json, m.status, n.state AS native_state
|
|
89
|
+
FROM mailbox_inputs m LEFT JOIN native_input_deliveries n ON n.input_id = m.id
|
|
90
|
+
WHERE m.kind = 'scheduled' AND m.channel_key = ? AND m.created_at >= ?
|
|
91
|
+
ORDER BY m.created_at, m.id`)
|
|
92
|
+
.all(kind.channel, now - exports.UPKEEP_WINDOW_MS);
|
|
93
|
+
const states = new Map();
|
|
94
|
+
let anyOpen = false;
|
|
95
|
+
for (const row of rows) {
|
|
96
|
+
const order = parseUpkeepOrder(JSON.parse(row.payload_json));
|
|
97
|
+
// A row parked uncertain stays claimed; it is settled through onLost, not left open.
|
|
98
|
+
const open = (row.status === 'pending' || row.status === 'claimed') && row.native_state !== 'uncertain';
|
|
99
|
+
anyOpen ||= open;
|
|
100
|
+
for (const subject of order.subjects) {
|
|
101
|
+
const current = states.get(subject.key);
|
|
102
|
+
states.set(subject.key, {
|
|
103
|
+
subject,
|
|
104
|
+
orders: [...(current?.orders ?? []), row.stimulus_id],
|
|
105
|
+
open: (current?.open ?? false) || open,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return { states, anyOpen };
|
|
110
|
+
}
|
|
111
|
+
/** A subject settled for good (upkeep_settled); a later write keeps the latest state. */
|
|
112
|
+
function recordSettled(adapter) {
|
|
113
|
+
return adapter.prepare(`INSERT OR REPLACE INTO upkeep_settled (kind, subject_key, state, settled_at) VALUES (?, ?, ?, ?)`);
|
|
114
|
+
}
|
|
115
|
+
/** Child runs of an order run that this process started and that have not ended yet. */
|
|
116
|
+
function runningChildren(adapter, modelRunId, startedAt) {
|
|
117
|
+
const row = adapter
|
|
118
|
+
.prepare(`SELECT count(*) AS n FROM model_runs
|
|
119
|
+
WHERE parent_model_run_id = ? AND status NOT IN ('committed', 'failed') AND created_at >= ?`)
|
|
120
|
+
.get(modelRunId, startedAt);
|
|
121
|
+
return row?.n ?? 0;
|
|
122
|
+
}
|
|
123
|
+
function createUpkeepOrders(options) {
|
|
124
|
+
const now = options.now ?? Date.now;
|
|
125
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
126
|
+
const childWaitMs = options.childWaitMs ?? 10 * 60 * 1000;
|
|
127
|
+
const byName = new Map(options.kinds.map((kind) => [kind.name, kind]));
|
|
128
|
+
const byChannel = new Map(options.kinds.map((kind) => [kind.channel, kind]));
|
|
129
|
+
const timers = [];
|
|
130
|
+
// Orders whose check is still waiting for child runs: their subjects are not ordered again yet.
|
|
131
|
+
const checking = new Set();
|
|
132
|
+
// An order is settled once: a row parked uncertain and then closed reports here twice.
|
|
133
|
+
const settledOrders = new Set();
|
|
134
|
+
let stopped = false;
|
|
135
|
+
const kindOf = (row) => {
|
|
136
|
+
const kind = byChannel.get(row.channelKey);
|
|
137
|
+
if (!kind)
|
|
138
|
+
throw new Error(`No upkeep kind serves channel ${row.channelKey}`);
|
|
139
|
+
return kind;
|
|
140
|
+
};
|
|
141
|
+
const settle = (kind, orderId, order, reason) => {
|
|
142
|
+
if (settledOrders.has(orderId))
|
|
143
|
+
return;
|
|
144
|
+
settledOrders.add(orderId);
|
|
145
|
+
const at = now();
|
|
146
|
+
const { states } = storedSubjects(options.adapter, kind, at);
|
|
147
|
+
const record = recordSettled(options.adapter);
|
|
148
|
+
for (const subject of order.subjects) {
|
|
149
|
+
const orders = states.get(subject.key)?.orders ?? [];
|
|
150
|
+
if (kind.checked(options.adapter, subject, orderRunIds(options.adapter, orders))) {
|
|
151
|
+
record.run(kind.name, subject.key, 'checked', at);
|
|
152
|
+
options.onEvent?.({ type: 'checked', kind: kind.name, subject: subject.key });
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const attempt = orders.length;
|
|
156
|
+
if (attempt >= exports.UPKEEP_MAX_ATTEMPTS) {
|
|
157
|
+
record.run(kind.name, subject.key, 'lost', at);
|
|
158
|
+
options.onEvent?.({ type: 'lost', kind: kind.name, subject: subject.key, attempt, reason });
|
|
159
|
+
}
|
|
160
|
+
else
|
|
161
|
+
options.onEvent?.({
|
|
162
|
+
type: 'waiting',
|
|
163
|
+
kind: kind.name,
|
|
164
|
+
subject: subject.key,
|
|
165
|
+
attempt,
|
|
166
|
+
reason,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
const tick = (kindName) => {
|
|
171
|
+
const kind = byName.get(kindName);
|
|
172
|
+
if (!kind)
|
|
173
|
+
throw new Error(`Unknown upkeep kind ${kindName}`);
|
|
174
|
+
if (stopped)
|
|
175
|
+
return;
|
|
176
|
+
const at = now();
|
|
177
|
+
const { states, anyOpen } = storedSubjects(options.adapter, kind, at);
|
|
178
|
+
// One order of a kind at a time keeps the common session's queue for the owner; an order whose
|
|
179
|
+
// child runs may still write is not over yet.
|
|
180
|
+
if (anyOpen || [...checking].some((id) => id.startsWith(upkeepOrderIdPrefix(kind.name))))
|
|
181
|
+
return;
|
|
182
|
+
const settled = new Set(options.adapter
|
|
183
|
+
.prepare(`SELECT subject_key FROM upkeep_settled WHERE kind = ?`)
|
|
184
|
+
.all(kind.name).map((row) => row.subject_key));
|
|
185
|
+
const record = recordSettled(options.adapter);
|
|
186
|
+
const due = [];
|
|
187
|
+
const perGroup = new Map();
|
|
188
|
+
const candidates = function* () {
|
|
189
|
+
for (let page = 0;; page += 1) {
|
|
190
|
+
const rows = kind.scan(options.adapter, at, page);
|
|
191
|
+
yield* rows;
|
|
192
|
+
if (rows.length < exports.UPKEEP_SCAN_PAGE)
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
for (const subject of candidates()) {
|
|
197
|
+
if (kind.group === undefined && due.length >= kind.maxPerOrder)
|
|
198
|
+
break;
|
|
199
|
+
const group = kind.group?.(subject);
|
|
200
|
+
if (group !== undefined && (perGroup.get(group) ?? 0) >= kind.maxPerOrder)
|
|
201
|
+
continue;
|
|
202
|
+
if (settled.has(subject.key))
|
|
203
|
+
continue;
|
|
204
|
+
const state = states.get(subject.key);
|
|
205
|
+
const orders = state?.orders ?? [];
|
|
206
|
+
// No order of the kind is open here, so these orders are over. Their settlement is recorded
|
|
207
|
+
// again: a stop during the child-run wait, a failed check or a crash in settle() leaves it
|
|
208
|
+
// unwritten, and the stored orders that show it are deleted after seven days.
|
|
209
|
+
if (orders.length > 0 &&
|
|
210
|
+
kind.checked(options.adapter, subject, orderRunIds(options.adapter, orders))) {
|
|
211
|
+
record.run(kind.name, subject.key, 'checked', at);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
// Reported lost when its last order was settled; it is never ordered again.
|
|
215
|
+
if (orders.length >= exports.UPKEEP_MAX_ATTEMPTS) {
|
|
216
|
+
record.run(kind.name, subject.key, 'lost', at);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
due.push(subject);
|
|
220
|
+
if (group !== undefined)
|
|
221
|
+
perGroup.set(group, (perGroup.get(group) ?? 0) + 1);
|
|
222
|
+
}
|
|
223
|
+
if (due.length === 0)
|
|
224
|
+
return;
|
|
225
|
+
const id = `${upkeepOrderIdPrefix(kind.name)}${at}:${(0, node_crypto_1.randomUUID)().slice(0, 8)}`;
|
|
226
|
+
const payload = { order: 'upkeep', kind: kind.name, subjects: due };
|
|
227
|
+
const receipt = options.accept({
|
|
228
|
+
id,
|
|
229
|
+
kind: 'scheduled',
|
|
230
|
+
channelKey: kind.channel,
|
|
231
|
+
occurredAt: at,
|
|
232
|
+
payload: payload,
|
|
233
|
+
});
|
|
234
|
+
if (receipt.state !== 'duplicate')
|
|
235
|
+
options.onEvent?.({ type: 'ordered', kind: kind.name, order: id, subjects: due.length });
|
|
236
|
+
};
|
|
237
|
+
return {
|
|
238
|
+
isUpkeepRow: (row) => row.kind === 'scheduled' && byChannel.has(row.channelKey),
|
|
239
|
+
render: (row, at) => kindOf(row).render(parseUpkeepOrder(row.payload).subjects, at),
|
|
240
|
+
// The check waits for child runs in the background so the owner's queue is never held.
|
|
241
|
+
onResult: (row, modelRunId) => {
|
|
242
|
+
const kind = kindOf(row);
|
|
243
|
+
const order = parseUpkeepOrder(row.payload);
|
|
244
|
+
checking.add(row.stimulusId);
|
|
245
|
+
void (async () => {
|
|
246
|
+
if (modelRunId !== null) {
|
|
247
|
+
const deadline = Date.now() + childWaitMs;
|
|
248
|
+
while (!stopped &&
|
|
249
|
+
runningChildren(options.adapter, modelRunId, options.processStartedAt) > 0 &&
|
|
250
|
+
Date.now() < deadline)
|
|
251
|
+
await sleep(5_000);
|
|
252
|
+
}
|
|
253
|
+
if (stopped)
|
|
254
|
+
return;
|
|
255
|
+
settle(kind, row.stimulusId, order, 'the order ended without the expected write or a no-update naming it');
|
|
256
|
+
})()
|
|
257
|
+
.catch((error) => {
|
|
258
|
+
// A check cut off by shutdown is not a loss: the next tick finds the subject again.
|
|
259
|
+
if (stopped)
|
|
260
|
+
return;
|
|
261
|
+
for (const subject of order.subjects)
|
|
262
|
+
options.onEvent?.({
|
|
263
|
+
type: 'lost',
|
|
264
|
+
kind: kind.name,
|
|
265
|
+
subject: subject.key,
|
|
266
|
+
attempt: 0,
|
|
267
|
+
reason: `upkeep check failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
268
|
+
});
|
|
269
|
+
})
|
|
270
|
+
.finally(() => checking.delete(row.stimulusId));
|
|
271
|
+
},
|
|
272
|
+
onLost: (row, reason) => {
|
|
273
|
+
const kind = kindOf(row);
|
|
274
|
+
settle(kind, row.stimulusId, parseUpkeepOrder(row.payload), reason);
|
|
275
|
+
},
|
|
276
|
+
tick,
|
|
277
|
+
start: () => {
|
|
278
|
+
if (timers.length > 0 || stopped)
|
|
279
|
+
return;
|
|
280
|
+
for (const kind of options.kinds) {
|
|
281
|
+
const run = () => {
|
|
282
|
+
try {
|
|
283
|
+
tick(kind.name);
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
// A scan that fails names its kind; no subject was ordered, so the next scan retries.
|
|
287
|
+
options.onEvent?.({
|
|
288
|
+
type: 'lost',
|
|
289
|
+
kind: kind.name,
|
|
290
|
+
subject: '*',
|
|
291
|
+
attempt: 0,
|
|
292
|
+
reason: `upkeep scan failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
const first = setTimeout(run, options.firstTickDelayMs ?? 60_000);
|
|
297
|
+
const every = setInterval(run, kind.intervalMs);
|
|
298
|
+
first.unref?.();
|
|
299
|
+
every.unref?.();
|
|
300
|
+
timers.push({ cancel: () => clearTimeout(first) }, { cancel: () => clearInterval(every) });
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
stop: () => {
|
|
304
|
+
stopped = true;
|
|
305
|
+
for (const timer of timers.splice(0))
|
|
306
|
+
timer.cancel();
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=upkeep-orders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upkeep-orders.js","sourceRoot":"","sources":["../../src/runtime/upkeep-orders.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { JudgmentAccess } from '@jungjaehoon/mama-core/knowledge';
|
|
2
|
+
import { type WorkListViewContext } from '../api/work-actions.js';
|
|
3
|
+
import { type UpkeepKind } from './upkeep-orders.js';
|
|
4
|
+
export declare const RECONCILE_ORDER_CHANNEL = "operator:reconcile";
|
|
5
|
+
export interface ReconcileKindOptions {
|
|
6
|
+
knowledge: WorkListViewContext['knowledge'];
|
|
7
|
+
/** The common session's access: only work it can read is chosen. */
|
|
8
|
+
access: () => JudgmentAccess;
|
|
9
|
+
timeZone: () => string;
|
|
10
|
+
/** reports.full_report_hours, read at each scan: the first after midnight is the morning one. */
|
|
11
|
+
fullReportHours: () => readonly number[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* U3, board reconcile. Once a day before the morning report the host orders two groups of
|
|
15
|
+
* subject, at most ten of each:
|
|
16
|
+
* - an open item with cited cards that moved after the item's latest revision, all its moved cards
|
|
17
|
+
* in one subject keyed by the item and its latest move, so a new move is a new subject;
|
|
18
|
+
* - an item in progress or in review whose latest source event is over 30 days old, chosen the way
|
|
19
|
+
* work.list lastEventBefore chooses it, oldest first, keyed by the item and its latest revision
|
|
20
|
+
* from outside the reconcile orders.
|
|
21
|
+
* A subject is checked by a revision on the item from the order's runs, or a work.no_update
|
|
22
|
+
* naming it. The runner keeps settled subjects past the mailbox's retention (upkeep_settled).
|
|
23
|
+
*/
|
|
24
|
+
export declare function reconcileUpkeepKind(options: ReconcileKindOptions): UpkeepKind;
|
|
25
|
+
//# sourceMappingURL=upkeep-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upkeep-reconcile.d.ts","sourceRoot":"","sources":["../../src/runtime/upkeep-reconcile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAKL,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAO5D,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,oEAAoE;IACpE,MAAM,EAAE,MAAM,cAAc,CAAC;IAC7B,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,iGAAiG;IACjG,eAAe,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;CAC1C;AAoID;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAsI7E"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RECONCILE_ORDER_CHANNEL = void 0;
|
|
4
|
+
exports.reconcileUpkeepKind = reconcileUpkeepKind;
|
|
5
|
+
const work_actions_js_1 = require("../api/work-actions.js");
|
|
6
|
+
const untrusted_content_js_1 = require("../utils/untrusted-content.js");
|
|
7
|
+
const timezone_js_1 = require("./timezone.js");
|
|
8
|
+
const upkeep_orders_js_1 = require("./upkeep-orders.js");
|
|
9
|
+
exports.RECONCILE_ORDER_CHANNEL = 'operator:reconcile';
|
|
10
|
+
const KIND = 'reconcile';
|
|
11
|
+
/** The stale step the daily page carried until U3: items in progress or in review. */
|
|
12
|
+
const STALE_STATUSES = ['in_progress', 'review'];
|
|
13
|
+
/** An item whose latest source event is older than this is stale. */
|
|
14
|
+
const STALE_AFTER_MS = 30 * 24 * 60 * 60 * 1000;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the day's order is due: from local midnight until the first full report after midnight
|
|
17
|
+
* (or the next midnight when there is none), once a local day. The hourly tick finds it due at its
|
|
18
|
+
* first run of the day; a restart in the same morning finds the order already placed, and a
|
|
19
|
+
* subject the order missed waits for the next day.
|
|
20
|
+
*/
|
|
21
|
+
function due(adapter, now, zone, hours) {
|
|
22
|
+
const day = (0, timezone_js_1.localDateKey)(now, zone);
|
|
23
|
+
const midnight = (0, timezone_js_1.epochAtLocalDateTime)(`${day}T00:00:00`, zone);
|
|
24
|
+
const after = hours.filter((hour) => hour > 0);
|
|
25
|
+
if (after.length > 0) {
|
|
26
|
+
const morning = String(Math.min(...after)).padStart(2, '0');
|
|
27
|
+
if (now >= (0, timezone_js_1.epochAtLocalDateTime)(`${day}T${morning}:00:00`, zone))
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return (adapter
|
|
31
|
+
.prepare(`SELECT 1 FROM mailbox_inputs
|
|
32
|
+
WHERE kind = 'scheduled' AND channel_key = ? AND created_at >= ? LIMIT 1`)
|
|
33
|
+
.get(exports.RECONCILE_ORDER_CHANNEL, midnight) === undefined);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The time of an item's latest revision on the source timeline: its event time, or its write time
|
|
37
|
+
* when it has none, as work.list's event spans read a revision. A backfill writes an earlier
|
|
38
|
+
* period after later revisions, so the last-written revision is not always the latest one.
|
|
39
|
+
*/
|
|
40
|
+
function latestRevisionAt(item) {
|
|
41
|
+
return Math.max(...(item.chain ?? []).map((entry) => entry.eventDatetime ?? entry.createdAt));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The card ids among the observations each item's revisions cite. Card ids are read from the
|
|
45
|
+
* observation's metadata (`cardId`), which only the Trello connector writes today; it stores the
|
|
46
|
+
* board id there for a board-level action, which names no card. Read from the item side, every
|
|
47
|
+
* join is on a key (an edge's object is the observation id).
|
|
48
|
+
*/
|
|
49
|
+
function citedCards(adapter) {
|
|
50
|
+
const rows = adapter
|
|
51
|
+
.prepare(`SELECT DISTINCT a.commitment_id AS commitmentId, o.source AS connector,
|
|
52
|
+
json_extract(o.metadata_json, '$.cardId') AS card
|
|
53
|
+
FROM commitment_assignments a
|
|
54
|
+
JOIN twin_edges e ON e.subject_kind = 'memory' AND e.subject_id = a.record_id
|
|
55
|
+
AND e.edge_type = 'derived_from' AND e.object_kind = 'observation'
|
|
56
|
+
JOIN observation_versions o ON o.observation_id = e.object_id
|
|
57
|
+
WHERE json_extract(o.metadata_json, '$.cardId') IS NOT NULL
|
|
58
|
+
AND json_extract(o.metadata_json, '$.cardId') IS NOT json_extract(o.metadata_json, '$.boardId')
|
|
59
|
+
ORDER BY commitmentId, connector, card`)
|
|
60
|
+
.all();
|
|
61
|
+
const cards = new Map();
|
|
62
|
+
for (const row of rows)
|
|
63
|
+
cards.set(row.commitmentId, [
|
|
64
|
+
...(cards.get(row.commitmentId) ?? []),
|
|
65
|
+
{ connector: row.connector, card: row.card },
|
|
66
|
+
]);
|
|
67
|
+
return cards;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Stored list moves in the attempt window, oldest first: a stored board event whose action data
|
|
71
|
+
* names the list the card went to (`data.listAfter`). A subject older than the window would count
|
|
72
|
+
* its attempts from zero again.
|
|
73
|
+
*/
|
|
74
|
+
function windowMoves(adapter, since, now) {
|
|
75
|
+
return adapter
|
|
76
|
+
.prepare(`SELECT source_connector AS connector, json_extract(metadata_json, '$.cardId') AS card,
|
|
77
|
+
source_id AS event, current_observation_id AS ref, event_datetime AS at
|
|
78
|
+
FROM connector_event_index
|
|
79
|
+
WHERE event_datetime >= ? AND event_datetime <= ?
|
|
80
|
+
AND json_extract(metadata_json, '$.data.listAfter') IS NOT NULL
|
|
81
|
+
AND json_extract(metadata_json, '$.cardId') IS NOT NULL
|
|
82
|
+
AND current_observation_id IS NOT NULL
|
|
83
|
+
ORDER BY event_datetime, source_id`)
|
|
84
|
+
.all(since, now);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Each item's latest revision not written by a reconcile order's run or its child runs. A stale
|
|
88
|
+
* subject is keyed by it: an order that keeps the item with a work.revise does not make it a new
|
|
89
|
+
* subject the next morning, while a revision from anywhere else does.
|
|
90
|
+
*/
|
|
91
|
+
function outsideRevisions(adapter, ids) {
|
|
92
|
+
if (ids.length === 0)
|
|
93
|
+
return new Map();
|
|
94
|
+
const prefix = `${(0, upkeep_orders_js_1.upkeepOrderIdPrefix)(KIND)}%`;
|
|
95
|
+
const rows = adapter
|
|
96
|
+
.prepare(`WITH order_runs AS (
|
|
97
|
+
SELECT model_run_id FROM model_runs
|
|
98
|
+
WHERE json_extract(input_refs_json, '$.sourceMessageRef') LIKE ?
|
|
99
|
+
UNION
|
|
100
|
+
SELECT c.model_run_id FROM model_runs c JOIN model_runs p ON c.parent_model_run_id = p.model_run_id
|
|
101
|
+
WHERE json_extract(p.input_refs_json, '$.sourceMessageRef') LIKE ?)
|
|
102
|
+
SELECT commitment_id AS commitmentId, MAX(revision) AS revision FROM commitment_assignments
|
|
103
|
+
WHERE commitment_id IN (${ids.map(() => '?').join(',')})
|
|
104
|
+
AND (model_run_id IS NULL OR model_run_id NOT IN (SELECT model_run_id FROM order_runs))
|
|
105
|
+
GROUP BY commitment_id`)
|
|
106
|
+
.all(prefix, prefix, ...ids);
|
|
107
|
+
return new Map(rows.map((row) => [row.commitmentId, row.revision]));
|
|
108
|
+
}
|
|
109
|
+
function title(item) {
|
|
110
|
+
return typeof item.values.title === 'string' ? item.values.title : '';
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* U3, board reconcile. Once a day before the morning report the host orders two groups of
|
|
114
|
+
* subject, at most ten of each:
|
|
115
|
+
* - an open item with cited cards that moved after the item's latest revision, all its moved cards
|
|
116
|
+
* in one subject keyed by the item and its latest move, so a new move is a new subject;
|
|
117
|
+
* - an item in progress or in review whose latest source event is over 30 days old, chosen the way
|
|
118
|
+
* work.list lastEventBefore chooses it, oldest first, keyed by the item and its latest revision
|
|
119
|
+
* from outside the reconcile orders.
|
|
120
|
+
* A subject is checked by a revision on the item from the order's runs, or a work.no_update
|
|
121
|
+
* naming it. The runner keeps settled subjects past the mailbox's retention (upkeep_settled).
|
|
122
|
+
*/
|
|
123
|
+
function reconcileUpkeepKind(options) {
|
|
124
|
+
return {
|
|
125
|
+
name: KIND,
|
|
126
|
+
channel: exports.RECONCILE_ORDER_CHANNEL,
|
|
127
|
+
intervalMs: 60 * 60 * 1000,
|
|
128
|
+
maxPerOrder: 10,
|
|
129
|
+
group: (subject) => subject.group,
|
|
130
|
+
scan: (adapter, now, page) => {
|
|
131
|
+
const zone = options.timeZone();
|
|
132
|
+
if (!due(adapter, now, zone, options.fullReportHours()))
|
|
133
|
+
return [];
|
|
134
|
+
const ledger = (0, work_actions_js_1.workListLedger)({ knowledge: options.knowledge, access: options.access(), timeZone: zone, now: () => now }, { status: STALE_STATUSES, lastEventBefore: now - STALE_AFTER_MS });
|
|
135
|
+
const open = new Map(ledger
|
|
136
|
+
.filter((entry) => work_actions_js_1.OPEN_WORK_STATUSES.includes(entry.status))
|
|
137
|
+
.map((entry) => [entry.item.commitmentId, entry]));
|
|
138
|
+
const cards = citedCards(adapter);
|
|
139
|
+
const citing = new Map();
|
|
140
|
+
for (const [commitmentId, list] of cards)
|
|
141
|
+
for (const card of list) {
|
|
142
|
+
const at = `${card.connector}\n${card.card}`;
|
|
143
|
+
citing.set(at, [...(citing.get(at) ?? []), commitmentId]);
|
|
144
|
+
}
|
|
145
|
+
// Per item, each cited card's latest move that the item's revisions have not caught up with.
|
|
146
|
+
const movesOf = new Map();
|
|
147
|
+
for (const move of windowMoves(adapter, now - upkeep_orders_js_1.UPKEEP_WINDOW_MS, now))
|
|
148
|
+
for (const commitmentId of citing.get(`${move.connector}\n${move.card}`) ?? []) {
|
|
149
|
+
const entry = open.get(commitmentId);
|
|
150
|
+
if (!entry || move.at <= latestRevisionAt(entry.item))
|
|
151
|
+
continue;
|
|
152
|
+
const byCard = movesOf.get(commitmentId) ?? new Map();
|
|
153
|
+
byCard.set(`${move.connector}\n${move.card}`, move);
|
|
154
|
+
movesOf.set(commitmentId, byCard);
|
|
155
|
+
}
|
|
156
|
+
const moved = [...movesOf].map(([commitmentId, byCard]) => {
|
|
157
|
+
const entry = open.get(commitmentId);
|
|
158
|
+
const moves = [...byCard.values()].sort((a, b) => a.at - b.at);
|
|
159
|
+
return {
|
|
160
|
+
key: `move:${commitmentId}:${moves.at(-1).connector}:${moves.at(-1).event}`,
|
|
161
|
+
group: 'move',
|
|
162
|
+
commitmentId,
|
|
163
|
+
title: title(entry.item),
|
|
164
|
+
status: entry.status,
|
|
165
|
+
lastEventAt: null,
|
|
166
|
+
cards: [],
|
|
167
|
+
moves,
|
|
168
|
+
revisedAt: latestRevisionAt(entry.item),
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
moved.sort((a, b) => a.moves.at(-1).at - b.moves.at(-1).at || a.key.localeCompare(b.key));
|
|
172
|
+
const staleEntries = ledger
|
|
173
|
+
.filter((entry) => entry.stale)
|
|
174
|
+
.sort((a, b) => a.lastEvent - b.lastEvent || a.item.commitmentId.localeCompare(b.item.commitmentId));
|
|
175
|
+
const revisions = outsideRevisions(adapter, staleEntries.map((entry) => entry.item.commitmentId));
|
|
176
|
+
const stale = staleEntries.map((entry) => ({
|
|
177
|
+
// An item the orders themselves created has no outside revision: revision 0.
|
|
178
|
+
key: `stale:${entry.item.commitmentId}:${revisions.get(entry.item.commitmentId) ?? 0}`,
|
|
179
|
+
group: 'stale',
|
|
180
|
+
commitmentId: entry.item.commitmentId,
|
|
181
|
+
title: title(entry.item),
|
|
182
|
+
status: entry.status,
|
|
183
|
+
lastEventAt: entry.lastEvent,
|
|
184
|
+
cards: cards.get(entry.item.commitmentId) ?? [],
|
|
185
|
+
moves: [],
|
|
186
|
+
revisedAt: null,
|
|
187
|
+
}));
|
|
188
|
+
return [...moved, ...stale].slice(page * upkeep_orders_js_1.UPKEEP_SCAN_PAGE, (page + 1) * upkeep_orders_js_1.UPKEEP_SCAN_PAGE);
|
|
189
|
+
},
|
|
190
|
+
checked: (adapter, subject, runIds) => {
|
|
191
|
+
const { commitmentId } = subject;
|
|
192
|
+
if (runIds.length === 0)
|
|
193
|
+
return false;
|
|
194
|
+
const revised = adapter
|
|
195
|
+
.prepare(`SELECT 1 FROM commitment_assignments
|
|
196
|
+
WHERE commitment_id = ? AND model_run_id IN (${runIds.map(() => '?').join(',')})
|
|
197
|
+
LIMIT 1`)
|
|
198
|
+
.get(commitmentId, ...runIds) !== undefined;
|
|
199
|
+
return (revised ||
|
|
200
|
+
(0, upkeep_orders_js_1.noUpdateCites)(adapter, runIds, { field: 'commitmentIds', values: [commitmentId] }));
|
|
201
|
+
},
|
|
202
|
+
render: (subjects, now) => {
|
|
203
|
+
const zone = options.timeZone();
|
|
204
|
+
const all = subjects;
|
|
205
|
+
const at = (ms) => (0, timezone_js_1.localNow)(ms, zone);
|
|
206
|
+
const lines = all.map((subject) => subject.group === 'move'
|
|
207
|
+
? `- moved ${subject.commitmentId} (${subject.status}), after the item's latest revision ${at(subject.revisedAt)}: ${subject.moves
|
|
208
|
+
.map((move) => `card ${move.card} (${move.connector}) moved ${at(move.at)}, event ${move.ref}`)
|
|
209
|
+
.join('; ')}`
|
|
210
|
+
: `- stale ${subject.commitmentId} (${subject.status}): latest source event ${at(subject.lastEventAt)}; ${subject.cards.length === 0
|
|
211
|
+
? 'cites no card'
|
|
212
|
+
: `cards ${subject.cards.map((card) => `${card.card} (${card.connector})`).join(', ')}`}`);
|
|
213
|
+
// Titles come from stored work, which sources can shape: they are data, never instructions.
|
|
214
|
+
const titles = all.map((subject) => `${subject.commitmentId}: ${subject.title.replace(/\s+/g, ' ').slice(0, 200)}`);
|
|
215
|
+
return [
|
|
216
|
+
`[upkeep_reconcile] ${all.length} work item${all.length === 1 ? '' : 's'} to reconcile with the board`,
|
|
217
|
+
`Current time: ${at(now.getTime())} (${zone})`,
|
|
218
|
+
'Each item below may no longer match its source: a card it cites moved after its latest revision, or it is still in progress or in review with no source event in over 30 days (work.list lastEventBefore, not changedBefore: a backfill or correction rewrote many items later without a new event). Settle each one, so the ledger matches the board:',
|
|
219
|
+
"1. Read each item with work.list view=detail with ids (up to 4 per call), and its last originals with source.read (a moved item's move events first).",
|
|
220
|
+
'2. Read each listed card live with its connector: trello.read view=card id=<card id>. An item that cites no card but is board work: find its card with trello.read view=search (by its title), and say so when none exists. A stored move only chose the item; the live card decides. When the live card differs from its stored events, the collection has a gap: say so in the reason.',
|
|
221
|
+
'3. Close, cancel, change or keep each item: work.revise with what changed and why, linking what it rests on with derived_from; or, when it stays as it is, work.no_update with commitmentIds naming it and why it stays.',
|
|
222
|
+
'4. The order is checked when it ends: each item needs step 3. Correct a refused write (help gives its contract) and write it again.',
|
|
223
|
+
'5. Reply exactly [ack].',
|
|
224
|
+
'Items, at most ten moved and ten stale a day, stale oldest first; the rest come in the next days:',
|
|
225
|
+
...lines,
|
|
226
|
+
(0, untrusted_content_js_1.wrapUntrustedContent)('work_titles', titles.join('\n')),
|
|
227
|
+
].join('\n');
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=upkeep-reconcile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upkeep-reconcile.js","sourceRoot":"","sources":["../../src/runtime/upkeep-reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type UpkeepKind } from './upkeep-orders.js';
|
|
2
|
+
export declare const WRITEBACK_ORDER_CHANNEL = "operator:writeback";
|
|
3
|
+
export interface WritebackKindOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The non-chat connectors the common session reads in full (ownerAccess.connectorWideRead).
|
|
6
|
+
* Their observations carry no memory scope, and the owner read path admits them by connector
|
|
7
|
+
* (observations.ts isObservationVisibilityRowVisible), so the same list decides they are common.
|
|
8
|
+
*/
|
|
9
|
+
wideReadConnectors: () => readonly string[];
|
|
10
|
+
/** The common session's principal: its question turns qualify, and its chat scope is common. */
|
|
11
|
+
ownerPrincipalId: string;
|
|
12
|
+
timeZone: () => string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* U2, write-back orders. A subject is one question turn (a committed owner_message run of the
|
|
16
|
+
* common session or an owner-role principal) that read common-scope sources and recorded nothing
|
|
17
|
+
* from them. The order carries only common-scope handles; the question text is never carried. It
|
|
18
|
+
* is checked when the order's run writes a revision or a fact/lesson citing one of the handles, or
|
|
19
|
+
* declares work.no_update naming them.
|
|
20
|
+
*/
|
|
21
|
+
export declare function writebackUpkeepKind(options: WritebackKindOptions): UpkeepKind;
|
|
22
|
+
//# sourceMappingURL=upkeep-writeback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upkeep-writeback.d.ts","sourceRoot":"","sources":["../../src/runtime/upkeep-writeback.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAK5D,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IAC5C,gGAAgG;IAChG,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,MAAM,CAAC;CACxB;AAgGD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,UAAU,CA0I7E"}
|