open-multi-agent-kit 0.96.0 → 0.96.2
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 +81 -0
- package/README.md +34 -6
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/commands/doctor-provider.d.ts.map +1 -1
- package/dist/commands/doctor-provider.js +15 -20
- package/dist/commands/doctor-provider.js.map +1 -1
- package/dist/commands/resource-doctor-cli.d.ts +22 -0
- package/dist/commands/resource-doctor-cli.d.ts.map +1 -0
- package/dist/commands/resource-doctor-cli.js +98 -0
- package/dist/commands/resource-doctor-cli.js.map +1 -0
- package/dist/commands/sdk-session-cli.d.ts +24 -0
- package/dist/commands/sdk-session-cli.d.ts.map +1 -0
- package/dist/commands/sdk-session-cli.js +225 -0
- package/dist/commands/sdk-session-cli.js.map +1 -0
- package/dist/core/advisory-judge-model.d.ts +18 -0
- package/dist/core/advisory-judge-model.d.ts.map +1 -0
- package/dist/core/advisory-judge-model.js +168 -0
- package/dist/core/advisory-judge-model.js.map +1 -0
- package/dist/core/advisory-judge-response.d.ts +8 -0
- package/dist/core/advisory-judge-response.d.ts.map +1 -0
- package/dist/core/advisory-judge-response.js +61 -0
- package/dist/core/advisory-judge-response.js.map +1 -0
- package/dist/core/advisory-judge-types.d.ts +53 -0
- package/dist/core/advisory-judge-types.d.ts.map +1 -0
- package/dist/core/advisory-judge-types.js +2 -0
- package/dist/core/advisory-judge-types.js.map +1 -0
- package/dist/core/advisory-judge.d.ts +8 -0
- package/dist/core/advisory-judge.d.ts.map +1 -0
- package/dist/core/advisory-judge.js +178 -0
- package/dist/core/advisory-judge.js.map +1 -0
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +41 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +396 -179
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +28 -4
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction-gate.d.ts +28 -0
- package/dist/core/compaction-gate.d.ts.map +1 -0
- package/dist/core/compaction-gate.js +34 -0
- package/dist/core/compaction-gate.js.map +1 -0
- package/dist/core/completion-sound.d.ts +109 -0
- package/dist/core/completion-sound.d.ts.map +1 -0
- package/dist/core/completion-sound.js +165 -0
- package/dist/core/completion-sound.js.map +1 -0
- package/dist/core/context-budget-system-prompt-items.d.ts.map +1 -1
- package/dist/core/context-budget-system-prompt-items.js +5 -3
- package/dist/core/context-budget-system-prompt-items.js.map +1 -1
- package/dist/core/domain-loadouts.d.ts.map +1 -1
- package/dist/core/domain-loadouts.js +2 -2
- package/dist/core/domain-loadouts.js.map +1 -1
- package/dist/core/durable-goal-checkpoint.d.ts +6 -0
- package/dist/core/durable-goal-checkpoint.d.ts.map +1 -0
- package/dist/core/durable-goal-checkpoint.js +195 -0
- package/dist/core/durable-goal-checkpoint.js.map +1 -0
- package/dist/core/durable-goal-parse.d.ts +3 -0
- package/dist/core/durable-goal-parse.d.ts.map +1 -0
- package/dist/core/durable-goal-parse.js +86 -0
- package/dist/core/durable-goal-parse.js.map +1 -0
- package/dist/core/durable-goal-reducer.d.ts +3 -0
- package/dist/core/durable-goal-reducer.d.ts.map +1 -0
- package/dist/core/durable-goal-reducer.js +175 -0
- package/dist/core/durable-goal-reducer.js.map +1 -0
- package/dist/core/durable-goal-store.d.ts +19 -0
- package/dist/core/durable-goal-store.d.ts.map +1 -0
- package/dist/core/durable-goal-store.js +126 -0
- package/dist/core/durable-goal-store.js.map +1 -0
- package/dist/core/durable-goal.d.ts +92 -0
- package/dist/core/durable-goal.d.ts.map +1 -0
- package/dist/core/durable-goal.js +62 -0
- package/dist/core/durable-goal.js.map +1 -0
- package/dist/core/extensions/builtin/goal-controller.d.ts +3 -0
- package/dist/core/extensions/builtin/goal-controller.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal-controller.js +125 -0
- package/dist/core/extensions/builtin/goal-controller.js.map +1 -0
- package/dist/core/extensions/builtin/identical-loop.d.ts +3 -0
- package/dist/core/extensions/builtin/identical-loop.d.ts.map +1 -0
- package/dist/core/extensions/builtin/identical-loop.js +31 -0
- package/dist/core/extensions/builtin/identical-loop.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset.js +13 -0
- package/dist/core/extensions/builtin/prompt-preset.js.map +1 -0
- package/dist/core/extensions/builtin/tool-pair-repair.d.ts +3 -0
- package/dist/core/extensions/builtin/tool-pair-repair.d.ts.map +1 -0
- package/dist/core/extensions/builtin/tool-pair-repair.js +12 -0
- package/dist/core/extensions/builtin/tool-pair-repair.js.map +1 -0
- package/dist/core/extensions/types.d.ts +6 -2
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/goal-continuation.d.ts +13 -0
- package/dist/core/goal-continuation.d.ts.map +1 -0
- package/dist/core/goal-continuation.js +10 -0
- package/dist/core/goal-continuation.js.map +1 -0
- package/dist/core/grok-harness.d.ts +1 -1
- package/dist/core/grok-harness.d.ts.map +1 -1
- package/dist/core/grok-harness.js +1 -1
- package/dist/core/grok-harness.js.map +1 -1
- package/dist/core/grok-playbook.d.ts +1 -1
- package/dist/core/grok-playbook.d.ts.map +1 -1
- package/dist/core/grok-playbook.js +1 -1
- package/dist/core/grok-playbook.js.map +1 -1
- package/dist/core/host-resource-probe.d.ts +63 -0
- package/dist/core/host-resource-probe.d.ts.map +1 -0
- package/dist/core/host-resource-probe.js +126 -0
- package/dist/core/host-resource-probe.js.map +1 -0
- package/dist/core/host-resource-snapshot.d.ts +54 -0
- package/dist/core/host-resource-snapshot.d.ts.map +1 -0
- package/dist/core/host-resource-snapshot.js +139 -0
- package/dist/core/host-resource-snapshot.js.map +1 -0
- package/dist/core/identical-loop.d.ts +15 -0
- package/dist/core/identical-loop.d.ts.map +1 -0
- package/dist/core/identical-loop.js +34 -0
- package/dist/core/identical-loop.js.map +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/model-prompt-policy.d.ts +11 -0
- package/dist/core/model-prompt-policy.d.ts.map +1 -0
- package/dist/core/model-prompt-policy.js +17 -0
- package/dist/core/model-prompt-policy.js.map +1 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +16 -4
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +2 -2
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/prompt-budget.d.ts +21 -0
- package/dist/core/prompt-budget.d.ts.map +1 -0
- package/dist/core/prompt-budget.js +51 -0
- package/dist/core/prompt-budget.js.map +1 -0
- package/dist/core/prompt-cache.d.ts +14 -0
- package/dist/core/prompt-cache.d.ts.map +1 -0
- package/dist/core/prompt-cache.js +16 -0
- package/dist/core/prompt-cache.js.map +1 -0
- package/dist/core/prompt-preset.d.ts +8 -0
- package/dist/core/prompt-preset.d.ts.map +1 -0
- package/dist/core/prompt-preset.js +56 -0
- package/dist/core/prompt-preset.js.map +1 -0
- package/dist/core/prompt-settlement.d.ts +81 -0
- package/dist/core/prompt-settlement.d.ts.map +1 -0
- package/dist/core/prompt-settlement.js +84 -0
- package/dist/core/prompt-settlement.js.map +1 -0
- package/dist/core/provider-resilience.d.ts +16 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +24 -2
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/provider-retry.d.ts +36 -0
- package/dist/core/provider-retry.d.ts.map +1 -0
- package/dist/core/provider-retry.js +73 -0
- package/dist/core/provider-retry.js.map +1 -0
- package/dist/core/provider-usage.d.ts +16 -2
- package/dist/core/provider-usage.d.ts.map +1 -1
- package/dist/core/provider-usage.js +150 -8
- package/dist/core/provider-usage.js.map +1 -1
- package/dist/core/reasoning-router-resolver.d.ts.map +1 -1
- package/dist/core/reasoning-router-resolver.js +1 -1
- package/dist/core/reasoning-router-resolver.js.map +1 -1
- package/dist/core/resource-admission-config.d.ts +55 -0
- package/dist/core/resource-admission-config.d.ts.map +1 -0
- package/dist/core/resource-admission-config.js +97 -0
- package/dist/core/resource-admission-config.js.map +1 -0
- package/dist/core/resource-admission.d.ts +81 -0
- package/dist/core/resource-admission.d.ts.map +1 -0
- package/dist/core/resource-admission.js +128 -0
- package/dist/core/resource-admission.js.map +1 -0
- package/dist/core/resource-governor-format.d.ts +50 -0
- package/dist/core/resource-governor-format.d.ts.map +1 -0
- package/dist/core/resource-governor-format.js +113 -0
- package/dist/core/resource-governor-format.js.map +1 -0
- package/dist/core/resource-governor-settings.d.ts +56 -0
- package/dist/core/resource-governor-settings.d.ts.map +1 -0
- package/dist/core/resource-governor-settings.js +89 -0
- package/dist/core/resource-governor-settings.js.map +1 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +32 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/resource-observation-journal.d.ts +74 -0
- package/dist/core/resource-observation-journal.d.ts.map +1 -0
- package/dist/core/resource-observation-journal.js +198 -0
- package/dist/core/resource-observation-journal.js.map +1 -0
- package/dist/core/resource-safety-gate.d.ts +54 -0
- package/dist/core/resource-safety-gate.d.ts.map +1 -0
- package/dist/core/resource-safety-gate.js +51 -0
- package/dist/core/resource-safety-gate.js.map +1 -0
- package/dist/core/run-journal.d.ts.map +1 -1
- package/dist/core/run-journal.js +13 -1
- package/dist/core/run-journal.js.map +1 -1
- package/dist/core/run-resource-lease.d.ts +73 -0
- package/dist/core/run-resource-lease.d.ts.map +1 -0
- package/dist/core/run-resource-lease.js +78 -0
- package/dist/core/run-resource-lease.js.map +1 -0
- package/dist/core/sandbox/backend.d.ts +12 -0
- package/dist/core/sandbox/backend.d.ts.map +1 -1
- package/dist/core/sandbox/backend.js +52 -42
- package/dist/core/sandbox/backend.js.map +1 -1
- package/dist/core/sandbox/policy.d.ts +2 -0
- package/dist/core/sandbox/policy.d.ts.map +1 -1
- package/dist/core/sandbox/policy.js +2 -1
- package/dist/core/sandbox/policy.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-bash-service.d.ts +12 -0
- package/dist/core/session-bash-service.d.ts.map +1 -1
- package/dist/core/session-bash-service.js +14 -0
- package/dist/core/session-bash-service.js.map +1 -1
- package/dist/core/session-system-prompt.d.ts +30 -0
- package/dist/core/session-system-prompt.d.ts.map +1 -0
- package/dist/core/session-system-prompt.js +39 -0
- package/dist/core/session-system-prompt.js.map +1 -0
- package/dist/core/session-termination.d.ts +7 -2
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +29 -1
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/settings-manager.d.ts +12 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +36 -0
- package/dist/core/settings-manager.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/strict-record.d.ts +2 -0
- package/dist/core/strict-record.d.ts.map +1 -0
- package/dist/core/strict-record.js +9 -0
- package/dist/core/strict-record.js.map +1 -0
- package/dist/core/subagent-lane-launcher.d.ts +64 -0
- package/dist/core/subagent-lane-launcher.d.ts.map +1 -0
- package/dist/core/subagent-lane-launcher.js +107 -0
- package/dist/core/subagent-lane-launcher.js.map +1 -0
- package/dist/core/system-cpu-sampler.d.ts +45 -0
- package/dist/core/system-cpu-sampler.d.ts.map +1 -0
- package/dist/core/system-cpu-sampler.js +95 -0
- package/dist/core/system-cpu-sampler.js.map +1 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +5 -8
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tool-pair-repair.d.ts +11 -0
- package/dist/core/tool-pair-repair.d.ts.map +1 -0
- package/dist/core/tool-pair-repair.js +38 -0
- package/dist/core/tool-pair-repair.js.map +1 -0
- package/dist/core/tools/artifact-spill.d.ts +13 -0
- package/dist/core/tools/artifact-spill.d.ts.map +1 -0
- package/dist/core/tools/artifact-spill.js +26 -0
- package/dist/core/tools/artifact-spill.js.map +1 -0
- package/dist/core/tools/bash.d.ts +7 -4
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +8 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +10 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +2 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/workload-classifier.d.ts +32 -0
- package/dist/core/workload-classifier.d.ts.map +1 -0
- package/dist/core/workload-classifier.js +66 -0
- package/dist/core/workload-classifier.js.map +1 -0
- package/dist/core/workload-family-matcher.d.ts +3 -0
- package/dist/core/workload-family-matcher.d.ts.map +1 -0
- package/dist/core/workload-family-matcher.js +126 -0
- package/dist/core/workload-family-matcher.js.map +1 -0
- package/dist/core/workload-permit-pool.d.ts +78 -0
- package/dist/core/workload-permit-pool.d.ts.map +1 -0
- package/dist/core/workload-permit-pool.js +138 -0
- package/dist/core/workload-permit-pool.js.map +1 -0
- package/dist/core/workload-shard-executor.d.ts +68 -0
- package/dist/core/workload-shard-executor.d.ts.map +1 -0
- package/dist/core/workload-shard-executor.js +156 -0
- package/dist/core/workload-shard-executor.js.map +1 -0
- package/dist/core/workload-shard-plan.d.ts +81 -0
- package/dist/core/workload-shard-plan.d.ts.map +1 -0
- package/dist/core/workload-shard-plan.js +183 -0
- package/dist/core/workload-shard-plan.js.map +1 -0
- package/dist/core/workload-shard-runner.d.ts +11 -0
- package/dist/core/workload-shard-runner.d.ts.map +1 -0
- package/dist/core/workload-shard-runner.js +98 -0
- package/dist/core/workload-shard-runner.js.map +1 -0
- package/dist/core/workload-shard-store.d.ts +44 -0
- package/dist/core/workload-shard-store.d.ts.map +1 -0
- package/dist/core/workload-shard-store.js +189 -0
- package/dist/core/workload-shard-store.js.map +1 -0
- package/dist/core/workload-sharders.d.ts +47 -0
- package/dist/core/workload-sharders.d.ts.map +1 -0
- package/dist/core/workload-sharders.js +162 -0
- package/dist/core/workload-sharders.js.map +1 -0
- package/dist/core/workload-shell-scan.d.ts +12 -0
- package/dist/core/workload-shell-scan.d.ts.map +1 -0
- package/dist/core/workload-shell-scan.js +79 -0
- package/dist/core/workload-shell-scan.js.map +1 -0
- package/dist/index.d.ts +18 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +14 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +81 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +14 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/docs/adaptorch-preview-spec.md +1 -1
- package/docs/adaptorch-preview.md +2 -2
- package/docs/book-to-skill.md +1 -1
- package/docs/containerization.md +9 -0
- package/docs/docs.json +11 -3
- package/docs/environment-variables.md +11 -4
- package/docs/extensions.md +14 -1
- package/docs/grok-harness.md +35 -12
- package/docs/index.md +7 -6
- package/docs/loadout-domains/grok-harness.md +2 -2
- package/docs/models.md +10 -9
- package/docs/provider-resilience.md +9 -3
- package/docs/providers.md +9 -4
- package/docs/run-protocol.md +32 -0
- package/docs/sdk.md +100 -3
- package/docs/security.md +22 -32
- package/docs/sessions.md +14 -0
- package/docs/settings.md +64 -2
- package/docs/skills.md +16 -0
- package/docs/usage.md +37 -15
- 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/index.ts +6 -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/subagent/agent-capability-router.test.ts +7 -0
- package/examples/extensions/subagent/domain-profiles.ts +0 -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 +7 -9
|
@@ -5,7 +5,7 @@ export declare const MAX_SESSION_TERMINATION_MESSAGE_LENGTH = 512;
|
|
|
5
5
|
* runtime bounds from this tuple so a newly added kind can never crash
|
|
6
6
|
* journaling with "termination kind is out of bounds" again.
|
|
7
7
|
*/
|
|
8
|
-
export declare const SESSION_TERMINATION_KIND_VALUES: readonly ["completed", "user_abort", "provider_abort", "provider_auth", "provider_rate_limit", "provider_network", "provider_protocol", "provider_refusal", "context_overflow", "transcript_invalid", "tool_timeout", "tool_fatal", "compaction", "persistence", "process_signal", "process_crash", "configuration", "internal_error"];
|
|
8
|
+
export declare const SESSION_TERMINATION_KIND_VALUES: readonly ["completed", "user_abort", "provider_abort", "provider_auth", "provider_rate_limit", "provider_network", "provider_protocol", "provider_refusal", "context_overflow", "transcript_invalid", "tool_timeout", "tool_fatal", "compaction", "persistence", "process_signal", "process_crash", "configuration", "internal_error", "resource_pressure"];
|
|
9
9
|
export type SessionTerminationKind = (typeof SESSION_TERMINATION_KIND_VALUES)[number];
|
|
10
10
|
export type SessionTerminationPhase = "completed" | "control" | "preflight" | "provider" | "tool" | "compaction" | "persistence" | "process" | "resume";
|
|
11
11
|
export type SessionTerminationSource = "observed" | "inferred_on_resume";
|
|
@@ -13,10 +13,12 @@ export type SessionSideEffects = "none" | "possible" | "confirmed";
|
|
|
13
13
|
export type SessionProcessSignal = "SIGINT" | "SIGTERM" | "SIGHUP" | "SIGQUIT";
|
|
14
14
|
export type ProviderTerminationCauseCode = "abort" | "auth" | "rate_limit" | "network" | "protocol" | "refusal" | "context_overflow";
|
|
15
15
|
export type ToolTerminationCauseCode = "timeout" | "fatal";
|
|
16
|
+
/** §15.4 resource-aware runtime roadmap: host-pressure termination causes. */
|
|
17
|
+
export type ResourceTerminationCauseCode = "memory" | "disk" | "cpu" | "heap" | "probe_unavailable" | "queue_overflow";
|
|
16
18
|
export type CompactionTerminationCauseCode = "aborted" | "failed" | "stale";
|
|
17
19
|
export type PersistenceTerminationCauseCode = "read_failed" | "append_failed" | "replace_failed" | "fsync_failed" | "lock_failed";
|
|
18
20
|
export type TranscriptTerminationCauseCode = "missing_result" | "duplicate_result" | "orphan_result" | "duplicate_call_id" | "interleaved_non_result" | "invalid_jsonl" | "invalid_tree" | "unsupported_version" | "trailing_fragment";
|
|
19
|
-
export type SessionTerminationCauseCode = "session.completed" | "session.user_abort" | `provider.${ProviderTerminationCauseCode}` | `tool.${ToolTerminationCauseCode}` | `compaction.${CompactionTerminationCauseCode}` | `persistence.${PersistenceTerminationCauseCode}` | "process.signal" | "process.crash" | `transcript.${TranscriptTerminationCauseCode}` | "configuration.invalid" | "internal.unclassified"
|
|
21
|
+
export type SessionTerminationCauseCode = "session.completed" | "session.user_abort" | `provider.${ProviderTerminationCauseCode}` | `tool.${ToolTerminationCauseCode}` | `compaction.${CompactionTerminationCauseCode}` | `persistence.${PersistenceTerminationCauseCode}` | "process.signal" | "process.crash" | `transcript.${TranscriptTerminationCauseCode}` | "configuration.invalid" | "internal.unclassified" | `resource.${ResourceTerminationCauseCode}`;
|
|
20
22
|
export type SessionTerminationCause = {
|
|
21
23
|
readonly area: "completed";
|
|
22
24
|
} | {
|
|
@@ -50,6 +52,9 @@ export type SessionTerminationCause = {
|
|
|
50
52
|
} | {
|
|
51
53
|
readonly area: "internal";
|
|
52
54
|
readonly code: "unclassified";
|
|
55
|
+
} | {
|
|
56
|
+
readonly area: "resource";
|
|
57
|
+
readonly code: ResourceTerminationCauseCode;
|
|
53
58
|
};
|
|
54
59
|
export interface ClassifySessionTerminationInput {
|
|
55
60
|
readonly sessionId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-termination.d.ts","sourceRoot":"","sources":["../../src/core/session-termination.ts"],"names":[],"mappings":"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","sourcesContent":["export const SESSION_TERMINATION_SCHEMA_VERSION = 1 as const;\nexport const MAX_SESSION_TERMINATION_MESSAGE_LENGTH = 512;\n\n/**\n * Canonical list of termination kinds. The run-journal validator derives its\n * runtime bounds from this tuple so a newly added kind can never crash\n * journaling with \"termination kind is out of bounds\" again.\n */\nexport const SESSION_TERMINATION_KIND_VALUES = [\n\t\"completed\",\n\t\"user_abort\",\n\t\"provider_abort\",\n\t\"provider_auth\",\n\t\"provider_rate_limit\",\n\t\"provider_network\",\n\t\"provider_protocol\",\n\t\"provider_refusal\",\n\t\"context_overflow\",\n\t\"transcript_invalid\",\n\t\"tool_timeout\",\n\t\"tool_fatal\",\n\t\"compaction\",\n\t\"persistence\",\n\t\"process_signal\",\n\t\"process_crash\",\n\t\"configuration\",\n\t\"internal_error\",\n] as const;\n\nexport type SessionTerminationKind = (typeof SESSION_TERMINATION_KIND_VALUES)[number];\n\nexport type SessionTerminationPhase =\n\t| \"completed\"\n\t| \"control\"\n\t| \"preflight\"\n\t| \"provider\"\n\t| \"tool\"\n\t| \"compaction\"\n\t| \"persistence\"\n\t| \"process\"\n\t| \"resume\";\n\nexport type SessionTerminationSource = \"observed\" | \"inferred_on_resume\";\nexport type SessionSideEffects = \"none\" | \"possible\" | \"confirmed\";\nexport type SessionProcessSignal = \"SIGINT\" | \"SIGTERM\" | \"SIGHUP\" | \"SIGQUIT\";\n\nexport type ProviderTerminationCauseCode =\n\t| \"abort\"\n\t| \"auth\"\n\t| \"rate_limit\"\n\t| \"network\"\n\t| \"protocol\"\n\t| \"refusal\"\n\t| \"context_overflow\";\nexport type ToolTerminationCauseCode = \"timeout\" | \"fatal\";\nexport type CompactionTerminationCauseCode = \"aborted\" | \"failed\" | \"stale\";\nexport type PersistenceTerminationCauseCode =\n\t| \"read_failed\"\n\t| \"append_failed\"\n\t| \"replace_failed\"\n\t| \"fsync_failed\"\n\t| \"lock_failed\";\nexport type TranscriptTerminationCauseCode =\n\t| \"missing_result\"\n\t| \"duplicate_result\"\n\t| \"orphan_result\"\n\t| \"duplicate_call_id\"\n\t| \"interleaved_non_result\"\n\t| \"invalid_jsonl\"\n\t| \"invalid_tree\"\n\t| \"unsupported_version\"\n\t| \"trailing_fragment\";\nexport type SessionTerminationCauseCode =\n\t| \"session.completed\"\n\t| \"session.user_abort\"\n\t| `provider.${ProviderTerminationCauseCode}`\n\t| `tool.${ToolTerminationCauseCode}`\n\t| `compaction.${CompactionTerminationCauseCode}`\n\t| `persistence.${PersistenceTerminationCauseCode}`\n\t| \"process.signal\"\n\t| \"process.crash\"\n\t| `transcript.${TranscriptTerminationCauseCode}`\n\t| \"configuration.invalid\"\n\t| \"internal.unclassified\";\n\nexport type SessionTerminationCause =\n\t| { readonly area: \"completed\" }\n\t| { readonly area: \"user\"; readonly code: \"abort\" }\n\t| { readonly area: \"provider\"; readonly code: ProviderTerminationCauseCode }\n\t| { readonly area: \"tool\"; readonly code: ToolTerminationCauseCode }\n\t| { readonly area: \"compaction\"; readonly code: CompactionTerminationCauseCode }\n\t| { readonly area: \"persistence\"; readonly code: PersistenceTerminationCauseCode }\n\t| { readonly area: \"process\"; readonly code: \"signal\"; readonly signal: SessionProcessSignal }\n\t| { readonly area: \"process\"; readonly code: \"crash\" }\n\t| { readonly area: \"transcript\"; readonly code: TranscriptTerminationCauseCode }\n\t| { readonly area: \"configuration\"; readonly code: \"invalid\" }\n\t| { readonly area: \"internal\"; readonly code: \"unclassified\" };\n\nexport interface ClassifySessionTerminationInput {\n\treadonly sessionId: string;\n\treadonly runId: string;\n\t/** Deterministic caller-provided ISO-8601 timestamp. */\n\treadonly timestamp: string;\n\treadonly source: SessionTerminationSource;\n\t/** Caller-supplied, pre-redacted diagnostic text. */\n\treadonly message: string;\n\treadonly cause: SessionTerminationCause;\n\treadonly sideEffects: SessionSideEffects;\n\treadonly retryAfterMs?: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly toolCallId?: string;\n\treadonly toolName?: string;\n}\n\nexport interface SessionTermination {\n\treadonly schemaVersion: typeof SESSION_TERMINATION_SCHEMA_VERSION;\n\treadonly sessionId: string;\n\treadonly runId: string;\n\treadonly kind: SessionTerminationKind;\n\treadonly phase: SessionTerminationPhase;\n\treadonly source: SessionTerminationSource;\n\treadonly message: string;\n\treadonly causeCode: SessionTerminationCauseCode;\n\t/** Stable operator guidance suitable for print, JSON, RPC, and TUI surfaces. */\n\treadonly nextAction: string;\n\treadonly retryable: boolean;\n\treadonly safeToAutoRetry: boolean;\n\treadonly sideEffects: SessionSideEffects;\n\treadonly timestamp: string;\n\treadonly retryAfterMs?: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly toolCallId?: string;\n\treadonly toolName?: string;\n\treadonly processSignal?: SessionProcessSignal;\n\treadonly transcriptIssue?: TranscriptTerminationCauseCode;\n}\n\nexport class SessionTerminationError extends Error {\n\treadonly termination: SessionTermination;\n\n\tconstructor(message: string, termination: SessionTermination) {\n\t\tsuper(message);\n\t\tthis.name = \"SessionTerminationError\";\n\t\tthis.termination = termination;\n\t}\n}\n\ninterface Classification {\n\treadonly kind: SessionTerminationKind;\n\treadonly phase: SessionTerminationPhase;\n\treadonly causeCode: SessionTerminationCauseCode;\n\treadonly retryable: boolean;\n\treadonly processSignal?: SessionProcessSignal;\n\treadonly transcriptIssue?: TranscriptTerminationCauseCode;\n}\n\nconst CREDENTIAL_SHAPES = [\n\t/-----BEGIN [A-Z ]*PRIVATE KEY-----/i,\n\t/\\b(?:sk-[A-Za-z0-9_-]{16,}|github_pat_[A-Za-z0-9_]{16,}|gh[pousr]_[A-Za-z0-9]{16,}|xox[baprs]-[A-Za-z0-9-]{16,}|AKIA[A-Z0-9]{16})\\b/,\n\t/\\bBearer\\s+[A-Za-z0-9._~+/-]{8,}={0,2}\\b/i,\n\t/\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b/,\n\t/(?:^|[^A-Za-z0-9])(?:[A-Za-z0-9]+[_-])*(?:authorization|api[-_ ]?key|access[-_ ]?token|token|password|secret(?:[-_ ]?key)?|private[-_ ]?key|cookie)[\"']?\\s*[:=]/i,\n] as const;\n\nconst TOP_LEVEL_KEYS = new Set([\n\t\"sessionId\",\n\t\"runId\",\n\t\"timestamp\",\n\t\"source\",\n\t\"message\",\n\t\"cause\",\n\t\"sideEffects\",\n\t\"retryAfterMs\",\n\t\"provider\",\n\t\"model\",\n\t\"toolCallId\",\n\t\"toolName\",\n]);\nconst PROVIDER_CAUSE_CODES = new Set<ProviderTerminationCauseCode>([\n\t\"abort\",\n\t\"auth\",\n\t\"rate_limit\",\n\t\"network\",\n\t\"protocol\",\n\t\"refusal\",\n\t\"context_overflow\",\n]);\nconst TOOL_CAUSE_CODES = new Set<ToolTerminationCauseCode>([\"timeout\", \"fatal\"]);\nconst COMPACTION_CAUSE_CODES = new Set<CompactionTerminationCauseCode>([\"aborted\", \"failed\", \"stale\"]);\nconst PERSISTENCE_CAUSE_CODES = new Set<PersistenceTerminationCauseCode>([\n\t\"read_failed\",\n\t\"append_failed\",\n\t\"replace_failed\",\n\t\"fsync_failed\",\n\t\"lock_failed\",\n]);\nconst TRANSCRIPT_CAUSE_CODES = new Set<TranscriptTerminationCauseCode>([\n\t\"missing_result\",\n\t\"duplicate_result\",\n\t\"orphan_result\",\n\t\"duplicate_call_id\",\n\t\"interleaved_non_result\",\n\t\"invalid_jsonl\",\n\t\"invalid_tree\",\n\t\"unsupported_version\",\n\t\"trailing_fragment\",\n]);\nconst PROCESS_SIGNALS = new Set<SessionProcessSignal>([\"SIGINT\", \"SIGTERM\", \"SIGHUP\", \"SIGQUIT\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst allowed = new Set(keys);\n\treturn Object.keys(value).every((key) => allowed.has(key));\n}\n\nfunction assertCause(cause: unknown): asserts cause is SessionTerminationCause {\n\tif (!isRecord(cause) || typeof cause.area !== \"string\") {\n\t\tthrow new TypeError(\"cause must be a bounded structured termination cause\");\n\t}\n\tconst code = cause.code;\n\tlet valid = false;\n\tswitch (cause.area) {\n\t\tcase \"completed\":\n\t\t\tvalid = hasOnlyKeys(cause, [\"area\"]);\n\t\t\tbreak;\n\t\tcase \"user\":\n\t\t\tvalid = code === \"abort\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"provider\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tPROVIDER_CAUSE_CODES.has(code as ProviderTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"tool\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tTOOL_CAUSE_CODES.has(code as ToolTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"compaction\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tCOMPACTION_CAUSE_CODES.has(code as CompactionTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"persistence\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tPERSISTENCE_CAUSE_CODES.has(code as PersistenceTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"process\":\n\t\t\tvalid =\n\t\t\t\t(code === \"crash\" && hasOnlyKeys(cause, [\"area\", \"code\"])) ||\n\t\t\t\t(code === \"signal\" &&\n\t\t\t\t\ttypeof cause.signal === \"string\" &&\n\t\t\t\t\tPROCESS_SIGNALS.has(cause.signal as SessionProcessSignal) &&\n\t\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\", \"signal\"]));\n\t\t\tbreak;\n\t\tcase \"transcript\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tTRANSCRIPT_CAUSE_CODES.has(code as TranscriptTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"configuration\":\n\t\t\tvalid = code === \"invalid\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"internal\":\n\t\t\tvalid = code === \"unclassified\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t}\n\tif (!valid) throw new TypeError(\"cause must be a bounded structured termination cause\");\n}\n\nfunction assertClassifierInput(input: unknown): asserts input is ClassifySessionTerminationInput {\n\tif (!isRecord(input) || Object.keys(input).some((key) => !TOP_LEVEL_KEYS.has(key))) {\n\t\tthrow new TypeError(\"input must contain only bounded structured termination fields\");\n\t}\n\tif (\n\t\ttypeof input.sessionId !== \"string\" ||\n\t\ttypeof input.runId !== \"string\" ||\n\t\ttypeof input.timestamp !== \"string\" ||\n\t\ttypeof input.message !== \"string\" ||\n\t\t(input.source !== \"observed\" && input.source !== \"inferred_on_resume\") ||\n\t\t(input.sideEffects !== \"none\" && input.sideEffects !== \"possible\" && input.sideEffects !== \"confirmed\") ||\n\t\t(input.retryAfterMs !== undefined && typeof input.retryAfterMs !== \"number\") ||\n\t\t(input.provider !== undefined && typeof input.provider !== \"string\") ||\n\t\t(input.model !== undefined && typeof input.model !== \"string\") ||\n\t\t(input.toolCallId !== undefined && typeof input.toolCallId !== \"string\") ||\n\t\t(input.toolName !== undefined && typeof input.toolName !== \"string\")\n\t) {\n\t\tthrow new TypeError(\"input must contain only bounded structured termination fields\");\n\t}\n\tassertCause(input.cause);\n}\n\nfunction assertIdentifier(value: string, name: string, maxLength: number): void {\n\tif (value.length === 0 || value.length > maxLength || /[\\u0000-\\u001f\\u007f]/.test(value)) {\n\t\tthrow new TypeError(`${name} must be non-empty bounded text without C0 or DEL control characters`);\n\t}\n}\n\n/** Validate text at the termination trust boundary without attempting redaction. */\nexport function assertPreRedactedTerminationMessage(message: string): void {\n\tif (message.length === 0 || message.length > MAX_SESSION_TERMINATION_MESSAGE_LENGTH) {\n\t\tthrow new TypeError(\n\t\t\t`message must contain 1-${MAX_SESSION_TERMINATION_MESSAGE_LENGTH} characters of pre-redacted text`,\n\t\t);\n\t}\n\tif (message.includes(\"\\0\")) {\n\t\tthrow new TypeError(\"message must not contain NUL\");\n\t}\n\tif (CREDENTIAL_SHAPES.some((pattern) => pattern.test(message))) {\n\t\tthrow new TypeError(\"message contains a credential-shaped literal; redact it before classification\");\n\t}\n}\n\nfunction assertTimestamp(timestamp: string): void {\n\tconst parsed = new Date(timestamp);\n\tif (!Number.isFinite(parsed.getTime()) || parsed.toISOString() !== timestamp) {\n\t\tthrow new TypeError(\"timestamp must be a canonical ISO-8601 UTC instant\");\n\t}\n}\n\nfunction classifyProvider(code: ProviderTerminationCauseCode): Classification {\n\tswitch (code) {\n\t\tcase \"abort\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_abort\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.abort\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"auth\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_auth\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.auth\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"rate_limit\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_rate_limit\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.rate_limit\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"network\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_network\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.network\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"protocol\":\n\t\t\t// Many \"protocol\" stops are sticky transcript shape bugs (orphan tool_call_id)\n\t\t\t// that succeed after transform-messages sanitizes and the turn is retried.\n\t\t\t// Mark retryable so auto-retry can heal; safeToAutoRetry stays false (needs sanitize path).\n\t\t\treturn {\n\t\t\t\tkind: \"provider_protocol\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.protocol\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"context_overflow\":\n\t\t\treturn {\n\t\t\t\tkind: \"context_overflow\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.context_overflow\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"refusal\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_refusal\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.refusal\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t}\n}\n\nfunction classifyCause(cause: SessionTerminationCause, source: SessionTerminationSource): Classification {\n\tswitch (cause.area) {\n\t\tcase \"completed\":\n\t\t\treturn {\n\t\t\t\tkind: \"completed\",\n\t\t\t\tphase: \"completed\",\n\t\t\t\tcauseCode: \"session.completed\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"user\":\n\t\t\treturn {\n\t\t\t\tkind: \"user_abort\",\n\t\t\t\tphase: \"control\",\n\t\t\t\tcauseCode: \"session.user_abort\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"provider\":\n\t\t\treturn classifyProvider(cause.code);\n\t\tcase \"tool\":\n\t\t\treturn cause.code === \"timeout\"\n\t\t\t\t? { kind: \"tool_timeout\", phase: \"tool\", causeCode: \"tool.timeout\", retryable: true }\n\t\t\t\t: { kind: \"tool_fatal\", phase: \"tool\", causeCode: \"tool.fatal\", retryable: false };\n\t\tcase \"compaction\":\n\t\t\treturn {\n\t\t\t\tkind: \"compaction\",\n\t\t\t\tphase: \"compaction\",\n\t\t\t\tcauseCode: `compaction.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"persistence\":\n\t\t\treturn {\n\t\t\t\tkind: \"persistence\",\n\t\t\t\tphase: \"persistence\",\n\t\t\t\tcauseCode: `persistence.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"process\":\n\t\t\tif (cause.code === \"signal\") {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"process_signal\",\n\t\t\t\t\tphase: \"process\",\n\t\t\t\t\tcauseCode: \"process.signal\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tprocessSignal: cause.signal,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tkind: \"process_crash\",\n\t\t\t\tphase: \"resume\",\n\t\t\t\tcauseCode: \"process.crash\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"transcript\":\n\t\t\treturn {\n\t\t\t\tkind: \"transcript_invalid\",\n\t\t\t\tphase: source === \"inferred_on_resume\" ? \"resume\" : \"preflight\",\n\t\t\t\tcauseCode: `transcript.${cause.code}`,\n\t\t\t\tretryable: false,\n\t\t\t\ttranscriptIssue: cause.code,\n\t\t\t};\n\t\tcase \"configuration\":\n\t\t\treturn {\n\t\t\t\tkind: \"configuration\",\n\t\t\t\tphase: \"preflight\",\n\t\t\t\tcauseCode: \"configuration.invalid\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"internal\":\n\t\t\treturn {\n\t\t\t\tkind: \"internal_error\",\n\t\t\t\tphase: \"preflight\",\n\t\t\t\tcauseCode: \"internal.unclassified\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t}\n}\n\nfunction isSafeToAutoRetry(classification: Classification, input: ClassifySessionTerminationInput): boolean {\n\t// provider_refusal: Fable/Claude often false-positive on benign turns. Safe to auto-retry once\n\t// when no tool side effects occurred (same class of recovery as rate_limit/network).\n\treturn (\n\t\tclassification.retryable &&\n\t\tinput.source === \"observed\" &&\n\t\tinput.sideEffects === \"none\" &&\n\t\t(classification.kind === \"provider_rate_limit\" ||\n\t\t\tclassification.kind === \"provider_network\" ||\n\t\t\tclassification.kind === \"provider_refusal\")\n\t);\n}\n\nfunction nextActionFor(classification: Classification, input: ClassifySessionTerminationInput): string {\n\tswitch (classification.kind) {\n\t\tcase \"completed\":\n\t\t\treturn \"No recovery action is required; continue with the next prompt.\";\n\t\tcase \"user_abort\":\n\t\t\treturn \"Review possible partial side effects, then retry only if intended.\";\n\t\tcase \"provider_abort\":\n\t\t\treturn \"Confirm provider availability, then retry the request.\";\n\t\tcase \"provider_auth\":\n\t\t\treturn `Run /login${input.provider ? ` ${input.provider}` : \"\"} or configure valid credentials, then retry.`;\n\t\tcase \"provider_rate_limit\":\n\t\t\treturn \"Wait for the provider retry window or choose another model, then retry.\";\n\t\tcase \"provider_network\":\n\t\t\treturn \"Check network and provider connectivity, then retry.\";\n\t\tcase \"provider_protocol\":\n\t\t\treturn \"Often an orphan tool_call_id / sticky transcript after a dropped error turn — auto-retry after sanitize, or /new session if it persists.\";\n\t\tcase \"provider_refusal\":\n\t\t\treturn \"Model declined this turn (content/safety stop). Usually a false positive on Fable/Claude — auto-retry once, or switch model (k3/qwen3.8-max/grok-4.5/deepseek) / rephrase as a pure coding task.\";\n\t\tcase \"context_overflow\":\n\t\t\treturn \"Compact or reduce context, or switch to a larger-context model.\";\n\t\tcase \"tool_timeout\":\n\t\t\treturn \"Inspect possible tool side effects and increase the tool timeout only if safe.\";\n\t\tcase \"tool_fatal\":\n\t\t\treturn \"Inspect the failed tool result and repair its configuration before retrying.\";\n\t\tcase \"compaction\":\n\t\t\tswitch (classification.causeCode) {\n\t\t\t\tcase \"compaction.aborted\":\n\t\t\t\t\treturn \"Retry /compact if cancellation was unintended; avoid Escape while compaction is running.\";\n\t\t\t\tcase \"compaction.stale\":\n\t\t\t\t\treturn \"Retry /compact after pending session changes settle.\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Resolve the reported compaction error, then retry /compact.\";\n\t\t\t}\n\t\tcase \"persistence\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId} before resuming.`;\n\t\tcase \"process_signal\":\n\t\t\treturn \"Review possible partial side effects before resuming the session.\";\n\t\tcase \"process_crash\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId} and review partial side effects.`;\n\t\tcase \"transcript_invalid\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId}; do not resume until integrity passes.`;\n\t\tcase \"configuration\":\n\t\t\treturn \"Correct the provider, model, tool, or session configuration and retry.\";\n\t\tcase \"internal_error\":\n\t\t\treturn `Inspect run ${input.runId} diagnostics and the run journal before retrying.`;\n\t}\n}\n\n/** Concise actionable rendering shared by non-JSON and TUI surfaces. */\nexport function formatSessionTermination(termination: SessionTermination): string {\n\tconst route =\n\t\ttermination.provider || termination.model\n\t\t\t? `${termination.provider ?? \"unknown\"}/${termination.model ?? \"unknown\"}`\n\t\t\t: \"n/a\";\n\treturn [\n\t\t`kind=${termination.kind}`,\n\t\t`provider/model=${route}`,\n\t\t`retryable=${termination.retryable}`,\n\t\t`cause=${termination.causeCode}`,\n\t\t`message=${termination.message}`,\n\t\t`run=${termination.runId}`,\n\t\t`next=${termination.nextAction}`,\n\t].join(\" \");\n}\n\n/**\n * Classify a bounded, structured termination cause. This intentionally accepts\n * no raw Error value, stack, provider body, or arbitrary cause code.\n */\nexport function classifySessionTermination(input: ClassifySessionTerminationInput): SessionTermination {\n\tassertClassifierInput(input);\n\tassertIdentifier(input.sessionId, \"sessionId\", 128);\n\tassertIdentifier(input.runId, \"runId\", 128);\n\tassertTimestamp(input.timestamp);\n\tassertPreRedactedTerminationMessage(input.message);\n\tif (input.provider !== undefined) assertIdentifier(input.provider, \"provider\", 128);\n\tif (input.model !== undefined) assertIdentifier(input.model, \"model\", 256);\n\tif (input.toolCallId !== undefined) assertIdentifier(input.toolCallId, \"toolCallId\", 512);\n\tif (input.toolName !== undefined) assertIdentifier(input.toolName, \"toolName\", 128);\n\tif (input.retryAfterMs !== undefined && (!Number.isSafeInteger(input.retryAfterMs) || input.retryAfterMs < 0)) {\n\t\tthrow new TypeError(\"retryAfterMs must be a non-negative safe integer\");\n\t}\n\tif (input.cause.area === \"process\" && input.cause.code === \"crash\" && input.source !== \"inferred_on_resume\") {\n\t\tthrow new TypeError(\"process crashes may only be classified as inferred_on_resume\");\n\t}\n\tif (input.cause.area === \"process\" && input.cause.code === \"signal\" && input.source !== \"observed\") {\n\t\tthrow new TypeError(\"process signals must be observed\");\n\t}\n\n\tconst classification = classifyCause(input.cause, input.source);\n\treturn Object.freeze({\n\t\tschemaVersion: SESSION_TERMINATION_SCHEMA_VERSION,\n\t\tsessionId: input.sessionId,\n\t\trunId: input.runId,\n\t\tkind: classification.kind,\n\t\tphase: classification.phase,\n\t\tsource: input.source,\n\t\tmessage: input.message,\n\t\tcauseCode: classification.causeCode,\n\t\tnextAction: nextActionFor(classification, input),\n\t\tretryable: classification.retryable,\n\t\tsafeToAutoRetry: isSafeToAutoRetry(classification, input),\n\t\tsideEffects: input.sideEffects,\n\t\ttimestamp: input.timestamp,\n\t\t...(input.retryAfterMs === undefined ? {} : { retryAfterMs: input.retryAfterMs }),\n\t\t...(input.provider === undefined ? {} : { provider: input.provider }),\n\t\t...(input.model === undefined ? {} : { model: input.model }),\n\t\t...(input.toolCallId === undefined ? {} : { toolCallId: input.toolCallId }),\n\t\t...(input.toolName === undefined ? {} : { toolName: input.toolName }),\n\t\t...(classification.processSignal === undefined ? {} : { processSignal: classification.processSignal }),\n\t\t...(classification.transcriptIssue === undefined ? {} : { transcriptIssue: classification.transcriptIssue }),\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-termination.d.ts","sourceRoot":"","sources":["../../src/core/session-termination.ts"],"names":[],"mappings":"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","sourcesContent":["export const SESSION_TERMINATION_SCHEMA_VERSION = 1 as const;\nexport const MAX_SESSION_TERMINATION_MESSAGE_LENGTH = 512;\n\n/**\n * Canonical list of termination kinds. The run-journal validator derives its\n * runtime bounds from this tuple so a newly added kind can never crash\n * journaling with \"termination kind is out of bounds\" again.\n */\nexport const SESSION_TERMINATION_KIND_VALUES = [\n\t\"completed\",\n\t\"user_abort\",\n\t\"provider_abort\",\n\t\"provider_auth\",\n\t\"provider_rate_limit\",\n\t\"provider_network\",\n\t\"provider_protocol\",\n\t\"provider_refusal\",\n\t\"context_overflow\",\n\t\"transcript_invalid\",\n\t\"tool_timeout\",\n\t\"tool_fatal\",\n\t\"compaction\",\n\t\"persistence\",\n\t\"process_signal\",\n\t\"process_crash\",\n\t\"configuration\",\n\t\"internal_error\",\n\t\"resource_pressure\",\n] as const;\n\nexport type SessionTerminationKind = (typeof SESSION_TERMINATION_KIND_VALUES)[number];\n\nexport type SessionTerminationPhase =\n\t| \"completed\"\n\t| \"control\"\n\t| \"preflight\"\n\t| \"provider\"\n\t| \"tool\"\n\t| \"compaction\"\n\t| \"persistence\"\n\t| \"process\"\n\t| \"resume\";\n\nexport type SessionTerminationSource = \"observed\" | \"inferred_on_resume\";\nexport type SessionSideEffects = \"none\" | \"possible\" | \"confirmed\";\nexport type SessionProcessSignal = \"SIGINT\" | \"SIGTERM\" | \"SIGHUP\" | \"SIGQUIT\";\n\nexport type ProviderTerminationCauseCode =\n\t| \"abort\"\n\t| \"auth\"\n\t| \"rate_limit\"\n\t| \"network\"\n\t| \"protocol\"\n\t| \"refusal\"\n\t| \"context_overflow\";\nexport type ToolTerminationCauseCode = \"timeout\" | \"fatal\";\n/** §15.4 resource-aware runtime roadmap: host-pressure termination causes. */\nexport type ResourceTerminationCauseCode = \"memory\" | \"disk\" | \"cpu\" | \"heap\" | \"probe_unavailable\" | \"queue_overflow\";\nexport type CompactionTerminationCauseCode = \"aborted\" | \"failed\" | \"stale\";\nexport type PersistenceTerminationCauseCode =\n\t| \"read_failed\"\n\t| \"append_failed\"\n\t| \"replace_failed\"\n\t| \"fsync_failed\"\n\t| \"lock_failed\";\nexport type TranscriptTerminationCauseCode =\n\t| \"missing_result\"\n\t| \"duplicate_result\"\n\t| \"orphan_result\"\n\t| \"duplicate_call_id\"\n\t| \"interleaved_non_result\"\n\t| \"invalid_jsonl\"\n\t| \"invalid_tree\"\n\t| \"unsupported_version\"\n\t| \"trailing_fragment\";\nexport type SessionTerminationCauseCode =\n\t| \"session.completed\"\n\t| \"session.user_abort\"\n\t| `provider.${ProviderTerminationCauseCode}`\n\t| `tool.${ToolTerminationCauseCode}`\n\t| `compaction.${CompactionTerminationCauseCode}`\n\t| `persistence.${PersistenceTerminationCauseCode}`\n\t| \"process.signal\"\n\t| \"process.crash\"\n\t| `transcript.${TranscriptTerminationCauseCode}`\n\t| \"configuration.invalid\"\n\t| \"internal.unclassified\"\n\t| `resource.${ResourceTerminationCauseCode}`;\n\nexport type SessionTerminationCause =\n\t| { readonly area: \"completed\" }\n\t| { readonly area: \"user\"; readonly code: \"abort\" }\n\t| { readonly area: \"provider\"; readonly code: ProviderTerminationCauseCode }\n\t| { readonly area: \"tool\"; readonly code: ToolTerminationCauseCode }\n\t| { readonly area: \"compaction\"; readonly code: CompactionTerminationCauseCode }\n\t| { readonly area: \"persistence\"; readonly code: PersistenceTerminationCauseCode }\n\t| { readonly area: \"process\"; readonly code: \"signal\"; readonly signal: SessionProcessSignal }\n\t| { readonly area: \"process\"; readonly code: \"crash\" }\n\t| { readonly area: \"transcript\"; readonly code: TranscriptTerminationCauseCode }\n\t| { readonly area: \"configuration\"; readonly code: \"invalid\" }\n\t| { readonly area: \"internal\"; readonly code: \"unclassified\" }\n\t| { readonly area: \"resource\"; readonly code: ResourceTerminationCauseCode };\n\nexport interface ClassifySessionTerminationInput {\n\treadonly sessionId: string;\n\treadonly runId: string;\n\t/** Deterministic caller-provided ISO-8601 timestamp. */\n\treadonly timestamp: string;\n\treadonly source: SessionTerminationSource;\n\t/** Caller-supplied, pre-redacted diagnostic text. */\n\treadonly message: string;\n\treadonly cause: SessionTerminationCause;\n\treadonly sideEffects: SessionSideEffects;\n\treadonly retryAfterMs?: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly toolCallId?: string;\n\treadonly toolName?: string;\n}\n\nexport interface SessionTermination {\n\treadonly schemaVersion: typeof SESSION_TERMINATION_SCHEMA_VERSION;\n\treadonly sessionId: string;\n\treadonly runId: string;\n\treadonly kind: SessionTerminationKind;\n\treadonly phase: SessionTerminationPhase;\n\treadonly source: SessionTerminationSource;\n\treadonly message: string;\n\treadonly causeCode: SessionTerminationCauseCode;\n\t/** Stable operator guidance suitable for print, JSON, RPC, and TUI surfaces. */\n\treadonly nextAction: string;\n\treadonly retryable: boolean;\n\treadonly safeToAutoRetry: boolean;\n\treadonly sideEffects: SessionSideEffects;\n\treadonly timestamp: string;\n\treadonly retryAfterMs?: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly toolCallId?: string;\n\treadonly toolName?: string;\n\treadonly processSignal?: SessionProcessSignal;\n\treadonly transcriptIssue?: TranscriptTerminationCauseCode;\n}\n\nexport class SessionTerminationError extends Error {\n\treadonly termination: SessionTermination;\n\n\tconstructor(message: string, termination: SessionTermination) {\n\t\tsuper(message);\n\t\tthis.name = \"SessionTerminationError\";\n\t\tthis.termination = termination;\n\t}\n}\n\ninterface Classification {\n\treadonly kind: SessionTerminationKind;\n\treadonly phase: SessionTerminationPhase;\n\treadonly causeCode: SessionTerminationCauseCode;\n\treadonly retryable: boolean;\n\treadonly processSignal?: SessionProcessSignal;\n\treadonly transcriptIssue?: TranscriptTerminationCauseCode;\n}\n\nconst CREDENTIAL_SHAPES = [\n\t/-----BEGIN [A-Z ]*PRIVATE KEY-----/i,\n\t/\\b(?:sk-[A-Za-z0-9_-]{16,}|github_pat_[A-Za-z0-9_]{16,}|gh[pousr]_[A-Za-z0-9]{16,}|xox[baprs]-[A-Za-z0-9-]{16,}|AKIA[A-Z0-9]{16})\\b/,\n\t/\\bBearer\\s+[A-Za-z0-9._~+/-]{8,}={0,2}\\b/i,\n\t/\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b/,\n\t/(?:^|[^A-Za-z0-9])(?:[A-Za-z0-9]+[_-])*(?:authorization|api[-_ ]?key|access[-_ ]?token|token|password|secret(?:[-_ ]?key)?|private[-_ ]?key|cookie)[\"']?\\s*[:=]/i,\n] as const;\n\nconst TOP_LEVEL_KEYS = new Set([\n\t\"sessionId\",\n\t\"runId\",\n\t\"timestamp\",\n\t\"source\",\n\t\"message\",\n\t\"cause\",\n\t\"sideEffects\",\n\t\"retryAfterMs\",\n\t\"provider\",\n\t\"model\",\n\t\"toolCallId\",\n\t\"toolName\",\n]);\nconst PROVIDER_CAUSE_CODES = new Set<ProviderTerminationCauseCode>([\n\t\"abort\",\n\t\"auth\",\n\t\"rate_limit\",\n\t\"network\",\n\t\"protocol\",\n\t\"refusal\",\n\t\"context_overflow\",\n]);\nconst TOOL_CAUSE_CODES = new Set<ToolTerminationCauseCode>([\"timeout\", \"fatal\"]);\nconst RESOURCE_CAUSE_CODES = new Set<ResourceTerminationCauseCode>([\n\t\"memory\",\n\t\"disk\",\n\t\"cpu\",\n\t\"heap\",\n\t\"probe_unavailable\",\n\t\"queue_overflow\",\n]);\nconst COMPACTION_CAUSE_CODES = new Set<CompactionTerminationCauseCode>([\"aborted\", \"failed\", \"stale\"]);\nconst PERSISTENCE_CAUSE_CODES = new Set<PersistenceTerminationCauseCode>([\n\t\"read_failed\",\n\t\"append_failed\",\n\t\"replace_failed\",\n\t\"fsync_failed\",\n\t\"lock_failed\",\n]);\nconst TRANSCRIPT_CAUSE_CODES = new Set<TranscriptTerminationCauseCode>([\n\t\"missing_result\",\n\t\"duplicate_result\",\n\t\"orphan_result\",\n\t\"duplicate_call_id\",\n\t\"interleaved_non_result\",\n\t\"invalid_jsonl\",\n\t\"invalid_tree\",\n\t\"unsupported_version\",\n\t\"trailing_fragment\",\n]);\nconst PROCESS_SIGNALS = new Set<SessionProcessSignal>([\"SIGINT\", \"SIGTERM\", \"SIGHUP\", \"SIGQUIT\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst allowed = new Set(keys);\n\treturn Object.keys(value).every((key) => allowed.has(key));\n}\n\nfunction assertCause(cause: unknown): asserts cause is SessionTerminationCause {\n\tif (!isRecord(cause) || typeof cause.area !== \"string\") {\n\t\tthrow new TypeError(\"cause must be a bounded structured termination cause\");\n\t}\n\tconst code = cause.code;\n\tlet valid = false;\n\tswitch (cause.area) {\n\t\tcase \"completed\":\n\t\t\tvalid = hasOnlyKeys(cause, [\"area\"]);\n\t\t\tbreak;\n\t\tcase \"user\":\n\t\t\tvalid = code === \"abort\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"provider\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tPROVIDER_CAUSE_CODES.has(code as ProviderTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"tool\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tTOOL_CAUSE_CODES.has(code as ToolTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"compaction\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tCOMPACTION_CAUSE_CODES.has(code as CompactionTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"persistence\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tPERSISTENCE_CAUSE_CODES.has(code as PersistenceTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"process\":\n\t\t\tvalid =\n\t\t\t\t(code === \"crash\" && hasOnlyKeys(cause, [\"area\", \"code\"])) ||\n\t\t\t\t(code === \"signal\" &&\n\t\t\t\t\ttypeof cause.signal === \"string\" &&\n\t\t\t\t\tPROCESS_SIGNALS.has(cause.signal as SessionProcessSignal) &&\n\t\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\", \"signal\"]));\n\t\t\tbreak;\n\t\tcase \"transcript\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tTRANSCRIPT_CAUSE_CODES.has(code as TranscriptTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"configuration\":\n\t\t\tvalid = code === \"invalid\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"internal\":\n\t\t\tvalid = code === \"unclassified\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"resource\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tRESOURCE_CAUSE_CODES.has(code as ResourceTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t}\n\tif (!valid) throw new TypeError(\"cause must be a bounded structured termination cause\");\n}\n\nfunction assertClassifierInput(input: unknown): asserts input is ClassifySessionTerminationInput {\n\tif (!isRecord(input) || Object.keys(input).some((key) => !TOP_LEVEL_KEYS.has(key))) {\n\t\tthrow new TypeError(\"input must contain only bounded structured termination fields\");\n\t}\n\tif (\n\t\ttypeof input.sessionId !== \"string\" ||\n\t\ttypeof input.runId !== \"string\" ||\n\t\ttypeof input.timestamp !== \"string\" ||\n\t\ttypeof input.message !== \"string\" ||\n\t\t(input.source !== \"observed\" && input.source !== \"inferred_on_resume\") ||\n\t\t(input.sideEffects !== \"none\" && input.sideEffects !== \"possible\" && input.sideEffects !== \"confirmed\") ||\n\t\t(input.retryAfterMs !== undefined && typeof input.retryAfterMs !== \"number\") ||\n\t\t(input.provider !== undefined && typeof input.provider !== \"string\") ||\n\t\t(input.model !== undefined && typeof input.model !== \"string\") ||\n\t\t(input.toolCallId !== undefined && typeof input.toolCallId !== \"string\") ||\n\t\t(input.toolName !== undefined && typeof input.toolName !== \"string\")\n\t) {\n\t\tthrow new TypeError(\"input must contain only bounded structured termination fields\");\n\t}\n\tassertCause(input.cause);\n}\n\nfunction assertIdentifier(value: string, name: string, maxLength: number): void {\n\tif (value.length === 0 || value.length > maxLength || /[\\u0000-\\u001f\\u007f]/.test(value)) {\n\t\tthrow new TypeError(`${name} must be non-empty bounded text without C0 or DEL control characters`);\n\t}\n}\n\n/** Validate text at the termination trust boundary without attempting redaction. */\nexport function assertPreRedactedTerminationMessage(message: string): void {\n\tif (message.length === 0 || message.length > MAX_SESSION_TERMINATION_MESSAGE_LENGTH) {\n\t\tthrow new TypeError(\n\t\t\t`message must contain 1-${MAX_SESSION_TERMINATION_MESSAGE_LENGTH} characters of pre-redacted text`,\n\t\t);\n\t}\n\tif (message.includes(\"\\0\")) {\n\t\tthrow new TypeError(\"message must not contain NUL\");\n\t}\n\tif (CREDENTIAL_SHAPES.some((pattern) => pattern.test(message))) {\n\t\tthrow new TypeError(\"message contains a credential-shaped literal; redact it before classification\");\n\t}\n}\n\nfunction assertTimestamp(timestamp: string): void {\n\tconst parsed = new Date(timestamp);\n\tif (!Number.isFinite(parsed.getTime()) || parsed.toISOString() !== timestamp) {\n\t\tthrow new TypeError(\"timestamp must be a canonical ISO-8601 UTC instant\");\n\t}\n}\n\nfunction classifyProvider(code: ProviderTerminationCauseCode): Classification {\n\tswitch (code) {\n\t\tcase \"abort\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_abort\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.abort\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"auth\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_auth\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.auth\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"rate_limit\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_rate_limit\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.rate_limit\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"network\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_network\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.network\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"protocol\":\n\t\t\t// Many \"protocol\" stops are sticky transcript shape bugs (orphan tool_call_id)\n\t\t\t// that succeed after transform-messages sanitizes and the turn is retried.\n\t\t\t// Mark retryable so auto-retry can heal; safeToAutoRetry stays false (needs sanitize path).\n\t\t\treturn {\n\t\t\t\tkind: \"provider_protocol\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.protocol\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"context_overflow\":\n\t\t\treturn {\n\t\t\t\tkind: \"context_overflow\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.context_overflow\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"refusal\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_refusal\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.refusal\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t}\n}\n\nfunction classifyCause(cause: SessionTerminationCause, source: SessionTerminationSource): Classification {\n\tswitch (cause.area) {\n\t\tcase \"completed\":\n\t\t\treturn {\n\t\t\t\tkind: \"completed\",\n\t\t\t\tphase: \"completed\",\n\t\t\t\tcauseCode: \"session.completed\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"user\":\n\t\t\treturn {\n\t\t\t\tkind: \"user_abort\",\n\t\t\t\tphase: \"control\",\n\t\t\t\tcauseCode: \"session.user_abort\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"provider\":\n\t\t\treturn classifyProvider(cause.code);\n\t\tcase \"tool\":\n\t\t\treturn cause.code === \"timeout\"\n\t\t\t\t? { kind: \"tool_timeout\", phase: \"tool\", causeCode: \"tool.timeout\", retryable: true }\n\t\t\t\t: { kind: \"tool_fatal\", phase: \"tool\", causeCode: \"tool.fatal\", retryable: false };\n\t\tcase \"compaction\":\n\t\t\treturn {\n\t\t\t\tkind: \"compaction\",\n\t\t\t\tphase: \"compaction\",\n\t\t\t\tcauseCode: `compaction.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"persistence\":\n\t\t\treturn {\n\t\t\t\tkind: \"persistence\",\n\t\t\t\tphase: \"persistence\",\n\t\t\t\tcauseCode: `persistence.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"process\":\n\t\t\tif (cause.code === \"signal\") {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"process_signal\",\n\t\t\t\t\tphase: \"process\",\n\t\t\t\t\tcauseCode: \"process.signal\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tprocessSignal: cause.signal,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tkind: \"process_crash\",\n\t\t\t\tphase: \"resume\",\n\t\t\t\tcauseCode: \"process.crash\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"transcript\":\n\t\t\treturn {\n\t\t\t\tkind: \"transcript_invalid\",\n\t\t\t\tphase: source === \"inferred_on_resume\" ? \"resume\" : \"preflight\",\n\t\t\t\tcauseCode: `transcript.${cause.code}`,\n\t\t\t\tretryable: false,\n\t\t\t\ttranscriptIssue: cause.code,\n\t\t\t};\n\t\tcase \"configuration\":\n\t\t\treturn {\n\t\t\t\tkind: \"configuration\",\n\t\t\t\tphase: \"preflight\",\n\t\t\t\tcauseCode: \"configuration.invalid\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"internal\":\n\t\t\treturn {\n\t\t\t\tkind: \"internal_error\",\n\t\t\t\tphase: \"preflight\",\n\t\t\t\tcauseCode: \"internal.unclassified\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"resource\":\n\t\t\t// §15.4: every resource cause is retryable; queue overflow surfaces at\n\t\t\t// the tool boundary, everything else at preflight admission.\n\t\t\treturn {\n\t\t\t\tkind: \"resource_pressure\",\n\t\t\t\tphase: cause.code === \"queue_overflow\" ? \"tool\" : \"preflight\",\n\t\t\t\tcauseCode: `resource.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t}\n}\n\nfunction isSafeToAutoRetry(classification: Classification, input: ClassifySessionTerminationInput): boolean {\n\t// provider_refusal: Fable/Claude often false-positive on benign turns. Safe to auto-retry once\n\t// when no tool side effects occurred (same class of recovery as rate_limit/network).\n\treturn (\n\t\tclassification.retryable &&\n\t\tinput.source === \"observed\" &&\n\t\tinput.sideEffects === \"none\" &&\n\t\t(classification.kind === \"provider_rate_limit\" ||\n\t\t\tclassification.kind === \"provider_network\" ||\n\t\t\tclassification.kind === \"provider_refusal\" ||\n\t\t\t// §15.4 mapping: only cpu pressure is safe to auto-retry (with delay).\n\t\t\tclassification.causeCode === \"resource.cpu\")\n\t);\n}\n\nfunction nextActionFor(classification: Classification, input: ClassifySessionTerminationInput): string {\n\tswitch (classification.kind) {\n\t\tcase \"completed\":\n\t\t\treturn \"No recovery action is required; continue with the next prompt.\";\n\t\tcase \"user_abort\":\n\t\t\treturn \"Review possible partial side effects, then retry only if intended.\";\n\t\tcase \"resource_pressure\":\n\t\t\treturn \"Host resources are constrained; reduce load or wait for recovery, then retry.\";\n\t\tcase \"provider_abort\":\n\t\t\treturn \"Confirm provider availability, then retry the request.\";\n\t\tcase \"provider_auth\":\n\t\t\treturn `Run /login${input.provider ? ` ${input.provider}` : \"\"} or configure valid credentials, then retry.`;\n\t\tcase \"provider_rate_limit\":\n\t\t\treturn \"Wait for the provider retry window or choose another model, then retry.\";\n\t\tcase \"provider_network\":\n\t\t\treturn \"Check network and provider connectivity, then retry.\";\n\t\tcase \"provider_protocol\":\n\t\t\treturn \"Often an orphan tool_call_id / sticky transcript after a dropped error turn — auto-retry after sanitize, or /new session if it persists.\";\n\t\tcase \"provider_refusal\":\n\t\t\treturn \"Model declined this turn (content/safety stop). Usually a false positive on Fable/Claude — auto-retry once, or switch model (k3/qwen3.8-max/grok-4.5/deepseek) / rephrase as a pure coding task.\";\n\t\tcase \"context_overflow\":\n\t\t\treturn \"Compact or reduce context, or switch to a larger-context model.\";\n\t\tcase \"tool_timeout\":\n\t\t\treturn \"Inspect possible tool side effects and increase the tool timeout only if safe.\";\n\t\tcase \"tool_fatal\":\n\t\t\treturn \"Inspect the failed tool result and repair its configuration before retrying.\";\n\t\tcase \"compaction\":\n\t\t\tswitch (classification.causeCode) {\n\t\t\t\tcase \"compaction.aborted\":\n\t\t\t\t\treturn \"Retry /compact if cancellation was unintended; avoid Escape while compaction is running.\";\n\t\t\t\tcase \"compaction.stale\":\n\t\t\t\t\treturn \"Retry /compact after pending session changes settle.\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Resolve the reported compaction error, then retry /compact.\";\n\t\t\t}\n\t\tcase \"persistence\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId} before resuming.`;\n\t\tcase \"process_signal\":\n\t\t\treturn \"Review possible partial side effects before resuming the session.\";\n\t\tcase \"process_crash\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId} and review partial side effects.`;\n\t\tcase \"transcript_invalid\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId}; do not resume until integrity passes.`;\n\t\tcase \"configuration\":\n\t\t\treturn \"Correct the provider, model, tool, or session configuration and retry.\";\n\t\tcase \"internal_error\":\n\t\t\treturn `Inspect run ${input.runId} diagnostics and the run journal before retrying.`;\n\t}\n}\n\n/** Concise actionable rendering shared by non-JSON and TUI surfaces. */\nexport function formatSessionTermination(termination: SessionTermination): string {\n\tconst route =\n\t\ttermination.provider || termination.model\n\t\t\t? `${termination.provider ?? \"unknown\"}/${termination.model ?? \"unknown\"}`\n\t\t\t: \"n/a\";\n\treturn [\n\t\t`kind=${termination.kind}`,\n\t\t`provider/model=${route}`,\n\t\t`retryable=${termination.retryable}`,\n\t\t`cause=${termination.causeCode}`,\n\t\t`message=${termination.message}`,\n\t\t`run=${termination.runId}`,\n\t\t`next=${termination.nextAction}`,\n\t].join(\" \");\n}\n\n/**\n * Classify a bounded, structured termination cause. This intentionally accepts\n * no raw Error value, stack, provider body, or arbitrary cause code.\n */\nexport function classifySessionTermination(input: ClassifySessionTerminationInput): SessionTermination {\n\tassertClassifierInput(input);\n\tassertIdentifier(input.sessionId, \"sessionId\", 128);\n\tassertIdentifier(input.runId, \"runId\", 128);\n\tassertTimestamp(input.timestamp);\n\tassertPreRedactedTerminationMessage(input.message);\n\tif (input.provider !== undefined) assertIdentifier(input.provider, \"provider\", 128);\n\tif (input.model !== undefined) assertIdentifier(input.model, \"model\", 256);\n\tif (input.toolCallId !== undefined) assertIdentifier(input.toolCallId, \"toolCallId\", 512);\n\tif (input.toolName !== undefined) assertIdentifier(input.toolName, \"toolName\", 128);\n\tif (input.retryAfterMs !== undefined && (!Number.isSafeInteger(input.retryAfterMs) || input.retryAfterMs < 0)) {\n\t\tthrow new TypeError(\"retryAfterMs must be a non-negative safe integer\");\n\t}\n\tif (input.cause.area === \"process\" && input.cause.code === \"crash\" && input.source !== \"inferred_on_resume\") {\n\t\tthrow new TypeError(\"process crashes may only be classified as inferred_on_resume\");\n\t}\n\tif (input.cause.area === \"process\" && input.cause.code === \"signal\" && input.source !== \"observed\") {\n\t\tthrow new TypeError(\"process signals must be observed\");\n\t}\n\n\tconst classification = classifyCause(input.cause, input.source);\n\treturn Object.freeze({\n\t\tschemaVersion: SESSION_TERMINATION_SCHEMA_VERSION,\n\t\tsessionId: input.sessionId,\n\t\trunId: input.runId,\n\t\tkind: classification.kind,\n\t\tphase: classification.phase,\n\t\tsource: input.source,\n\t\tmessage: input.message,\n\t\tcauseCode: classification.causeCode,\n\t\tnextAction: nextActionFor(classification, input),\n\t\tretryable: classification.retryable,\n\t\tsafeToAutoRetry: isSafeToAutoRetry(classification, input),\n\t\tsideEffects: input.sideEffects,\n\t\ttimestamp: input.timestamp,\n\t\t...(input.retryAfterMs === undefined ? {} : { retryAfterMs: input.retryAfterMs }),\n\t\t...(input.provider === undefined ? {} : { provider: input.provider }),\n\t\t...(input.model === undefined ? {} : { model: input.model }),\n\t\t...(input.toolCallId === undefined ? {} : { toolCallId: input.toolCallId }),\n\t\t...(input.toolName === undefined ? {} : { toolName: input.toolName }),\n\t\t...(classification.processSignal === undefined ? {} : { processSignal: classification.processSignal }),\n\t\t...(classification.transcriptIssue === undefined ? {} : { transcriptIssue: classification.transcriptIssue }),\n\t});\n}\n"]}
|
|
@@ -24,6 +24,7 @@ export const SESSION_TERMINATION_KIND_VALUES = [
|
|
|
24
24
|
"process_crash",
|
|
25
25
|
"configuration",
|
|
26
26
|
"internal_error",
|
|
27
|
+
"resource_pressure",
|
|
27
28
|
];
|
|
28
29
|
export class SessionTerminationError extends Error {
|
|
29
30
|
termination;
|
|
@@ -64,6 +65,14 @@ const PROVIDER_CAUSE_CODES = new Set([
|
|
|
64
65
|
"context_overflow",
|
|
65
66
|
]);
|
|
66
67
|
const TOOL_CAUSE_CODES = new Set(["timeout", "fatal"]);
|
|
68
|
+
const RESOURCE_CAUSE_CODES = new Set([
|
|
69
|
+
"memory",
|
|
70
|
+
"disk",
|
|
71
|
+
"cpu",
|
|
72
|
+
"heap",
|
|
73
|
+
"probe_unavailable",
|
|
74
|
+
"queue_overflow",
|
|
75
|
+
]);
|
|
67
76
|
const COMPACTION_CAUSE_CODES = new Set(["aborted", "failed", "stale"]);
|
|
68
77
|
const PERSISTENCE_CAUSE_CODES = new Set([
|
|
69
78
|
"read_failed",
|
|
@@ -148,6 +157,12 @@ function assertCause(cause) {
|
|
|
148
157
|
case "internal":
|
|
149
158
|
valid = code === "unclassified" && hasOnlyKeys(cause, ["area", "code"]);
|
|
150
159
|
break;
|
|
160
|
+
case "resource":
|
|
161
|
+
valid =
|
|
162
|
+
typeof code === "string" &&
|
|
163
|
+
RESOURCE_CAUSE_CODES.has(code) &&
|
|
164
|
+
hasOnlyKeys(cause, ["area", "code"]);
|
|
165
|
+
break;
|
|
151
166
|
}
|
|
152
167
|
if (!valid)
|
|
153
168
|
throw new TypeError("cause must be a bounded structured termination cause");
|
|
@@ -324,6 +339,15 @@ function classifyCause(cause, source) {
|
|
|
324
339
|
causeCode: "internal.unclassified",
|
|
325
340
|
retryable: false,
|
|
326
341
|
};
|
|
342
|
+
case "resource":
|
|
343
|
+
// §15.4: every resource cause is retryable; queue overflow surfaces at
|
|
344
|
+
// the tool boundary, everything else at preflight admission.
|
|
345
|
+
return {
|
|
346
|
+
kind: "resource_pressure",
|
|
347
|
+
phase: cause.code === "queue_overflow" ? "tool" : "preflight",
|
|
348
|
+
causeCode: `resource.${cause.code}`,
|
|
349
|
+
retryable: true,
|
|
350
|
+
};
|
|
327
351
|
}
|
|
328
352
|
}
|
|
329
353
|
function isSafeToAutoRetry(classification, input) {
|
|
@@ -334,7 +358,9 @@ function isSafeToAutoRetry(classification, input) {
|
|
|
334
358
|
input.sideEffects === "none" &&
|
|
335
359
|
(classification.kind === "provider_rate_limit" ||
|
|
336
360
|
classification.kind === "provider_network" ||
|
|
337
|
-
classification.kind === "provider_refusal"
|
|
361
|
+
classification.kind === "provider_refusal" ||
|
|
362
|
+
// §15.4 mapping: only cpu pressure is safe to auto-retry (with delay).
|
|
363
|
+
classification.causeCode === "resource.cpu"));
|
|
338
364
|
}
|
|
339
365
|
function nextActionFor(classification, input) {
|
|
340
366
|
switch (classification.kind) {
|
|
@@ -342,6 +368,8 @@ function nextActionFor(classification, input) {
|
|
|
342
368
|
return "No recovery action is required; continue with the next prompt.";
|
|
343
369
|
case "user_abort":
|
|
344
370
|
return "Review possible partial side effects, then retry only if intended.";
|
|
371
|
+
case "resource_pressure":
|
|
372
|
+
return "Host resources are constrained; reduce load or wait for recovery, then retry.";
|
|
345
373
|
case "provider_abort":
|
|
346
374
|
return "Confirm provider availability, then retry the request.";
|
|
347
375
|
case "provider_auth":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-termination.js","sourceRoot":"","sources":["../../src/core/session-termination.ts"],"names":[],"mappings":"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","sourcesContent":["export const SESSION_TERMINATION_SCHEMA_VERSION = 1 as const;\nexport const MAX_SESSION_TERMINATION_MESSAGE_LENGTH = 512;\n\n/**\n * Canonical list of termination kinds. The run-journal validator derives its\n * runtime bounds from this tuple so a newly added kind can never crash\n * journaling with \"termination kind is out of bounds\" again.\n */\nexport const SESSION_TERMINATION_KIND_VALUES = [\n\t\"completed\",\n\t\"user_abort\",\n\t\"provider_abort\",\n\t\"provider_auth\",\n\t\"provider_rate_limit\",\n\t\"provider_network\",\n\t\"provider_protocol\",\n\t\"provider_refusal\",\n\t\"context_overflow\",\n\t\"transcript_invalid\",\n\t\"tool_timeout\",\n\t\"tool_fatal\",\n\t\"compaction\",\n\t\"persistence\",\n\t\"process_signal\",\n\t\"process_crash\",\n\t\"configuration\",\n\t\"internal_error\",\n] as const;\n\nexport type SessionTerminationKind = (typeof SESSION_TERMINATION_KIND_VALUES)[number];\n\nexport type SessionTerminationPhase =\n\t| \"completed\"\n\t| \"control\"\n\t| \"preflight\"\n\t| \"provider\"\n\t| \"tool\"\n\t| \"compaction\"\n\t| \"persistence\"\n\t| \"process\"\n\t| \"resume\";\n\nexport type SessionTerminationSource = \"observed\" | \"inferred_on_resume\";\nexport type SessionSideEffects = \"none\" | \"possible\" | \"confirmed\";\nexport type SessionProcessSignal = \"SIGINT\" | \"SIGTERM\" | \"SIGHUP\" | \"SIGQUIT\";\n\nexport type ProviderTerminationCauseCode =\n\t| \"abort\"\n\t| \"auth\"\n\t| \"rate_limit\"\n\t| \"network\"\n\t| \"protocol\"\n\t| \"refusal\"\n\t| \"context_overflow\";\nexport type ToolTerminationCauseCode = \"timeout\" | \"fatal\";\nexport type CompactionTerminationCauseCode = \"aborted\" | \"failed\" | \"stale\";\nexport type PersistenceTerminationCauseCode =\n\t| \"read_failed\"\n\t| \"append_failed\"\n\t| \"replace_failed\"\n\t| \"fsync_failed\"\n\t| \"lock_failed\";\nexport type TranscriptTerminationCauseCode =\n\t| \"missing_result\"\n\t| \"duplicate_result\"\n\t| \"orphan_result\"\n\t| \"duplicate_call_id\"\n\t| \"interleaved_non_result\"\n\t| \"invalid_jsonl\"\n\t| \"invalid_tree\"\n\t| \"unsupported_version\"\n\t| \"trailing_fragment\";\nexport type SessionTerminationCauseCode =\n\t| \"session.completed\"\n\t| \"session.user_abort\"\n\t| `provider.${ProviderTerminationCauseCode}`\n\t| `tool.${ToolTerminationCauseCode}`\n\t| `compaction.${CompactionTerminationCauseCode}`\n\t| `persistence.${PersistenceTerminationCauseCode}`\n\t| \"process.signal\"\n\t| \"process.crash\"\n\t| `transcript.${TranscriptTerminationCauseCode}`\n\t| \"configuration.invalid\"\n\t| \"internal.unclassified\";\n\nexport type SessionTerminationCause =\n\t| { readonly area: \"completed\" }\n\t| { readonly area: \"user\"; readonly code: \"abort\" }\n\t| { readonly area: \"provider\"; readonly code: ProviderTerminationCauseCode }\n\t| { readonly area: \"tool\"; readonly code: ToolTerminationCauseCode }\n\t| { readonly area: \"compaction\"; readonly code: CompactionTerminationCauseCode }\n\t| { readonly area: \"persistence\"; readonly code: PersistenceTerminationCauseCode }\n\t| { readonly area: \"process\"; readonly code: \"signal\"; readonly signal: SessionProcessSignal }\n\t| { readonly area: \"process\"; readonly code: \"crash\" }\n\t| { readonly area: \"transcript\"; readonly code: TranscriptTerminationCauseCode }\n\t| { readonly area: \"configuration\"; readonly code: \"invalid\" }\n\t| { readonly area: \"internal\"; readonly code: \"unclassified\" };\n\nexport interface ClassifySessionTerminationInput {\n\treadonly sessionId: string;\n\treadonly runId: string;\n\t/** Deterministic caller-provided ISO-8601 timestamp. */\n\treadonly timestamp: string;\n\treadonly source: SessionTerminationSource;\n\t/** Caller-supplied, pre-redacted diagnostic text. */\n\treadonly message: string;\n\treadonly cause: SessionTerminationCause;\n\treadonly sideEffects: SessionSideEffects;\n\treadonly retryAfterMs?: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly toolCallId?: string;\n\treadonly toolName?: string;\n}\n\nexport interface SessionTermination {\n\treadonly schemaVersion: typeof SESSION_TERMINATION_SCHEMA_VERSION;\n\treadonly sessionId: string;\n\treadonly runId: string;\n\treadonly kind: SessionTerminationKind;\n\treadonly phase: SessionTerminationPhase;\n\treadonly source: SessionTerminationSource;\n\treadonly message: string;\n\treadonly causeCode: SessionTerminationCauseCode;\n\t/** Stable operator guidance suitable for print, JSON, RPC, and TUI surfaces. */\n\treadonly nextAction: string;\n\treadonly retryable: boolean;\n\treadonly safeToAutoRetry: boolean;\n\treadonly sideEffects: SessionSideEffects;\n\treadonly timestamp: string;\n\treadonly retryAfterMs?: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly toolCallId?: string;\n\treadonly toolName?: string;\n\treadonly processSignal?: SessionProcessSignal;\n\treadonly transcriptIssue?: TranscriptTerminationCauseCode;\n}\n\nexport class SessionTerminationError extends Error {\n\treadonly termination: SessionTermination;\n\n\tconstructor(message: string, termination: SessionTermination) {\n\t\tsuper(message);\n\t\tthis.name = \"SessionTerminationError\";\n\t\tthis.termination = termination;\n\t}\n}\n\ninterface Classification {\n\treadonly kind: SessionTerminationKind;\n\treadonly phase: SessionTerminationPhase;\n\treadonly causeCode: SessionTerminationCauseCode;\n\treadonly retryable: boolean;\n\treadonly processSignal?: SessionProcessSignal;\n\treadonly transcriptIssue?: TranscriptTerminationCauseCode;\n}\n\nconst CREDENTIAL_SHAPES = [\n\t/-----BEGIN [A-Z ]*PRIVATE KEY-----/i,\n\t/\\b(?:sk-[A-Za-z0-9_-]{16,}|github_pat_[A-Za-z0-9_]{16,}|gh[pousr]_[A-Za-z0-9]{16,}|xox[baprs]-[A-Za-z0-9-]{16,}|AKIA[A-Z0-9]{16})\\b/,\n\t/\\bBearer\\s+[A-Za-z0-9._~+/-]{8,}={0,2}\\b/i,\n\t/\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b/,\n\t/(?:^|[^A-Za-z0-9])(?:[A-Za-z0-9]+[_-])*(?:authorization|api[-_ ]?key|access[-_ ]?token|token|password|secret(?:[-_ ]?key)?|private[-_ ]?key|cookie)[\"']?\\s*[:=]/i,\n] as const;\n\nconst TOP_LEVEL_KEYS = new Set([\n\t\"sessionId\",\n\t\"runId\",\n\t\"timestamp\",\n\t\"source\",\n\t\"message\",\n\t\"cause\",\n\t\"sideEffects\",\n\t\"retryAfterMs\",\n\t\"provider\",\n\t\"model\",\n\t\"toolCallId\",\n\t\"toolName\",\n]);\nconst PROVIDER_CAUSE_CODES = new Set<ProviderTerminationCauseCode>([\n\t\"abort\",\n\t\"auth\",\n\t\"rate_limit\",\n\t\"network\",\n\t\"protocol\",\n\t\"refusal\",\n\t\"context_overflow\",\n]);\nconst TOOL_CAUSE_CODES = new Set<ToolTerminationCauseCode>([\"timeout\", \"fatal\"]);\nconst COMPACTION_CAUSE_CODES = new Set<CompactionTerminationCauseCode>([\"aborted\", \"failed\", \"stale\"]);\nconst PERSISTENCE_CAUSE_CODES = new Set<PersistenceTerminationCauseCode>([\n\t\"read_failed\",\n\t\"append_failed\",\n\t\"replace_failed\",\n\t\"fsync_failed\",\n\t\"lock_failed\",\n]);\nconst TRANSCRIPT_CAUSE_CODES = new Set<TranscriptTerminationCauseCode>([\n\t\"missing_result\",\n\t\"duplicate_result\",\n\t\"orphan_result\",\n\t\"duplicate_call_id\",\n\t\"interleaved_non_result\",\n\t\"invalid_jsonl\",\n\t\"invalid_tree\",\n\t\"unsupported_version\",\n\t\"trailing_fragment\",\n]);\nconst PROCESS_SIGNALS = new Set<SessionProcessSignal>([\"SIGINT\", \"SIGTERM\", \"SIGHUP\", \"SIGQUIT\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst allowed = new Set(keys);\n\treturn Object.keys(value).every((key) => allowed.has(key));\n}\n\nfunction assertCause(cause: unknown): asserts cause is SessionTerminationCause {\n\tif (!isRecord(cause) || typeof cause.area !== \"string\") {\n\t\tthrow new TypeError(\"cause must be a bounded structured termination cause\");\n\t}\n\tconst code = cause.code;\n\tlet valid = false;\n\tswitch (cause.area) {\n\t\tcase \"completed\":\n\t\t\tvalid = hasOnlyKeys(cause, [\"area\"]);\n\t\t\tbreak;\n\t\tcase \"user\":\n\t\t\tvalid = code === \"abort\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"provider\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tPROVIDER_CAUSE_CODES.has(code as ProviderTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"tool\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tTOOL_CAUSE_CODES.has(code as ToolTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"compaction\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tCOMPACTION_CAUSE_CODES.has(code as CompactionTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"persistence\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tPERSISTENCE_CAUSE_CODES.has(code as PersistenceTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"process\":\n\t\t\tvalid =\n\t\t\t\t(code === \"crash\" && hasOnlyKeys(cause, [\"area\", \"code\"])) ||\n\t\t\t\t(code === \"signal\" &&\n\t\t\t\t\ttypeof cause.signal === \"string\" &&\n\t\t\t\t\tPROCESS_SIGNALS.has(cause.signal as SessionProcessSignal) &&\n\t\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\", \"signal\"]));\n\t\t\tbreak;\n\t\tcase \"transcript\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tTRANSCRIPT_CAUSE_CODES.has(code as TranscriptTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"configuration\":\n\t\t\tvalid = code === \"invalid\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"internal\":\n\t\t\tvalid = code === \"unclassified\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t}\n\tif (!valid) throw new TypeError(\"cause must be a bounded structured termination cause\");\n}\n\nfunction assertClassifierInput(input: unknown): asserts input is ClassifySessionTerminationInput {\n\tif (!isRecord(input) || Object.keys(input).some((key) => !TOP_LEVEL_KEYS.has(key))) {\n\t\tthrow new TypeError(\"input must contain only bounded structured termination fields\");\n\t}\n\tif (\n\t\ttypeof input.sessionId !== \"string\" ||\n\t\ttypeof input.runId !== \"string\" ||\n\t\ttypeof input.timestamp !== \"string\" ||\n\t\ttypeof input.message !== \"string\" ||\n\t\t(input.source !== \"observed\" && input.source !== \"inferred_on_resume\") ||\n\t\t(input.sideEffects !== \"none\" && input.sideEffects !== \"possible\" && input.sideEffects !== \"confirmed\") ||\n\t\t(input.retryAfterMs !== undefined && typeof input.retryAfterMs !== \"number\") ||\n\t\t(input.provider !== undefined && typeof input.provider !== \"string\") ||\n\t\t(input.model !== undefined && typeof input.model !== \"string\") ||\n\t\t(input.toolCallId !== undefined && typeof input.toolCallId !== \"string\") ||\n\t\t(input.toolName !== undefined && typeof input.toolName !== \"string\")\n\t) {\n\t\tthrow new TypeError(\"input must contain only bounded structured termination fields\");\n\t}\n\tassertCause(input.cause);\n}\n\nfunction assertIdentifier(value: string, name: string, maxLength: number): void {\n\tif (value.length === 0 || value.length > maxLength || /[\\u0000-\\u001f\\u007f]/.test(value)) {\n\t\tthrow new TypeError(`${name} must be non-empty bounded text without C0 or DEL control characters`);\n\t}\n}\n\n/** Validate text at the termination trust boundary without attempting redaction. */\nexport function assertPreRedactedTerminationMessage(message: string): void {\n\tif (message.length === 0 || message.length > MAX_SESSION_TERMINATION_MESSAGE_LENGTH) {\n\t\tthrow new TypeError(\n\t\t\t`message must contain 1-${MAX_SESSION_TERMINATION_MESSAGE_LENGTH} characters of pre-redacted text`,\n\t\t);\n\t}\n\tif (message.includes(\"\\0\")) {\n\t\tthrow new TypeError(\"message must not contain NUL\");\n\t}\n\tif (CREDENTIAL_SHAPES.some((pattern) => pattern.test(message))) {\n\t\tthrow new TypeError(\"message contains a credential-shaped literal; redact it before classification\");\n\t}\n}\n\nfunction assertTimestamp(timestamp: string): void {\n\tconst parsed = new Date(timestamp);\n\tif (!Number.isFinite(parsed.getTime()) || parsed.toISOString() !== timestamp) {\n\t\tthrow new TypeError(\"timestamp must be a canonical ISO-8601 UTC instant\");\n\t}\n}\n\nfunction classifyProvider(code: ProviderTerminationCauseCode): Classification {\n\tswitch (code) {\n\t\tcase \"abort\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_abort\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.abort\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"auth\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_auth\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.auth\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"rate_limit\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_rate_limit\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.rate_limit\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"network\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_network\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.network\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"protocol\":\n\t\t\t// Many \"protocol\" stops are sticky transcript shape bugs (orphan tool_call_id)\n\t\t\t// that succeed after transform-messages sanitizes and the turn is retried.\n\t\t\t// Mark retryable so auto-retry can heal; safeToAutoRetry stays false (needs sanitize path).\n\t\t\treturn {\n\t\t\t\tkind: \"provider_protocol\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.protocol\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"context_overflow\":\n\t\t\treturn {\n\t\t\t\tkind: \"context_overflow\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.context_overflow\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"refusal\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_refusal\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.refusal\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t}\n}\n\nfunction classifyCause(cause: SessionTerminationCause, source: SessionTerminationSource): Classification {\n\tswitch (cause.area) {\n\t\tcase \"completed\":\n\t\t\treturn {\n\t\t\t\tkind: \"completed\",\n\t\t\t\tphase: \"completed\",\n\t\t\t\tcauseCode: \"session.completed\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"user\":\n\t\t\treturn {\n\t\t\t\tkind: \"user_abort\",\n\t\t\t\tphase: \"control\",\n\t\t\t\tcauseCode: \"session.user_abort\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"provider\":\n\t\t\treturn classifyProvider(cause.code);\n\t\tcase \"tool\":\n\t\t\treturn cause.code === \"timeout\"\n\t\t\t\t? { kind: \"tool_timeout\", phase: \"tool\", causeCode: \"tool.timeout\", retryable: true }\n\t\t\t\t: { kind: \"tool_fatal\", phase: \"tool\", causeCode: \"tool.fatal\", retryable: false };\n\t\tcase \"compaction\":\n\t\t\treturn {\n\t\t\t\tkind: \"compaction\",\n\t\t\t\tphase: \"compaction\",\n\t\t\t\tcauseCode: `compaction.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"persistence\":\n\t\t\treturn {\n\t\t\t\tkind: \"persistence\",\n\t\t\t\tphase: \"persistence\",\n\t\t\t\tcauseCode: `persistence.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"process\":\n\t\t\tif (cause.code === \"signal\") {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"process_signal\",\n\t\t\t\t\tphase: \"process\",\n\t\t\t\t\tcauseCode: \"process.signal\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tprocessSignal: cause.signal,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tkind: \"process_crash\",\n\t\t\t\tphase: \"resume\",\n\t\t\t\tcauseCode: \"process.crash\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"transcript\":\n\t\t\treturn {\n\t\t\t\tkind: \"transcript_invalid\",\n\t\t\t\tphase: source === \"inferred_on_resume\" ? \"resume\" : \"preflight\",\n\t\t\t\tcauseCode: `transcript.${cause.code}`,\n\t\t\t\tretryable: false,\n\t\t\t\ttranscriptIssue: cause.code,\n\t\t\t};\n\t\tcase \"configuration\":\n\t\t\treturn {\n\t\t\t\tkind: \"configuration\",\n\t\t\t\tphase: \"preflight\",\n\t\t\t\tcauseCode: \"configuration.invalid\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"internal\":\n\t\t\treturn {\n\t\t\t\tkind: \"internal_error\",\n\t\t\t\tphase: \"preflight\",\n\t\t\t\tcauseCode: \"internal.unclassified\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t}\n}\n\nfunction isSafeToAutoRetry(classification: Classification, input: ClassifySessionTerminationInput): boolean {\n\t// provider_refusal: Fable/Claude often false-positive on benign turns. Safe to auto-retry once\n\t// when no tool side effects occurred (same class of recovery as rate_limit/network).\n\treturn (\n\t\tclassification.retryable &&\n\t\tinput.source === \"observed\" &&\n\t\tinput.sideEffects === \"none\" &&\n\t\t(classification.kind === \"provider_rate_limit\" ||\n\t\t\tclassification.kind === \"provider_network\" ||\n\t\t\tclassification.kind === \"provider_refusal\")\n\t);\n}\n\nfunction nextActionFor(classification: Classification, input: ClassifySessionTerminationInput): string {\n\tswitch (classification.kind) {\n\t\tcase \"completed\":\n\t\t\treturn \"No recovery action is required; continue with the next prompt.\";\n\t\tcase \"user_abort\":\n\t\t\treturn \"Review possible partial side effects, then retry only if intended.\";\n\t\tcase \"provider_abort\":\n\t\t\treturn \"Confirm provider availability, then retry the request.\";\n\t\tcase \"provider_auth\":\n\t\t\treturn `Run /login${input.provider ? ` ${input.provider}` : \"\"} or configure valid credentials, then retry.`;\n\t\tcase \"provider_rate_limit\":\n\t\t\treturn \"Wait for the provider retry window or choose another model, then retry.\";\n\t\tcase \"provider_network\":\n\t\t\treturn \"Check network and provider connectivity, then retry.\";\n\t\tcase \"provider_protocol\":\n\t\t\treturn \"Often an orphan tool_call_id / sticky transcript after a dropped error turn — auto-retry after sanitize, or /new session if it persists.\";\n\t\tcase \"provider_refusal\":\n\t\t\treturn \"Model declined this turn (content/safety stop). Usually a false positive on Fable/Claude — auto-retry once, or switch model (k3/qwen3.8-max/grok-4.5/deepseek) / rephrase as a pure coding task.\";\n\t\tcase \"context_overflow\":\n\t\t\treturn \"Compact or reduce context, or switch to a larger-context model.\";\n\t\tcase \"tool_timeout\":\n\t\t\treturn \"Inspect possible tool side effects and increase the tool timeout only if safe.\";\n\t\tcase \"tool_fatal\":\n\t\t\treturn \"Inspect the failed tool result and repair its configuration before retrying.\";\n\t\tcase \"compaction\":\n\t\t\tswitch (classification.causeCode) {\n\t\t\t\tcase \"compaction.aborted\":\n\t\t\t\t\treturn \"Retry /compact if cancellation was unintended; avoid Escape while compaction is running.\";\n\t\t\t\tcase \"compaction.stale\":\n\t\t\t\t\treturn \"Retry /compact after pending session changes settle.\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Resolve the reported compaction error, then retry /compact.\";\n\t\t\t}\n\t\tcase \"persistence\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId} before resuming.`;\n\t\tcase \"process_signal\":\n\t\t\treturn \"Review possible partial side effects before resuming the session.\";\n\t\tcase \"process_crash\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId} and review partial side effects.`;\n\t\tcase \"transcript_invalid\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId}; do not resume until integrity passes.`;\n\t\tcase \"configuration\":\n\t\t\treturn \"Correct the provider, model, tool, or session configuration and retry.\";\n\t\tcase \"internal_error\":\n\t\t\treturn `Inspect run ${input.runId} diagnostics and the run journal before retrying.`;\n\t}\n}\n\n/** Concise actionable rendering shared by non-JSON and TUI surfaces. */\nexport function formatSessionTermination(termination: SessionTermination): string {\n\tconst route =\n\t\ttermination.provider || termination.model\n\t\t\t? `${termination.provider ?? \"unknown\"}/${termination.model ?? \"unknown\"}`\n\t\t\t: \"n/a\";\n\treturn [\n\t\t`kind=${termination.kind}`,\n\t\t`provider/model=${route}`,\n\t\t`retryable=${termination.retryable}`,\n\t\t`cause=${termination.causeCode}`,\n\t\t`message=${termination.message}`,\n\t\t`run=${termination.runId}`,\n\t\t`next=${termination.nextAction}`,\n\t].join(\" \");\n}\n\n/**\n * Classify a bounded, structured termination cause. This intentionally accepts\n * no raw Error value, stack, provider body, or arbitrary cause code.\n */\nexport function classifySessionTermination(input: ClassifySessionTerminationInput): SessionTermination {\n\tassertClassifierInput(input);\n\tassertIdentifier(input.sessionId, \"sessionId\", 128);\n\tassertIdentifier(input.runId, \"runId\", 128);\n\tassertTimestamp(input.timestamp);\n\tassertPreRedactedTerminationMessage(input.message);\n\tif (input.provider !== undefined) assertIdentifier(input.provider, \"provider\", 128);\n\tif (input.model !== undefined) assertIdentifier(input.model, \"model\", 256);\n\tif (input.toolCallId !== undefined) assertIdentifier(input.toolCallId, \"toolCallId\", 512);\n\tif (input.toolName !== undefined) assertIdentifier(input.toolName, \"toolName\", 128);\n\tif (input.retryAfterMs !== undefined && (!Number.isSafeInteger(input.retryAfterMs) || input.retryAfterMs < 0)) {\n\t\tthrow new TypeError(\"retryAfterMs must be a non-negative safe integer\");\n\t}\n\tif (input.cause.area === \"process\" && input.cause.code === \"crash\" && input.source !== \"inferred_on_resume\") {\n\t\tthrow new TypeError(\"process crashes may only be classified as inferred_on_resume\");\n\t}\n\tif (input.cause.area === \"process\" && input.cause.code === \"signal\" && input.source !== \"observed\") {\n\t\tthrow new TypeError(\"process signals must be observed\");\n\t}\n\n\tconst classification = classifyCause(input.cause, input.source);\n\treturn Object.freeze({\n\t\tschemaVersion: SESSION_TERMINATION_SCHEMA_VERSION,\n\t\tsessionId: input.sessionId,\n\t\trunId: input.runId,\n\t\tkind: classification.kind,\n\t\tphase: classification.phase,\n\t\tsource: input.source,\n\t\tmessage: input.message,\n\t\tcauseCode: classification.causeCode,\n\t\tnextAction: nextActionFor(classification, input),\n\t\tretryable: classification.retryable,\n\t\tsafeToAutoRetry: isSafeToAutoRetry(classification, input),\n\t\tsideEffects: input.sideEffects,\n\t\ttimestamp: input.timestamp,\n\t\t...(input.retryAfterMs === undefined ? {} : { retryAfterMs: input.retryAfterMs }),\n\t\t...(input.provider === undefined ? {} : { provider: input.provider }),\n\t\t...(input.model === undefined ? {} : { model: input.model }),\n\t\t...(input.toolCallId === undefined ? {} : { toolCallId: input.toolCallId }),\n\t\t...(input.toolName === undefined ? {} : { toolName: input.toolName }),\n\t\t...(classification.processSignal === undefined ? {} : { processSignal: classification.processSignal }),\n\t\t...(classification.transcriptIssue === undefined ? {} : { transcriptIssue: classification.transcriptIssue }),\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-termination.js","sourceRoot":"","sources":["../../src/core/session-termination.ts"],"names":[],"mappings":"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","sourcesContent":["export const SESSION_TERMINATION_SCHEMA_VERSION = 1 as const;\nexport const MAX_SESSION_TERMINATION_MESSAGE_LENGTH = 512;\n\n/**\n * Canonical list of termination kinds. The run-journal validator derives its\n * runtime bounds from this tuple so a newly added kind can never crash\n * journaling with \"termination kind is out of bounds\" again.\n */\nexport const SESSION_TERMINATION_KIND_VALUES = [\n\t\"completed\",\n\t\"user_abort\",\n\t\"provider_abort\",\n\t\"provider_auth\",\n\t\"provider_rate_limit\",\n\t\"provider_network\",\n\t\"provider_protocol\",\n\t\"provider_refusal\",\n\t\"context_overflow\",\n\t\"transcript_invalid\",\n\t\"tool_timeout\",\n\t\"tool_fatal\",\n\t\"compaction\",\n\t\"persistence\",\n\t\"process_signal\",\n\t\"process_crash\",\n\t\"configuration\",\n\t\"internal_error\",\n\t\"resource_pressure\",\n] as const;\n\nexport type SessionTerminationKind = (typeof SESSION_TERMINATION_KIND_VALUES)[number];\n\nexport type SessionTerminationPhase =\n\t| \"completed\"\n\t| \"control\"\n\t| \"preflight\"\n\t| \"provider\"\n\t| \"tool\"\n\t| \"compaction\"\n\t| \"persistence\"\n\t| \"process\"\n\t| \"resume\";\n\nexport type SessionTerminationSource = \"observed\" | \"inferred_on_resume\";\nexport type SessionSideEffects = \"none\" | \"possible\" | \"confirmed\";\nexport type SessionProcessSignal = \"SIGINT\" | \"SIGTERM\" | \"SIGHUP\" | \"SIGQUIT\";\n\nexport type ProviderTerminationCauseCode =\n\t| \"abort\"\n\t| \"auth\"\n\t| \"rate_limit\"\n\t| \"network\"\n\t| \"protocol\"\n\t| \"refusal\"\n\t| \"context_overflow\";\nexport type ToolTerminationCauseCode = \"timeout\" | \"fatal\";\n/** §15.4 resource-aware runtime roadmap: host-pressure termination causes. */\nexport type ResourceTerminationCauseCode = \"memory\" | \"disk\" | \"cpu\" | \"heap\" | \"probe_unavailable\" | \"queue_overflow\";\nexport type CompactionTerminationCauseCode = \"aborted\" | \"failed\" | \"stale\";\nexport type PersistenceTerminationCauseCode =\n\t| \"read_failed\"\n\t| \"append_failed\"\n\t| \"replace_failed\"\n\t| \"fsync_failed\"\n\t| \"lock_failed\";\nexport type TranscriptTerminationCauseCode =\n\t| \"missing_result\"\n\t| \"duplicate_result\"\n\t| \"orphan_result\"\n\t| \"duplicate_call_id\"\n\t| \"interleaved_non_result\"\n\t| \"invalid_jsonl\"\n\t| \"invalid_tree\"\n\t| \"unsupported_version\"\n\t| \"trailing_fragment\";\nexport type SessionTerminationCauseCode =\n\t| \"session.completed\"\n\t| \"session.user_abort\"\n\t| `provider.${ProviderTerminationCauseCode}`\n\t| `tool.${ToolTerminationCauseCode}`\n\t| `compaction.${CompactionTerminationCauseCode}`\n\t| `persistence.${PersistenceTerminationCauseCode}`\n\t| \"process.signal\"\n\t| \"process.crash\"\n\t| `transcript.${TranscriptTerminationCauseCode}`\n\t| \"configuration.invalid\"\n\t| \"internal.unclassified\"\n\t| `resource.${ResourceTerminationCauseCode}`;\n\nexport type SessionTerminationCause =\n\t| { readonly area: \"completed\" }\n\t| { readonly area: \"user\"; readonly code: \"abort\" }\n\t| { readonly area: \"provider\"; readonly code: ProviderTerminationCauseCode }\n\t| { readonly area: \"tool\"; readonly code: ToolTerminationCauseCode }\n\t| { readonly area: \"compaction\"; readonly code: CompactionTerminationCauseCode }\n\t| { readonly area: \"persistence\"; readonly code: PersistenceTerminationCauseCode }\n\t| { readonly area: \"process\"; readonly code: \"signal\"; readonly signal: SessionProcessSignal }\n\t| { readonly area: \"process\"; readonly code: \"crash\" }\n\t| { readonly area: \"transcript\"; readonly code: TranscriptTerminationCauseCode }\n\t| { readonly area: \"configuration\"; readonly code: \"invalid\" }\n\t| { readonly area: \"internal\"; readonly code: \"unclassified\" }\n\t| { readonly area: \"resource\"; readonly code: ResourceTerminationCauseCode };\n\nexport interface ClassifySessionTerminationInput {\n\treadonly sessionId: string;\n\treadonly runId: string;\n\t/** Deterministic caller-provided ISO-8601 timestamp. */\n\treadonly timestamp: string;\n\treadonly source: SessionTerminationSource;\n\t/** Caller-supplied, pre-redacted diagnostic text. */\n\treadonly message: string;\n\treadonly cause: SessionTerminationCause;\n\treadonly sideEffects: SessionSideEffects;\n\treadonly retryAfterMs?: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly toolCallId?: string;\n\treadonly toolName?: string;\n}\n\nexport interface SessionTermination {\n\treadonly schemaVersion: typeof SESSION_TERMINATION_SCHEMA_VERSION;\n\treadonly sessionId: string;\n\treadonly runId: string;\n\treadonly kind: SessionTerminationKind;\n\treadonly phase: SessionTerminationPhase;\n\treadonly source: SessionTerminationSource;\n\treadonly message: string;\n\treadonly causeCode: SessionTerminationCauseCode;\n\t/** Stable operator guidance suitable for print, JSON, RPC, and TUI surfaces. */\n\treadonly nextAction: string;\n\treadonly retryable: boolean;\n\treadonly safeToAutoRetry: boolean;\n\treadonly sideEffects: SessionSideEffects;\n\treadonly timestamp: string;\n\treadonly retryAfterMs?: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly toolCallId?: string;\n\treadonly toolName?: string;\n\treadonly processSignal?: SessionProcessSignal;\n\treadonly transcriptIssue?: TranscriptTerminationCauseCode;\n}\n\nexport class SessionTerminationError extends Error {\n\treadonly termination: SessionTermination;\n\n\tconstructor(message: string, termination: SessionTermination) {\n\t\tsuper(message);\n\t\tthis.name = \"SessionTerminationError\";\n\t\tthis.termination = termination;\n\t}\n}\n\ninterface Classification {\n\treadonly kind: SessionTerminationKind;\n\treadonly phase: SessionTerminationPhase;\n\treadonly causeCode: SessionTerminationCauseCode;\n\treadonly retryable: boolean;\n\treadonly processSignal?: SessionProcessSignal;\n\treadonly transcriptIssue?: TranscriptTerminationCauseCode;\n}\n\nconst CREDENTIAL_SHAPES = [\n\t/-----BEGIN [A-Z ]*PRIVATE KEY-----/i,\n\t/\\b(?:sk-[A-Za-z0-9_-]{16,}|github_pat_[A-Za-z0-9_]{16,}|gh[pousr]_[A-Za-z0-9]{16,}|xox[baprs]-[A-Za-z0-9-]{16,}|AKIA[A-Z0-9]{16})\\b/,\n\t/\\bBearer\\s+[A-Za-z0-9._~+/-]{8,}={0,2}\\b/i,\n\t/\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b/,\n\t/(?:^|[^A-Za-z0-9])(?:[A-Za-z0-9]+[_-])*(?:authorization|api[-_ ]?key|access[-_ ]?token|token|password|secret(?:[-_ ]?key)?|private[-_ ]?key|cookie)[\"']?\\s*[:=]/i,\n] as const;\n\nconst TOP_LEVEL_KEYS = new Set([\n\t\"sessionId\",\n\t\"runId\",\n\t\"timestamp\",\n\t\"source\",\n\t\"message\",\n\t\"cause\",\n\t\"sideEffects\",\n\t\"retryAfterMs\",\n\t\"provider\",\n\t\"model\",\n\t\"toolCallId\",\n\t\"toolName\",\n]);\nconst PROVIDER_CAUSE_CODES = new Set<ProviderTerminationCauseCode>([\n\t\"abort\",\n\t\"auth\",\n\t\"rate_limit\",\n\t\"network\",\n\t\"protocol\",\n\t\"refusal\",\n\t\"context_overflow\",\n]);\nconst TOOL_CAUSE_CODES = new Set<ToolTerminationCauseCode>([\"timeout\", \"fatal\"]);\nconst RESOURCE_CAUSE_CODES = new Set<ResourceTerminationCauseCode>([\n\t\"memory\",\n\t\"disk\",\n\t\"cpu\",\n\t\"heap\",\n\t\"probe_unavailable\",\n\t\"queue_overflow\",\n]);\nconst COMPACTION_CAUSE_CODES = new Set<CompactionTerminationCauseCode>([\"aborted\", \"failed\", \"stale\"]);\nconst PERSISTENCE_CAUSE_CODES = new Set<PersistenceTerminationCauseCode>([\n\t\"read_failed\",\n\t\"append_failed\",\n\t\"replace_failed\",\n\t\"fsync_failed\",\n\t\"lock_failed\",\n]);\nconst TRANSCRIPT_CAUSE_CODES = new Set<TranscriptTerminationCauseCode>([\n\t\"missing_result\",\n\t\"duplicate_result\",\n\t\"orphan_result\",\n\t\"duplicate_call_id\",\n\t\"interleaved_non_result\",\n\t\"invalid_jsonl\",\n\t\"invalid_tree\",\n\t\"unsupported_version\",\n\t\"trailing_fragment\",\n]);\nconst PROCESS_SIGNALS = new Set<SessionProcessSignal>([\"SIGINT\", \"SIGTERM\", \"SIGHUP\", \"SIGQUIT\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n\tconst allowed = new Set(keys);\n\treturn Object.keys(value).every((key) => allowed.has(key));\n}\n\nfunction assertCause(cause: unknown): asserts cause is SessionTerminationCause {\n\tif (!isRecord(cause) || typeof cause.area !== \"string\") {\n\t\tthrow new TypeError(\"cause must be a bounded structured termination cause\");\n\t}\n\tconst code = cause.code;\n\tlet valid = false;\n\tswitch (cause.area) {\n\t\tcase \"completed\":\n\t\t\tvalid = hasOnlyKeys(cause, [\"area\"]);\n\t\t\tbreak;\n\t\tcase \"user\":\n\t\t\tvalid = code === \"abort\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"provider\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tPROVIDER_CAUSE_CODES.has(code as ProviderTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"tool\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tTOOL_CAUSE_CODES.has(code as ToolTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"compaction\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tCOMPACTION_CAUSE_CODES.has(code as CompactionTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"persistence\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tPERSISTENCE_CAUSE_CODES.has(code as PersistenceTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"process\":\n\t\t\tvalid =\n\t\t\t\t(code === \"crash\" && hasOnlyKeys(cause, [\"area\", \"code\"])) ||\n\t\t\t\t(code === \"signal\" &&\n\t\t\t\t\ttypeof cause.signal === \"string\" &&\n\t\t\t\t\tPROCESS_SIGNALS.has(cause.signal as SessionProcessSignal) &&\n\t\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\", \"signal\"]));\n\t\t\tbreak;\n\t\tcase \"transcript\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tTRANSCRIPT_CAUSE_CODES.has(code as TranscriptTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"configuration\":\n\t\t\tvalid = code === \"invalid\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"internal\":\n\t\t\tvalid = code === \"unclassified\" && hasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t\tcase \"resource\":\n\t\t\tvalid =\n\t\t\t\ttypeof code === \"string\" &&\n\t\t\t\tRESOURCE_CAUSE_CODES.has(code as ResourceTerminationCauseCode) &&\n\t\t\t\thasOnlyKeys(cause, [\"area\", \"code\"]);\n\t\t\tbreak;\n\t}\n\tif (!valid) throw new TypeError(\"cause must be a bounded structured termination cause\");\n}\n\nfunction assertClassifierInput(input: unknown): asserts input is ClassifySessionTerminationInput {\n\tif (!isRecord(input) || Object.keys(input).some((key) => !TOP_LEVEL_KEYS.has(key))) {\n\t\tthrow new TypeError(\"input must contain only bounded structured termination fields\");\n\t}\n\tif (\n\t\ttypeof input.sessionId !== \"string\" ||\n\t\ttypeof input.runId !== \"string\" ||\n\t\ttypeof input.timestamp !== \"string\" ||\n\t\ttypeof input.message !== \"string\" ||\n\t\t(input.source !== \"observed\" && input.source !== \"inferred_on_resume\") ||\n\t\t(input.sideEffects !== \"none\" && input.sideEffects !== \"possible\" && input.sideEffects !== \"confirmed\") ||\n\t\t(input.retryAfterMs !== undefined && typeof input.retryAfterMs !== \"number\") ||\n\t\t(input.provider !== undefined && typeof input.provider !== \"string\") ||\n\t\t(input.model !== undefined && typeof input.model !== \"string\") ||\n\t\t(input.toolCallId !== undefined && typeof input.toolCallId !== \"string\") ||\n\t\t(input.toolName !== undefined && typeof input.toolName !== \"string\")\n\t) {\n\t\tthrow new TypeError(\"input must contain only bounded structured termination fields\");\n\t}\n\tassertCause(input.cause);\n}\n\nfunction assertIdentifier(value: string, name: string, maxLength: number): void {\n\tif (value.length === 0 || value.length > maxLength || /[\\u0000-\\u001f\\u007f]/.test(value)) {\n\t\tthrow new TypeError(`${name} must be non-empty bounded text without C0 or DEL control characters`);\n\t}\n}\n\n/** Validate text at the termination trust boundary without attempting redaction. */\nexport function assertPreRedactedTerminationMessage(message: string): void {\n\tif (message.length === 0 || message.length > MAX_SESSION_TERMINATION_MESSAGE_LENGTH) {\n\t\tthrow new TypeError(\n\t\t\t`message must contain 1-${MAX_SESSION_TERMINATION_MESSAGE_LENGTH} characters of pre-redacted text`,\n\t\t);\n\t}\n\tif (message.includes(\"\\0\")) {\n\t\tthrow new TypeError(\"message must not contain NUL\");\n\t}\n\tif (CREDENTIAL_SHAPES.some((pattern) => pattern.test(message))) {\n\t\tthrow new TypeError(\"message contains a credential-shaped literal; redact it before classification\");\n\t}\n}\n\nfunction assertTimestamp(timestamp: string): void {\n\tconst parsed = new Date(timestamp);\n\tif (!Number.isFinite(parsed.getTime()) || parsed.toISOString() !== timestamp) {\n\t\tthrow new TypeError(\"timestamp must be a canonical ISO-8601 UTC instant\");\n\t}\n}\n\nfunction classifyProvider(code: ProviderTerminationCauseCode): Classification {\n\tswitch (code) {\n\t\tcase \"abort\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_abort\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.abort\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"auth\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_auth\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.auth\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"rate_limit\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_rate_limit\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.rate_limit\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"network\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_network\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.network\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"protocol\":\n\t\t\t// Many \"protocol\" stops are sticky transcript shape bugs (orphan tool_call_id)\n\t\t\t// that succeed after transform-messages sanitizes and the turn is retried.\n\t\t\t// Mark retryable so auto-retry can heal; safeToAutoRetry stays false (needs sanitize path).\n\t\t\treturn {\n\t\t\t\tkind: \"provider_protocol\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.protocol\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"context_overflow\":\n\t\t\treturn {\n\t\t\t\tkind: \"context_overflow\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.context_overflow\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"refusal\":\n\t\t\treturn {\n\t\t\t\tkind: \"provider_refusal\",\n\t\t\t\tphase: \"provider\",\n\t\t\t\tcauseCode: \"provider.refusal\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t}\n}\n\nfunction classifyCause(cause: SessionTerminationCause, source: SessionTerminationSource): Classification {\n\tswitch (cause.area) {\n\t\tcase \"completed\":\n\t\t\treturn {\n\t\t\t\tkind: \"completed\",\n\t\t\t\tphase: \"completed\",\n\t\t\t\tcauseCode: \"session.completed\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"user\":\n\t\t\treturn {\n\t\t\t\tkind: \"user_abort\",\n\t\t\t\tphase: \"control\",\n\t\t\t\tcauseCode: \"session.user_abort\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"provider\":\n\t\t\treturn classifyProvider(cause.code);\n\t\tcase \"tool\":\n\t\t\treturn cause.code === \"timeout\"\n\t\t\t\t? { kind: \"tool_timeout\", phase: \"tool\", causeCode: \"tool.timeout\", retryable: true }\n\t\t\t\t: { kind: \"tool_fatal\", phase: \"tool\", causeCode: \"tool.fatal\", retryable: false };\n\t\tcase \"compaction\":\n\t\t\treturn {\n\t\t\t\tkind: \"compaction\",\n\t\t\t\tphase: \"compaction\",\n\t\t\t\tcauseCode: `compaction.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"persistence\":\n\t\t\treturn {\n\t\t\t\tkind: \"persistence\",\n\t\t\t\tphase: \"persistence\",\n\t\t\t\tcauseCode: `persistence.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"process\":\n\t\t\tif (cause.code === \"signal\") {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"process_signal\",\n\t\t\t\t\tphase: \"process\",\n\t\t\t\t\tcauseCode: \"process.signal\",\n\t\t\t\t\tretryable: false,\n\t\t\t\t\tprocessSignal: cause.signal,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tkind: \"process_crash\",\n\t\t\t\tphase: \"resume\",\n\t\t\t\tcauseCode: \"process.crash\",\n\t\t\t\tretryable: true,\n\t\t\t};\n\t\tcase \"transcript\":\n\t\t\treturn {\n\t\t\t\tkind: \"transcript_invalid\",\n\t\t\t\tphase: source === \"inferred_on_resume\" ? \"resume\" : \"preflight\",\n\t\t\t\tcauseCode: `transcript.${cause.code}`,\n\t\t\t\tretryable: false,\n\t\t\t\ttranscriptIssue: cause.code,\n\t\t\t};\n\t\tcase \"configuration\":\n\t\t\treturn {\n\t\t\t\tkind: \"configuration\",\n\t\t\t\tphase: \"preflight\",\n\t\t\t\tcauseCode: \"configuration.invalid\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"internal\":\n\t\t\treturn {\n\t\t\t\tkind: \"internal_error\",\n\t\t\t\tphase: \"preflight\",\n\t\t\t\tcauseCode: \"internal.unclassified\",\n\t\t\t\tretryable: false,\n\t\t\t};\n\t\tcase \"resource\":\n\t\t\t// §15.4: every resource cause is retryable; queue overflow surfaces at\n\t\t\t// the tool boundary, everything else at preflight admission.\n\t\t\treturn {\n\t\t\t\tkind: \"resource_pressure\",\n\t\t\t\tphase: cause.code === \"queue_overflow\" ? \"tool\" : \"preflight\",\n\t\t\t\tcauseCode: `resource.${cause.code}`,\n\t\t\t\tretryable: true,\n\t\t\t};\n\t}\n}\n\nfunction isSafeToAutoRetry(classification: Classification, input: ClassifySessionTerminationInput): boolean {\n\t// provider_refusal: Fable/Claude often false-positive on benign turns. Safe to auto-retry once\n\t// when no tool side effects occurred (same class of recovery as rate_limit/network).\n\treturn (\n\t\tclassification.retryable &&\n\t\tinput.source === \"observed\" &&\n\t\tinput.sideEffects === \"none\" &&\n\t\t(classification.kind === \"provider_rate_limit\" ||\n\t\t\tclassification.kind === \"provider_network\" ||\n\t\t\tclassification.kind === \"provider_refusal\" ||\n\t\t\t// §15.4 mapping: only cpu pressure is safe to auto-retry (with delay).\n\t\t\tclassification.causeCode === \"resource.cpu\")\n\t);\n}\n\nfunction nextActionFor(classification: Classification, input: ClassifySessionTerminationInput): string {\n\tswitch (classification.kind) {\n\t\tcase \"completed\":\n\t\t\treturn \"No recovery action is required; continue with the next prompt.\";\n\t\tcase \"user_abort\":\n\t\t\treturn \"Review possible partial side effects, then retry only if intended.\";\n\t\tcase \"resource_pressure\":\n\t\t\treturn \"Host resources are constrained; reduce load or wait for recovery, then retry.\";\n\t\tcase \"provider_abort\":\n\t\t\treturn \"Confirm provider availability, then retry the request.\";\n\t\tcase \"provider_auth\":\n\t\t\treturn `Run /login${input.provider ? ` ${input.provider}` : \"\"} or configure valid credentials, then retry.`;\n\t\tcase \"provider_rate_limit\":\n\t\t\treturn \"Wait for the provider retry window or choose another model, then retry.\";\n\t\tcase \"provider_network\":\n\t\t\treturn \"Check network and provider connectivity, then retry.\";\n\t\tcase \"provider_protocol\":\n\t\t\treturn \"Often an orphan tool_call_id / sticky transcript after a dropped error turn — auto-retry after sanitize, or /new session if it persists.\";\n\t\tcase \"provider_refusal\":\n\t\t\treturn \"Model declined this turn (content/safety stop). Usually a false positive on Fable/Claude — auto-retry once, or switch model (k3/qwen3.8-max/grok-4.5/deepseek) / rephrase as a pure coding task.\";\n\t\tcase \"context_overflow\":\n\t\t\treturn \"Compact or reduce context, or switch to a larger-context model.\";\n\t\tcase \"tool_timeout\":\n\t\t\treturn \"Inspect possible tool side effects and increase the tool timeout only if safe.\";\n\t\tcase \"tool_fatal\":\n\t\t\treturn \"Inspect the failed tool result and repair its configuration before retrying.\";\n\t\tcase \"compaction\":\n\t\t\tswitch (classification.causeCode) {\n\t\t\t\tcase \"compaction.aborted\":\n\t\t\t\t\treturn \"Retry /compact if cancellation was unintended; avoid Escape while compaction is running.\";\n\t\t\t\tcase \"compaction.stale\":\n\t\t\t\t\treturn \"Retry /compact after pending session changes settle.\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Resolve the reported compaction error, then retry /compact.\";\n\t\t\t}\n\t\tcase \"persistence\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId} before resuming.`;\n\t\tcase \"process_signal\":\n\t\t\treturn \"Review possible partial side effects before resuming the session.\";\n\t\tcase \"process_crash\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId} and review partial side effects.`;\n\t\tcase \"transcript_invalid\":\n\t\t\treturn `Run omk session doctor --session ${input.sessionId}; do not resume until integrity passes.`;\n\t\tcase \"configuration\":\n\t\t\treturn \"Correct the provider, model, tool, or session configuration and retry.\";\n\t\tcase \"internal_error\":\n\t\t\treturn `Inspect run ${input.runId} diagnostics and the run journal before retrying.`;\n\t}\n}\n\n/** Concise actionable rendering shared by non-JSON and TUI surfaces. */\nexport function formatSessionTermination(termination: SessionTermination): string {\n\tconst route =\n\t\ttermination.provider || termination.model\n\t\t\t? `${termination.provider ?? \"unknown\"}/${termination.model ?? \"unknown\"}`\n\t\t\t: \"n/a\";\n\treturn [\n\t\t`kind=${termination.kind}`,\n\t\t`provider/model=${route}`,\n\t\t`retryable=${termination.retryable}`,\n\t\t`cause=${termination.causeCode}`,\n\t\t`message=${termination.message}`,\n\t\t`run=${termination.runId}`,\n\t\t`next=${termination.nextAction}`,\n\t].join(\" \");\n}\n\n/**\n * Classify a bounded, structured termination cause. This intentionally accepts\n * no raw Error value, stack, provider body, or arbitrary cause code.\n */\nexport function classifySessionTermination(input: ClassifySessionTerminationInput): SessionTermination {\n\tassertClassifierInput(input);\n\tassertIdentifier(input.sessionId, \"sessionId\", 128);\n\tassertIdentifier(input.runId, \"runId\", 128);\n\tassertTimestamp(input.timestamp);\n\tassertPreRedactedTerminationMessage(input.message);\n\tif (input.provider !== undefined) assertIdentifier(input.provider, \"provider\", 128);\n\tif (input.model !== undefined) assertIdentifier(input.model, \"model\", 256);\n\tif (input.toolCallId !== undefined) assertIdentifier(input.toolCallId, \"toolCallId\", 512);\n\tif (input.toolName !== undefined) assertIdentifier(input.toolName, \"toolName\", 128);\n\tif (input.retryAfterMs !== undefined && (!Number.isSafeInteger(input.retryAfterMs) || input.retryAfterMs < 0)) {\n\t\tthrow new TypeError(\"retryAfterMs must be a non-negative safe integer\");\n\t}\n\tif (input.cause.area === \"process\" && input.cause.code === \"crash\" && input.source !== \"inferred_on_resume\") {\n\t\tthrow new TypeError(\"process crashes may only be classified as inferred_on_resume\");\n\t}\n\tif (input.cause.area === \"process\" && input.cause.code === \"signal\" && input.source !== \"observed\") {\n\t\tthrow new TypeError(\"process signals must be observed\");\n\t}\n\n\tconst classification = classifyCause(input.cause, input.source);\n\treturn Object.freeze({\n\t\tschemaVersion: SESSION_TERMINATION_SCHEMA_VERSION,\n\t\tsessionId: input.sessionId,\n\t\trunId: input.runId,\n\t\tkind: classification.kind,\n\t\tphase: classification.phase,\n\t\tsource: input.source,\n\t\tmessage: input.message,\n\t\tcauseCode: classification.causeCode,\n\t\tnextAction: nextActionFor(classification, input),\n\t\tretryable: classification.retryable,\n\t\tsafeToAutoRetry: isSafeToAutoRetry(classification, input),\n\t\tsideEffects: input.sideEffects,\n\t\ttimestamp: input.timestamp,\n\t\t...(input.retryAfterMs === undefined ? {} : { retryAfterMs: input.retryAfterMs }),\n\t\t...(input.provider === undefined ? {} : { provider: input.provider }),\n\t\t...(input.model === undefined ? {} : { model: input.model }),\n\t\t...(input.toolCallId === undefined ? {} : { toolCallId: input.toolCallId }),\n\t\t...(input.toolName === undefined ? {} : { toolName: input.toolName }),\n\t\t...(classification.processSignal === undefined ? {} : { processSignal: classification.processSignal }),\n\t\t...(classification.transcriptIssue === undefined ? {} : { transcriptIssue: classification.transcriptIssue }),\n\t});\n}\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Transport } from "omk-ai";
|
|
2
|
+
import type { NotificationSettings } from "./completion-sound.ts";
|
|
3
|
+
import type { ResourceGovernorSettings } from "./resource-governor-settings.ts";
|
|
2
4
|
export interface CompactionSettings {
|
|
3
5
|
enabled?: boolean;
|
|
4
6
|
model?: string;
|
|
@@ -121,6 +123,10 @@ export interface Settings {
|
|
|
121
123
|
compaction?: CompactionSettings;
|
|
122
124
|
contextBudget?: ContextBudgetSettings;
|
|
123
125
|
agent?: AgentRuntimeSettings;
|
|
126
|
+
/** Resource-aware runtime governor: observe records, adaptive/strict throttle per-run tool concurrency (docs/settings.md). */
|
|
127
|
+
resourceGovernor?: ResourceGovernorSettings;
|
|
128
|
+
/** Completion notifications; `notifications.completionSound` is default-off (docs/settings.md). */
|
|
129
|
+
notifications?: NotificationSettings;
|
|
124
130
|
branchSummary?: BranchSummarySettings;
|
|
125
131
|
retry?: RetrySettings;
|
|
126
132
|
/** Root-level recovery: block sticky safety models, auto-failover on content/safety stop. */
|
|
@@ -136,6 +142,7 @@ export interface Settings {
|
|
|
136
142
|
packages?: PackageSource[];
|
|
137
143
|
extensions?: string[];
|
|
138
144
|
skills?: string[];
|
|
145
|
+
defaultActiveSkills?: string[];
|
|
139
146
|
prompts?: string[];
|
|
140
147
|
themes?: string[];
|
|
141
148
|
enableSkillCommands?: boolean;
|
|
@@ -242,6 +249,8 @@ export declare class SettingsManager {
|
|
|
242
249
|
/** Global-only: project settings cannot expand prompt-resource access. */
|
|
243
250
|
getContextBudgetEnabled(): boolean;
|
|
244
251
|
getAgentRuntimeSettings(): AgentRuntimeSettings;
|
|
252
|
+
getResourceGovernorSettings(): ResourceGovernorSettings;
|
|
253
|
+
getNotificationSettings(): NotificationSettings;
|
|
245
254
|
setContextBudgetEnabled(enabled: boolean): void;
|
|
246
255
|
getCompactionModel(): string | undefined;
|
|
247
256
|
setCompactionEnabled(enabled: boolean): void;
|
|
@@ -306,6 +315,9 @@ export declare class SettingsManager {
|
|
|
306
315
|
setProjectExtensionPaths(paths: string[]): void;
|
|
307
316
|
getSkillPaths(): string[];
|
|
308
317
|
setSkillPaths(paths: string[]): void;
|
|
318
|
+
/** Global-only operator defaults; project settings cannot activate or shadow this profile. */
|
|
319
|
+
getDefaultActiveSkills(): string[];
|
|
320
|
+
setDefaultActiveSkills(names: string[]): void;
|
|
309
321
|
setProjectSkillPaths(paths: string[]): void;
|
|
310
322
|
getPromptTemplatePaths(): string[];
|
|
311
323
|
setPromptTemplatePaths(paths: string[]): void;
|