open-multi-agent-kit 0.98.4 → 0.98.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +3 -2
- package/dist/commands/run-command.d.ts +2 -1
- package/dist/commands/run-command.d.ts.map +1 -1
- package/dist/commands/run-command.js +9 -1
- package/dist/commands/run-command.js.map +1 -1
- package/dist/commands/verified-run-cli.d.ts +6 -0
- package/dist/commands/verified-run-cli.d.ts.map +1 -0
- package/dist/commands/verified-run-cli.js +190 -0
- package/dist/commands/verified-run-cli.js.map +1 -0
- package/dist/core/agent-session-services.d.ts +8 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +41 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +7 -8
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +61 -41
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/prompt-settlement.d.ts +4 -3
- package/dist/core/prompt-settlement.d.ts.map +1 -1
- package/dist/core/prompt-settlement.js.map +1 -1
- package/dist/core/run-budget-policy.d.ts +18 -0
- package/dist/core/run-budget-policy.d.ts.map +1 -0
- package/dist/core/run-budget-policy.js +52 -0
- package/dist/core/run-budget-policy.js.map +1 -0
- package/dist/core/run-budget.d.ts +33 -0
- package/dist/core/run-budget.d.ts.map +1 -0
- package/dist/core/run-budget.js +89 -0
- package/dist/core/run-budget.js.map +1 -0
- package/dist/core/run-execution-api.d.ts +15 -0
- package/dist/core/run-execution-api.d.ts.map +1 -0
- package/dist/core/run-execution-api.js +7 -0
- package/dist/core/run-execution-api.js.map +1 -0
- package/dist/core/run-journal.d.ts.map +1 -1
- package/dist/core/run-journal.js +30 -208
- package/dist/core/run-journal.js.map +1 -1
- package/dist/core/session-bash-service.d.ts +2 -2
- package/dist/core/session-bash-service.d.ts.map +1 -1
- package/dist/core/session-bash-service.js +21 -9
- package/dist/core/session-bash-service.js.map +1 -1
- package/dist/core/session-failure-cause.d.ts.map +1 -1
- package/dist/core/session-failure-cause.js +5 -0
- package/dist/core/session-failure-cause.js.map +1 -1
- package/dist/core/session-prompt-lifecycle.d.ts +25 -0
- package/dist/core/session-prompt-lifecycle.d.ts.map +1 -0
- package/dist/core/session-prompt-lifecycle.js +87 -0
- package/dist/core/session-prompt-lifecycle.js.map +1 -0
- package/dist/core/session-run-budget.d.ts +28 -0
- package/dist/core/session-run-budget.d.ts.map +1 -0
- package/dist/core/session-run-budget.js +127 -0
- package/dist/core/session-run-budget.js.map +1 -0
- package/dist/core/session-run-termination.d.ts.map +1 -1
- package/dist/core/session-run-termination.js +14 -3
- package/dist/core/session-run-termination.js.map +1 -1
- package/dist/core/session-termination-types.d.ts +97 -0
- package/dist/core/session-termination-types.d.ts.map +1 -0
- package/dist/core/session-termination-types.js +26 -0
- package/dist/core/session-termination-types.js.map +1 -0
- package/dist/core/session-termination.d.ts +3 -97
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +24 -28
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/subagent-lane-launcher.d.ts +3 -2
- package/dist/core/subagent-lane-launcher.d.ts.map +1 -1
- package/dist/core/subagent-lane-launcher.js +24 -13
- package/dist/core/subagent-lane-launcher.js.map +1 -1
- package/dist/core/verified-run/broker.d.ts +26 -0
- package/dist/core/verified-run/broker.d.ts.map +1 -0
- package/dist/core/verified-run/broker.js +210 -0
- package/dist/core/verified-run/broker.js.map +1 -0
- package/dist/core/verified-run/candidate.d.ts +24 -0
- package/dist/core/verified-run/candidate.d.ts.map +1 -0
- package/dist/core/verified-run/candidate.js +167 -0
- package/dist/core/verified-run/candidate.js.map +1 -0
- package/dist/core/verified-run/check-receipt.d.ts +18 -0
- package/dist/core/verified-run/check-receipt.d.ts.map +1 -0
- package/dist/core/verified-run/check-receipt.js +92 -0
- package/dist/core/verified-run/check-receipt.js.map +1 -0
- package/dist/core/verified-run/coordinator.d.ts +39 -0
- package/dist/core/verified-run/coordinator.d.ts.map +1 -0
- package/dist/core/verified-run/coordinator.js +190 -0
- package/dist/core/verified-run/coordinator.js.map +1 -0
- package/dist/core/verified-run/dag-candidates.d.ts +8 -0
- package/dist/core/verified-run/dag-candidates.d.ts.map +1 -0
- package/dist/core/verified-run/dag-candidates.js +65 -0
- package/dist/core/verified-run/dag-candidates.js.map +1 -0
- package/dist/core/verified-run/dag-phase.d.ts +7 -0
- package/dist/core/verified-run/dag-phase.d.ts.map +1 -0
- package/dist/core/verified-run/dag-phase.js +92 -0
- package/dist/core/verified-run/dag-phase.js.map +1 -0
- package/dist/core/verified-run/dag-projection.d.ts +7 -0
- package/dist/core/verified-run/dag-projection.d.ts.map +1 -0
- package/dist/core/verified-run/dag-projection.js +90 -0
- package/dist/core/verified-run/dag-projection.js.map +1 -0
- package/dist/core/verified-run/dag-recovery.d.ts +13 -0
- package/dist/core/verified-run/dag-recovery.d.ts.map +1 -0
- package/dist/core/verified-run/dag-recovery.js +98 -0
- package/dist/core/verified-run/dag-recovery.js.map +1 -0
- package/dist/core/verified-run/dag-retry-projection.d.ts +9 -0
- package/dist/core/verified-run/dag-retry-projection.d.ts.map +1 -0
- package/dist/core/verified-run/dag-retry-projection.js +43 -0
- package/dist/core/verified-run/dag-retry-projection.js.map +1 -0
- package/dist/core/verified-run/dag-types.d.ts +47 -0
- package/dist/core/verified-run/dag-types.d.ts.map +1 -0
- package/dist/core/verified-run/dag-types.js +2 -0
- package/dist/core/verified-run/dag-types.js.map +1 -0
- package/dist/core/verified-run/event-parser.d.ts +3 -0
- package/dist/core/verified-run/event-parser.d.ts.map +1 -0
- package/dist/core/verified-run/event-parser.js +153 -0
- package/dist/core/verified-run/event-parser.js.map +1 -0
- package/dist/core/verified-run/events.d.ts +4 -0
- package/dist/core/verified-run/events.d.ts.map +1 -0
- package/dist/core/verified-run/events.js +3 -0
- package/dist/core/verified-run/events.js.map +1 -0
- package/dist/core/verified-run/evidence-binding.d.ts +18 -0
- package/dist/core/verified-run/evidence-binding.d.ts.map +1 -0
- package/dist/core/verified-run/evidence-binding.js +81 -0
- package/dist/core/verified-run/evidence-binding.js.map +1 -0
- package/dist/core/verified-run/evidence.d.ts +27 -0
- package/dist/core/verified-run/evidence.d.ts.map +1 -0
- package/dist/core/verified-run/evidence.js +100 -0
- package/dist/core/verified-run/evidence.js.map +1 -0
- package/dist/core/verified-run/journal.d.ts +32 -0
- package/dist/core/verified-run/journal.d.ts.map +1 -0
- package/dist/core/verified-run/journal.js +103 -0
- package/dist/core/verified-run/journal.js.map +1 -0
- package/dist/core/verified-run/namespace-identity.d.ts +11 -0
- package/dist/core/verified-run/namespace-identity.d.ts.map +1 -0
- package/dist/core/verified-run/namespace-identity.js +77 -0
- package/dist/core/verified-run/namespace-identity.js.map +1 -0
- package/dist/core/verified-run/owned-execution.d.ts +21 -0
- package/dist/core/verified-run/owned-execution.d.ts.map +1 -0
- package/dist/core/verified-run/owned-execution.js +43 -0
- package/dist/core/verified-run/owned-execution.js.map +1 -0
- package/dist/core/verified-run/phase-context.d.ts +9 -0
- package/dist/core/verified-run/phase-context.d.ts.map +1 -0
- package/dist/core/verified-run/phase-context.js +2 -0
- package/dist/core/verified-run/phase-context.js.map +1 -0
- package/dist/core/verified-run/process-gate.d.ts +5 -0
- package/dist/core/verified-run/process-gate.d.ts.map +1 -0
- package/dist/core/verified-run/process-gate.js +31 -0
- package/dist/core/verified-run/process-gate.js.map +1 -0
- package/dist/core/verified-run/projection.d.ts +4 -0
- package/dist/core/verified-run/projection.d.ts.map +1 -0
- package/dist/core/verified-run/projection.js +219 -0
- package/dist/core/verified-run/projection.js.map +1 -0
- package/dist/core/verified-run/recovery-clock.d.ts +19 -0
- package/dist/core/verified-run/recovery-clock.d.ts.map +1 -0
- package/dist/core/verified-run/recovery-clock.js +69 -0
- package/dist/core/verified-run/recovery-clock.js.map +1 -0
- package/dist/core/verified-run/recovery-command.d.ts +11 -0
- package/dist/core/verified-run/recovery-command.d.ts.map +1 -0
- package/dist/core/verified-run/recovery-command.js +73 -0
- package/dist/core/verified-run/recovery-command.js.map +1 -0
- package/dist/core/verified-run/recovery-projection.d.ts +12 -0
- package/dist/core/verified-run/recovery-projection.d.ts.map +1 -0
- package/dist/core/verified-run/recovery-projection.js +88 -0
- package/dist/core/verified-run/recovery-projection.js.map +1 -0
- package/dist/core/verified-run/recovery.d.ts +12 -0
- package/dist/core/verified-run/recovery.d.ts.map +1 -0
- package/dist/core/verified-run/recovery.js +115 -0
- package/dist/core/verified-run/recovery.js.map +1 -0
- package/dist/core/verified-run/run-types.d.ts +103 -0
- package/dist/core/verified-run/run-types.d.ts.map +1 -0
- package/dist/core/verified-run/run-types.js +2 -0
- package/dist/core/verified-run/run-types.js.map +1 -0
- package/dist/core/verified-run/scripted-writer.d.ts +15 -0
- package/dist/core/verified-run/scripted-writer.d.ts.map +1 -0
- package/dist/core/verified-run/scripted-writer.js +94 -0
- package/dist/core/verified-run/scripted-writer.js.map +1 -0
- package/dist/core/verified-run/session-port.d.ts +27 -0
- package/dist/core/verified-run/session-port.d.ts.map +1 -0
- package/dist/core/verified-run/session-port.js +2 -0
- package/dist/core/verified-run/session-port.js.map +1 -0
- package/dist/core/verified-run/storage.d.ts +15 -0
- package/dist/core/verified-run/storage.d.ts.map +1 -0
- package/dist/core/verified-run/storage.js +96 -0
- package/dist/core/verified-run/storage.js.map +1 -0
- package/dist/core/verified-run/verification-phase.d.ts +5 -0
- package/dist/core/verified-run/verification-phase.d.ts.map +1 -0
- package/dist/core/verified-run/verification-phase.js +56 -0
- package/dist/core/verified-run/verification-phase.js.map +1 -0
- package/dist/core/verified-run/work-recovery.d.ts +8 -0
- package/dist/core/verified-run/work-recovery.d.ts.map +1 -0
- package/dist/core/verified-run/work-recovery.js +44 -0
- package/dist/core/verified-run/work-recovery.js.map +1 -0
- package/dist/core/verified-run/writer-completion.d.ts +4 -0
- package/dist/core/verified-run/writer-completion.d.ts.map +1 -0
- package/dist/core/verified-run/writer-completion.js +27 -0
- package/dist/core/verified-run/writer-completion.js.map +1 -0
- package/dist/core/verified-run/writer-phase.d.ts +8 -0
- package/dist/core/verified-run/writer-phase.d.ts.map +1 -0
- package/dist/core/verified-run/writer-phase.js +76 -0
- package/dist/core/verified-run/writer-phase.js.map +1 -0
- package/dist/core/verified-run/writer-projection.d.ts +11 -0
- package/dist/core/verified-run/writer-projection.d.ts.map +1 -0
- package/dist/core/verified-run/writer-projection.js +70 -0
- package/dist/core/verified-run/writer-projection.js.map +1 -0
- package/dist/core/verified-run/writer-recovery.d.ts +16 -0
- package/dist/core/verified-run/writer-recovery.d.ts.map +1 -0
- package/dist/core/verified-run/writer-recovery.js +107 -0
- package/dist/core/verified-run/writer-recovery.js.map +1 -0
- package/dist/core/workload-permit-pool.d.ts +1 -3
- package/dist/core/workload-permit-pool.d.ts.map +1 -1
- package/dist/core/workload-permit-pool.js +11 -11
- package/dist/core/workload-permit-pool.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -8
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/session-failure.d.ts +13 -0
- package/dist/modes/interactive/components/session-failure.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-failure.js +81 -0
- package/dist/modes/interactive/components/session-failure.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +45 -31
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tui-diagnostics.d.ts +36 -0
- package/dist/modes/interactive/tui-diagnostics.d.ts.map +1 -0
- package/dist/modes/interactive/tui-diagnostics.js +105 -0
- package/dist/modes/interactive/tui-diagnostics.js.map +1 -0
- package/dist/modes/interactive/tui-runtime-info.d.ts +20 -0
- package/dist/modes/interactive/tui-runtime-info.d.ts.map +1 -0
- package/dist/modes/interactive/tui-runtime-info.js +76 -0
- package/dist/modes/interactive/tui-runtime-info.js.map +1 -0
- package/docs/development.md +10 -0
- package/docs/keybindings.md +1 -1
- package/docs/release-audit-0.98.5.md +84 -0
- package/docs/run-protocol.md +33 -1
- package/docs/runtime-algorithms.md +26 -0
- package/docs/sdk.md +193 -0
- package/docs/usage.md +54 -0
- package/docs/verified-run-testing.md +417 -0
- package/docs/verified-run.md +388 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +6 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer-phase.js","sourceRoot":"","sources":["../../../src/core/verified-run/writer-phase.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { performance } from \"node:perf_hooks\";\nimport { executeDag } from \"./dag-phase.ts\";\nimport { executeRunCommand, type OwnedRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { executeScriptedWriter } from \"./scripted-writer.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport async function executeWriter(\n\tcontext: RunPhaseContext,\n\toptions: {\n\t\treadonly workspace: string;\n\t\treadonly deadline: number;\n\t\treadonly runtime?: VerifiedRunRuntime;\n\t},\n): Promise<void> {\n\tconst { contract, journal } = context;\n\tconst execute = (request: OwnedRunCommand, toolSignal?: AbortSignal) => {\n\t\tconst signals = [context.signal, toolSignal].filter((signal): signal is AbortSignal => signal !== undefined);\n\t\treturn executeRunCommand(journal, request, {\n\t\t\t...contract.budget,\n\t\t\t...(signals.length ? { signal: AbortSignal.any(signals) } : {}),\n\t\t});\n\t};\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-dag-v1\":\n\t\t\treturn executeDag(context, options);\n\t\tcase \"linux-command-v1\": {\n\t\t\tconst writer = await execute({\n\t\t\t\trole: \"writer\",\n\t\t\t\targv: contract.writer,\n\t\t\t\tworkspace: options.workspace,\n\t\t\t\tdeadline: options.deadline,\n\t\t\t\tclaimId: null,\n\t\t\t});\n\t\t\tif (writer.result.failure) throw new VerifiedRunError(writer.result.failure);\n\t\t\treturn;\n\t\t}\n\t\tcase \"linux-scripted-agent-v1\": {\n\t\t\tconst runtime = options.runtime;\n\t\t\tif (!runtime) throw new VerifiedRunError(\"writer_backend_missing\");\n\t\t\tconst writer = contract.writer;\n\t\t\tconst requestLimit = writer.maxRequests - journal.state.modelRequests;\n\t\t\tif (requestLimit <= 0) throw new VerifiedRunError(\"model_request_limit\");\n\t\t\tjournal.append({ kind: \"writer_opened\" });\n\t\t\tlet completed = false;\n\t\t\ttry {\n\t\t\t\tawait executeScriptedWriter(writer, contract.goal, {\n\t\t\t\t\truntime,\n\t\t\t\t\tworkspace: options.workspace,\n\t\t\t\t\tdeadline: options.deadline,\n\t\t\t\t\trequestLimit,\n\t\t\t\t\t...(context.signal ? { signal: context.signal } : {}),\n\t\t\t\t\tbeforeRequest: () => {\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t\tjournal.append({ kind: \"model_request\", requestId: randomUUID() });\n\t\t\t\t\t\tif (performance.now() >= options.deadline) throw new VerifiedRunError(\"deadline\");\n\t\t\t\t\t},\n\t\t\t\t\texecuteStep: (index, signal) => {\n\t\t\t\t\t\tconst argv = writer.steps[index];\n\t\t\t\t\t\tif (!argv) throw new VerifiedRunError(\"writer_step\");\n\t\t\t\t\t\treturn execute(\n\t\t\t\t\t\t\t{ role: \"writer\", argv, workspace: options.workspace, deadline: options.deadline, claimId: null },\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tcompleted = true;\n\t\t\t} finally {\n\t\t\t\tif (journal.state.activeExecutionIds.length === 0) journal.append({ kind: \"writer_closed\", completed });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RunEvent, WriterReduction } from "./run-types.ts";
|
|
2
|
+
type WriterEvent = Extract<RunEvent, {
|
|
3
|
+
kind: "writer_opened" | "model_request" | "writer_closed";
|
|
4
|
+
}>;
|
|
5
|
+
export declare function acceptWriterDispatch(context: WriterReduction, event: Extract<RunEvent, {
|
|
6
|
+
kind: "dispatch";
|
|
7
|
+
}>): void;
|
|
8
|
+
/** Mutates only the private replay accumulator; no work, clocks, or caller data are consulted. */
|
|
9
|
+
export declare function reduceWriterEvent(context: WriterReduction, event: WriterEvent): void;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=writer-projection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer-projection.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/writer-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGhE,KAAK,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,eAAe,GAAG,eAAe,GAAG,eAAe,CAAA;CAAE,CAAC,CAAC;AAEpG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC,GAAG,IAAI,CA6BnH;AAED,kGAAkG;AAClG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CA0CpF","sourcesContent":["import type { RunEvent, WriterReduction } from \"./run-types.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\ntype WriterEvent = Extract<RunEvent, { kind: \"writer_opened\" | \"model_request\" | \"writer_closed\" }>;\n\nexport function acceptWriterDispatch(context: WriterReduction, event: Extract<RunEvent, { kind: \"dispatch\" }>): void {\n\tconst { state, contract } = context;\n\tif (event.claimId !== null || state.candidateDigest) throw new VerifiedRunError(\"integrity\");\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-v1\":\n\t\t\tif (context.writerStarted) throw new VerifiedRunError(\"integrity\");\n\t\t\tbreak;\n\t\tcase \"linux-scripted-agent-v1\":\n\t\t\tif (\n\t\t\t\t!state.writerOpen ||\n\t\t\t\tcontext.writerCommands >= contract.writer.steps.length ||\n\t\t\t\tstate.modelRequests - context.requestBaseline <= context.writerCommands\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\tbreak;\n\t\tcase \"linux-command-dag-v1\":\n\t\t\tif (\n\t\t\t\tcontext.writerStarted ||\n\t\t\t\t!state.tasks.some((task) => task.status === \"running\" && task.generation === state.generation)\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"task_not_ready\");\n\t\t\tbreak;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n\tcontext.writerStarted = true;\n\tcontext.writerCommands += 1;\n}\n\n/** Mutates only the private replay accumulator; no work, clocks, or caller data are consulted. */\nexport function reduceWriterEvent(context: WriterReduction, event: WriterEvent): void {\n\tconst state = context.state;\n\tconst scripted = context.contract.profile === \"linux-scripted-agent-v1\" ? context.contract.writer : undefined;\n\tswitch (event.kind) {\n\t\tcase \"writer_opened\":\n\t\t\tif (!scripted || context.producerStarted || context.writerStarted || state.candidateDigest)\n\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\tcontext.producerStarted = true;\n\t\t\tcontext.state = { ...state, writerOpen: true, execution: \"running\", settlement: \"open\" };\n\t\t\treturn;\n\t\tcase \"model_request\":\n\t\t\tif (\n\t\t\t\t!scripted ||\n\t\t\t\t!state.writerOpen ||\n\t\t\t\tcontext.requests.has(event.requestId) ||\n\t\t\t\tstate.activeExecutionIds.length ||\n\t\t\t\tstate.modelRequests >= scripted.maxRequests\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"model_request_limit\");\n\t\t\tcontext.requests.add(event.requestId);\n\t\t\tcontext.state = { ...state, modelRequests: state.modelRequests + 1 };\n\t\t\treturn;\n\t\tcase \"writer_closed\":\n\t\t\tif (\n\t\t\t\t!scripted ||\n\t\t\t\t!state.writerOpen ||\n\t\t\t\tstate.activeExecutionIds.length ||\n\t\t\t\t(event.completed &&\n\t\t\t\t\t(!context.writerFinished ||\n\t\t\t\t\t\tstate.failure ||\n\t\t\t\t\t\tcontext.writerCommands !== scripted.steps.length ||\n\t\t\t\t\t\tstate.modelRequests - context.requestBaseline < scripted.steps.length + 1))\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\tcontext.writerFinished = event.completed;\n\t\t\tcontext.state = { ...state, writerOpen: false, settlement: \"settled\" };\n\t\t\treturn;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = event;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { VerifiedRunError } from "./storage.js";
|
|
2
|
+
export function acceptWriterDispatch(context, event) {
|
|
3
|
+
const { state, contract } = context;
|
|
4
|
+
if (event.claimId !== null || state.candidateDigest)
|
|
5
|
+
throw new VerifiedRunError("integrity");
|
|
6
|
+
switch (contract.profile) {
|
|
7
|
+
case "linux-command-v1":
|
|
8
|
+
if (context.writerStarted)
|
|
9
|
+
throw new VerifiedRunError("integrity");
|
|
10
|
+
break;
|
|
11
|
+
case "linux-scripted-agent-v1":
|
|
12
|
+
if (!state.writerOpen ||
|
|
13
|
+
context.writerCommands >= contract.writer.steps.length ||
|
|
14
|
+
state.modelRequests - context.requestBaseline <= context.writerCommands)
|
|
15
|
+
throw new VerifiedRunError("integrity");
|
|
16
|
+
break;
|
|
17
|
+
case "linux-command-dag-v1":
|
|
18
|
+
if (context.writerStarted ||
|
|
19
|
+
!state.tasks.some((task) => task.status === "running" && task.generation === state.generation))
|
|
20
|
+
throw new VerifiedRunError("task_not_ready");
|
|
21
|
+
break;
|
|
22
|
+
default: {
|
|
23
|
+
const exhaustive = contract;
|
|
24
|
+
throw new VerifiedRunError(String(exhaustive));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
context.writerStarted = true;
|
|
28
|
+
context.writerCommands += 1;
|
|
29
|
+
}
|
|
30
|
+
/** Mutates only the private replay accumulator; no work, clocks, or caller data are consulted. */
|
|
31
|
+
export function reduceWriterEvent(context, event) {
|
|
32
|
+
const state = context.state;
|
|
33
|
+
const scripted = context.contract.profile === "linux-scripted-agent-v1" ? context.contract.writer : undefined;
|
|
34
|
+
switch (event.kind) {
|
|
35
|
+
case "writer_opened":
|
|
36
|
+
if (!scripted || context.producerStarted || context.writerStarted || state.candidateDigest)
|
|
37
|
+
throw new VerifiedRunError("integrity");
|
|
38
|
+
context.producerStarted = true;
|
|
39
|
+
context.state = { ...state, writerOpen: true, execution: "running", settlement: "open" };
|
|
40
|
+
return;
|
|
41
|
+
case "model_request":
|
|
42
|
+
if (!scripted ||
|
|
43
|
+
!state.writerOpen ||
|
|
44
|
+
context.requests.has(event.requestId) ||
|
|
45
|
+
state.activeExecutionIds.length ||
|
|
46
|
+
state.modelRequests >= scripted.maxRequests)
|
|
47
|
+
throw new VerifiedRunError("model_request_limit");
|
|
48
|
+
context.requests.add(event.requestId);
|
|
49
|
+
context.state = { ...state, modelRequests: state.modelRequests + 1 };
|
|
50
|
+
return;
|
|
51
|
+
case "writer_closed":
|
|
52
|
+
if (!scripted ||
|
|
53
|
+
!state.writerOpen ||
|
|
54
|
+
state.activeExecutionIds.length ||
|
|
55
|
+
(event.completed &&
|
|
56
|
+
(!context.writerFinished ||
|
|
57
|
+
state.failure ||
|
|
58
|
+
context.writerCommands !== scripted.steps.length ||
|
|
59
|
+
state.modelRequests - context.requestBaseline < scripted.steps.length + 1)))
|
|
60
|
+
throw new VerifiedRunError("integrity");
|
|
61
|
+
context.writerFinished = event.completed;
|
|
62
|
+
context.state = { ...state, writerOpen: false, settlement: "settled" };
|
|
63
|
+
return;
|
|
64
|
+
default: {
|
|
65
|
+
const exhaustive = event;
|
|
66
|
+
throw new VerifiedRunError(String(exhaustive));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=writer-projection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer-projection.js","sourceRoot":"","sources":["../../../src/core/verified-run/writer-projection.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RunEvent, WriterReduction } from \"./run-types.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\ntype WriterEvent = Extract<RunEvent, { kind: \"writer_opened\" | \"model_request\" | \"writer_closed\" }>;\n\nexport function acceptWriterDispatch(context: WriterReduction, event: Extract<RunEvent, { kind: \"dispatch\" }>): void {\n\tconst { state, contract } = context;\n\tif (event.claimId !== null || state.candidateDigest) throw new VerifiedRunError(\"integrity\");\n\tswitch (contract.profile) {\n\t\tcase \"linux-command-v1\":\n\t\t\tif (context.writerStarted) throw new VerifiedRunError(\"integrity\");\n\t\t\tbreak;\n\t\tcase \"linux-scripted-agent-v1\":\n\t\t\tif (\n\t\t\t\t!state.writerOpen ||\n\t\t\t\tcontext.writerCommands >= contract.writer.steps.length ||\n\t\t\t\tstate.modelRequests - context.requestBaseline <= context.writerCommands\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\tbreak;\n\t\tcase \"linux-command-dag-v1\":\n\t\t\tif (\n\t\t\t\tcontext.writerStarted ||\n\t\t\t\t!state.tasks.some((task) => task.status === \"running\" && task.generation === state.generation)\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"task_not_ready\");\n\t\t\tbreak;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = contract;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n\tcontext.writerStarted = true;\n\tcontext.writerCommands += 1;\n}\n\n/** Mutates only the private replay accumulator; no work, clocks, or caller data are consulted. */\nexport function reduceWriterEvent(context: WriterReduction, event: WriterEvent): void {\n\tconst state = context.state;\n\tconst scripted = context.contract.profile === \"linux-scripted-agent-v1\" ? context.contract.writer : undefined;\n\tswitch (event.kind) {\n\t\tcase \"writer_opened\":\n\t\t\tif (!scripted || context.producerStarted || context.writerStarted || state.candidateDigest)\n\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\tcontext.producerStarted = true;\n\t\t\tcontext.state = { ...state, writerOpen: true, execution: \"running\", settlement: \"open\" };\n\t\t\treturn;\n\t\tcase \"model_request\":\n\t\t\tif (\n\t\t\t\t!scripted ||\n\t\t\t\t!state.writerOpen ||\n\t\t\t\tcontext.requests.has(event.requestId) ||\n\t\t\t\tstate.activeExecutionIds.length ||\n\t\t\t\tstate.modelRequests >= scripted.maxRequests\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"model_request_limit\");\n\t\t\tcontext.requests.add(event.requestId);\n\t\t\tcontext.state = { ...state, modelRequests: state.modelRequests + 1 };\n\t\t\treturn;\n\t\tcase \"writer_closed\":\n\t\t\tif (\n\t\t\t\t!scripted ||\n\t\t\t\t!state.writerOpen ||\n\t\t\t\tstate.activeExecutionIds.length ||\n\t\t\t\t(event.completed &&\n\t\t\t\t\t(!context.writerFinished ||\n\t\t\t\t\t\tstate.failure ||\n\t\t\t\t\t\tcontext.writerCommands !== scripted.steps.length ||\n\t\t\t\t\t\tstate.modelRequests - context.requestBaseline < scripted.steps.length + 1))\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\tcontext.writerFinished = event.completed;\n\t\t\tcontext.state = { ...state, writerOpen: false, settlement: \"settled\" };\n\t\t\treturn;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = event;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RunWriterRestartCommand } from "omk-protocol";
|
|
2
|
+
import type { RunProjection } from "./run-types.ts";
|
|
3
|
+
import type { VerifiedRunRuntime } from "./session-port.ts";
|
|
4
|
+
export interface WriterRecoveryInspection {
|
|
5
|
+
readonly state: RunProjection;
|
|
6
|
+
readonly readiness: "ready" | "terminal" | "input_checkpoint_missing" | "candidate_present" | "unsettled" | "expired" | "clock_changed" | "clock_rollback" | "recovery_limit" | "model_request_limit" | "integrity";
|
|
7
|
+
readonly remainingWorkMs: number | null;
|
|
8
|
+
readonly ownership: "lease_required";
|
|
9
|
+
}
|
|
10
|
+
export declare function inspectWriterRecovery(runPath: string): WriterRecoveryInspection;
|
|
11
|
+
/** Re-run isolated local work in a new copy. Never reuse an interrupted workspace or replenish a budget. */
|
|
12
|
+
export declare function restartIsolatedWriter(runPath: string, command: RunWriterRestartCommand, options: {
|
|
13
|
+
readonly runtime?: VerifiedRunRuntime;
|
|
14
|
+
readonly signal?: AbortSignal;
|
|
15
|
+
}): Promise<RunProjection>;
|
|
16
|
+
//# sourceMappingURL=writer-recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer-recovery.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/writer-recovery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAO5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAO5D,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,SAAS,EACf,OAAO,GACP,UAAU,GACV,0BAA0B,GAC1B,mBAAmB,GACnB,WAAW,GACX,SAAS,GACT,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,qBAAqB,GACrB,WAAW,CAAC;IACf,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;CACrC;AAaD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,wBAAwB,CA0C/E;AAED,4GAA4G;AAC5G,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAC/E,OAAO,CAAC,aAAa,CAAC,CAkCxB","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunWriterRestartCommand } from \"omk-protocol\";\nimport { probeVerifiedSandbox } from \"./broker.ts\";\nimport { loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { preflightCheckReceipts } from \"./check-receipt.ts\";\nimport type { JournalSnapshot } from \"./journal.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { requireRunJournal, withRecoveryLease } from \"./recovery-command.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\nimport { verifyCandidate } from \"./verification-phase.ts\";\nimport { assertWorkRecoverable } from \"./work-recovery.ts\";\nimport { publishWriterCandidate } from \"./writer-completion.ts\";\nimport { executeWriter } from \"./writer-phase.ts\";\n\nexport interface WriterRecoveryInspection {\n\treadonly state: RunProjection;\n\treadonly readiness:\n\t\t| \"ready\"\n\t\t| \"terminal\"\n\t\t| \"input_checkpoint_missing\"\n\t\t| \"candidate_present\"\n\t\t| \"unsettled\"\n\t\t| \"expired\"\n\t\t| \"clock_changed\"\n\t\t| \"clock_rollback\"\n\t\t| \"recovery_limit\"\n\t\t| \"model_request_limit\"\n\t\t| \"integrity\";\n\treadonly remainingWorkMs: number | null;\n\treadonly ownership: \"lease_required\";\n}\n\nfunction assertWriterRecoverable(runPath: string, snapshot: JournalSnapshot): number {\n\tconst { contract, remainingMs } = assertWorkRecoverable(runPath, snapshot);\n\tif (contract.profile === \"linux-command-dag-v1\") throw new VerifiedRunError(\"task_recovery_required\");\n\tif (\n\t\tcontract.profile === \"linux-scripted-agent-v1\" &&\n\t\tcontract.writer.maxRequests - snapshot.state.modelRequests < contract.writer.steps.length + 1\n\t)\n\t\tthrow new VerifiedRunError(\"model_request_limit\");\n\treturn remainingMs;\n}\n\nexport function inspectWriterRecovery(runPath: string): WriterRecoveryInspection {\n\tconst snapshot = requireRunJournal(runPath);\n\tlet readiness: WriterRecoveryInspection[\"readiness\"] = \"ready\";\n\tlet remainingWorkMs: number | null = null;\n\ttry {\n\t\tremainingWorkMs = assertWriterRecoverable(runPath, snapshot);\n\t} catch (error) {\n\t\tif (!(error instanceof Error)) throw error;\n\t\tswitch (error instanceof VerifiedRunError ? error.code : \"integrity\") {\n\t\t\tcase \"resume_terminal\":\n\t\t\t\treadiness = \"terminal\";\n\t\t\t\tbreak;\n\t\t\tcase \"deadline\":\n\t\t\t\treadiness = \"expired\";\n\t\t\t\tremainingWorkMs = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"input_checkpoint_missing\":\n\t\t\t\treadiness = \"input_checkpoint_missing\";\n\t\t\t\tbreak;\n\t\t\tcase \"candidate_present\":\n\t\t\t\treadiness = \"candidate_present\";\n\t\t\t\tbreak;\n\t\t\tcase \"unsettled\":\n\t\t\t\treadiness = \"unsettled\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_changed\":\n\t\t\t\treadiness = \"clock_changed\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_rollback\":\n\t\t\t\treadiness = \"clock_rollback\";\n\t\t\t\tbreak;\n\t\t\tcase \"recovery_limit\":\n\t\t\t\treadiness = \"recovery_limit\";\n\t\t\t\tbreak;\n\t\t\tcase \"model_request_limit\":\n\t\t\t\treadiness = \"model_request_limit\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treadiness = \"integrity\";\n\t\t}\n\t}\n\treturn Object.freeze({ state: snapshot.state, readiness, remainingWorkMs, ownership: \"lease_required\" });\n}\n\n/** Re-run isolated local work in a new copy. Never reuse an interrupted workspace or replenish a budget. */\nexport async function restartIsolatedWriter(\n\trunPath: string,\n\tcommand: RunWriterRestartCommand,\n\toptions: { readonly runtime?: VerifiedRunRuntime; readonly signal?: AbortSignal },\n): Promise<RunProjection> {\n\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\treturn withRecoveryLease(runPath, command, async ({ snapshot, journal }) => {\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tconst first = snapshot.records[0]?.event;\n\t\tif (first?.kind !== \"created\") throw new VerifiedRunError(\"integrity\");\n\t\tif (first.contract.profile === \"linux-scripted-agent-v1\" && !options.runtime)\n\t\t\tthrow new VerifiedRunError(\"writer_backend_missing\");\n\t\tpreflightCheckReceipts(first.contract);\n\t\tprobeVerifiedSandbox();\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\t\tjournal.append({\n\t\t\tkind: \"writer_restarted\",\n\t\t\tcommand,\n\t\t\tobservedMs: readRunClock().nowMs,\n\t\t\treconciledExecutionIds: snapshot.state.activeExecutionIds,\n\t\t});\n\t\tconst state = journal.state;\n\t\tif (!state.budget || !state.inputDigest) throw new VerifiedRunError(\"integrity\");\n\t\tconst deadline = performance.now() + remainingRunTime(state.budget, state.budget.workDeadlineMs);\n\t\tconst base = loadCandidate(runPath, state.inputDigest, first.contract.budget);\n\t\tconst workspace = join(runPath, `writer-${state.generation}`);\n\t\tmaterializeCandidate(base, workspace);\n\t\tconst context = {\n\t\t\trunPath,\n\t\t\tcontract: first.contract,\n\t\t\tjournal,\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t};\n\t\tawait executeWriter(context, { workspace, deadline, ...(options.runtime ? { runtime: options.runtime } : {}) });\n\t\tpublishWriterCandidate(context, workspace, deadline);\n\t\treturn verifyCandidate(context);\n\t});\n}\n"]}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { performance } from "node:perf_hooks";
|
|
3
|
+
import { probeVerifiedSandbox } from "./broker.js";
|
|
4
|
+
import { loadCandidate, materializeCandidate } from "./candidate.js";
|
|
5
|
+
import { preflightCheckReceipts } from "./check-receipt.js";
|
|
6
|
+
import { readRunClock, remainingRunTime } from "./recovery-clock.js";
|
|
7
|
+
import { requireRunJournal, withRecoveryLease } from "./recovery-command.js";
|
|
8
|
+
import { VerifiedRunError } from "./storage.js";
|
|
9
|
+
import { verifyCandidate } from "./verification-phase.js";
|
|
10
|
+
import { assertWorkRecoverable } from "./work-recovery.js";
|
|
11
|
+
import { publishWriterCandidate } from "./writer-completion.js";
|
|
12
|
+
import { executeWriter } from "./writer-phase.js";
|
|
13
|
+
function assertWriterRecoverable(runPath, snapshot) {
|
|
14
|
+
const { contract, remainingMs } = assertWorkRecoverable(runPath, snapshot);
|
|
15
|
+
if (contract.profile === "linux-command-dag-v1")
|
|
16
|
+
throw new VerifiedRunError("task_recovery_required");
|
|
17
|
+
if (contract.profile === "linux-scripted-agent-v1" &&
|
|
18
|
+
contract.writer.maxRequests - snapshot.state.modelRequests < contract.writer.steps.length + 1)
|
|
19
|
+
throw new VerifiedRunError("model_request_limit");
|
|
20
|
+
return remainingMs;
|
|
21
|
+
}
|
|
22
|
+
export function inspectWriterRecovery(runPath) {
|
|
23
|
+
const snapshot = requireRunJournal(runPath);
|
|
24
|
+
let readiness = "ready";
|
|
25
|
+
let remainingWorkMs = null;
|
|
26
|
+
try {
|
|
27
|
+
remainingWorkMs = assertWriterRecoverable(runPath, snapshot);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (!(error instanceof Error))
|
|
31
|
+
throw error;
|
|
32
|
+
switch (error instanceof VerifiedRunError ? error.code : "integrity") {
|
|
33
|
+
case "resume_terminal":
|
|
34
|
+
readiness = "terminal";
|
|
35
|
+
break;
|
|
36
|
+
case "deadline":
|
|
37
|
+
readiness = "expired";
|
|
38
|
+
remainingWorkMs = 0;
|
|
39
|
+
break;
|
|
40
|
+
case "input_checkpoint_missing":
|
|
41
|
+
readiness = "input_checkpoint_missing";
|
|
42
|
+
break;
|
|
43
|
+
case "candidate_present":
|
|
44
|
+
readiness = "candidate_present";
|
|
45
|
+
break;
|
|
46
|
+
case "unsettled":
|
|
47
|
+
readiness = "unsettled";
|
|
48
|
+
break;
|
|
49
|
+
case "clock_changed":
|
|
50
|
+
readiness = "clock_changed";
|
|
51
|
+
break;
|
|
52
|
+
case "clock_rollback":
|
|
53
|
+
readiness = "clock_rollback";
|
|
54
|
+
break;
|
|
55
|
+
case "recovery_limit":
|
|
56
|
+
readiness = "recovery_limit";
|
|
57
|
+
break;
|
|
58
|
+
case "model_request_limit":
|
|
59
|
+
readiness = "model_request_limit";
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
readiness = "integrity";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return Object.freeze({ state: snapshot.state, readiness, remainingWorkMs, ownership: "lease_required" });
|
|
66
|
+
}
|
|
67
|
+
/** Re-run isolated local work in a new copy. Never reuse an interrupted workspace or replenish a budget. */
|
|
68
|
+
export async function restartIsolatedWriter(runPath, command, options) {
|
|
69
|
+
if (options.signal?.aborted)
|
|
70
|
+
throw new VerifiedRunError("cancelled");
|
|
71
|
+
return withRecoveryLease(runPath, command, async ({ snapshot, journal }) => {
|
|
72
|
+
assertWriterRecoverable(runPath, snapshot);
|
|
73
|
+
const first = snapshot.records[0]?.event;
|
|
74
|
+
if (first?.kind !== "created")
|
|
75
|
+
throw new VerifiedRunError("integrity");
|
|
76
|
+
if (first.contract.profile === "linux-scripted-agent-v1" && !options.runtime)
|
|
77
|
+
throw new VerifiedRunError("writer_backend_missing");
|
|
78
|
+
preflightCheckReceipts(first.contract);
|
|
79
|
+
probeVerifiedSandbox();
|
|
80
|
+
assertWriterRecoverable(runPath, snapshot);
|
|
81
|
+
if (options.signal?.aborted)
|
|
82
|
+
throw new VerifiedRunError("cancelled");
|
|
83
|
+
journal.append({
|
|
84
|
+
kind: "writer_restarted",
|
|
85
|
+
command,
|
|
86
|
+
observedMs: readRunClock().nowMs,
|
|
87
|
+
reconciledExecutionIds: snapshot.state.activeExecutionIds,
|
|
88
|
+
});
|
|
89
|
+
const state = journal.state;
|
|
90
|
+
if (!state.budget || !state.inputDigest)
|
|
91
|
+
throw new VerifiedRunError("integrity");
|
|
92
|
+
const deadline = performance.now() + remainingRunTime(state.budget, state.budget.workDeadlineMs);
|
|
93
|
+
const base = loadCandidate(runPath, state.inputDigest, first.contract.budget);
|
|
94
|
+
const workspace = join(runPath, `writer-${state.generation}`);
|
|
95
|
+
materializeCandidate(base, workspace);
|
|
96
|
+
const context = {
|
|
97
|
+
runPath,
|
|
98
|
+
contract: first.contract,
|
|
99
|
+
journal,
|
|
100
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
101
|
+
};
|
|
102
|
+
await executeWriter(context, { workspace, deadline, ...(options.runtime ? { runtime: options.runtime } : {}) });
|
|
103
|
+
publishWriterCandidate(context, workspace, deadline);
|
|
104
|
+
return verifyCandidate(context);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=writer-recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer-recovery.js","sourceRoot":"","sources":["../../../src/core/verified-run/writer-recovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\nimport type { RunWriterRestartCommand } from \"omk-protocol\";\nimport { probeVerifiedSandbox } from \"./broker.ts\";\nimport { loadCandidate, materializeCandidate } from \"./candidate.ts\";\nimport { preflightCheckReceipts } from \"./check-receipt.ts\";\nimport type { JournalSnapshot } from \"./journal.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { requireRunJournal, withRecoveryLease } from \"./recovery-command.ts\";\nimport type { RunProjection } from \"./run-types.ts\";\nimport type { VerifiedRunRuntime } from \"./session-port.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\nimport { verifyCandidate } from \"./verification-phase.ts\";\nimport { assertWorkRecoverable } from \"./work-recovery.ts\";\nimport { publishWriterCandidate } from \"./writer-completion.ts\";\nimport { executeWriter } from \"./writer-phase.ts\";\n\nexport interface WriterRecoveryInspection {\n\treadonly state: RunProjection;\n\treadonly readiness:\n\t\t| \"ready\"\n\t\t| \"terminal\"\n\t\t| \"input_checkpoint_missing\"\n\t\t| \"candidate_present\"\n\t\t| \"unsettled\"\n\t\t| \"expired\"\n\t\t| \"clock_changed\"\n\t\t| \"clock_rollback\"\n\t\t| \"recovery_limit\"\n\t\t| \"model_request_limit\"\n\t\t| \"integrity\";\n\treadonly remainingWorkMs: number | null;\n\treadonly ownership: \"lease_required\";\n}\n\nfunction assertWriterRecoverable(runPath: string, snapshot: JournalSnapshot): number {\n\tconst { contract, remainingMs } = assertWorkRecoverable(runPath, snapshot);\n\tif (contract.profile === \"linux-command-dag-v1\") throw new VerifiedRunError(\"task_recovery_required\");\n\tif (\n\t\tcontract.profile === \"linux-scripted-agent-v1\" &&\n\t\tcontract.writer.maxRequests - snapshot.state.modelRequests < contract.writer.steps.length + 1\n\t)\n\t\tthrow new VerifiedRunError(\"model_request_limit\");\n\treturn remainingMs;\n}\n\nexport function inspectWriterRecovery(runPath: string): WriterRecoveryInspection {\n\tconst snapshot = requireRunJournal(runPath);\n\tlet readiness: WriterRecoveryInspection[\"readiness\"] = \"ready\";\n\tlet remainingWorkMs: number | null = null;\n\ttry {\n\t\tremainingWorkMs = assertWriterRecoverable(runPath, snapshot);\n\t} catch (error) {\n\t\tif (!(error instanceof Error)) throw error;\n\t\tswitch (error instanceof VerifiedRunError ? error.code : \"integrity\") {\n\t\t\tcase \"resume_terminal\":\n\t\t\t\treadiness = \"terminal\";\n\t\t\t\tbreak;\n\t\t\tcase \"deadline\":\n\t\t\t\treadiness = \"expired\";\n\t\t\t\tremainingWorkMs = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"input_checkpoint_missing\":\n\t\t\t\treadiness = \"input_checkpoint_missing\";\n\t\t\t\tbreak;\n\t\t\tcase \"candidate_present\":\n\t\t\t\treadiness = \"candidate_present\";\n\t\t\t\tbreak;\n\t\t\tcase \"unsettled\":\n\t\t\t\treadiness = \"unsettled\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_changed\":\n\t\t\t\treadiness = \"clock_changed\";\n\t\t\t\tbreak;\n\t\t\tcase \"clock_rollback\":\n\t\t\t\treadiness = \"clock_rollback\";\n\t\t\t\tbreak;\n\t\t\tcase \"recovery_limit\":\n\t\t\t\treadiness = \"recovery_limit\";\n\t\t\t\tbreak;\n\t\t\tcase \"model_request_limit\":\n\t\t\t\treadiness = \"model_request_limit\";\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treadiness = \"integrity\";\n\t\t}\n\t}\n\treturn Object.freeze({ state: snapshot.state, readiness, remainingWorkMs, ownership: \"lease_required\" });\n}\n\n/** Re-run isolated local work in a new copy. Never reuse an interrupted workspace or replenish a budget. */\nexport async function restartIsolatedWriter(\n\trunPath: string,\n\tcommand: RunWriterRestartCommand,\n\toptions: { readonly runtime?: VerifiedRunRuntime; readonly signal?: AbortSignal },\n): Promise<RunProjection> {\n\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\treturn withRecoveryLease(runPath, command, async ({ snapshot, journal }) => {\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tconst first = snapshot.records[0]?.event;\n\t\tif (first?.kind !== \"created\") throw new VerifiedRunError(\"integrity\");\n\t\tif (first.contract.profile === \"linux-scripted-agent-v1\" && !options.runtime)\n\t\t\tthrow new VerifiedRunError(\"writer_backend_missing\");\n\t\tpreflightCheckReceipts(first.contract);\n\t\tprobeVerifiedSandbox();\n\t\tassertWriterRecoverable(runPath, snapshot);\n\t\tif (options.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\t\tjournal.append({\n\t\t\tkind: \"writer_restarted\",\n\t\t\tcommand,\n\t\t\tobservedMs: readRunClock().nowMs,\n\t\t\treconciledExecutionIds: snapshot.state.activeExecutionIds,\n\t\t});\n\t\tconst state = journal.state;\n\t\tif (!state.budget || !state.inputDigest) throw new VerifiedRunError(\"integrity\");\n\t\tconst deadline = performance.now() + remainingRunTime(state.budget, state.budget.workDeadlineMs);\n\t\tconst base = loadCandidate(runPath, state.inputDigest, first.contract.budget);\n\t\tconst workspace = join(runPath, `writer-${state.generation}`);\n\t\tmaterializeCandidate(base, workspace);\n\t\tconst context = {\n\t\t\trunPath,\n\t\t\tcontract: first.contract,\n\t\t\tjournal,\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t};\n\t\tawait executeWriter(context, { workspace, deadline, ...(options.runtime ? { runtime: options.runtime } : {}) });\n\t\tpublishWriterCandidate(context, workspace, deadline);\n\t\treturn verifyCandidate(context);\n\t});\n}\n"]}
|
|
@@ -54,8 +54,6 @@ export declare class WorkloadPermitPool {
|
|
|
54
54
|
private readonly now;
|
|
55
55
|
private activeWeight;
|
|
56
56
|
private readonly queue;
|
|
57
|
-
private readonly releasedPermitIds;
|
|
58
|
-
private readonly activePermitIds;
|
|
59
57
|
private doubleReleases;
|
|
60
58
|
constructor(options?: WorkloadPermitPoolOptions);
|
|
61
59
|
/**
|
|
@@ -65,7 +63,7 @@ export declare class WorkloadPermitPool {
|
|
|
65
63
|
*/
|
|
66
64
|
setCapacity(capacity: number): void;
|
|
67
65
|
/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */
|
|
68
|
-
acquire(
|
|
66
|
+
acquire(input: WorkloadPermitRequest): Promise<WorkloadPermit>;
|
|
69
67
|
snapshot(): WorkloadPermitPoolSnapshot;
|
|
70
68
|
/** Diagnostic count of double releases (§10.3 no-op + diagnostic). */
|
|
71
69
|
get doubleReleaseCount(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-permit-pool.d.ts","sourceRoot":"","sources":["../../src/core/workload-permit-pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,sBAAsB,CAAC;AAExG,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,IAAI,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAK3D;CACD;AAUD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,MAAM,MAAM,yBAAyB,GAAG;IACvC,uEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CACjB,CAAC;AAEF,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"workload-permit-pool.d.ts","sourceRoot":"","sources":["../../src/core/workload-permit-pool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,sBAAsB,CAAC;AAExG,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,IAAI,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAK3D;CACD;AAUD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,MAAM,MAAM,yBAAyB,GAAG;IACvC,uEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CACjB,CAAC;AAEF,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,cAAc,CAAK;IAE3B,YAAY,OAAO,CAAC,EAAE,yBAAyB,EAI9C;IAED;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAGlC;IAED,+EAA+E;IAC/E,OAAO,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CA8B7D;IAED,QAAQ,IAAI,0BAA0B,CAErC;IAED,uEAAsE;IACtE,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED,OAAO,CAAC,KAAK;IAmBb,gFAA+E;IAC/E,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,aAAa;CAUrB","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { WorkloadClass } from \"./workload-classifier.ts\";\n\n/**\n * Shared workload permit pool (OMK v0.97.x roadmap §10, M3/PR5).\n *\n * Bounds concurrent heavy/cpu subprocesses independently of tool concurrency\n * (§10.1: 4 concurrent reads != 4 concurrent `npm test` processes). One pool\n * instance is shared by a session and, later, its child subagents (§14.1) —\n * a child creating its own pool would oversubscribe the host.\n *\n * §10.3 rules implemented here: strict FIFO (§10.4), abort- and\n * timeout-aware waiting, exactly-once release with double-release recorded\n * as a diagnostic no-op, immediate rejection of requests wider than\n * capacity, and a hard queue cap whose overflow surfaces as a structured\n * error code (§15.4 `queue_overflow`). Waiter timers stay ref'd — a permit\n * wait is actively awaited work — and are cleared on settle.\n */\n\nexport interface WorkloadPermitRequest {\n\treadonly requestId: string;\n\treadonly promptRunId: string;\n\treadonly workloadClass: WorkloadClass;\n\treadonly weight: 1 | 2;\n\treadonly signal?: AbortSignal;\n\treadonly timeoutMs?: number;\n}\n\nexport interface WorkloadPermit {\n\treadonly permitId: string;\n\treadonly requestId: string;\n\treadonly acquiredAt: string;\n\trelease(): void;\n}\n\nexport interface WorkloadPermitPoolSnapshot {\n\treadonly capacity: number;\n\treadonly activeWeight: number;\n\treadonly queuedCount: number;\n}\n\nexport type WorkloadPermitErrorCode = \"queue_overflow\" | \"timeout\" | \"aborted\" | \"over_capacity_weight\";\n\nexport class WorkloadPermitError extends Error {\n\treadonly code: WorkloadPermitErrorCode;\n\treadonly requestId: string;\n\n\tconstructor(code: WorkloadPermitErrorCode, requestId: string) {\n\t\tsuper(`workload permit ${code} (request ${requestId})`);\n\t\tthis.name = \"WorkloadPermitError\";\n\t\tthis.code = code;\n\t\tthis.requestId = requestId;\n\t}\n}\n\ninterface Waiter {\n\treadonly request: WorkloadPermitRequest;\n\treadonly resolve: (permit: WorkloadPermit) => void;\n\treadonly reject: (error: WorkloadPermitError) => void;\n\ttimer: ReturnType<typeof setTimeout> | null;\n\tabortListener: (() => void) | null;\n}\n\nexport const DEFAULT_PERMIT_QUEUE_CAP = 32;\n\nexport type WorkloadPermitPoolOptions = {\n\t/** Concurrent weight budget; §7.2 heavy caps feed this. Default 2. */\n\tcapacity?: number;\n\t/** §10.3 queue length hard cap. Default 32. */\n\tmaxQueue?: number;\n\t/** Injectable clock for deterministic tests. */\n\tnow?: () => Date;\n};\n\nexport class WorkloadPermitPool {\n\tprivate capacity: number;\n\tprivate readonly maxQueue: number;\n\tprivate readonly now: () => Date;\n\tprivate activeWeight = 0;\n\tprivate readonly queue: Waiter[] = [];\n\tprivate doubleReleases = 0;\n\n\tconstructor(options?: WorkloadPermitPoolOptions) {\n\t\tthis.capacity = sanitizeCapacity(options?.capacity, 2);\n\t\tthis.maxQueue = sanitizeCapacity(options?.maxQueue, DEFAULT_PERMIT_QUEUE_CAP);\n\t\tthis.now = options?.now ?? (() => new Date());\n\t}\n\n\t/**\n\t * Update capacity from a new admission decision. In-flight permits are\n\t * never revoked; a reduction only delays future grants until active\n\t * weight drains below the new capacity.\n\t */\n\tsetCapacity(capacity: number): void {\n\t\tthis.capacity = sanitizeCapacity(capacity, this.capacity);\n\t\tthis.grantWhilePossible();\n\t}\n\n\t/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */\n\tacquire(input: WorkloadPermitRequest): Promise<WorkloadPermit> {\n\t\tconst request = { ...input };\n\t\tif (request.weight > this.capacity) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"over_capacity_weight\", request.requestId));\n\t\t}\n\t\tif (request.signal?.aborted) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"aborted\", request.requestId));\n\t\t}\n\t\tif (this.queue.length === 0 && this.activeWeight + request.weight <= this.capacity) {\n\t\t\treturn Promise.resolve(this.grant(request));\n\t\t}\n\t\tif (this.queue.length >= this.maxQueue) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"queue_overflow\", request.requestId));\n\t\t}\n\t\treturn new Promise<WorkloadPermit>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { request, resolve, reject, timer: null, abortListener: null };\n\t\t\tif (typeof request.timeoutMs === \"number\" && Number.isFinite(request.timeoutMs) && request.timeoutMs > 0) {\n\t\t\t\twaiter.timer = setTimeout(() => {\n\t\t\t\t\tthis.evict(waiter, \"timeout\");\n\t\t\t\t}, request.timeoutMs);\n\t\t\t}\n\t\t\tif (request.signal) {\n\t\t\t\tconst signal = request.signal;\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tthis.evict(waiter, \"aborted\");\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.queue.push(waiter);\n\t\t});\n\t}\n\n\tsnapshot(): WorkloadPermitPoolSnapshot {\n\t\treturn { capacity: this.capacity, activeWeight: this.activeWeight, queuedCount: this.queue.length };\n\t}\n\n\t/** Diagnostic count of double releases (§10.3 no-op + diagnostic). */\n\tget doubleReleaseCount(): number {\n\t\treturn this.doubleReleases;\n\t}\n\n\tprivate grant(request: WorkloadPermitRequest): WorkloadPermit {\n\t\tconst acquiredAt = this.now().toISOString();\n\t\tconst permitId = `permit-${randomUUID()}`;\n\t\tthis.activeWeight += request.weight;\n\t\tlet released = false;\n\t\tconst release = (): void => {\n\t\t\t// §10.3 exactly-once: a late or repeated settlement must not return\n\t\t\t// weight it no longer owns.\n\t\t\tif (released) {\n\t\t\t\tthis.doubleReleases += 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treleased = true;\n\t\t\tthis.activeWeight -= request.weight;\n\t\t\tthis.grantWhilePossible();\n\t\t};\n\t\treturn { permitId, requestId: request.requestId, acquiredAt, release };\n\t}\n\n\t/** Grant queued waiters strictly in FIFO order while the head fits (§10.4). */\n\tprivate grantWhilePossible(): void {\n\t\twhile (this.queue.length > 0) {\n\t\t\tconst head = this.queue[0];\n\t\t\tif (head.request.weight > this.capacity) {\n\t\t\t\t// Capacity shrank below the head's weight: reject rather than\n\t\t\t\t// starving everyone behind it forever.\n\t\t\t\tthis.queue.shift();\n\t\t\t\tthis.settleCleanup(head);\n\t\t\t\thead.reject(new WorkloadPermitError(\"over_capacity_weight\", head.request.requestId));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.activeWeight + head.request.weight > this.capacity) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.queue.shift();\n\t\t\tthis.settleCleanup(head);\n\t\t\thead.resolve(this.grant(head.request));\n\t\t}\n\t}\n\n\tprivate evict(waiter: Waiter, code: WorkloadPermitErrorCode): void {\n\t\tconst index = this.queue.indexOf(waiter);\n\t\tif (index === -1) {\n\t\t\treturn; // Already granted or already evicted.\n\t\t}\n\t\tthis.queue.splice(index, 1);\n\t\tthis.settleCleanup(waiter);\n\t\twaiter.reject(new WorkloadPermitError(code, waiter.request.requestId));\n\t\tthis.grantWhilePossible();\n\t}\n\n\tprivate settleCleanup(waiter: Waiter): void {\n\t\tif (waiter.timer !== null) {\n\t\t\tclearTimeout(waiter.timer);\n\t\t\twaiter.timer = null;\n\t\t}\n\t\tif (waiter.abortListener !== null) {\n\t\t\twaiter.request.signal?.removeEventListener(\"abort\", waiter.abortListener);\n\t\t\twaiter.abortListener = null;\n\t\t}\n\t}\n}\n\nfunction sanitizeCapacity(value: number | undefined, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n"]}
|
|
@@ -16,8 +16,6 @@ export class WorkloadPermitPool {
|
|
|
16
16
|
now;
|
|
17
17
|
activeWeight = 0;
|
|
18
18
|
queue = [];
|
|
19
|
-
releasedPermitIds = new Set();
|
|
20
|
-
activePermitIds = new Set();
|
|
21
19
|
doubleReleases = 0;
|
|
22
20
|
constructor(options) {
|
|
23
21
|
this.capacity = sanitizeCapacity(options?.capacity, 2);
|
|
@@ -34,7 +32,8 @@ export class WorkloadPermitPool {
|
|
|
34
32
|
this.grantWhilePossible();
|
|
35
33
|
}
|
|
36
34
|
/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */
|
|
37
|
-
acquire(
|
|
35
|
+
acquire(input) {
|
|
36
|
+
const request = { ...input };
|
|
38
37
|
if (request.weight > this.capacity) {
|
|
39
38
|
return Promise.reject(new WorkloadPermitError("over_capacity_weight", request.requestId));
|
|
40
39
|
}
|
|
@@ -72,22 +71,22 @@ export class WorkloadPermitPool {
|
|
|
72
71
|
return this.doubleReleases;
|
|
73
72
|
}
|
|
74
73
|
grant(request) {
|
|
75
|
-
|
|
74
|
+
const acquiredAt = this.now().toISOString();
|
|
76
75
|
const permitId = `permit-${randomUUID()}`;
|
|
77
|
-
this.
|
|
76
|
+
this.activeWeight += request.weight;
|
|
77
|
+
let released = false;
|
|
78
78
|
const release = () => {
|
|
79
79
|
// §10.3 exactly-once: a late or repeated settlement must not return
|
|
80
80
|
// weight it no longer owns.
|
|
81
|
-
if (
|
|
81
|
+
if (released) {
|
|
82
82
|
this.doubleReleases += 1;
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
|
|
86
|
-
this.
|
|
87
|
-
this.activeWeight = Math.max(0, this.activeWeight - request.weight);
|
|
85
|
+
released = true;
|
|
86
|
+
this.activeWeight -= request.weight;
|
|
88
87
|
this.grantWhilePossible();
|
|
89
88
|
};
|
|
90
|
-
return { permitId, requestId: request.requestId, acquiredAt
|
|
89
|
+
return { permitId, requestId: request.requestId, acquiredAt, release };
|
|
91
90
|
}
|
|
92
91
|
/** Grant queued waiters strictly in FIFO order while the head fits (§10.4). */
|
|
93
92
|
grantWhilePossible() {
|
|
@@ -117,6 +116,7 @@ export class WorkloadPermitPool {
|
|
|
117
116
|
this.queue.splice(index, 1);
|
|
118
117
|
this.settleCleanup(waiter);
|
|
119
118
|
waiter.reject(new WorkloadPermitError(code, waiter.request.requestId));
|
|
119
|
+
this.grantWhilePossible();
|
|
120
120
|
}
|
|
121
121
|
settleCleanup(waiter) {
|
|
122
122
|
if (waiter.timer !== null) {
|
|
@@ -130,7 +130,7 @@ export class WorkloadPermitPool {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
function sanitizeCapacity(value, fallback) {
|
|
133
|
-
if (typeof value !== "number" || !Number.isFinite(value) || value <
|
|
133
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
134
134
|
return fallback;
|
|
135
135
|
}
|
|
136
136
|
return Math.floor(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workload-permit-pool.js","sourceRoot":"","sources":["../../src/core/workload-permit-pool.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { WorkloadClass } from \"./workload-classifier.ts\";\n\n/**\n * Shared workload permit pool (OMK v0.97.x roadmap §10, M3/PR5).\n *\n * Bounds concurrent heavy/cpu subprocesses independently of tool concurrency\n * (§10.1: 4 concurrent reads != 4 concurrent `npm test` processes). One pool\n * instance is shared by a session and, later, its child subagents (§14.1) —\n * a child creating its own pool would oversubscribe the host.\n *\n * §10.3 rules implemented here: strict FIFO (§10.4), abort- and\n * timeout-aware waiting, exactly-once release with double-release recorded\n * as a diagnostic no-op, immediate rejection of requests wider than\n * capacity, and a hard queue cap whose overflow surfaces as a structured\n * error code (§15.4 `queue_overflow`). Waiter timers stay ref'd — a permit\n * wait is actively awaited work — and are cleared on settle.\n */\n\nexport interface WorkloadPermitRequest {\n\treadonly requestId: string;\n\treadonly promptRunId: string;\n\treadonly workloadClass: WorkloadClass;\n\treadonly weight: 1 | 2;\n\treadonly signal?: AbortSignal;\n\treadonly timeoutMs?: number;\n}\n\nexport interface WorkloadPermit {\n\treadonly permitId: string;\n\treadonly requestId: string;\n\treadonly acquiredAt: string;\n\trelease(): void;\n}\n\nexport interface WorkloadPermitPoolSnapshot {\n\treadonly capacity: number;\n\treadonly activeWeight: number;\n\treadonly queuedCount: number;\n}\n\nexport type WorkloadPermitErrorCode = \"queue_overflow\" | \"timeout\" | \"aborted\" | \"over_capacity_weight\";\n\nexport class WorkloadPermitError extends Error {\n\treadonly code: WorkloadPermitErrorCode;\n\treadonly requestId: string;\n\n\tconstructor(code: WorkloadPermitErrorCode, requestId: string) {\n\t\tsuper(`workload permit ${code} (request ${requestId})`);\n\t\tthis.name = \"WorkloadPermitError\";\n\t\tthis.code = code;\n\t\tthis.requestId = requestId;\n\t}\n}\n\ninterface Waiter {\n\treadonly request: WorkloadPermitRequest;\n\treadonly resolve: (permit: WorkloadPermit) => void;\n\treadonly reject: (error: WorkloadPermitError) => void;\n\ttimer: ReturnType<typeof setTimeout> | null;\n\tabortListener: (() => void) | null;\n}\n\nexport const DEFAULT_PERMIT_QUEUE_CAP = 32;\n\nexport type WorkloadPermitPoolOptions = {\n\t/** Concurrent weight budget; §7.2 heavy caps feed this. Default 2. */\n\tcapacity?: number;\n\t/** §10.3 queue length hard cap. Default 32. */\n\tmaxQueue?: number;\n\t/** Injectable clock for deterministic tests. */\n\tnow?: () => Date;\n};\n\nexport class WorkloadPermitPool {\n\tprivate capacity: number;\n\tprivate readonly maxQueue: number;\n\tprivate readonly now: () => Date;\n\tprivate activeWeight = 0;\n\tprivate readonly queue: Waiter[] = [];\n\tprivate readonly releasedPermitIds = new Set<string>();\n\tprivate readonly activePermitIds = new Set<string>();\n\tprivate doubleReleases = 0;\n\n\tconstructor(options?: WorkloadPermitPoolOptions) {\n\t\tthis.capacity = sanitizeCapacity(options?.capacity, 2);\n\t\tthis.maxQueue = sanitizeCapacity(options?.maxQueue, DEFAULT_PERMIT_QUEUE_CAP);\n\t\tthis.now = options?.now ?? (() => new Date());\n\t}\n\n\t/**\n\t * Update capacity from a new admission decision. In-flight permits are\n\t * never revoked; a reduction only delays future grants until active\n\t * weight drains below the new capacity.\n\t */\n\tsetCapacity(capacity: number): void {\n\t\tthis.capacity = sanitizeCapacity(capacity, this.capacity);\n\t\tthis.grantWhilePossible();\n\t}\n\n\t/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */\n\tacquire(request: WorkloadPermitRequest): Promise<WorkloadPermit> {\n\t\tif (request.weight > this.capacity) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"over_capacity_weight\", request.requestId));\n\t\t}\n\t\tif (request.signal?.aborted) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"aborted\", request.requestId));\n\t\t}\n\t\tif (this.queue.length === 0 && this.activeWeight + request.weight <= this.capacity) {\n\t\t\treturn Promise.resolve(this.grant(request));\n\t\t}\n\t\tif (this.queue.length >= this.maxQueue) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"queue_overflow\", request.requestId));\n\t\t}\n\t\treturn new Promise<WorkloadPermit>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { request, resolve, reject, timer: null, abortListener: null };\n\t\t\tif (typeof request.timeoutMs === \"number\" && Number.isFinite(request.timeoutMs) && request.timeoutMs > 0) {\n\t\t\t\twaiter.timer = setTimeout(() => {\n\t\t\t\t\tthis.evict(waiter, \"timeout\");\n\t\t\t\t}, request.timeoutMs);\n\t\t\t}\n\t\t\tif (request.signal) {\n\t\t\t\tconst signal = request.signal;\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tthis.evict(waiter, \"aborted\");\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.queue.push(waiter);\n\t\t});\n\t}\n\n\tsnapshot(): WorkloadPermitPoolSnapshot {\n\t\treturn { capacity: this.capacity, activeWeight: this.activeWeight, queuedCount: this.queue.length };\n\t}\n\n\t/** Diagnostic count of double releases (§10.3 no-op + diagnostic). */\n\tget doubleReleaseCount(): number {\n\t\treturn this.doubleReleases;\n\t}\n\n\tprivate grant(request: WorkloadPermitRequest): WorkloadPermit {\n\t\tthis.activeWeight += request.weight;\n\t\tconst permitId = `permit-${randomUUID()}`;\n\t\tthis.activePermitIds.add(permitId);\n\t\tconst release = (): void => {\n\t\t\t// §10.3 exactly-once: a late or repeated settlement must not return\n\t\t\t// weight it no longer owns.\n\t\t\tif (this.releasedPermitIds.has(permitId) || !this.activePermitIds.has(permitId)) {\n\t\t\t\tthis.doubleReleases += 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.activePermitIds.delete(permitId);\n\t\t\tthis.releasedPermitIds.add(permitId);\n\t\t\tthis.activeWeight = Math.max(0, this.activeWeight - request.weight);\n\t\t\tthis.grantWhilePossible();\n\t\t};\n\t\treturn { permitId, requestId: request.requestId, acquiredAt: this.now().toISOString(), release };\n\t}\n\n\t/** Grant queued waiters strictly in FIFO order while the head fits (§10.4). */\n\tprivate grantWhilePossible(): void {\n\t\twhile (this.queue.length > 0) {\n\t\t\tconst head = this.queue[0];\n\t\t\tif (head.request.weight > this.capacity) {\n\t\t\t\t// Capacity shrank below the head's weight: reject rather than\n\t\t\t\t// starving everyone behind it forever.\n\t\t\t\tthis.queue.shift();\n\t\t\t\tthis.settleCleanup(head);\n\t\t\t\thead.reject(new WorkloadPermitError(\"over_capacity_weight\", head.request.requestId));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.activeWeight + head.request.weight > this.capacity) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.queue.shift();\n\t\t\tthis.settleCleanup(head);\n\t\t\thead.resolve(this.grant(head.request));\n\t\t}\n\t}\n\n\tprivate evict(waiter: Waiter, code: WorkloadPermitErrorCode): void {\n\t\tconst index = this.queue.indexOf(waiter);\n\t\tif (index === -1) {\n\t\t\treturn; // Already granted or already evicted.\n\t\t}\n\t\tthis.queue.splice(index, 1);\n\t\tthis.settleCleanup(waiter);\n\t\twaiter.reject(new WorkloadPermitError(code, waiter.request.requestId));\n\t}\n\n\tprivate settleCleanup(waiter: Waiter): void {\n\t\tif (waiter.timer !== null) {\n\t\t\tclearTimeout(waiter.timer);\n\t\t\twaiter.timer = null;\n\t\t}\n\t\tif (waiter.abortListener !== null) {\n\t\t\twaiter.request.signal?.removeEventListener(\"abort\", waiter.abortListener);\n\t\t\twaiter.abortListener = null;\n\t\t}\n\t}\n}\n\nfunction sanitizeCapacity(value: number | undefined, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 1) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"workload-permit-pool.js","sourceRoot":"","sources":["../../src/core/workload-permit-pool.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { WorkloadClass } from \"./workload-classifier.ts\";\n\n/**\n * Shared workload permit pool (OMK v0.97.x roadmap §10, M3/PR5).\n *\n * Bounds concurrent heavy/cpu subprocesses independently of tool concurrency\n * (§10.1: 4 concurrent reads != 4 concurrent `npm test` processes). One pool\n * instance is shared by a session and, later, its child subagents (§14.1) —\n * a child creating its own pool would oversubscribe the host.\n *\n * §10.3 rules implemented here: strict FIFO (§10.4), abort- and\n * timeout-aware waiting, exactly-once release with double-release recorded\n * as a diagnostic no-op, immediate rejection of requests wider than\n * capacity, and a hard queue cap whose overflow surfaces as a structured\n * error code (§15.4 `queue_overflow`). Waiter timers stay ref'd — a permit\n * wait is actively awaited work — and are cleared on settle.\n */\n\nexport interface WorkloadPermitRequest {\n\treadonly requestId: string;\n\treadonly promptRunId: string;\n\treadonly workloadClass: WorkloadClass;\n\treadonly weight: 1 | 2;\n\treadonly signal?: AbortSignal;\n\treadonly timeoutMs?: number;\n}\n\nexport interface WorkloadPermit {\n\treadonly permitId: string;\n\treadonly requestId: string;\n\treadonly acquiredAt: string;\n\trelease(): void;\n}\n\nexport interface WorkloadPermitPoolSnapshot {\n\treadonly capacity: number;\n\treadonly activeWeight: number;\n\treadonly queuedCount: number;\n}\n\nexport type WorkloadPermitErrorCode = \"queue_overflow\" | \"timeout\" | \"aborted\" | \"over_capacity_weight\";\n\nexport class WorkloadPermitError extends Error {\n\treadonly code: WorkloadPermitErrorCode;\n\treadonly requestId: string;\n\n\tconstructor(code: WorkloadPermitErrorCode, requestId: string) {\n\t\tsuper(`workload permit ${code} (request ${requestId})`);\n\t\tthis.name = \"WorkloadPermitError\";\n\t\tthis.code = code;\n\t\tthis.requestId = requestId;\n\t}\n}\n\ninterface Waiter {\n\treadonly request: WorkloadPermitRequest;\n\treadonly resolve: (permit: WorkloadPermit) => void;\n\treadonly reject: (error: WorkloadPermitError) => void;\n\ttimer: ReturnType<typeof setTimeout> | null;\n\tabortListener: (() => void) | null;\n}\n\nexport const DEFAULT_PERMIT_QUEUE_CAP = 32;\n\nexport type WorkloadPermitPoolOptions = {\n\t/** Concurrent weight budget; §7.2 heavy caps feed this. Default 2. */\n\tcapacity?: number;\n\t/** §10.3 queue length hard cap. Default 32. */\n\tmaxQueue?: number;\n\t/** Injectable clock for deterministic tests. */\n\tnow?: () => Date;\n};\n\nexport class WorkloadPermitPool {\n\tprivate capacity: number;\n\tprivate readonly maxQueue: number;\n\tprivate readonly now: () => Date;\n\tprivate activeWeight = 0;\n\tprivate readonly queue: Waiter[] = [];\n\tprivate doubleReleases = 0;\n\n\tconstructor(options?: WorkloadPermitPoolOptions) {\n\t\tthis.capacity = sanitizeCapacity(options?.capacity, 2);\n\t\tthis.maxQueue = sanitizeCapacity(options?.maxQueue, DEFAULT_PERMIT_QUEUE_CAP);\n\t\tthis.now = options?.now ?? (() => new Date());\n\t}\n\n\t/**\n\t * Update capacity from a new admission decision. In-flight permits are\n\t * never revoked; a reduction only delays future grants until active\n\t * weight drains below the new capacity.\n\t */\n\tsetCapacity(capacity: number): void {\n\t\tthis.capacity = sanitizeCapacity(capacity, this.capacity);\n\t\tthis.grantWhilePossible();\n\t}\n\n\t/** Acquire a permit. Strict FIFO; rejects with {@link WorkloadPermitError}. */\n\tacquire(input: WorkloadPermitRequest): Promise<WorkloadPermit> {\n\t\tconst request = { ...input };\n\t\tif (request.weight > this.capacity) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"over_capacity_weight\", request.requestId));\n\t\t}\n\t\tif (request.signal?.aborted) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"aborted\", request.requestId));\n\t\t}\n\t\tif (this.queue.length === 0 && this.activeWeight + request.weight <= this.capacity) {\n\t\t\treturn Promise.resolve(this.grant(request));\n\t\t}\n\t\tif (this.queue.length >= this.maxQueue) {\n\t\t\treturn Promise.reject(new WorkloadPermitError(\"queue_overflow\", request.requestId));\n\t\t}\n\t\treturn new Promise<WorkloadPermit>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { request, resolve, reject, timer: null, abortListener: null };\n\t\t\tif (typeof request.timeoutMs === \"number\" && Number.isFinite(request.timeoutMs) && request.timeoutMs > 0) {\n\t\t\t\twaiter.timer = setTimeout(() => {\n\t\t\t\t\tthis.evict(waiter, \"timeout\");\n\t\t\t\t}, request.timeoutMs);\n\t\t\t}\n\t\t\tif (request.signal) {\n\t\t\t\tconst signal = request.signal;\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tthis.evict(waiter, \"aborted\");\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.queue.push(waiter);\n\t\t});\n\t}\n\n\tsnapshot(): WorkloadPermitPoolSnapshot {\n\t\treturn { capacity: this.capacity, activeWeight: this.activeWeight, queuedCount: this.queue.length };\n\t}\n\n\t/** Diagnostic count of double releases (§10.3 no-op + diagnostic). */\n\tget doubleReleaseCount(): number {\n\t\treturn this.doubleReleases;\n\t}\n\n\tprivate grant(request: WorkloadPermitRequest): WorkloadPermit {\n\t\tconst acquiredAt = this.now().toISOString();\n\t\tconst permitId = `permit-${randomUUID()}`;\n\t\tthis.activeWeight += request.weight;\n\t\tlet released = false;\n\t\tconst release = (): void => {\n\t\t\t// §10.3 exactly-once: a late or repeated settlement must not return\n\t\t\t// weight it no longer owns.\n\t\t\tif (released) {\n\t\t\t\tthis.doubleReleases += 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treleased = true;\n\t\t\tthis.activeWeight -= request.weight;\n\t\t\tthis.grantWhilePossible();\n\t\t};\n\t\treturn { permitId, requestId: request.requestId, acquiredAt, release };\n\t}\n\n\t/** Grant queued waiters strictly in FIFO order while the head fits (§10.4). */\n\tprivate grantWhilePossible(): void {\n\t\twhile (this.queue.length > 0) {\n\t\t\tconst head = this.queue[0];\n\t\t\tif (head.request.weight > this.capacity) {\n\t\t\t\t// Capacity shrank below the head's weight: reject rather than\n\t\t\t\t// starving everyone behind it forever.\n\t\t\t\tthis.queue.shift();\n\t\t\t\tthis.settleCleanup(head);\n\t\t\t\thead.reject(new WorkloadPermitError(\"over_capacity_weight\", head.request.requestId));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this.activeWeight + head.request.weight > this.capacity) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.queue.shift();\n\t\t\tthis.settleCleanup(head);\n\t\t\thead.resolve(this.grant(head.request));\n\t\t}\n\t}\n\n\tprivate evict(waiter: Waiter, code: WorkloadPermitErrorCode): void {\n\t\tconst index = this.queue.indexOf(waiter);\n\t\tif (index === -1) {\n\t\t\treturn; // Already granted or already evicted.\n\t\t}\n\t\tthis.queue.splice(index, 1);\n\t\tthis.settleCleanup(waiter);\n\t\twaiter.reject(new WorkloadPermitError(code, waiter.request.requestId));\n\t\tthis.grantWhilePossible();\n\t}\n\n\tprivate settleCleanup(waiter: Waiter): void {\n\t\tif (waiter.timer !== null) {\n\t\t\tclearTimeout(waiter.timer);\n\t\t\twaiter.timer = null;\n\t\t}\n\t\tif (waiter.abortListener !== null) {\n\t\t\twaiter.request.signal?.removeEventListener(\"abort\", waiter.abortListener);\n\t\t\twaiter.abortListener = null;\n\t\t}\n\t}\n}\n\nfunction sanitizeCapacity(value: number | undefined, fallback: number): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n\t\treturn fallback;\n\t}\n\treturn Math.floor(value);\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { getAgentDir, VERSION } from "./config.ts";
|
|
|
7
7
|
export { ADVISORY_JUDGE_PROMPT_VERSION, type AdvisoryJudge, type AdvisoryJudgeCandidate, type AdvisoryJudgeCandidateScore, type AdvisoryJudgeCriterion, type AdvisoryJudgeDecision, type AdvisoryJudgeDecisionReason, type AdvisoryJudgeDecisionStatus, type AdvisoryJudgeInput, AdvisoryJudgeInputError, type AdvisoryJudgeRequest, type AdvisoryJudgeRequestCandidate, chooseWithAdvisoryJudge, } from "./core/advisory-judge.ts";
|
|
8
8
|
export { type AdvisoryJudgeCompletion, AdvisoryJudgeModelError, type AdvisoryJudgeModelErrorCode, createModelAdvisoryJudge, type ModelAdvisoryJudgeOptions, } from "./core/advisory-judge-model.ts";
|
|
9
9
|
export { AgentSession, type AgentSessionConfig, type AgentSessionEvent, type AgentSessionEventListener, type ModelCycleResult, type ParsedSkillBlock, type PromptOptions, parseSkillBlock, type SessionStats, } from "./core/agent-session.ts";
|
|
10
|
+
export * from "./core/run-execution-api.ts";
|
|
10
11
|
export { type ApiKeyCredential, type AuthCredential, type AuthStatus, AuthStorage, type AuthStorageBackend, FileAuthStorageBackend, InMemoryAuthStorageBackend, type OAuthCredential, } from "./core/auth-storage.ts";
|
|
11
12
|
export { type ApiAction, ApiBroker, type ApiMethod, type ApiOutcome, AUTOPILOT_MAX, type AutomationHarnessScoreInput, AutomationHarnessScorer, type AutomationScoreBreakdown, type AutomationTrace, type AutomationTraceAction, type AutomationTraceContextPlan, type AutomationTraceEnvApiUse, type AutonomyProfile, type BrokerFetcher, type BrokerFetchRequest, type BrokerFetchResponse, type Capability, canonicalHash, classifyEnvKey, DynamicToolPortfolioOptimizer, EnvBroker, type EnvBrokerLedger, type EnvMode, type EnvRecord, type EnvResolutionRequest, type EnvUseEvent, type EvidenceActor, type EvidenceEvent, type EvidenceEventInput, EvidenceLedger, type EvidenceOutcome, type EvidencePointer, type ExecutionStrategy, type Postcondition, PostconditionVerifier, type RiskLevel, redactForModel, type Sensitivity, strategyForRisk, ToolExecutionBroker, type ToolExecutionCandidate, type ToolExecutionChoice, type ToolExecutionNeed, type VerificationContext, type VerificationResult, } from "./core/automation/index.ts";
|
|
12
13
|
export { type BranchPreparation, type BranchSummaryResult, type CollectEntriesResult, type CompactionBarrierResult, type CompactionCommitDecision, type CompactionEnvelope, type CompactionHysteresisConfig, type CompactionHysteresisState, type CompactionResult, type CompactionTransaction, type CutPointResult, calculateContextTokens, collectEntriesForBranchSummary, compact, createCompactionEnvelope, createCompactionHysteresisConfig, createCompactionHysteresisState, createCompactionSourceIdentity, createCompactionTransaction, createSessionRevisionToken, DEFAULT_COMPACTION_SETTINGS, decideCompactionCommit, estimateTokens, evaluateCompactionBarrier, type FileOperations, findCutPoint, findTurnStartIndex, type GenerateBranchSummaryOptions, generateBranchSummary, generateSummary, getLastAssistantUsage, prepareBranchEntries, serializeConversation, shouldCompact, stepCompactionHysteresis, validateCompactionEnvelope, } from "./core/compaction/index.ts";
|
|
@@ -39,11 +40,11 @@ export { DefaultPackageManager } from "./core/package-manager.ts";
|
|
|
39
40
|
export type { ResourceCollision, ResourceDiagnostic, ResourceLoader } from "./core/resource-loader.ts";
|
|
40
41
|
export { DefaultResourceLoader, loadProjectContextFiles } from "./core/resource-loader.ts";
|
|
41
42
|
export { extractReverseSkillFactsFromMarkdown, formatReverseSkillFromSource, formatReverseSkillMarkdown, formatReverseSkillRouteDecision, getReverseSkillToolAliases, normalizeReverseSkillName, normalizeReverseSkillText, planReverseSkillToolChecks, REVERSE_SKILL_ROUTES, type ReverseSkillPlatform, type ReverseSkillRisk, type ReverseSkillRoute, type ReverseSkillRouteDecision, type ReverseSkillRouteInput, type ReverseSkillRouteScore, type ReverseSkillSourceFacts, type ReverseSkillSourceInput, type ReverseSkillSpecInput, routeReverseSkill, } from "./core/reverse-skill.ts";
|
|
42
|
-
export { appendRunJournalRecordDurably, type OpenRunJournalStoreOptions, type RunJournalQuarantineReport, RunJournalStore, RunJournalStoreCorruptionError, writeQuarantineBytesDurably, } from "./core/run-journal-store.ts";
|
|
43
43
|
export { type BashSandboxMode, createWorkspaceSandboxPolicy, resolveBashSandboxMode, } from "./core/sandbox/default-policy.ts";
|
|
44
44
|
export { AgentSessionRuntime, type AgentSessionRuntimeDiagnostic, type AgentSessionServices, type CreateAgentSessionFromServicesOptions, type CreateAgentSessionOptions, type CreateAgentSessionResult, type CreateAgentSessionRuntimeFactory, type CreateAgentSessionRuntimeResult, type CreateAgentSessionServicesOptions, createAgentSession, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, createBashTool, createCodingTools, createEditTool, createFindTool, createGrepTool, createLsTool, createReadOnlyTools, createReadTool, createWriteTool, type PromptTemplate, } from "./core/sdk.ts";
|
|
45
|
+
export { createRunCoordinator } from "./core/agent-session-services.ts";
|
|
46
|
+
export type { VerifiedRunRuntime, VerifiedRunSession, VerifiedRunSessionInput, } from "./core/verified-run/session-port.ts";
|
|
45
47
|
export { type BranchSummaryEntry, buildSessionContext, type CompactionEntry, type CompactionProvenanceDetails, CURRENT_SESSION_VERSION, type CustomEntry, type CustomMessageEntry, type FileEntry, getLatestCompactionEntry, type ModelChangeEntry, migrateSessionEntries, type NewSessionOptions, parseSessionEntries, type SessionContext, type SessionEntry, type SessionEntryBase, type SessionHeader, type SessionInfo, type SessionInfoEntry, SessionManager, type SessionMessageEntry, type SessionQuarantineReport, type ThinkingLevelChangeEntry, } from "./core/session-manager.ts";
|
|
46
|
-
export { classifySessionTermination, formatSessionTermination, type SessionTermination, type SessionTerminationCause, SessionTerminationError, type SessionTerminationKind, } from "./core/session-termination.ts";
|
|
47
48
|
export { type AgentRuntimeSettings, type CompactionSettings, type ImageSettings, type PackageSource, type RetrySettings, SettingsManager, type ToolSchedulerSetting, } from "./core/settings-manager.ts";
|
|
48
49
|
export { formatSkillsForPrompt, type LoadSkillsFromDirOptions, type LoadSkillsResult, loadSkills, loadSkillsFromDir, type Skill, type SkillFrontmatter, } from "./core/skills.ts";
|
|
49
50
|
export { createSyntheticSourceInfo } from "./core/source-info.ts";
|