botmux 2.33.0 → 2.33.1
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/README.en.md +12 -1
- package/README.md +45 -1
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +11 -0
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/cli/bots-list-output.d.ts +21 -0
- package/dist/cli/bots-list-output.d.ts.map +1 -0
- package/dist/cli/bots-list-output.js +23 -0
- package/dist/cli/bots-list-output.js.map +1 -0
- package/dist/cli/workflow.d.ts +13 -0
- package/dist/cli/workflow.d.ts.map +1 -0
- package/dist/cli/workflow.js +781 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/cli.js +69 -14
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +211 -4
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/session-manager.d.ts +6 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +22 -12
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/worker-pool.d.ts +13 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +100 -6
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +3 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +884 -3
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/auth.d.ts +36 -0
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +22 -0
- package/dist/dashboard/auth.js.map +1 -1
- package/dist/dashboard/web/app.js +20 -1
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +356 -0
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/workflow-catalog.d.ts +2 -0
- package/dist/dashboard/web/workflow-catalog.d.ts.map +1 -0
- package/dist/dashboard/web/workflow-catalog.js +323 -0
- package/dist/dashboard/web/workflow-catalog.js.map +1 -0
- package/dist/dashboard/web/workflows.d.ts +2 -0
- package/dist/dashboard/web/workflows.d.ts.map +1 -0
- package/dist/dashboard/web/workflows.js +1618 -0
- package/dist/dashboard/web/workflows.js.map +1 -0
- package/dist/dashboard/workflow-api.d.ts +23 -0
- package/dist/dashboard/workflow-api.d.ts.map +1 -0
- package/dist/dashboard/workflow-api.js +463 -0
- package/dist/dashboard/workflow-api.js.map +1 -0
- package/dist/dashboard-web/app.js +494 -199
- package/dist/dashboard-web/index.html +1 -0
- package/dist/dashboard-web/style.css +160 -6
- package/dist/dashboard-web/terminal-replay.html +227 -0
- package/dist/dashboard.js +29 -12
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +12 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +12 -0
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +3 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +27 -1
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +19 -2
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +21 -2
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/workflow-card-handler.d.ts +50 -0
- package/dist/im/lark/workflow-card-handler.d.ts.map +1 -0
- package/dist/im/lark/workflow-card-handler.js +152 -0
- package/dist/im/lark/workflow-card-handler.js.map +1 -0
- package/dist/im/lark/workflow-cards.d.ts +46 -0
- package/dist/im/lark/workflow-cards.d.ts.map +1 -0
- package/dist/im/lark/workflow-cards.js +226 -0
- package/dist/im/lark/workflow-cards.js.map +1 -0
- package/dist/im/lark/workflow-progress-card.d.ts +76 -0
- package/dist/im/lark/workflow-progress-card.d.ts.map +1 -0
- package/dist/im/lark/workflow-progress-card.js +279 -0
- package/dist/im/lark/workflow-progress-card.js.map +1 -0
- package/dist/im/lark/workflow-slash-command.d.ts +92 -0
- package/dist/im/lark/workflow-slash-command.d.ts.map +1 -0
- package/dist/im/lark/workflow-slash-command.js +185 -0
- package/dist/im/lark/workflow-slash-command.js.map +1 -0
- package/dist/services/group-creator.d.ts.map +1 -1
- package/dist/services/group-creator.js +17 -4
- package/dist/services/group-creator.js.map +1 -1
- package/dist/services/groups-store.d.ts +11 -0
- package/dist/services/groups-store.d.ts.map +1 -1
- package/dist/services/groups-store.js +26 -0
- package/dist/services/groups-store.js.map +1 -1
- package/dist/services/jsonl-cursor.d.ts +12 -0
- package/dist/services/jsonl-cursor.d.ts.map +1 -0
- package/dist/services/jsonl-cursor.js +45 -0
- package/dist/services/jsonl-cursor.js.map +1 -0
- package/dist/services/schedule-store.d.ts +35 -0
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +108 -1
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +399 -0
- package/dist/skills/definitions.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/cli-usage-limit.d.ts.map +1 -1
- package/dist/utils/cli-usage-limit.js +4 -0
- package/dist/utils/cli-usage-limit.js.map +1 -1
- package/dist/worker.js +118 -14
- package/dist/worker.js.map +1 -1
- package/dist/workflows/attempt-resume.d.ts +114 -0
- package/dist/workflows/attempt-resume.d.ts.map +1 -0
- package/dist/workflows/attempt-resume.js +385 -0
- package/dist/workflows/attempt-resume.js.map +1 -0
- package/dist/workflows/attempt-terminal.d.ts +21 -0
- package/dist/workflows/attempt-terminal.d.ts.map +1 -0
- package/dist/workflows/attempt-terminal.js +7 -0
- package/dist/workflows/attempt-terminal.js.map +1 -0
- package/dist/workflows/blob.d.ts +27 -0
- package/dist/workflows/blob.d.ts.map +1 -0
- package/dist/workflows/blob.js +39 -0
- package/dist/workflows/blob.js.map +1 -0
- package/dist/workflows/cancel-run.d.ts +45 -0
- package/dist/workflows/cancel-run.d.ts.map +1 -0
- package/dist/workflows/cancel-run.js +99 -0
- package/dist/workflows/cancel-run.js.map +1 -0
- package/dist/workflows/cancel.d.ts +111 -0
- package/dist/workflows/cancel.d.ts.map +1 -0
- package/dist/workflows/cancel.js +120 -0
- package/dist/workflows/cancel.js.map +1 -0
- package/dist/workflows/catalog.d.ts +60 -0
- package/dist/workflows/catalog.d.ts.map +1 -0
- package/dist/workflows/catalog.js +119 -0
- package/dist/workflows/catalog.js.map +1 -0
- package/dist/workflows/cold-attach.d.ts +30 -0
- package/dist/workflows/cold-attach.d.ts.map +1 -0
- package/dist/workflows/cold-attach.js +40 -0
- package/dist/workflows/cold-attach.js.map +1 -0
- package/dist/workflows/cold-scan.d.ts +21 -0
- package/dist/workflows/cold-scan.d.ts.map +1 -0
- package/dist/workflows/cold-scan.js +70 -0
- package/dist/workflows/cold-scan.js.map +1 -0
- package/dist/workflows/daemon-spawn.d.ts +117 -0
- package/dist/workflows/daemon-spawn.d.ts.map +1 -0
- package/dist/workflows/daemon-spawn.js +551 -0
- package/dist/workflows/daemon-spawn.js.map +1 -0
- package/dist/workflows/definition.d.ts +1309 -0
- package/dist/workflows/definition.d.ts.map +1 -0
- package/dist/workflows/definition.js +334 -0
- package/dist/workflows/definition.js.map +1 -0
- package/dist/workflows/effect-input.d.ts +4 -0
- package/dist/workflows/effect-input.d.ts.map +1 -0
- package/dist/workflows/effect-input.js +18 -0
- package/dist/workflows/effect-input.js.map +1 -0
- package/dist/workflows/events/append.d.ts +77 -0
- package/dist/workflows/events/append.d.ts.map +1 -0
- package/dist/workflows/events/append.js +214 -0
- package/dist/workflows/events/append.js.map +1 -0
- package/dist/workflows/events/idempotency.d.ts +77 -0
- package/dist/workflows/events/idempotency.d.ts.map +1 -0
- package/dist/workflows/events/idempotency.js +116 -0
- package/dist/workflows/events/idempotency.js.map +1 -0
- package/dist/workflows/events/index.d.ts +7 -0
- package/dist/workflows/events/index.d.ts.map +1 -0
- package/dist/workflows/events/index.js +7 -0
- package/dist/workflows/events/index.js.map +1 -0
- package/dist/workflows/events/payloads.d.ts +917 -0
- package/dist/workflows/events/payloads.d.ts.map +1 -0
- package/dist/workflows/events/payloads.js +337 -0
- package/dist/workflows/events/payloads.js.map +1 -0
- package/dist/workflows/events/replay.d.ts +238 -0
- package/dist/workflows/events/replay.d.ts.map +1 -0
- package/dist/workflows/events/replay.js +608 -0
- package/dist/workflows/events/replay.js.map +1 -0
- package/dist/workflows/events/schema.d.ts +5242 -0
- package/dist/workflows/events/schema.d.ts.map +1 -0
- package/dist/workflows/events/schema.js +295 -0
- package/dist/workflows/events/schema.js.map +1 -0
- package/dist/workflows/events/types.d.ts +34 -0
- package/dist/workflows/events/types.d.ts.map +1 -0
- package/dist/workflows/events/types.js +2 -0
- package/dist/workflows/events/types.js.map +1 -0
- package/dist/workflows/fanout.d.ts +36 -0
- package/dist/workflows/fanout.d.ts.map +1 -0
- package/dist/workflows/fanout.js +114 -0
- package/dist/workflows/fanout.js.map +1 -0
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts +41 -0
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/botmux-schedule.js +121 -0
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -0
- package/dist/workflows/hostExecutors/feishu-im.d.ts +12 -0
- package/dist/workflows/hostExecutors/feishu-im.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/feishu-im.js +49 -0
- package/dist/workflows/hostExecutors/feishu-im.js.map +1 -0
- package/dist/workflows/hostExecutors/feishu-reply.d.ts +24 -0
- package/dist/workflows/hostExecutors/feishu-reply.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/feishu-reply.js +88 -0
- package/dist/workflows/hostExecutors/feishu-reply.js.map +1 -0
- package/dist/workflows/hostExecutors/feishu-send.d.ts +23 -0
- package/dist/workflows/hostExecutors/feishu-send.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/feishu-send.js +124 -0
- package/dist/workflows/hostExecutors/feishu-send.js.map +1 -0
- package/dist/workflows/hostExecutors/index.d.ts +8 -0
- package/dist/workflows/hostExecutors/index.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/index.js +8 -0
- package/dist/workflows/hostExecutors/index.js.map +1 -0
- package/dist/workflows/hostExecutors/protocol.d.ts +42 -0
- package/dist/workflows/hostExecutors/protocol.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/protocol.js +181 -0
- package/dist/workflows/hostExecutors/protocol.js.map +1 -0
- package/dist/workflows/hostExecutors/registry.d.ts +10 -0
- package/dist/workflows/hostExecutors/registry.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/registry.js +36 -0
- package/dist/workflows/hostExecutors/registry.js.map +1 -0
- package/dist/workflows/hostExecutors/types.d.ts +78 -0
- package/dist/workflows/hostExecutors/types.d.ts.map +1 -0
- package/dist/workflows/hostExecutors/types.js +2 -0
- package/dist/workflows/hostExecutors/types.js.map +1 -0
- package/dist/workflows/loader.d.ts +16 -0
- package/dist/workflows/loader.d.ts.map +1 -0
- package/dist/workflows/loader.js +56 -0
- package/dist/workflows/loader.js.map +1 -0
- package/dist/workflows/loop.d.ts +50 -0
- package/dist/workflows/loop.d.ts.map +1 -0
- package/dist/workflows/loop.js +350 -0
- package/dist/workflows/loop.js.map +1 -0
- package/dist/workflows/ops-projection.d.ts +168 -0
- package/dist/workflows/ops-projection.d.ts.map +1 -0
- package/dist/workflows/ops-projection.js +707 -0
- package/dist/workflows/ops-projection.js.map +1 -0
- package/dist/workflows/orchestrator.d.ts +107 -0
- package/dist/workflows/orchestrator.d.ts.map +1 -0
- package/dist/workflows/orchestrator.js +197 -0
- package/dist/workflows/orchestrator.js.map +1 -0
- package/dist/workflows/output-binding.d.ts +70 -0
- package/dist/workflows/output-binding.d.ts.map +1 -0
- package/dist/workflows/output-binding.js +265 -0
- package/dist/workflows/output-binding.js.map +1 -0
- package/dist/workflows/params.d.ts +61 -0
- package/dist/workflows/params.d.ts.map +1 -0
- package/dist/workflows/params.js +195 -0
- package/dist/workflows/params.js.map +1 -0
- package/dist/workflows/resume.d.ts +263 -0
- package/dist/workflows/resume.d.ts.map +1 -0
- package/dist/workflows/resume.js +808 -0
- package/dist/workflows/resume.js.map +1 -0
- package/dist/workflows/run-id.d.ts +2 -0
- package/dist/workflows/run-id.d.ts.map +1 -0
- package/dist/workflows/run-id.js +7 -0
- package/dist/workflows/run-id.js.map +1 -0
- package/dist/workflows/run-init.d.ts +48 -0
- package/dist/workflows/run-init.d.ts.map +1 -0
- package/dist/workflows/run-init.js +99 -0
- package/dist/workflows/run-init.js.map +1 -0
- package/dist/workflows/runs-dir.d.ts +4 -0
- package/dist/workflows/runs-dir.d.ts.map +1 -0
- package/dist/workflows/runs-dir.js +15 -0
- package/dist/workflows/runs-dir.js.map +1 -0
- package/dist/workflows/runtime.d.ts +211 -0
- package/dist/workflows/runtime.d.ts.map +1 -0
- package/dist/workflows/runtime.js +594 -0
- package/dist/workflows/runtime.js.map +1 -0
- package/dist/workflows/spawn-bot.d.ts +165 -0
- package/dist/workflows/spawn-bot.d.ts.map +1 -0
- package/dist/workflows/spawn-bot.js +215 -0
- package/dist/workflows/spawn-bot.js.map +1 -0
- package/dist/workflows/system.d.ts +49 -0
- package/dist/workflows/system.d.ts.map +1 -0
- package/dist/workflows/system.js +48 -0
- package/dist/workflows/system.js.map +1 -0
- package/dist/workflows/trigger-run.d.ts +70 -0
- package/dist/workflows/trigger-run.d.ts.map +1 -0
- package/dist/workflows/trigger-run.js +88 -0
- package/dist/workflows/trigger-run.js.map +1 -0
- package/dist/workflows/wait.d.ts +120 -0
- package/dist/workflows/wait.d.ts.map +1 -0
- package/dist/workflows/wait.js +181 -0
- package/dist/workflows/wait.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator loop runner.
|
|
3
|
+
*
|
|
4
|
+
* Drives `decideNextActions → dispatch* → replay → repeat` until either
|
|
5
|
+
* the run reaches a terminal status or the orchestrator returns no
|
|
6
|
+
* actions (which on a non-terminal run means we're paused on an open
|
|
7
|
+
* `waitCreated`).
|
|
8
|
+
*
|
|
9
|
+
* Per-tick dispatch model (v0.1.3+):
|
|
10
|
+
* 1. Split ready actions into `dispatch*` (gate / work) and `complete*`
|
|
11
|
+
* (settle node / run). The two phases have different concurrency
|
|
12
|
+
* semantics — dispatch can race, settles must not.
|
|
13
|
+
* 2. Within the dispatch phase: cap concurrency by `defaults.maxConcurrency`
|
|
14
|
+
* (default 4) and enforce per-bot serialization (one in-flight subagent
|
|
15
|
+
* per bot within a tick). Deferred dispatches just stay in the next
|
|
16
|
+
* tick's ready set; no separate scheduling state needed.
|
|
17
|
+
* 3. Run dispatches via `Promise.allSettled` so a sibling throwing doesn't
|
|
18
|
+
* starve the rest. After settle, replay fresh and patch any non-terminal
|
|
19
|
+
* activity with an `activityFailed` (errorClass=fatal, errorCode=
|
|
20
|
+
* WorkerCrashed; closest fit in the existing enum — see payloads.ts) —
|
|
21
|
+
* but NEVER write a second terminal if the dispatch already wrote one
|
|
22
|
+
* before throwing. If a dispatch throws BEFORE writing `attemptCreated`,
|
|
23
|
+
* we have no attempt to attach the failure to; the tick returns
|
|
24
|
+
* `no-progress` rather than re-dispatching the same action forever.
|
|
25
|
+
* 4. Settle actions (`completeNode*` / `completeRun*`) run sequentially so
|
|
26
|
+
* event log order stays readable and `completeRun*` is never racy.
|
|
27
|
+
*
|
|
28
|
+
* Re-entry: external events (e.g. `waitResolved` written by the lark
|
|
29
|
+
* card handler) don't drive this loop — the caller is responsible for
|
|
30
|
+
* invoking `runLoop` again when it knows new events have landed. See
|
|
31
|
+
* `src/workflows/fanout.ts` (Slice D-4) for the daemon-side trigger.
|
|
32
|
+
*/
|
|
33
|
+
import { decideNextActions, } from './orchestrator.js';
|
|
34
|
+
import { replay } from './events/replay.js';
|
|
35
|
+
import { resume } from './resume.js';
|
|
36
|
+
import { completeNodeFailed, completeNodeSucceeded, completeRunFailed, completeRunSucceeded, dispatchGate, dispatchWork, } from './runtime.js';
|
|
37
|
+
import { logger } from '../utils/logger.js';
|
|
38
|
+
const DEFAULT_MAX_CONCURRENCY = 4;
|
|
39
|
+
const CANCEL_OBSERVER_INTERVAL_MS = 200;
|
|
40
|
+
export async function runLoop(ctx, options = {}) {
|
|
41
|
+
const maxTicks = options.maxTicks ?? 1000;
|
|
42
|
+
let ticks = 0;
|
|
43
|
+
let snapshot = replay(await ctx.log.readAll());
|
|
44
|
+
while (ticks < maxTicks) {
|
|
45
|
+
if (isTerminalStatus(snapshot)) {
|
|
46
|
+
return { reason: 'terminal', ticks, lastSnapshot: snapshot };
|
|
47
|
+
}
|
|
48
|
+
// ─── Recovery phase ────────────────────────────────────────────────
|
|
49
|
+
// Side-effect family contract: `effectAttempted` written, terminal
|
|
50
|
+
// missing. Run resume() with the registered reconcilers to close
|
|
51
|
+
// those out before any forward decision. Without reconcilers we
|
|
52
|
+
// CANNOT silently proceed — the dangling effect represents real
|
|
53
|
+
// external state we'd be ignoring.
|
|
54
|
+
const danglingCancelSet = new Set(snapshot.danglingCancels);
|
|
55
|
+
const danglingRecoverableActivities = snapshot.danglingActivities.filter((activityId) => !snapshot.danglingWaits.includes(activityId) || danglingCancelSet.has(activityId));
|
|
56
|
+
if (snapshot.danglingEffectAttempted.length > 0 ||
|
|
57
|
+
danglingRecoverableActivities.length > 0) {
|
|
58
|
+
if (snapshot.danglingEffectAttempted.length > 0 &&
|
|
59
|
+
(!ctx.reconcilers || ctx.reconcilers.size === 0)) {
|
|
60
|
+
logger.warn?.(`runLoop(${ctx.log.runId}): danglingEffectAttempted=${snapshot.danglingEffectAttempted.length} but ctx.reconcilers missing/empty — stopping with no-progress.`);
|
|
61
|
+
return { reason: 'no-progress', ticks, lastSnapshot: snapshot };
|
|
62
|
+
}
|
|
63
|
+
const before = new Set(snapshot.danglingEffectAttempted);
|
|
64
|
+
const beforeRecoverable = new Set(danglingRecoverableActivities);
|
|
65
|
+
await resume({
|
|
66
|
+
log: ctx.log,
|
|
67
|
+
runId: ctx.log.runId,
|
|
68
|
+
daemonId: 'runloop',
|
|
69
|
+
reconcilers: ctx.reconcilers ?? new Map(),
|
|
70
|
+
loadEffectInput: ctx.loadEffectInput,
|
|
71
|
+
now: ctx.now,
|
|
72
|
+
});
|
|
73
|
+
snapshot = replay(await ctx.log.readAll());
|
|
74
|
+
// If the same set of dangling effects survived recovery, the
|
|
75
|
+
// reconcilers concluded manual/transient. Don't dispatch new work
|
|
76
|
+
// — operator needs to look at the failed reconcile evidence.
|
|
77
|
+
const stillDangling = snapshot.danglingEffectAttempted.filter((a) => before.has(a));
|
|
78
|
+
if (before.size > 0 && stillDangling.length === before.size) {
|
|
79
|
+
logger.warn?.(`runLoop(${ctx.log.runId}): resume() made no progress on ${stillDangling.length} dangling effect(s) — stopping with no-progress.`);
|
|
80
|
+
return { reason: 'no-progress', ticks, lastSnapshot: snapshot };
|
|
81
|
+
}
|
|
82
|
+
if (before.size === 0 && beforeRecoverable.size > 0) {
|
|
83
|
+
const afterCancelSet = new Set(snapshot.danglingCancels);
|
|
84
|
+
const stillRecoverable = snapshot.danglingActivities.filter((activityId) => beforeRecoverable.has(activityId) &&
|
|
85
|
+
(!snapshot.danglingWaits.includes(activityId) || afterCancelSet.has(activityId)));
|
|
86
|
+
if (stillRecoverable.length === beforeRecoverable.size) {
|
|
87
|
+
logger.warn?.(`runLoop(${ctx.log.runId}): resume() made no progress on ${stillRecoverable.length} dangling non-effect activity/activities — stopping with no-progress.`);
|
|
88
|
+
return { reason: 'no-progress', ticks, lastSnapshot: snapshot };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Progress made; re-enter loop with fresh snapshot before
|
|
92
|
+
// computing actions.
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const actions = decideNextActions(snapshot, ctx.def);
|
|
96
|
+
if (actions.length === 0) {
|
|
97
|
+
// Empty actions on a non-terminal run: must be waiting on a
|
|
98
|
+
// human gate or open wait. Distinguish from "stuck" (no waits
|
|
99
|
+
// but also no actions) via danglingWaits — at least one open.
|
|
100
|
+
const stopped = snapshot.danglingWaits.length > 0 ? 'awaiting-wait' : 'no-progress';
|
|
101
|
+
return { reason: stopped, ticks, lastSnapshot: snapshot };
|
|
102
|
+
}
|
|
103
|
+
const maxConcurrency = ctx.def.defaults?.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY;
|
|
104
|
+
const { dispatches, settles } = partitionActions(actions);
|
|
105
|
+
const { selected, deferred } = selectDispatchBatch(dispatches, maxConcurrency);
|
|
106
|
+
let anyUnpatchable = false;
|
|
107
|
+
if (selected.length > 0) {
|
|
108
|
+
// v0.1.4-a: per-dispatch AbortControllers so out-of-band callers
|
|
109
|
+
// (cancelWorkflowRunOnDaemon → ctx.registerAborters) can fire abort
|
|
110
|
+
// before the EventLog polling fallback notices `cancelRequested`.
|
|
111
|
+
const aborters = new Map();
|
|
112
|
+
for (const a of selected)
|
|
113
|
+
aborters.set(a.activityId, new AbortController());
|
|
114
|
+
ctx.registerAborters?.(aborters);
|
|
115
|
+
const stopObserver = startCancelObserver(ctx, aborters);
|
|
116
|
+
try {
|
|
117
|
+
const settled = await Promise.allSettled(selected.map((a) => runDispatch(ctx, a, snapshot, aborters.get(a.activityId).signal)));
|
|
118
|
+
// Replay once before patching infrastructure failures so we don't
|
|
119
|
+
// double-terminal an activity whose dispatch wrote `activityFailed`
|
|
120
|
+
// and then threw on a follow-up step.
|
|
121
|
+
const post = replay(await ctx.log.readAll());
|
|
122
|
+
for (let i = 0; i < settled.length; i++) {
|
|
123
|
+
const result = settled[i];
|
|
124
|
+
if (result.status === 'fulfilled')
|
|
125
|
+
continue;
|
|
126
|
+
const action = selected[i];
|
|
127
|
+
const outcome = await maybePatchInfrastructureFailure(ctx, post, action, result.reason);
|
|
128
|
+
if (outcome === 'unpatchable') {
|
|
129
|
+
// Dispatch blew up before writing `attemptCreated`, so there's
|
|
130
|
+
// no per-attempt failure we can pin the error to. Re-running
|
|
131
|
+
// the loop would re-emit the same dispatch and infinite-loop
|
|
132
|
+
// until maxTicks. Stop here so the operator can diagnose
|
|
133
|
+
// (e.g. log-write failure, blob-write OOM). Sibling dispatches
|
|
134
|
+
// that DID write events still keep their events.
|
|
135
|
+
anyUnpatchable = true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
stopObserver();
|
|
141
|
+
ctx.registerAborters?.(undefined);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Settle phase: sequential so event log stays in causal order and
|
|
145
|
+
// `completeRun*` is never racy with a sibling complete.
|
|
146
|
+
for (const action of settles) {
|
|
147
|
+
try {
|
|
148
|
+
await runSettle(ctx, action);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
logger.warn?.(`runLoop(${ctx.log.runId}): settle action ${action.kind} threw — stopping tick: ${err instanceof Error ? err.message : String(err)}`);
|
|
152
|
+
snapshot = replay(await ctx.log.readAll());
|
|
153
|
+
return { reason: 'no-progress', ticks, lastSnapshot: snapshot };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
snapshot = replay(await ctx.log.readAll());
|
|
157
|
+
ticks++;
|
|
158
|
+
if (anyUnpatchable) {
|
|
159
|
+
// See the `anyUnpatchable = true` branch above. We deliberately
|
|
160
|
+
// return after applying any sibling settle actions so the operator
|
|
161
|
+
// sees the snapshot in its progressed-as-far-as-possible state.
|
|
162
|
+
return { reason: 'no-progress', ticks, lastSnapshot: snapshot };
|
|
163
|
+
}
|
|
164
|
+
// Defensive: dispatches all got deferred AND no settles ran — we'd
|
|
165
|
+
// loop forever with nothing to do. Per-bot serialization shouldn't
|
|
166
|
+
// hit this in practice because decideNextActions only emits ready
|
|
167
|
+
// actions, but treat as no-progress to be safe.
|
|
168
|
+
if (selected.length === 0 && settles.length === 0 && deferred > 0) {
|
|
169
|
+
logger.warn?.(`runLoop(${ctx.log.runId}): all ${deferred} dispatches deferred and no settle work — stopping with no-progress.`);
|
|
170
|
+
return { reason: 'no-progress', ticks, lastSnapshot: snapshot };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Edge case: the tick that hit maxTicks may itself have written the
|
|
174
|
+
// run terminal. Prefer the precise reason over the safety-cap reason.
|
|
175
|
+
if (isTerminalStatus(snapshot)) {
|
|
176
|
+
return { reason: 'terminal', ticks, lastSnapshot: snapshot };
|
|
177
|
+
}
|
|
178
|
+
return { reason: 'max-ticks', ticks, lastSnapshot: snapshot };
|
|
179
|
+
}
|
|
180
|
+
function isTerminalStatus(snapshot) {
|
|
181
|
+
return (snapshot.run.status === 'succeeded' ||
|
|
182
|
+
snapshot.run.status === 'failed' ||
|
|
183
|
+
snapshot.run.status === 'cancelled');
|
|
184
|
+
}
|
|
185
|
+
function partitionActions(actions) {
|
|
186
|
+
const dispatches = [];
|
|
187
|
+
const settles = [];
|
|
188
|
+
for (const a of actions) {
|
|
189
|
+
if (a.kind === 'dispatchGate' || a.kind === 'dispatchWork')
|
|
190
|
+
dispatches.push(a);
|
|
191
|
+
else
|
|
192
|
+
settles.push(a);
|
|
193
|
+
}
|
|
194
|
+
return { dispatches, settles };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Apply per-bot serialization + global concurrency cap. Same-bot siblings
|
|
198
|
+
* are silently deferred — they survive into the next tick's ready set
|
|
199
|
+
* because their nodeState stays idle (no `attemptCreated` written yet).
|
|
200
|
+
*/
|
|
201
|
+
function selectDispatchBatch(dispatches, maxConcurrency) {
|
|
202
|
+
const inflightBots = new Set();
|
|
203
|
+
const selected = [];
|
|
204
|
+
let deferred = 0;
|
|
205
|
+
for (const a of dispatches) {
|
|
206
|
+
if (selected.length >= maxConcurrency) {
|
|
207
|
+
deferred++;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (a.kind === 'dispatchWork' && a.node.type === 'subagent') {
|
|
211
|
+
if (inflightBots.has(a.node.bot)) {
|
|
212
|
+
deferred++;
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
inflightBots.add(a.node.bot);
|
|
216
|
+
}
|
|
217
|
+
selected.push(a);
|
|
218
|
+
}
|
|
219
|
+
return { selected, deferred };
|
|
220
|
+
}
|
|
221
|
+
async function runDispatch(ctx, action, snapshot, cancelSignal) {
|
|
222
|
+
if (action.kind === 'dispatchGate') {
|
|
223
|
+
// dispatchGate writes events synchronously — no long-running worker
|
|
224
|
+
// to cancel, so we ignore the signal. If a cancel arrives mid-tick
|
|
225
|
+
// the orchestrator short-circuit on the next tick will stop further
|
|
226
|
+
// dispatch.
|
|
227
|
+
await dispatchGate(ctx, action);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
await dispatchWork(ctx, action, { snapshot, cancelSignal });
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Polling fallback that fires abort signals when `cancelRequested` for
|
|
234
|
+
* the run lands in the EventLog after the tick already started.
|
|
235
|
+
*
|
|
236
|
+
* Daemon-driven cancel (cancelWorkflowRunOnDaemon) fires synchronously
|
|
237
|
+
* via `ctx.registerAborters` and doesn't need this observer. The
|
|
238
|
+
* observer is just a safety net for callers that write `cancelRequested`
|
|
239
|
+
* directly to the log without going through the daemon (cold attach,
|
|
240
|
+
* tests, future async producers).
|
|
241
|
+
*/
|
|
242
|
+
function startCancelObserver(ctx, aborters) {
|
|
243
|
+
let stopped = false;
|
|
244
|
+
let firing = false;
|
|
245
|
+
const tick = async () => {
|
|
246
|
+
if (stopped || firing)
|
|
247
|
+
return;
|
|
248
|
+
firing = true;
|
|
249
|
+
try {
|
|
250
|
+
const snapshot = replay(await ctx.log.readAll());
|
|
251
|
+
const origin = snapshot.cancelledRunIntent?.cancelOriginEventId;
|
|
252
|
+
if (!origin)
|
|
253
|
+
return;
|
|
254
|
+
const reason = { cancelOriginEventId: origin };
|
|
255
|
+
for (const ac of aborters.values()) {
|
|
256
|
+
if (!ac.signal.aborted)
|
|
257
|
+
ac.abort(reason);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
logger.warn?.(`runLoop(${ctx.log.runId}): cancel observer poll failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
262
|
+
}
|
|
263
|
+
finally {
|
|
264
|
+
firing = false;
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
const handle = setInterval(() => void tick(), CANCEL_OBSERVER_INTERVAL_MS);
|
|
268
|
+
// unref so the timer doesn't keep the process alive if the loop hangs.
|
|
269
|
+
handle.unref?.();
|
|
270
|
+
return () => {
|
|
271
|
+
stopped = true;
|
|
272
|
+
clearInterval(handle);
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
async function runSettle(ctx, action) {
|
|
276
|
+
switch (action.kind) {
|
|
277
|
+
case 'completeNodeSucceeded':
|
|
278
|
+
await completeNodeSucceeded(ctx, action);
|
|
279
|
+
return;
|
|
280
|
+
case 'completeNodeFailed':
|
|
281
|
+
await completeNodeFailed(ctx, action);
|
|
282
|
+
return;
|
|
283
|
+
case 'completeRunSucceeded':
|
|
284
|
+
await completeRunSucceeded(ctx, action);
|
|
285
|
+
return;
|
|
286
|
+
case 'completeRunFailed':
|
|
287
|
+
await completeRunFailed(ctx, action);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
// Exhaustive — TS will flag if a new settle kind appears.
|
|
291
|
+
const _exhaustive = action;
|
|
292
|
+
void _exhaustive;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Post-`allSettled` recovery: when a dispatch threw, check whether the
|
|
296
|
+
* activity is still non-terminal in the latest replay. If yes, write one
|
|
297
|
+
* `activityFailed` (errorClass=fatal, errorCode=WorkerCrashed — closest
|
|
298
|
+
* existing enum fit for a dispatch-time hard throw, see payloads.ts) so
|
|
299
|
+
* downstream replay stops waiting. If the dispatch already wrote a
|
|
300
|
+
* terminal event before throwing (e.g. activitySucceeded then sidecar
|
|
301
|
+
* OOM), skip — appending another terminal would corrupt replay's
|
|
302
|
+
* per-attempt state.
|
|
303
|
+
*
|
|
304
|
+
* Returns one of:
|
|
305
|
+
* - 'patched' → infra-failure event appended; loop can continue
|
|
306
|
+
* - 'alreadyTerminal' → dispatch self-terminated already; no patch needed
|
|
307
|
+
* - 'unpatchable' → throw happened before any attemptCreated; loop
|
|
308
|
+
* MUST stop or it will re-dispatch the same action
|
|
309
|
+
* on the next tick. Caller is responsible for
|
|
310
|
+
* turning this into `no-progress`.
|
|
311
|
+
*/
|
|
312
|
+
async function maybePatchInfrastructureFailure(ctx, snapshot, action, reason) {
|
|
313
|
+
const activityId = action.activityId;
|
|
314
|
+
const activity = snapshot.activities.get(activityId);
|
|
315
|
+
const status = activity?.status;
|
|
316
|
+
if (status === 'succeeded' ||
|
|
317
|
+
status === 'failed' ||
|
|
318
|
+
status === 'cancelled' ||
|
|
319
|
+
status === 'timedOut') {
|
|
320
|
+
logger.warn?.(`runLoop(${ctx.log.runId}): dispatch ${action.kind} for ${activityId} threw after already settling (${status}); skipping infrastructure fallback: ${reason instanceof Error ? reason.message : String(reason)}`);
|
|
321
|
+
return 'alreadyTerminal';
|
|
322
|
+
}
|
|
323
|
+
const latest = activity?.attempts[activity.attempts.length - 1];
|
|
324
|
+
const attemptId = latest?.attemptId;
|
|
325
|
+
if (!attemptId) {
|
|
326
|
+
// Dispatch threw before writing `attemptCreated` — likely a log/blob
|
|
327
|
+
// write failure inside dispatchWork. We can't tie an `activityFailed`
|
|
328
|
+
// to a non-existent attempt, and re-running the loop would just
|
|
329
|
+
// re-emit the same dispatch and burn through `maxTicks`. Mark
|
|
330
|
+
// unpatchable so the caller stops the run.
|
|
331
|
+
logger.warn?.(`runLoop(${ctx.log.runId}): dispatch ${action.kind} for ${activityId} threw before attemptCreated; stopping run to avoid infinite retry: ${reason instanceof Error ? reason.message : String(reason)}`);
|
|
332
|
+
return 'unpatchable';
|
|
333
|
+
}
|
|
334
|
+
await ctx.log.append({
|
|
335
|
+
runId: ctx.log.runId,
|
|
336
|
+
type: 'activityFailed',
|
|
337
|
+
actor: 'scheduler',
|
|
338
|
+
payload: {
|
|
339
|
+
activityId,
|
|
340
|
+
attemptId,
|
|
341
|
+
error: {
|
|
342
|
+
errorClass: 'fatal',
|
|
343
|
+
errorCode: 'WorkerCrashed',
|
|
344
|
+
errorMessage: reason instanceof Error ? reason.message : String(reason),
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
return 'patched';
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/workflows/loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { type WorkflowEvent } from './events/schema.js';
|
|
2
|
+
import { type ActivityState, type NodeState, type RunState, type Snapshot } from './events/replay.js';
|
|
3
|
+
import type { OutputRef } from './events/payloads.js';
|
|
4
|
+
export declare const TERMINAL_RUN_STATUSES: Set<string>;
|
|
5
|
+
export declare function isValidRunId(runId: string): boolean;
|
|
6
|
+
export declare function isValidPathSegment(s: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Path-traversal guard — returns true iff `child`, after `..`/`.` resolution,
|
|
9
|
+
* still lives inside `parent`. Exported so dashboard surfaces that build
|
|
10
|
+
* paths from caller-supplied ids (e.g. attempt terminal-log raw endpoint)
|
|
11
|
+
* can apply the same defense-in-depth check on top of `isValidRunId` /
|
|
12
|
+
* `isValidPathSegment`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isPathInsideDir(parent: string, child: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the on-disk `terminal.log` path for a given attempt sidecar.
|
|
17
|
+
* Production callers MUST validate runId / activityId / attemptId with
|
|
18
|
+
* `isValidRunId` + `isValidPathSegment` first, and re-check `isPathInsideDir`
|
|
19
|
+
* after joining to defend against any future segment-regex relaxation.
|
|
20
|
+
*/
|
|
21
|
+
export declare function attemptTerminalLogPath(runsDir: string, runId: string, activityId: string, attemptId: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the on-disk raw `pty.log` path for a given attempt sidecar.
|
|
24
|
+
* Same validation contract as `attemptTerminalLogPath` — callers MUST
|
|
25
|
+
* pre-validate ids and re-check `isPathInsideDir` after joining.
|
|
26
|
+
*/
|
|
27
|
+
export declare function attemptPtyLogPath(runsDir: string, runId: string, activityId: string, attemptId: string): string;
|
|
28
|
+
export type RunRow = {
|
|
29
|
+
runId: string;
|
|
30
|
+
workflowId: string;
|
|
31
|
+
status: string;
|
|
32
|
+
lastSeq: number;
|
|
33
|
+
dEf: number;
|
|
34
|
+
dAct: number;
|
|
35
|
+
dWait: number;
|
|
36
|
+
updatedAt: number;
|
|
37
|
+
failedNodeId?: string;
|
|
38
|
+
errorCode?: string;
|
|
39
|
+
errorClass?: string;
|
|
40
|
+
errorMessage?: string;
|
|
41
|
+
chatId?: string;
|
|
42
|
+
larkAppId?: string;
|
|
43
|
+
};
|
|
44
|
+
export type ListRunsOptions = {
|
|
45
|
+
/** Include terminal runs. Default false (matches `botmux workflow ls`). */
|
|
46
|
+
all?: boolean;
|
|
47
|
+
/** Explicit status filter. Wins over `all` when provided. */
|
|
48
|
+
statuses?: Set<string>;
|
|
49
|
+
/** Read chat-binding.json per row (extra fs op per run). */
|
|
50
|
+
includeBinding?: boolean;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Project every run in `runsDir` to a row. Most-recently-updated first.
|
|
54
|
+
*
|
|
55
|
+
* - ENOENT on `runsDir` → `[]` (nothing to list).
|
|
56
|
+
* - Non-directory entries / unreadable / corrupt event logs → skipped.
|
|
57
|
+
* - Filter precedence: explicit `statuses` (any) > `all` (terminal kept) >
|
|
58
|
+
* default (terminal hidden).
|
|
59
|
+
*/
|
|
60
|
+
export declare function listRuns(runsDir: string, opts?: ListRunsOptions): Promise<RunRow[]>;
|
|
61
|
+
export declare function projectRunRow(runId: string, events: WorkflowEvent[], snap: Snapshot): RunRow;
|
|
62
|
+
export type RunSnapshotDTO = {
|
|
63
|
+
runId: string;
|
|
64
|
+
run: RunState;
|
|
65
|
+
lastSeq: number;
|
|
66
|
+
nodes: NodeState[];
|
|
67
|
+
activities: ActivityState[];
|
|
68
|
+
dangling: {
|
|
69
|
+
activities: string[];
|
|
70
|
+
effectAttempted: string[];
|
|
71
|
+
waits: string[];
|
|
72
|
+
cancels: string[];
|
|
73
|
+
};
|
|
74
|
+
outputs: Record<string, OutputRef>;
|
|
75
|
+
attemptIO: Record<string, AttemptIODTO>;
|
|
76
|
+
chatBinding?: {
|
|
77
|
+
chatId: string;
|
|
78
|
+
larkAppId: string;
|
|
79
|
+
};
|
|
80
|
+
updatedAt: number;
|
|
81
|
+
};
|
|
82
|
+
export type BlobPreviewDTO = {
|
|
83
|
+
outputHash?: string;
|
|
84
|
+
outputBytes?: number;
|
|
85
|
+
contentType?: string;
|
|
86
|
+
truncated?: boolean;
|
|
87
|
+
value?: unknown;
|
|
88
|
+
text?: string;
|
|
89
|
+
error?: string;
|
|
90
|
+
};
|
|
91
|
+
export type AttemptIODTO = {
|
|
92
|
+
input?: BlobPreviewDTO;
|
|
93
|
+
resolvedInput?: BlobPreviewDTO;
|
|
94
|
+
output?: BlobPreviewDTO;
|
|
95
|
+
log?: BlobPreviewDTO;
|
|
96
|
+
terminal?: AttemptTerminalDTO;
|
|
97
|
+
/** Full humanGate prompt when the producer spilled it to a blob via
|
|
98
|
+
* `promptRef`. Read on demand via the same 64 KiB preview ladder as
|
|
99
|
+
* output / input blobs; cards never use this. */
|
|
100
|
+
waitPrompt?: BlobPreviewDTO;
|
|
101
|
+
};
|
|
102
|
+
export type AttemptTerminalDTO = {
|
|
103
|
+
sessionId: string;
|
|
104
|
+
cliSessionId?: string;
|
|
105
|
+
webPort: number;
|
|
106
|
+
status: 'live' | 'closed';
|
|
107
|
+
larkAppId?: string;
|
|
108
|
+
botName?: string;
|
|
109
|
+
cliId?: string;
|
|
110
|
+
workingDir?: string;
|
|
111
|
+
logPath?: string;
|
|
112
|
+
startedAt: number;
|
|
113
|
+
updatedAt: number;
|
|
114
|
+
closedAt?: number;
|
|
115
|
+
error?: string;
|
|
116
|
+
/** True when a raw PTY byte log (`pty.log`) exists alongside the sidecar.
|
|
117
|
+
* Drives the replay viewer's "terminal cinema" vs "diagnostic log"
|
|
118
|
+
* toggle. Older attempts predate this file and project as `false`. */
|
|
119
|
+
hasPtyLog?: boolean;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Build a JSON-serializable snapshot for a single run. Returns null when
|
|
123
|
+
* the run is missing / has no events / has a corrupt log. Callers
|
|
124
|
+
* (dashboard `/snapshot` endpoint) should map null → 404.
|
|
125
|
+
*/
|
|
126
|
+
export declare function readRunSnapshot(runsDir: string, runId: string): Promise<RunSnapshotDTO | null>;
|
|
127
|
+
export type EventWindowOptions = {
|
|
128
|
+
/** Initial fetch: last N events. Ignored if before/afterSeq is set. */
|
|
129
|
+
tail?: number;
|
|
130
|
+
/** Cursor: events with seq < beforeSeq, returned in seq-asc order. */
|
|
131
|
+
beforeSeq?: number;
|
|
132
|
+
/** Cursor: events with seq > afterSeq, returned in seq-asc order. */
|
|
133
|
+
afterSeq?: number;
|
|
134
|
+
/** Page size for before/afterSeq. Default 200, max 1000. */
|
|
135
|
+
limit?: number;
|
|
136
|
+
};
|
|
137
|
+
export type EventWindow = {
|
|
138
|
+
events: WorkflowEvent[];
|
|
139
|
+
oldestSeq: number | null;
|
|
140
|
+
newestSeq: number | null;
|
|
141
|
+
totalCount: number;
|
|
142
|
+
hasOlder: boolean;
|
|
143
|
+
hasNewer: boolean;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Slice a run's event log into a paginated window.
|
|
147
|
+
*
|
|
148
|
+
* Mode precedence: `afterSeq` > `beforeSeq` > `tail` (default). This
|
|
149
|
+
* matches the dashboard usage: detail page first loads `?tail=100`,
|
|
150
|
+
* then polls `?afterSeq=<newest>` and back-scrolls `?beforeSeq=<oldest>`.
|
|
151
|
+
*
|
|
152
|
+
* Pagination bookkeeping (`hasOlder` / `hasNewer`) is computed from the
|
|
153
|
+
* full event list and the returned slice's bounds. Returns null if the
|
|
154
|
+
* runId is invalid or the run is missing.
|
|
155
|
+
*/
|
|
156
|
+
export declare function readEventWindow(runsDir: string, runId: string, opts?: EventWindowOptions): Promise<EventWindow | null>;
|
|
157
|
+
/**
|
|
158
|
+
* Extract `<seq>` from a WorkflowEvent `eventId` of the form
|
|
159
|
+
* `<runId>-<seq>` (events doc v0.1.2 §3.1). Returns 0 for malformed
|
|
160
|
+
* ids; callers should treat that as "unknown" rather than position 0.
|
|
161
|
+
*/
|
|
162
|
+
export declare function eventSeqFromId(eventId: string): number;
|
|
163
|
+
export declare function extractEventContext(payload: unknown): {
|
|
164
|
+
nodeId?: string;
|
|
165
|
+
activityId?: string;
|
|
166
|
+
errorCode?: string;
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=ops-projection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops-projection.d.ts","sourceRoot":"","sources":["../../src/workflows/ops-projection.ts"],"names":[],"mappings":"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"}
|