lorenz 0.1.5 → 0.1.7
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.md +83 -20
- package/RELEASE-MANIFEST.json +6 -1
- package/node_modules/@lorenz/agent-sdk/dist/index.d.ts +1 -0
- package/node_modules/@lorenz/agent-sdk/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/agent-sdk/dist/index.js +1 -0
- package/node_modules/@lorenz/agent-sdk/dist/index.js.map +1 -1
- package/node_modules/@lorenz/agent-sdk/dist/module.d.ts +38 -0
- package/node_modules/@lorenz/agent-sdk/dist/module.d.ts.map +1 -0
- package/node_modules/@lorenz/agent-sdk/dist/module.js +41 -0
- package/node_modules/@lorenz/agent-sdk/dist/module.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/agentExecutorLoader.d.ts +30 -0
- package/node_modules/@lorenz/cli/dist/agentExecutorLoader.d.ts.map +1 -0
- package/node_modules/@lorenz/cli/dist/agentExecutorLoader.js +63 -0
- package/node_modules/@lorenz/cli/dist/agentExecutorLoader.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/daemon.d.ts +42 -19
- package/node_modules/@lorenz/cli/dist/daemon.d.ts.map +1 -1
- package/node_modules/@lorenz/cli/dist/daemon.js +74 -28
- package/node_modules/@lorenz/cli/dist/daemon.js.map +1 -1
- package/node_modules/@lorenz/cli/dist/daemonLock.d.ts +59 -0
- package/node_modules/@lorenz/cli/dist/daemonLock.d.ts.map +1 -0
- package/node_modules/@lorenz/cli/dist/daemonLock.js +304 -0
- package/node_modules/@lorenz/cli/dist/daemonLock.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/daemonStatus.d.ts +16 -0
- package/node_modules/@lorenz/cli/dist/daemonStatus.d.ts.map +1 -0
- package/node_modules/@lorenz/cli/dist/daemonStatus.js +21 -0
- package/node_modules/@lorenz/cli/dist/daemonStatus.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/doctor.d.ts +6 -0
- package/node_modules/@lorenz/cli/dist/doctor.d.ts.map +1 -1
- package/node_modules/@lorenz/cli/dist/doctor.js +38 -1
- package/node_modules/@lorenz/cli/dist/doctor.js.map +1 -1
- package/node_modules/@lorenz/cli/dist/extensionLoader.d.ts +126 -0
- package/node_modules/@lorenz/cli/dist/extensionLoader.d.ts.map +1 -0
- package/node_modules/@lorenz/cli/dist/extensionLoader.js +187 -0
- package/node_modules/@lorenz/cli/dist/extensionLoader.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/flags-manifest.d.ts +42 -0
- package/node_modules/@lorenz/cli/dist/flags-manifest.d.ts.map +1 -0
- package/node_modules/@lorenz/cli/dist/flags-manifest.js +67 -0
- package/node_modules/@lorenz/cli/dist/flags-manifest.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/index.d.ts +6 -0
- package/node_modules/@lorenz/cli/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/cli/dist/index.js +4 -0
- package/node_modules/@lorenz/cli/dist/index.js.map +1 -1
- package/node_modules/@lorenz/cli/dist/leadershipStore.d.ts +42 -0
- package/node_modules/@lorenz/cli/dist/leadershipStore.d.ts.map +1 -0
- package/node_modules/@lorenz/cli/dist/leadershipStore.js +2 -0
- package/node_modules/@lorenz/cli/dist/leadershipStore.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/main.d.ts +11 -7
- package/node_modules/@lorenz/cli/dist/main.d.ts.map +1 -1
- package/node_modules/@lorenz/cli/dist/main.js +58 -8
- package/node_modules/@lorenz/cli/dist/main.js.map +1 -1
- package/node_modules/@lorenz/cli/dist/toolLoader.d.ts +28 -0
- package/node_modules/@lorenz/cli/dist/toolLoader.d.ts.map +1 -0
- package/node_modules/@lorenz/cli/dist/toolLoader.js +62 -0
- package/node_modules/@lorenz/cli/dist/toolLoader.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/trackerLoader.d.ts +24 -0
- package/node_modules/@lorenz/cli/dist/trackerLoader.d.ts.map +1 -0
- package/node_modules/@lorenz/cli/dist/trackerLoader.js +34 -0
- package/node_modules/@lorenz/cli/dist/trackerLoader.js.map +1 -0
- package/node_modules/@lorenz/cli/dist/workerDriverLoader.d.ts +15 -55
- package/node_modules/@lorenz/cli/dist/workerDriverLoader.d.ts.map +1 -1
- package/node_modules/@lorenz/cli/dist/workerDriverLoader.js +26 -203
- package/node_modules/@lorenz/cli/dist/workerDriverLoader.js.map +1 -1
- package/node_modules/@lorenz/cli/package.json +1 -0
- package/node_modules/@lorenz/config/dist/index.d.ts +1 -1
- package/node_modules/@lorenz/config/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/config/dist/index.js +1 -1
- package/node_modules/@lorenz/config/dist/index.js.map +1 -1
- package/node_modules/@lorenz/config/dist/parse.d.ts +17 -0
- package/node_modules/@lorenz/config/dist/parse.d.ts.map +1 -1
- package/node_modules/@lorenz/config/dist/parse.js +107 -11
- package/node_modules/@lorenz/config/dist/parse.js.map +1 -1
- package/node_modules/@lorenz/config/dist/schemas.d.ts +0 -2
- package/node_modules/@lorenz/config/dist/schemas.d.ts.map +1 -1
- package/node_modules/@lorenz/config/dist/schemas.js +5 -1
- package/node_modules/@lorenz/config/dist/schemas.js.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/coordinator.d.ts +55 -21
- package/node_modules/@lorenz/dispatch-coordinator/dist/coordinator.d.ts.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/coordinator.js +187 -82
- package/node_modules/@lorenz/dispatch-coordinator/dist/coordinator.js.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/gate.d.ts +6 -4
- package/node_modules/@lorenz/dispatch-coordinator/dist/gate.d.ts.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/gate.js +9 -6
- package/node_modules/@lorenz/dispatch-coordinator/dist/gate.js.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/index.d.ts +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/index.js +5 -6
- package/node_modules/@lorenz/dispatch-coordinator/dist/index.js.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/mcpEndpointManager.d.ts +7 -5
- package/node_modules/@lorenz/dispatch-coordinator/dist/mcpEndpointManager.d.ts.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/mcpEndpointManager.js +12 -10
- package/node_modules/@lorenz/dispatch-coordinator/dist/mcpEndpointManager.js.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/nullEndpointManager.d.ts +11 -10
- package/node_modules/@lorenz/dispatch-coordinator/dist/nullEndpointManager.d.ts.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/nullEndpointManager.js +15 -22
- package/node_modules/@lorenz/dispatch-coordinator/dist/nullEndpointManager.js.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/types.d.ts +16 -15
- package/node_modules/@lorenz/dispatch-coordinator/dist/types.d.ts.map +1 -1
- package/node_modules/@lorenz/dispatch-coordinator/dist/types.js +6 -7
- package/node_modules/@lorenz/dispatch-coordinator/dist/types.js.map +1 -1
- package/node_modules/@lorenz/domain/dist/index.d.ts +75 -9
- package/node_modules/@lorenz/domain/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/domain/dist/index.js +40 -0
- package/node_modules/@lorenz/domain/dist/index.js.map +1 -1
- package/node_modules/@lorenz/flags/dist/coerce.d.ts +12 -0
- package/node_modules/@lorenz/flags/dist/coerce.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/coerce.js +44 -0
- package/node_modules/@lorenz/flags/dist/coerce.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/default.d.ts +6 -0
- package/node_modules/@lorenz/flags/dist/default.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/default.js +22 -0
- package/node_modules/@lorenz/flags/dist/default.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/deprecations.d.ts +20 -0
- package/node_modules/@lorenz/flags/dist/deprecations.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/deprecations.js +42 -0
- package/node_modules/@lorenz/flags/dist/deprecations.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/env.d.ts +17 -0
- package/node_modules/@lorenz/flags/dist/env.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/env.js +90 -0
- package/node_modules/@lorenz/flags/dist/env.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/errors.d.ts +22 -0
- package/node_modules/@lorenz/flags/dist/errors.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/errors.js +61 -0
- package/node_modules/@lorenz/flags/dist/errors.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/index.d.ts +8 -0
- package/node_modules/@lorenz/flags/dist/index.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/index.js +11 -0
- package/node_modules/@lorenz/flags/dist/index.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/keys.d.ts +6 -0
- package/node_modules/@lorenz/flags/dist/keys.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/keys.js +15 -0
- package/node_modules/@lorenz/flags/dist/keys.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/layers.d.ts +14 -0
- package/node_modules/@lorenz/flags/dist/layers.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/layers.js +107 -0
- package/node_modules/@lorenz/flags/dist/layers.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/manifest.d.ts +71 -0
- package/node_modules/@lorenz/flags/dist/manifest.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/manifest.js +137 -0
- package/node_modules/@lorenz/flags/dist/manifest.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/resolve.d.ts +8 -0
- package/node_modules/@lorenz/flags/dist/resolve.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/resolve.js +178 -0
- package/node_modules/@lorenz/flags/dist/resolve.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/testing.d.ts +19 -0
- package/node_modules/@lorenz/flags/dist/testing.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/testing.js +68 -0
- package/node_modules/@lorenz/flags/dist/testing.js.map +1 -0
- package/node_modules/@lorenz/flags/dist/types.d.ts +93 -0
- package/node_modules/@lorenz/flags/dist/types.d.ts.map +1 -0
- package/node_modules/@lorenz/flags/dist/types.js +2 -0
- package/node_modules/@lorenz/flags/dist/types.js.map +1 -0
- package/node_modules/@lorenz/flags/package.json +16 -0
- package/node_modules/@lorenz/jira-tracker/dist/index.d.ts +1 -0
- package/node_modules/@lorenz/jira-tracker/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/jira-tracker/dist/index.js +1 -0
- package/node_modules/@lorenz/jira-tracker/dist/index.js.map +1 -1
- package/node_modules/@lorenz/jira-tracker/dist/provider.d.ts.map +1 -1
- package/node_modules/@lorenz/jira-tracker/dist/provider.js +3 -36
- package/node_modules/@lorenz/jira-tracker/dist/provider.js.map +1 -1
- package/node_modules/@lorenz/jira-tracker/dist/register.d.ts +5 -3
- package/node_modules/@lorenz/jira-tracker/dist/register.d.ts.map +1 -1
- package/node_modules/@lorenz/jira-tracker/dist/register.js +9 -3
- package/node_modules/@lorenz/jira-tracker/dist/register.js.map +1 -1
- package/node_modules/@lorenz/jira-tracker/dist/tools.d.ts +18 -0
- package/node_modules/@lorenz/jira-tracker/dist/tools.d.ts.map +1 -0
- package/node_modules/@lorenz/{tracker-sdk/dist/toolPack.js → jira-tracker/dist/tools.js} +76 -78
- package/node_modules/@lorenz/jira-tracker/dist/tools.js.map +1 -0
- package/node_modules/@lorenz/jira-tracker/package.json +1 -0
- package/node_modules/@lorenz/linear-tracker/dist/provider.d.ts.map +1 -1
- package/node_modules/@lorenz/linear-tracker/dist/provider.js +0 -2
- package/node_modules/@lorenz/linear-tracker/dist/provider.js.map +1 -1
- package/node_modules/@lorenz/local-tracker/dist/provider.d.ts.map +1 -1
- package/node_modules/@lorenz/local-tracker/dist/provider.js +0 -2
- package/node_modules/@lorenz/local-tracker/dist/provider.js.map +1 -1
- package/node_modules/@lorenz/mcp/dist/agentEndpoint.d.ts +16 -3
- package/node_modules/@lorenz/mcp/dist/agentEndpoint.d.ts.map +1 -1
- package/node_modules/@lorenz/mcp/dist/agentEndpoint.js +105 -17
- package/node_modules/@lorenz/mcp/dist/agentEndpoint.js.map +1 -1
- package/node_modules/@lorenz/mcp/dist/auth.d.ts +88 -0
- package/node_modules/@lorenz/mcp/dist/auth.d.ts.map +1 -1
- package/node_modules/@lorenz/mcp/dist/auth.js +53 -0
- package/node_modules/@lorenz/mcp/dist/auth.js.map +1 -1
- package/node_modules/@lorenz/mcp/dist/index.d.ts +3 -2
- package/node_modules/@lorenz/mcp/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/mcp/dist/index.js +1 -1
- package/node_modules/@lorenz/mcp/dist/index.js.map +1 -1
- package/node_modules/@lorenz/mcp/dist/server.d.ts +22 -0
- package/node_modules/@lorenz/mcp/dist/server.d.ts.map +1 -1
- package/node_modules/@lorenz/mcp/dist/server.js +85 -12
- package/node_modules/@lorenz/mcp/dist/server.js.map +1 -1
- package/node_modules/@lorenz/mcp/dist/tools.d.ts.map +1 -1
- package/node_modules/@lorenz/mcp/dist/tools.js +5 -8
- package/node_modules/@lorenz/mcp/dist/tools.js.map +1 -1
- package/node_modules/@lorenz/orchestrator/dist/claimStore.d.ts +157 -0
- package/node_modules/@lorenz/orchestrator/dist/claimStore.d.ts.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/claimStore.js +621 -0
- package/node_modules/@lorenz/orchestrator/dist/claimStore.js.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/codec.d.ts +38 -0
- package/node_modules/@lorenz/orchestrator/dist/codec.d.ts.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/codec.js +176 -0
- package/node_modules/@lorenz/orchestrator/dist/codec.js.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/index.d.ts +55 -51
- package/node_modules/@lorenz/orchestrator/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/orchestrator/dist/index.js +285 -45
- package/node_modules/@lorenz/orchestrator/dist/index.js.map +1 -1
- package/node_modules/@lorenz/orchestrator/dist/sqlite.d.ts +34 -0
- package/node_modules/@lorenz/orchestrator/dist/sqlite.d.ts.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/sqlite.js +142 -0
- package/node_modules/@lorenz/orchestrator/dist/sqlite.js.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/state.d.ts +47 -0
- package/node_modules/@lorenz/orchestrator/dist/state.d.ts.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/state.js +15 -0
- package/node_modules/@lorenz/orchestrator/dist/state.js.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/turso.d.ts +28 -0
- package/node_modules/@lorenz/orchestrator/dist/turso.d.ts.map +1 -0
- package/node_modules/@lorenz/orchestrator/dist/turso.js +125 -0
- package/node_modules/@lorenz/orchestrator/dist/turso.js.map +1 -0
- package/node_modules/@lorenz/orchestrator/package.json +6 -2
- package/node_modules/@lorenz/presenter/dist/index.d.ts +14 -0
- package/node_modules/@lorenz/presenter/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/presenter/dist/index.js +18 -0
- package/node_modules/@lorenz/presenter/dist/index.js.map +1 -1
- package/node_modules/@lorenz/projections/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/projections/dist/index.js +1 -0
- package/node_modules/@lorenz/projections/dist/index.js.map +1 -1
- package/node_modules/@lorenz/runtime/dist/index.d.ts +27 -8
- package/node_modules/@lorenz/runtime/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/runtime/dist/index.js +422 -98
- package/node_modules/@lorenz/runtime/dist/index.js.map +1 -1
- package/node_modules/@lorenz/runtime-events/dist/index.d.ts +14 -0
- package/node_modules/@lorenz/runtime-events/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/slack-tracker/dist/client.d.ts +0 -7
- package/node_modules/@lorenz/slack-tracker/dist/client.d.ts.map +1 -1
- package/node_modules/@lorenz/slack-tracker/dist/client.js +4 -5
- package/node_modules/@lorenz/slack-tracker/dist/client.js.map +1 -1
- package/node_modules/@lorenz/slack-tracker/dist/index.d.ts +0 -1
- package/node_modules/@lorenz/slack-tracker/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/slack-tracker/dist/index.js +0 -1
- package/node_modules/@lorenz/slack-tracker/dist/index.js.map +1 -1
- package/node_modules/@lorenz/slack-tracker/dist/provider.d.ts.map +1 -1
- package/node_modules/@lorenz/slack-tracker/dist/provider.js +0 -2
- package/node_modules/@lorenz/slack-tracker/dist/provider.js.map +1 -1
- package/node_modules/@lorenz/ssh/dist/index.d.ts +2 -0
- package/node_modules/@lorenz/ssh/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/ssh/dist/index.js +2 -1
- package/node_modules/@lorenz/ssh/dist/index.js.map +1 -1
- package/node_modules/@lorenz/tool-sdk/dist/index.d.ts +1 -0
- package/node_modules/@lorenz/tool-sdk/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/tool-sdk/dist/index.js +1 -0
- package/node_modules/@lorenz/tool-sdk/dist/index.js.map +1 -1
- package/node_modules/@lorenz/tool-sdk/dist/module.d.ts +38 -0
- package/node_modules/@lorenz/tool-sdk/dist/module.d.ts.map +1 -0
- package/node_modules/@lorenz/tool-sdk/dist/module.js +42 -0
- package/node_modules/@lorenz/tool-sdk/dist/module.js.map +1 -0
- package/node_modules/@lorenz/tracker-sdk/dist/index.d.ts +2 -2
- package/node_modules/@lorenz/tracker-sdk/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/tracker-sdk/dist/index.js +1 -1
- package/node_modules/@lorenz/tracker-sdk/dist/index.js.map +1 -1
- package/node_modules/@lorenz/tracker-sdk/dist/module.d.ts +37 -0
- package/node_modules/@lorenz/tracker-sdk/dist/module.d.ts.map +1 -0
- package/node_modules/@lorenz/tracker-sdk/dist/module.js +38 -0
- package/node_modules/@lorenz/tracker-sdk/dist/module.js.map +1 -0
- package/node_modules/@lorenz/tracker-sdk/dist/provider.d.ts +11 -55
- package/node_modules/@lorenz/tracker-sdk/dist/provider.d.ts.map +1 -1
- package/node_modules/@lorenz/tracker-sdk/package.json +1 -2
- package/node_modules/@lorenz/worker-host-pool/dist/index.d.ts +34 -6
- package/node_modules/@lorenz/worker-host-pool/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/worker-host-pool/dist/index.js +110 -143
- package/node_modules/@lorenz/worker-host-pool/dist/index.js.map +1 -1
- package/node_modules/@lorenz/worker-sdk/dist/index.d.ts +1 -0
- package/node_modules/@lorenz/worker-sdk/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/worker-sdk/dist/index.js +1 -0
- package/node_modules/@lorenz/worker-sdk/dist/index.js.map +1 -1
- package/node_modules/@lorenz/worker-sdk/dist/local.d.ts +74 -0
- package/node_modules/@lorenz/worker-sdk/dist/local.d.ts.map +1 -0
- package/node_modules/@lorenz/worker-sdk/dist/local.js +112 -0
- package/node_modules/@lorenz/worker-sdk/dist/local.js.map +1 -0
- package/node_modules/@lorenz/worker-sdk/dist/module.d.ts +8 -16
- package/node_modules/@lorenz/worker-sdk/dist/module.d.ts.map +1 -1
- package/node_modules/@lorenz/worker-sdk/dist/module.js +15 -35
- package/node_modules/@lorenz/worker-sdk/dist/module.js.map +1 -1
- package/node_modules/@lorenz/workflow/dist/index.d.ts +11 -0
- package/node_modules/@lorenz/workflow/dist/index.d.ts.map +1 -1
- package/node_modules/@lorenz/workflow/dist/index.js +3 -0
- package/node_modules/@lorenz/workflow/dist/index.js.map +1 -1
- package/package.json +4 -1
- package/node_modules/@lorenz/linear-tracker/dist/toolOps.d.ts +0 -8
- package/node_modules/@lorenz/linear-tracker/dist/toolOps.d.ts.map +0 -1
- package/node_modules/@lorenz/linear-tracker/dist/toolOps.js +0 -251
- package/node_modules/@lorenz/linear-tracker/dist/toolOps.js.map +0 -1
- package/node_modules/@lorenz/local-tracker/dist/toolOps.d.ts +0 -9
- package/node_modules/@lorenz/local-tracker/dist/toolOps.d.ts.map +0 -1
- package/node_modules/@lorenz/local-tracker/dist/toolOps.js +0 -86
- package/node_modules/@lorenz/local-tracker/dist/toolOps.js.map +0 -1
- package/node_modules/@lorenz/slack-tracker/dist/toolOps.d.ts +0 -13
- package/node_modules/@lorenz/slack-tracker/dist/toolOps.d.ts.map +0 -1
- package/node_modules/@lorenz/slack-tracker/dist/toolOps.js +0 -76
- package/node_modules/@lorenz/slack-tracker/dist/toolOps.js.map +0 -1
- package/node_modules/@lorenz/tracker-sdk/dist/toolPack.d.ts +0 -10
- package/node_modules/@lorenz/tracker-sdk/dist/toolPack.d.ts.map +0 -1
- package/node_modules/@lorenz/tracker-sdk/dist/toolPack.js.map +0 -1
|
@@ -28,6 +28,7 @@ const POISON_WORKER_ERROR_PREFIXES = [
|
|
|
28
28
|
// `hook failed with status N` (no `workspace ` prefix) and stays healthy.
|
|
29
29
|
"workspace hook failed with status ",
|
|
30
30
|
];
|
|
31
|
+
const CLAIM_OWNER_HEARTBEAT_INTERVAL_MS = 10_000;
|
|
31
32
|
export function classifyWorkerOutcome(error) {
|
|
32
33
|
const message = error instanceof Error ? error.message : String(error);
|
|
33
34
|
return POISON_WORKER_ERROR_PREFIXES.some((prefix) => message.startsWith(prefix))
|
|
@@ -64,7 +65,21 @@ function mergePollOptions(existing, requested) {
|
|
|
64
65
|
waitForRuns: existingIntent.waitForRuns || requestedIntent.waitForRuns,
|
|
65
66
|
});
|
|
66
67
|
}
|
|
68
|
+
class ClaimStoreRuntimeError extends Error {
|
|
69
|
+
reason;
|
|
70
|
+
original;
|
|
71
|
+
constructor(reason, original) {
|
|
72
|
+
super(errorMessage(original));
|
|
73
|
+
this.reason = reason;
|
|
74
|
+
this.original = original;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function throwRuntimeError(error) {
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
67
80
|
class ActiveRunHandle {
|
|
81
|
+
issueId;
|
|
82
|
+
slotIndex;
|
|
68
83
|
key;
|
|
69
84
|
runId;
|
|
70
85
|
activeRuns;
|
|
@@ -75,7 +90,10 @@ class ActiveRunHandle {
|
|
|
75
90
|
* generic `agent_run_aborted` (which would otherwise classify as healthy).
|
|
76
91
|
*/
|
|
77
92
|
reason = null;
|
|
78
|
-
|
|
93
|
+
abandonClaimOnSettlement = false;
|
|
94
|
+
constructor(issueId, slotIndex, key, runId, activeRuns) {
|
|
95
|
+
this.issueId = issueId;
|
|
96
|
+
this.slotIndex = slotIndex;
|
|
79
97
|
this.key = key;
|
|
80
98
|
this.runId = runId;
|
|
81
99
|
this.activeRuns = activeRuns;
|
|
@@ -89,9 +107,11 @@ class ActiveRunHandle {
|
|
|
89
107
|
abort() {
|
|
90
108
|
this.controller.abort();
|
|
91
109
|
}
|
|
92
|
-
finishExternally(reason = null) {
|
|
110
|
+
finishExternally(reason = null, options = {}) {
|
|
93
111
|
if (reason)
|
|
94
112
|
this.reason = reason;
|
|
113
|
+
if (options.abandonClaimOnSettlement)
|
|
114
|
+
this.abandonClaimOnSettlement = true;
|
|
95
115
|
this.abort();
|
|
96
116
|
this.release();
|
|
97
117
|
}
|
|
@@ -126,6 +146,8 @@ export class LorenzRuntime {
|
|
|
126
146
|
activePollOptions = null;
|
|
127
147
|
pendingPollOptions = null;
|
|
128
148
|
workerPoolDrained = false;
|
|
149
|
+
claimOwnerHeartbeatTimer = null;
|
|
150
|
+
pendingStoppedClaimSettlements = 0;
|
|
129
151
|
/**
|
|
130
152
|
* Live tracker push subscription (see {@link RuntimeTrackerClient.watch}), opened once in the
|
|
131
153
|
* recurring `start()` loop and closed on `stop()`. `undefined` for pull-only trackers and the
|
|
@@ -135,11 +157,10 @@ export class LorenzRuntime {
|
|
|
135
157
|
changeStream;
|
|
136
158
|
changeStreamOpening = false;
|
|
137
159
|
/**
|
|
138
|
-
* The reload-surviving coordinator singleton. Built
|
|
160
|
+
* The reload-surviving coordinator singleton. Built here from either the
|
|
139
161
|
* pre-built `input.coordinator` (preferred), or a null-endpoint passthrough
|
|
140
|
-
* wrapping a bare `input.workerPool
|
|
141
|
-
*
|
|
142
|
-
* when neither is supplied (the static/local path, byte-identical to today).
|
|
162
|
+
* wrapping a bare `input.workerPool`, which keeps the default runtime boundary unchanged.
|
|
163
|
+
* `undefined` when neither is supplied, which uses the static/local path.
|
|
143
164
|
*/
|
|
144
165
|
coordinator;
|
|
145
166
|
constructor(input) {
|
|
@@ -157,7 +178,7 @@ export class LorenzRuntime {
|
|
|
157
178
|
const coordinator = this.coordinator;
|
|
158
179
|
this.orchestrator =
|
|
159
180
|
input.orchestrator ??
|
|
160
|
-
new Orchestrator(input.workflow.settings, this.clock,
|
|
181
|
+
new Orchestrator(input.workflow.settings, this.clock, input.claimStore,
|
|
161
182
|
// The coordinator IS the orchestrator's capacity authority (it satisfies
|
|
162
183
|
// the CapacityProbe shape directly). It is installed for the orchestrator's
|
|
163
184
|
// lifetime whenever it exists, but a reload can disable the underlying pool
|
|
@@ -208,6 +229,7 @@ export class LorenzRuntime {
|
|
|
208
229
|
blocked: orchestration.blocked.map((entry) => ({ ...entry })),
|
|
209
230
|
usageTotals: orchestration.usageTotals,
|
|
210
231
|
rateLimits: orchestration.rateLimits,
|
|
232
|
+
claimStore: orchestration.claimStore,
|
|
211
233
|
logFile: this.workflow.settings.logging.logFile,
|
|
212
234
|
});
|
|
213
235
|
}
|
|
@@ -246,9 +268,14 @@ export class LorenzRuntime {
|
|
|
246
268
|
void this.closeChangeStream();
|
|
247
269
|
// finishExternally (abort + release) mirrors the other abort sites and clears
|
|
248
270
|
// isActive, so the resulting agent_run_aborted rejection is treated as a clean
|
|
249
|
-
// shutdown in runClaim rather than recorded as a failed run.
|
|
250
|
-
|
|
251
|
-
|
|
271
|
+
// shutdown in runClaim rather than recorded as a failed run. Durable claims are
|
|
272
|
+
// abandoned only after the runner settles; until then a shared store must still
|
|
273
|
+
// show the slot as owned.
|
|
274
|
+
for (const handle of [...this.activeRuns.values()]) {
|
|
275
|
+
this.markStoppedClaimSettlementPending(handle);
|
|
276
|
+
handle.finishExternally(null, { abandonClaimOnSettlement: true });
|
|
277
|
+
}
|
|
278
|
+
this.stopClaimOwnerHeartbeatIfIdle();
|
|
252
279
|
this.retryScheduler.stop();
|
|
253
280
|
this.emit();
|
|
254
281
|
}
|
|
@@ -390,16 +417,16 @@ export class LorenzRuntime {
|
|
|
390
417
|
this.appStatus = this.inFlight.size > 0 ? "running" : "polling";
|
|
391
418
|
this.lastPollAt = this.clock.now().toISOString();
|
|
392
419
|
this.lastError = null;
|
|
393
|
-
this.emit();
|
|
394
420
|
const dispatched = [];
|
|
395
421
|
try {
|
|
422
|
+
this.emit();
|
|
396
423
|
await this.reloadWorkflowIfConfigured();
|
|
397
424
|
this.validateDispatch(this.workflow.settings);
|
|
398
425
|
await this.cleanupTerminalWorkspacesOnce();
|
|
399
|
-
this.reconcileStalledRuns();
|
|
426
|
+
await this.reconcileStalledRuns();
|
|
400
427
|
await this.reconcileTrackedIssues();
|
|
401
428
|
const issues = await this.client.fetchCandidateIssues();
|
|
402
|
-
const eligibleIssues = this.orchestrator.
|
|
429
|
+
const eligibleIssues = await this.orchestrator.eligibleIssuesAsync(issues);
|
|
403
430
|
if (!options.dryRun)
|
|
404
431
|
this.syncRetryTimersForIssues(issues);
|
|
405
432
|
this.candidates = issues.length;
|
|
@@ -416,7 +443,7 @@ export class LorenzRuntime {
|
|
|
416
443
|
await Promise.allSettled(dispatched);
|
|
417
444
|
}
|
|
418
445
|
this.pollStatus = "idle";
|
|
419
|
-
this.
|
|
446
|
+
this.updateAppStatusFromInFlight();
|
|
420
447
|
this.nextPollAt = new Date(this.clock.now().getTime() + this.workflow.settings.polling.intervalMs).toISOString();
|
|
421
448
|
}
|
|
422
449
|
catch (error) {
|
|
@@ -436,12 +463,11 @@ export class LorenzRuntime {
|
|
|
436
463
|
this.addEvent("dispatch_skipped", `${issue.identifier} missing_before_dispatch`);
|
|
437
464
|
return [];
|
|
438
465
|
}
|
|
439
|
-
const claim = this.orchestrator.
|
|
466
|
+
const claim = await this.orchestrator.claimAsync(refreshed);
|
|
440
467
|
if (!claim) {
|
|
441
468
|
this.addEvent("dispatch_skipped", `${refreshed.identifier} stale_before_dispatch`);
|
|
442
469
|
return [];
|
|
443
470
|
}
|
|
444
|
-
this.syncRetryTimer(refreshed.id);
|
|
445
471
|
const slotIndex = claim.kind === "running" ? claim.entry.slotIndex : claim.reservation.slotIndex;
|
|
446
472
|
const key = slotKey(refreshed.id, slotIndex);
|
|
447
473
|
const runId = `run-${this.nextRunNumber}`;
|
|
@@ -449,26 +475,44 @@ export class LorenzRuntime {
|
|
|
449
475
|
// The handle is registered for the WHOLE run lifecycle - including the reserved
|
|
450
476
|
// path's acquire window - so stop()/reconcile abort an in-acquire run (the
|
|
451
477
|
// signal reaches the pool's FIFO waiter) exactly as they abort a running one.
|
|
452
|
-
const handle = new ActiveRunHandle(key, runId, this.activeRuns);
|
|
478
|
+
const handle = new ActiveRunHandle(refreshed.id, slotIndex, key, runId, this.activeRuns);
|
|
453
479
|
this.activeRuns.set(key, handle);
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
480
|
+
try {
|
|
481
|
+
this.syncRetryTimer(refreshed.id);
|
|
482
|
+
await this.startClaimOwnerHeartbeat();
|
|
483
|
+
// On the static/local path the run starts immediately. On the pool-governed
|
|
484
|
+
// path run_reserving marks dispatch intent and run_started moves AFTER
|
|
485
|
+
// bindReservation (inside runReservedClaim): a capacity-refused dispatch
|
|
486
|
+
// never emits a phantom run_started.
|
|
487
|
+
if (claim.kind === "running") {
|
|
488
|
+
this.addEvent("run_started", `${refreshed.identifier} slot=${slotIndex}`);
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
this.addEvent("run_reserving", `${refreshed.identifier} slot=${slotIndex}`);
|
|
492
|
+
}
|
|
493
|
+
this.input.onIssueDispatched?.(refreshed);
|
|
460
494
|
}
|
|
461
|
-
|
|
462
|
-
|
|
495
|
+
catch (error) {
|
|
496
|
+
try {
|
|
497
|
+
await this.orchestrator.abandonClaimAsync(refreshed.id, slotIndex);
|
|
498
|
+
}
|
|
499
|
+
catch {
|
|
500
|
+
// Preserve the heartbeat failure; if the backend is unavailable, abandon may fail too.
|
|
501
|
+
}
|
|
502
|
+
finally {
|
|
503
|
+
handle.release();
|
|
504
|
+
this.stopClaimOwnerHeartbeatIfIdle();
|
|
505
|
+
}
|
|
506
|
+
throw error;
|
|
463
507
|
}
|
|
464
|
-
this.input.onIssueDispatched?.(refreshed);
|
|
465
508
|
const run = claim.kind === "running"
|
|
466
509
|
? this.runClaim(refreshed, claim.entry.slotIndex, claim.entry.agentKind, runId, claim.entry.workerHost ?? null, handle)
|
|
467
510
|
: this.runReservedClaim(refreshed, claim.reservation, runId, handle);
|
|
468
511
|
this.inFlight.add(run);
|
|
469
512
|
void run.finally(() => {
|
|
470
513
|
this.inFlight.delete(run);
|
|
471
|
-
this.
|
|
514
|
+
this.stopClaimOwnerHeartbeatIfIdle();
|
|
515
|
+
this.updateAppStatusFromInFlight();
|
|
472
516
|
this.emit();
|
|
473
517
|
});
|
|
474
518
|
this.emit();
|
|
@@ -484,6 +528,62 @@ export class LorenzRuntime {
|
|
|
484
528
|
return null;
|
|
485
529
|
}
|
|
486
530
|
}
|
|
531
|
+
async startClaimOwnerHeartbeat() {
|
|
532
|
+
await this.orchestrator.heartbeatClaimOwnerAsync();
|
|
533
|
+
if (this.claimOwnerHeartbeatTimer)
|
|
534
|
+
return;
|
|
535
|
+
this.claimOwnerHeartbeatTimer = this.clock.setTimeout(() => {
|
|
536
|
+
void this.heartbeatClaimOwnerWhileActive();
|
|
537
|
+
}, CLAIM_OWNER_HEARTBEAT_INTERVAL_MS);
|
|
538
|
+
this.claimOwnerHeartbeatTimer.unref?.();
|
|
539
|
+
}
|
|
540
|
+
async heartbeatClaimOwnerWhileActive() {
|
|
541
|
+
this.claimOwnerHeartbeatTimer = null;
|
|
542
|
+
if (this.activeRuns.size === 0 && this.pendingStoppedClaimSettlements === 0)
|
|
543
|
+
return;
|
|
544
|
+
try {
|
|
545
|
+
await this.orchestrator.heartbeatClaimOwnerAsync();
|
|
546
|
+
}
|
|
547
|
+
catch (error) {
|
|
548
|
+
this.handleClaimOwnerHeartbeatFailure(error);
|
|
549
|
+
}
|
|
550
|
+
if (this.activeRuns.size === 0 && this.pendingStoppedClaimSettlements === 0)
|
|
551
|
+
return;
|
|
552
|
+
this.claimOwnerHeartbeatTimer = this.clock.setTimeout(() => {
|
|
553
|
+
void this.heartbeatClaimOwnerWhileActive();
|
|
554
|
+
}, CLAIM_OWNER_HEARTBEAT_INTERVAL_MS);
|
|
555
|
+
this.claimOwnerHeartbeatTimer.unref?.();
|
|
556
|
+
}
|
|
557
|
+
handleClaimOwnerHeartbeatFailure(error) {
|
|
558
|
+
const message = `claim_owner_heartbeat_failed ${errorMessage(error)}`;
|
|
559
|
+
this.stopped = true;
|
|
560
|
+
this.appStatus = "error";
|
|
561
|
+
this.lastError = message;
|
|
562
|
+
for (const handle of [...this.activeRuns.values()]) {
|
|
563
|
+
this.markStoppedClaimSettlementPending(handle);
|
|
564
|
+
handle.finishExternally(null, { abandonClaimOnSettlement: true });
|
|
565
|
+
}
|
|
566
|
+
this.retryScheduler.stop();
|
|
567
|
+
this.addEvent("poll_error", message);
|
|
568
|
+
}
|
|
569
|
+
stopClaimOwnerHeartbeatIfIdle() {
|
|
570
|
+
if (this.activeRuns.size > 0)
|
|
571
|
+
return;
|
|
572
|
+
if (this.pendingStoppedClaimSettlements > 0)
|
|
573
|
+
return;
|
|
574
|
+
this.stopClaimOwnerHeartbeat();
|
|
575
|
+
}
|
|
576
|
+
stopClaimOwnerHeartbeat() {
|
|
577
|
+
if (!this.claimOwnerHeartbeatTimer)
|
|
578
|
+
return;
|
|
579
|
+
this.clock.clearTimeout(this.claimOwnerHeartbeatTimer);
|
|
580
|
+
this.claimOwnerHeartbeatTimer = null;
|
|
581
|
+
}
|
|
582
|
+
updateAppStatusFromInFlight() {
|
|
583
|
+
if (this.appStatus === "error")
|
|
584
|
+
return;
|
|
585
|
+
this.appStatus = this.inFlight.size > 0 ? "running" : "idle";
|
|
586
|
+
}
|
|
487
587
|
/**
|
|
488
588
|
* Phase 1 -> negotiation -> phase 2 for a pool-governed (reserved) claim: drive the
|
|
489
589
|
* coordinator's acquire inside this detached per-run promise (a cold provision never blocks
|
|
@@ -498,8 +598,9 @@ export class LorenzRuntime {
|
|
|
498
598
|
// production implies a coordinator. An injected probe without one (test
|
|
499
599
|
// wiring) is treated like an acquire fault: cancel and skip, never strand.
|
|
500
600
|
this.addEvent("dispatch_skipped", `${issue.identifier} worker_pool_acquire_error coordinator_missing`);
|
|
501
|
-
this.
|
|
502
|
-
|
|
601
|
+
await this.cancelReservationAfterSkippedAcquire(issue, reservation, handle, {
|
|
602
|
+
syncRetryTimer: true,
|
|
603
|
+
});
|
|
503
604
|
return;
|
|
504
605
|
}
|
|
505
606
|
let acquired;
|
|
@@ -535,9 +636,9 @@ export class LorenzRuntime {
|
|
|
535
636
|
// coordinator already settled any just-bound lease healthy before throwing,
|
|
536
637
|
// so there is nothing to settle here.
|
|
537
638
|
this.addEvent("dispatch_skipped", `${issue.identifier} worker_pool_acquire_error ${errorMessage(error)}`);
|
|
538
|
-
this.
|
|
539
|
-
|
|
540
|
-
|
|
639
|
+
await this.cancelReservationAfterSkippedAcquire(issue, reservation, handle, {
|
|
640
|
+
syncRetryTimer: true,
|
|
641
|
+
});
|
|
541
642
|
return;
|
|
542
643
|
}
|
|
543
644
|
if (acquired.status !== "bound") {
|
|
@@ -548,13 +649,51 @@ export class LorenzRuntime {
|
|
|
548
649
|
// affinity and attempt counter intact; never record history for a run that
|
|
549
650
|
// did not start.
|
|
550
651
|
this.addEvent("dispatch_skipped", `${issue.identifier} worker_host_capacity`);
|
|
551
|
-
this.
|
|
552
|
-
|
|
553
|
-
|
|
652
|
+
await this.cancelReservationAfterSkippedAcquire(issue, reservation, handle, {
|
|
653
|
+
syncRetryTimer: true,
|
|
654
|
+
});
|
|
554
655
|
return;
|
|
555
656
|
}
|
|
556
657
|
const slot = acquired.slot;
|
|
557
|
-
|
|
658
|
+
let entry;
|
|
659
|
+
try {
|
|
660
|
+
entry = await this.orchestrator.bindReservationAsync(reservation, slot.workerHost);
|
|
661
|
+
}
|
|
662
|
+
catch (error) {
|
|
663
|
+
const bindError = errorMessage(error);
|
|
664
|
+
let releaseErrorMessage = null;
|
|
665
|
+
try {
|
|
666
|
+
await slot.release("healthy");
|
|
667
|
+
}
|
|
668
|
+
catch (releaseError) {
|
|
669
|
+
releaseErrorMessage = errorMessage(releaseError);
|
|
670
|
+
}
|
|
671
|
+
handle.release();
|
|
672
|
+
const bindFailureMessage = `claim_bind_failed ${bindError}`;
|
|
673
|
+
this.markRuntimeError(bindFailureMessage);
|
|
674
|
+
let retrySyncError = null;
|
|
675
|
+
if (handle.abandonClaimOnSettlement) {
|
|
676
|
+
await this.settleStoppedClaim(handle, issue.id, reservation.slotIndex);
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
try {
|
|
680
|
+
await this.orchestrator.abandonClaimAsync(issue.id, reservation.slotIndex);
|
|
681
|
+
retrySyncError = this.syncRetryTimerSafely(issue.id);
|
|
682
|
+
}
|
|
683
|
+
catch {
|
|
684
|
+
// Preserve the bind failure event; if the backend is unavailable, abandon may fail too.
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
this.stopClaimOwnerHeartbeatIfIdle();
|
|
688
|
+
this.addEvent("dispatch_skipped", `${issue.identifier} bind_reservation_error ${bindError}`);
|
|
689
|
+
if (releaseErrorMessage) {
|
|
690
|
+
this.addEvent("dispatch_skipped", `${issue.identifier} bind_reservation_release_error ${releaseErrorMessage}`);
|
|
691
|
+
}
|
|
692
|
+
this.addEvent("poll_error", bindFailureMessage);
|
|
693
|
+
if (retrySyncError)
|
|
694
|
+
this.addEvent("poll_error", retrySyncError);
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
558
697
|
if (!entry) {
|
|
559
698
|
// The reservation was cancelled/expired during the acquire (cleanup, stop,
|
|
560
699
|
// or the expiry sweep): release the bound worker back to warm inventory (the
|
|
@@ -562,16 +701,60 @@ export class LorenzRuntime {
|
|
|
562
701
|
await slot.release("healthy");
|
|
563
702
|
this.addEvent("dispatch_skipped", `${issue.identifier} reservation_lapsed`);
|
|
564
703
|
handle.release();
|
|
704
|
+
await this.settleStoppedClaim(handle, issue.id, reservation.slotIndex);
|
|
565
705
|
return;
|
|
566
706
|
}
|
|
567
707
|
this.addEvent("run_started", `${issue.identifier} slot=${reservation.slotIndex}`);
|
|
568
708
|
await this.runClaim(issue, reservation.slotIndex, reservation.agentKind, runId, slot.workerHost, handle, slot);
|
|
569
709
|
}
|
|
710
|
+
async cancelReservationAfterSkippedAcquire(issue, reservation, handle, options = {}) {
|
|
711
|
+
let cancelled = false;
|
|
712
|
+
let cancelError;
|
|
713
|
+
try {
|
|
714
|
+
await this.orchestrator.cancelReservationAsync(reservation);
|
|
715
|
+
cancelled = true;
|
|
716
|
+
}
|
|
717
|
+
catch (error) {
|
|
718
|
+
cancelError = error;
|
|
719
|
+
}
|
|
720
|
+
finally {
|
|
721
|
+
handle.release();
|
|
722
|
+
await this.settleStoppedClaim(handle, issue.id, reservation.slotIndex);
|
|
723
|
+
this.stopClaimOwnerHeartbeatIfIdle();
|
|
724
|
+
}
|
|
725
|
+
if (cancelled && options.syncRetryTimer) {
|
|
726
|
+
const retrySyncError = this.syncRetryTimerSafely(issue.id);
|
|
727
|
+
if (retrySyncError)
|
|
728
|
+
this.addEvent("poll_error", retrySyncError);
|
|
729
|
+
}
|
|
730
|
+
if (!cancelError)
|
|
731
|
+
return;
|
|
732
|
+
const message = `claim_cancel_failed ${errorMessage(cancelError)}`;
|
|
733
|
+
if (this.appStatus !== "error") {
|
|
734
|
+
this.appStatus = "error";
|
|
735
|
+
this.lastError = message;
|
|
736
|
+
}
|
|
737
|
+
this.addEvent("poll_error", message);
|
|
738
|
+
}
|
|
570
739
|
async runClaim(issue, slotIndex, agentKind, runId, workerHost, handle, slot = null) {
|
|
571
740
|
const startedAt = this.clock.now().toISOString();
|
|
572
741
|
const effectiveWorkerHost = workerHost;
|
|
573
742
|
let workerOutcome = "healthy";
|
|
574
743
|
const heartbeatSlot = slot;
|
|
744
|
+
let claimStoreRuntimeError = null;
|
|
745
|
+
let updateQueue = Promise.resolve();
|
|
746
|
+
const enqueueUpdate = (update) => {
|
|
747
|
+
const next = updateQueue.then(async () => {
|
|
748
|
+
heartbeatSlot?.heartbeat();
|
|
749
|
+
await this.orchestrator.applyUpdateAsync(issue.id, slotIndex, update);
|
|
750
|
+
this.addEvent(update.type, agentUpdateRuntimeMessage(issue.identifier, update));
|
|
751
|
+
this.input.onAgentUpdate?.(issue, update);
|
|
752
|
+
});
|
|
753
|
+
updateQueue = next.catch((error) => {
|
|
754
|
+
claimStoreRuntimeError ??= new ClaimStoreRuntimeError("claim_update_failed", error);
|
|
755
|
+
handle.abort();
|
|
756
|
+
});
|
|
757
|
+
};
|
|
575
758
|
try {
|
|
576
759
|
const result = await this.runner({
|
|
577
760
|
issue,
|
|
@@ -588,26 +771,33 @@ export class LorenzRuntime {
|
|
|
588
771
|
// path; force the per-slot suffix whenever co-residence is possible.
|
|
589
772
|
// Single-tenant (default) keeps the bare path.
|
|
590
773
|
forceSlotSuffix: (this.workflow.settings.worker.workerPool?.slotsPerMachine ?? 1) > 1,
|
|
591
|
-
onUpdate:
|
|
592
|
-
heartbeatSlot?.heartbeat();
|
|
593
|
-
this.orchestrator.applyUpdate(issue.id, slotIndex, update);
|
|
594
|
-
this.addEvent(update.type, agentUpdateRuntimeMessage(issue.identifier, update));
|
|
595
|
-
this.input.onAgentUpdate?.(issue, update);
|
|
596
|
-
},
|
|
774
|
+
onUpdate: enqueueUpdate,
|
|
597
775
|
fetchIssue: async (current) => {
|
|
598
776
|
const refreshed = await this.client.fetchIssuesByIds([current.id]);
|
|
599
777
|
return refreshed[0] ?? current;
|
|
600
778
|
},
|
|
601
779
|
abortSignal: handle.signal,
|
|
602
780
|
});
|
|
781
|
+
await updateQueue;
|
|
782
|
+
if (claimStoreRuntimeError)
|
|
783
|
+
throwRuntimeError(claimStoreRuntimeError);
|
|
603
784
|
if (!handle.isActive)
|
|
604
785
|
return;
|
|
605
786
|
const finalIssue = result.finalIssue ?? (await this.fetchIssueOrSelf(issue));
|
|
606
787
|
if (!handle.isActive)
|
|
607
788
|
return;
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
789
|
+
let finished;
|
|
790
|
+
try {
|
|
791
|
+
finished = await this.orchestrator.finishAsync(issue.id, slotIndex, true, undefined, "continuation");
|
|
792
|
+
}
|
|
793
|
+
catch (error) {
|
|
794
|
+
this.recordClaimStoreFailure("claim_finish_failed", error);
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
if (!finished) {
|
|
798
|
+
this.addEvent("dispatch_skipped", `${issue.identifier} claim_lost_before_finish`);
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
611
801
|
this.recordHistory(buildRunHistoryEntry({
|
|
612
802
|
id: runId,
|
|
613
803
|
issue,
|
|
@@ -616,15 +806,30 @@ export class LorenzRuntime {
|
|
|
616
806
|
agentKind,
|
|
617
807
|
outcome: "success",
|
|
618
808
|
turnCount: result.turnCount,
|
|
619
|
-
runningEntry:
|
|
809
|
+
runningEntry: finished,
|
|
620
810
|
workspacePath: result.workspace,
|
|
621
811
|
startedAt,
|
|
622
812
|
endedAt: this.clock.now().toISOString(),
|
|
623
813
|
durationMs: durationMs(startedAt, this.clock.now().toISOString()),
|
|
624
814
|
}));
|
|
815
|
+
const retrySyncError = this.syncRetryTimerSafely(issue.id);
|
|
625
816
|
this.addEvent("run_completed", `${issue.identifier} turns=${result.turnCount}`);
|
|
817
|
+
if (retrySyncError)
|
|
818
|
+
this.addEvent("poll_error", retrySyncError);
|
|
626
819
|
}
|
|
627
820
|
catch (error) {
|
|
821
|
+
await updateQueue;
|
|
822
|
+
const runtimeError = error instanceof ClaimStoreRuntimeError ? error : claimStoreRuntimeError;
|
|
823
|
+
if (runtimeError) {
|
|
824
|
+
this.recordClaimStoreFailure(runtimeError.reason, runtimeError.original);
|
|
825
|
+
try {
|
|
826
|
+
await this.orchestrator.abandonClaimAsync(issue.id, slotIndex);
|
|
827
|
+
}
|
|
828
|
+
catch (abandonError) {
|
|
829
|
+
this.recordClaimStoreFailure("claim_abandon_failed", abandonError);
|
|
830
|
+
}
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
628
833
|
// Classify the worker outcome BEFORE any early return so a run finished
|
|
629
834
|
// externally (e.g. a stall reconciliation aborted it -> the runner throws
|
|
630
835
|
// `agent_run_aborted`) still poisons the worker: a stall-finished run is
|
|
@@ -636,26 +841,36 @@ export class LorenzRuntime {
|
|
|
636
841
|
// run_failed event the TUI renders as a red error banner on Ctrl+C.
|
|
637
842
|
if (!handle.isActive)
|
|
638
843
|
return;
|
|
639
|
-
|
|
640
|
-
|
|
844
|
+
let finished;
|
|
845
|
+
try {
|
|
846
|
+
finished = await this.orchestrator.finishAsync(issue.id, slotIndex, true, errorMessage(error), "failure");
|
|
847
|
+
}
|
|
848
|
+
catch (finishError) {
|
|
849
|
+
this.recordClaimStoreFailure("claim_finish_failed", finishError);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
if (!finished) {
|
|
853
|
+
this.addEvent("dispatch_skipped", `${issue.identifier} claim_lost_before_finish`);
|
|
641
854
|
return;
|
|
642
|
-
|
|
643
|
-
this.syncRetryTimer(issue.id);
|
|
855
|
+
}
|
|
644
856
|
this.recordHistory(buildRunHistoryEntry({
|
|
645
857
|
id: runId,
|
|
646
858
|
issue,
|
|
647
859
|
slotIndex,
|
|
648
860
|
agentKind,
|
|
649
861
|
outcome: "failed",
|
|
650
|
-
turnCount:
|
|
651
|
-
runningEntry:
|
|
862
|
+
turnCount: finished.turnCount,
|
|
863
|
+
runningEntry: finished,
|
|
652
864
|
startedAt,
|
|
653
865
|
endedAt: this.clock.now().toISOString(),
|
|
654
866
|
durationMs: durationMs(startedAt, this.clock.now().toISOString()),
|
|
655
867
|
error: errorMessage(error),
|
|
656
868
|
fallbackLastEvent: "turn_failed",
|
|
657
869
|
}));
|
|
870
|
+
const retrySyncError = this.syncRetryTimerSafely(issue.id);
|
|
658
871
|
this.addEvent("run_failed", `${issue.identifier} ${errorMessage(error)}`);
|
|
872
|
+
if (retrySyncError)
|
|
873
|
+
this.addEvent("poll_error", retrySyncError);
|
|
659
874
|
}
|
|
660
875
|
finally {
|
|
661
876
|
handle.release();
|
|
@@ -680,6 +895,32 @@ export class LorenzRuntime {
|
|
|
680
895
|
await slot.release("healthy");
|
|
681
896
|
}
|
|
682
897
|
}
|
|
898
|
+
await this.settleStoppedClaim(handle, issue.id, slotIndex);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
markStoppedClaimSettlementPending(handle) {
|
|
902
|
+
if (handle.abandonClaimOnSettlement)
|
|
903
|
+
return;
|
|
904
|
+
this.pendingStoppedClaimSettlements += 1;
|
|
905
|
+
}
|
|
906
|
+
async settleStoppedClaim(handle, issueId, slotIndex) {
|
|
907
|
+
if (!handle.abandonClaimOnSettlement)
|
|
908
|
+
return;
|
|
909
|
+
handle.abandonClaimOnSettlement = false;
|
|
910
|
+
try {
|
|
911
|
+
await this.orchestrator.abandonClaimAsync(issueId, slotIndex);
|
|
912
|
+
}
|
|
913
|
+
catch (error) {
|
|
914
|
+
const message = `claim_abandon_failed ${errorMessage(error)}`;
|
|
915
|
+
if (this.appStatus !== "error") {
|
|
916
|
+
this.appStatus = "error";
|
|
917
|
+
this.lastError = message;
|
|
918
|
+
}
|
|
919
|
+
this.addEvent("poll_error", message);
|
|
920
|
+
}
|
|
921
|
+
finally {
|
|
922
|
+
this.pendingStoppedClaimSettlements = Math.max(0, this.pendingStoppedClaimSettlements - 1);
|
|
923
|
+
this.stopClaimOwnerHeartbeatIfIdle();
|
|
683
924
|
}
|
|
684
925
|
}
|
|
685
926
|
async fetchIssueOrSelf(issue) {
|
|
@@ -717,12 +958,14 @@ export class LorenzRuntime {
|
|
|
717
958
|
// applied, so dispatch can never use settings that do not match the live pool.
|
|
718
959
|
//
|
|
719
960
|
// The coordinator (and its pool) is a reload-surviving singleton: diff
|
|
720
|
-
// prev-vs-next worker-pool settings instead of being reconstructed.
|
|
721
|
-
//
|
|
722
|
-
//
|
|
723
|
-
//
|
|
724
|
-
//
|
|
725
|
-
//
|
|
961
|
+
// prev-vs-next worker-pool settings instead of being reconstructed. The pool is
|
|
962
|
+
// the single dispatch path, so a parsed config always carries a worker_pool (an
|
|
963
|
+
// absent block defaults to the enabled `local` pool). The
|
|
964
|
+
// `disabledWorkerPoolSettings(prevWorkerPool)` fallback only fires for a settings
|
|
965
|
+
// object built outside parseConfig that genuinely omits the block; reconcile then
|
|
966
|
+
// drains the live pool to zero instead of leaking its (paid) workers. A present
|
|
967
|
+
// block (including an explicit `enabled: false`) reconciles directly: reconcile
|
|
968
|
+
// handles the disable-and-drain itself.
|
|
726
969
|
if (this.coordinator) {
|
|
727
970
|
const next = workflow.settings.worker.workerPool ?? disabledWorkerPoolSettings(prevWorkerPool);
|
|
728
971
|
// Awaited: reconcile is async so the coordinator's injected driverLoader
|
|
@@ -747,29 +990,41 @@ export class LorenzRuntime {
|
|
|
747
990
|
}
|
|
748
991
|
}
|
|
749
992
|
async reconcileTrackedIssues() {
|
|
750
|
-
const snapshot = this.orchestrator.
|
|
993
|
+
const snapshot = await this.orchestrator.snapshotAsync();
|
|
751
994
|
const tracked = new Map();
|
|
752
995
|
// Reserving (in-acquire) slots are tracked host-less so an issue that goes
|
|
753
996
|
// terminal mid-acquire is still aborted and cleaned up; running/retrying
|
|
754
997
|
// entries below override with their richer metadata when present.
|
|
755
|
-
for (const entry of snapshot.reserving)
|
|
998
|
+
for (const entry of snapshot.reserving) {
|
|
999
|
+
if (!(await this.orchestrator.ownsClaimAsync(entry.issueId, entry.slotIndex)))
|
|
1000
|
+
continue;
|
|
756
1001
|
tracked.set(entry.issueId, {
|
|
1002
|
+
kind: "claim",
|
|
757
1003
|
identifier: entry.identifier,
|
|
758
1004
|
workerHost: null,
|
|
759
1005
|
workspacePath: null,
|
|
760
1006
|
});
|
|
761
|
-
|
|
1007
|
+
}
|
|
1008
|
+
for (const entry of snapshot.running) {
|
|
1009
|
+
if (!(await this.orchestrator.ownsClaimAsync(entry.issue.id, entry.slotIndex)))
|
|
1010
|
+
continue;
|
|
762
1011
|
tracked.set(entry.issue.id, {
|
|
1012
|
+
kind: "claim",
|
|
763
1013
|
identifier: entry.issue.identifier,
|
|
764
1014
|
workerHost: entry.workerHost,
|
|
765
1015
|
workspacePath: entry.workspacePath,
|
|
766
1016
|
});
|
|
767
|
-
|
|
1017
|
+
}
|
|
1018
|
+
for (const entry of snapshot.retrying) {
|
|
1019
|
+
if (tracked.has(entry.issueId))
|
|
1020
|
+
continue;
|
|
768
1021
|
tracked.set(entry.issueId, {
|
|
1022
|
+
kind: "retry",
|
|
769
1023
|
identifier: entry.identifier,
|
|
770
1024
|
workerHost: entry.workerHost,
|
|
771
1025
|
workspacePath: entry.workspacePath,
|
|
772
1026
|
});
|
|
1027
|
+
}
|
|
773
1028
|
if (tracked.size === 0)
|
|
774
1029
|
return;
|
|
775
1030
|
let refreshed;
|
|
@@ -782,18 +1037,25 @@ export class LorenzRuntime {
|
|
|
782
1037
|
}
|
|
783
1038
|
const refreshedIds = new Set(refreshed.map((issue) => issue.id));
|
|
784
1039
|
for (const issue of refreshed) {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
1040
|
+
const meta = tracked.get(issue.id);
|
|
1041
|
+
const active = issueIsActive(issue, this.workflow.settings);
|
|
1042
|
+
const routed = routedToThisWorker(issue, this.workflow.settings);
|
|
1043
|
+
if (active && routed && !issueHasOpenBlockers(issue, this.workflow.settings)) {
|
|
1044
|
+
await this.orchestrator.refreshRunningIssueAsync(issue);
|
|
1045
|
+
continue;
|
|
1046
|
+
}
|
|
1047
|
+
try {
|
|
1048
|
+
await this.orchestrator.cleanupIssueAsync(issue.id);
|
|
1049
|
+
}
|
|
1050
|
+
catch (error) {
|
|
1051
|
+
this.recordClaimStoreFailure("claim_cleanup_failed", error);
|
|
789
1052
|
continue;
|
|
790
1053
|
}
|
|
791
1054
|
this.abortIssueRuns(issue.id);
|
|
792
|
-
this.orchestrator.cleanupIssue(issue.id);
|
|
793
1055
|
this.clearRetryTimer(issue.id);
|
|
794
1056
|
const reason = reconciliationStopReason(issue, this.workflow.settings);
|
|
795
1057
|
if (isTerminalState(issue.state, this.workflow.settings.tracker.terminalStates)) {
|
|
796
|
-
await this.removeIssueWorkspaces(this.workflow.settings, issue.identifier ||
|
|
1058
|
+
await this.removeIssueWorkspaces(this.workflow.settings, issue.identifier || meta?.identifier, meta?.workerHost, issue);
|
|
797
1059
|
this.addEvent("workspace_cleanup", `${issue.identifier} ${reason}`);
|
|
798
1060
|
}
|
|
799
1061
|
else {
|
|
@@ -803,15 +1065,26 @@ export class LorenzRuntime {
|
|
|
803
1065
|
for (const [issueId, meta] of tracked.entries()) {
|
|
804
1066
|
if (refreshedIds.has(issueId))
|
|
805
1067
|
continue;
|
|
1068
|
+
try {
|
|
1069
|
+
await this.orchestrator.cleanupIssueAsync(issueId);
|
|
1070
|
+
}
|
|
1071
|
+
catch (error) {
|
|
1072
|
+
this.recordClaimStoreFailure("claim_cleanup_failed", error);
|
|
1073
|
+
continue;
|
|
1074
|
+
}
|
|
806
1075
|
this.abortIssueRuns(issueId);
|
|
807
|
-
this.orchestrator.cleanupIssue(issueId);
|
|
808
1076
|
this.clearRetryTimer(issueId);
|
|
809
1077
|
this.addEvent("run_reconciled", `${meta.identifier} missing`);
|
|
810
1078
|
}
|
|
811
1079
|
}
|
|
812
|
-
reconcileStalledRuns() {
|
|
813
|
-
|
|
814
|
-
|
|
1080
|
+
async reconcileStalledRuns() {
|
|
1081
|
+
// Let already-settled runner and run-claim continuations finish before acting on a stale snapshot.
|
|
1082
|
+
await Promise.resolve();
|
|
1083
|
+
await Promise.resolve();
|
|
1084
|
+
for (const snapshotEntry of (await this.orchestrator.snapshotAsync()).running) {
|
|
1085
|
+
if (!(await this.orchestrator.ownsClaimAsync(snapshotEntry.issue.id, snapshotEntry.slotIndex)))
|
|
1086
|
+
continue;
|
|
1087
|
+
const currentEntry = await this.runningEntry(snapshotEntry.issue.id, snapshotEntry.slotIndex);
|
|
815
1088
|
if (!currentEntry)
|
|
816
1089
|
continue;
|
|
817
1090
|
const effective = settingsForIssueState(this.workflow.settings, currentEntry.issue.state);
|
|
@@ -829,11 +1102,22 @@ export class LorenzRuntime {
|
|
|
829
1102
|
const activeHandle = this.activeRuns.get(key);
|
|
830
1103
|
const runId = activeHandle?.runId ?? `stalled-${currentEntry.issue.id}-${currentEntry.slotIndex}`;
|
|
831
1104
|
const error = `agent_stalled after ${timeoutMs}ms`;
|
|
832
|
-
const entry = this.runningEntry(snapshotEntry.issue.id, snapshotEntry.slotIndex);
|
|
1105
|
+
const entry = await this.runningEntry(snapshotEntry.issue.id, snapshotEntry.slotIndex);
|
|
833
1106
|
if (!entry)
|
|
834
1107
|
continue;
|
|
835
|
-
|
|
836
|
-
|
|
1108
|
+
let finished;
|
|
1109
|
+
try {
|
|
1110
|
+
finished = await this.orchestrator.finishAsync(entry.issue.id, entry.slotIndex, true, error, "failure");
|
|
1111
|
+
}
|
|
1112
|
+
catch (finishError) {
|
|
1113
|
+
this.recordClaimStoreFailure("claim_finish_failed", finishError);
|
|
1114
|
+
continue;
|
|
1115
|
+
}
|
|
1116
|
+
if (!finished) {
|
|
1117
|
+
activeHandle?.finishExternally();
|
|
1118
|
+
this.addEvent("dispatch_skipped", `${entry.identifier} claim_lost_before_finish`);
|
|
1119
|
+
continue;
|
|
1120
|
+
}
|
|
837
1121
|
activeHandle?.finishExternally("stalled");
|
|
838
1122
|
const endedAt = this.clock.now().toISOString();
|
|
839
1123
|
this.recordHistory(buildRunHistoryEntry({
|
|
@@ -851,13 +1135,14 @@ export class LorenzRuntime {
|
|
|
851
1135
|
error,
|
|
852
1136
|
fallbackLastEvent: "agent_stalled",
|
|
853
1137
|
}));
|
|
1138
|
+
const retrySyncError = this.syncRetryTimerSafely(entry.issue.id);
|
|
854
1139
|
this.addEvent("run_stalled", `${entry.identifier} ${error}`);
|
|
1140
|
+
if (retrySyncError)
|
|
1141
|
+
this.addEvent("poll_error", retrySyncError);
|
|
855
1142
|
}
|
|
856
1143
|
}
|
|
857
|
-
runningEntry(issueId, slotIndex) {
|
|
858
|
-
return this.orchestrator
|
|
859
|
-
.snapshot()
|
|
860
|
-
.running.find((entry) => entry.issue.id === issueId && entry.slotIndex === slotIndex);
|
|
1144
|
+
async runningEntry(issueId, slotIndex) {
|
|
1145
|
+
return (await this.orchestrator.snapshotAsync()).running.find((entry) => entry.issue.id === issueId && entry.slotIndex === slotIndex);
|
|
861
1146
|
}
|
|
862
1147
|
// Cleanup is driven by what is actually on disk: list existing per-issue workspace
|
|
863
1148
|
// directories and look up just those issues, instead of enumerating every terminal
|
|
@@ -905,23 +1190,27 @@ export class LorenzRuntime {
|
|
|
905
1190
|
return;
|
|
906
1191
|
}
|
|
907
1192
|
this.retryScheduler.sync(runtimeRetryEntry(retry), (scheduled) => {
|
|
908
|
-
|
|
909
|
-
.
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
current
|
|
913
|
-
|
|
914
|
-
|
|
1193
|
+
try {
|
|
1194
|
+
const current = this.orchestrator
|
|
1195
|
+
.snapshot()
|
|
1196
|
+
.retrying.find((entry) => entry.issueId === scheduled.issueId);
|
|
1197
|
+
if (!current ||
|
|
1198
|
+
current.attempt !== scheduled.attempt ||
|
|
1199
|
+
current.dueAtIso !== scheduled.dueAtIso) {
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
this.addEvent("retry_timer_due", `${scheduled.issueIdentifier} attempt=${scheduled.attempt}`);
|
|
1203
|
+
if (this.pollInProgress) {
|
|
1204
|
+
this.queuePendingPoll({}, true);
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
this.pollOnce().catch((error) => {
|
|
1208
|
+
this.recordRetryTimerError(error);
|
|
1209
|
+
});
|
|
915
1210
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
this.queuePendingPoll({}, true);
|
|
919
|
-
return;
|
|
1211
|
+
catch (error) {
|
|
1212
|
+
this.recordRetryTimerError(error);
|
|
920
1213
|
}
|
|
921
|
-
this.pollOnce().catch((error) => {
|
|
922
|
-
this.lastError = errorMessage(error);
|
|
923
|
-
this.addEvent("retry_timer_error", this.lastError);
|
|
924
|
-
});
|
|
925
1214
|
});
|
|
926
1215
|
}
|
|
927
1216
|
clearRetryTimer(issueId) {
|
|
@@ -939,6 +1228,33 @@ export class LorenzRuntime {
|
|
|
939
1228
|
recordHistory(entry) {
|
|
940
1229
|
this.projection.recordRunHistory(entry);
|
|
941
1230
|
}
|
|
1231
|
+
recordRetryTimerError(error) {
|
|
1232
|
+
const message = errorMessage(error);
|
|
1233
|
+
this.markRuntimeError(message);
|
|
1234
|
+
this.addEvent("retry_timer_error", message);
|
|
1235
|
+
}
|
|
1236
|
+
recordClaimStoreFailure(reason, error) {
|
|
1237
|
+
const message = `${reason} ${errorMessage(error)}`;
|
|
1238
|
+
this.markRuntimeError(message);
|
|
1239
|
+
this.addEvent("poll_error", message);
|
|
1240
|
+
}
|
|
1241
|
+
syncRetryTimerSafely(issueId) {
|
|
1242
|
+
try {
|
|
1243
|
+
this.syncRetryTimer(issueId);
|
|
1244
|
+
return null;
|
|
1245
|
+
}
|
|
1246
|
+
catch (error) {
|
|
1247
|
+
const message = `retry_timer_sync_failed ${errorMessage(error)}`;
|
|
1248
|
+
this.markRuntimeError(message);
|
|
1249
|
+
return message;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
markRuntimeError(message) {
|
|
1253
|
+
if (this.appStatus !== "error") {
|
|
1254
|
+
this.appStatus = "error";
|
|
1255
|
+
this.lastError = message;
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
942
1258
|
addEvent(type, message) {
|
|
943
1259
|
const event = { type, message, at: this.clock.now().toISOString() };
|
|
944
1260
|
this.projection.recordEvent(event);
|
|
@@ -966,7 +1282,15 @@ export class LorenzRuntime {
|
|
|
966
1282
|
return this.input.appendLogEvent(logFile, event);
|
|
967
1283
|
}
|
|
968
1284
|
emit() {
|
|
969
|
-
|
|
1285
|
+
let snapshot;
|
|
1286
|
+
try {
|
|
1287
|
+
snapshot = this.snapshot();
|
|
1288
|
+
}
|
|
1289
|
+
catch (error) {
|
|
1290
|
+
if (this.appStatus === "error")
|
|
1291
|
+
return;
|
|
1292
|
+
throw error;
|
|
1293
|
+
}
|
|
970
1294
|
for (const listener of this.listeners)
|
|
971
1295
|
listener(snapshot);
|
|
972
1296
|
}
|
|
@@ -1109,13 +1433,13 @@ function disabledWorkerPoolSettings(prev) {
|
|
|
1109
1433
|
/**
|
|
1110
1434
|
* Wraps a bare {@link WorkerPool} in a null-endpoint passthrough {@link DispatchCoordinator} so the
|
|
1111
1435
|
* runtime drives every run through the uniform coordinator surface while a bare-pool injection
|
|
1112
|
-
* stays byte-identical at the runtime boundary.
|
|
1113
|
-
* (`
|
|
1436
|
+
* stays byte-identical at the runtime boundary. The null manager mints nothing
|
|
1437
|
+
* (`perRunClaimEnforcement=false`, every `RunSlot.mcpEndpoint=null`), so this is a passthrough over
|
|
1114
1438
|
* the pool: `acquireRunSlot` delegates to `pool.acquire`, settle delegates straight to the
|
|
1115
1439
|
* `WorkerLease`, and `reconcile`/`drain`/`governs`/`canAcquire` forward verbatim. Returns
|
|
1116
1440
|
* `undefined` when no pool is supplied (the static/local path).
|
|
1117
1441
|
*
|
|
1118
|
-
* `settings` only needs to satisfy the coordinator's constructor;
|
|
1442
|
+
* `settings` only needs to satisfy the coordinator's constructor; this wrapper does
|
|
1119
1443
|
* not read it past construction (the pool owns live settings), so the live `worker.workerPool`
|
|
1120
1444
|
* settings are passed when present and a disabled placeholder otherwise.
|
|
1121
1445
|
*/
|