ocmm 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/.codex/agents/dw-builder.toml +3 -3
  2. package/.codex/agents/dw-clarifier.toml +2 -2
  3. package/.codex/agents/dw-code-search.toml +2 -2
  4. package/.codex/agents/dw-coding.toml +2 -2
  5. package/.codex/agents/dw-complex.toml +2 -2
  6. package/.codex/agents/dw-creative.toml +2 -2
  7. package/.codex/agents/dw-deep.toml +3 -3
  8. package/.codex/agents/dw-doc-search.toml +2 -2
  9. package/.codex/agents/dw-documenting.toml +2 -2
  10. package/.codex/agents/dw-explore.toml +2 -2
  11. package/.codex/agents/dw-frontend.toml +2 -2
  12. package/.codex/agents/dw-hard-reasoning.toml +2 -2
  13. package/.codex/agents/dw-media-reader.toml +2 -2
  14. package/.codex/agents/dw-normal-task.toml +2 -2
  15. package/.codex/agents/dw-oracle-2nd.toml +8 -0
  16. package/.codex/agents/dw-oracle.toml +3 -3
  17. package/.codex/agents/dw-orchestrator.toml +2 -2
  18. package/.codex/agents/dw-plan-critic.toml +2 -2
  19. package/.codex/agents/dw-planner.toml +3 -3
  20. package/.codex/agents/dw-quick.toml +2 -2
  21. package/.codex/agents/dw-research.toml +2 -2
  22. package/.codex/agents/dw-reviewer.toml +2 -2
  23. package/README.md +193 -46
  24. package/dist/cli/shim.d.ts +4 -2
  25. package/dist/cli/shim.js +26 -11
  26. package/dist/cli/shim.js.map +1 -1
  27. package/dist/codex/plugin-generator.js +121 -96
  28. package/dist/codex/plugin-generator.js.map +1 -1
  29. package/dist/config/load.d.ts +32 -23
  30. package/dist/config/load.js +384 -90
  31. package/dist/config/load.js.map +1 -1
  32. package/dist/config/merge.d.ts +18 -0
  33. package/dist/config/merge.js +46 -0
  34. package/dist/config/merge.js.map +1 -0
  35. package/dist/config/normalize.d.ts +1 -0
  36. package/dist/config/normalize.js +22 -16
  37. package/dist/config/normalize.js.map +1 -1
  38. package/dist/config/profile-aliases.d.ts +12 -0
  39. package/dist/config/profile-aliases.js +127 -0
  40. package/dist/config/profile-aliases.js.map +1 -0
  41. package/dist/config/profile-types.d.ts +13 -0
  42. package/dist/config/profile-types.js +2 -0
  43. package/dist/config/profile-types.js.map +1 -0
  44. package/dist/config/review-agent-migration.d.ts +89 -0
  45. package/dist/config/review-agent-migration.js +237 -0
  46. package/dist/config/review-agent-migration.js.map +1 -0
  47. package/dist/config/schema.d.ts +1364 -219
  48. package/dist/config/schema.js +169 -36
  49. package/dist/config/schema.js.map +1 -1
  50. package/dist/config/tolerant-parse.d.ts +41 -0
  51. package/dist/config/tolerant-parse.js +164 -0
  52. package/dist/config/tolerant-parse.js.map +1 -0
  53. package/dist/data/agents.d.ts +2 -1
  54. package/dist/data/agents.js +25 -10
  55. package/dist/data/agents.js.map +1 -1
  56. package/dist/data/categories.js +2 -1
  57. package/dist/data/categories.js.map +1 -1
  58. package/dist/hooks/chat-params.d.ts +2 -0
  59. package/dist/hooks/chat-params.js +182 -16
  60. package/dist/hooks/chat-params.js.map +1 -1
  61. package/dist/hooks/config.d.ts +14 -2
  62. package/dist/hooks/config.js +538 -60
  63. package/dist/hooks/config.js.map +1 -1
  64. package/dist/hooks/event.d.ts +3 -11
  65. package/dist/hooks/event.js +5 -9
  66. package/dist/hooks/event.js.map +1 -1
  67. package/dist/index.js +21 -14
  68. package/dist/index.js.map +1 -1
  69. package/dist/intent/model-family.d.ts +2 -0
  70. package/dist/intent/model-family.js +11 -0
  71. package/dist/intent/model-family.js.map +1 -1
  72. package/dist/intent/prompt-loader.d.ts +3 -3
  73. package/dist/intent/prompt-loader.js +3 -3
  74. package/dist/permissions/index.d.ts +3 -0
  75. package/dist/permissions/index.js +43 -28
  76. package/dist/permissions/index.js.map +1 -1
  77. package/dist/review-agents/expand.d.ts +36 -0
  78. package/dist/review-agents/expand.js +157 -0
  79. package/dist/review-agents/expand.js.map +1 -0
  80. package/dist/review-agents/names.d.ts +16 -0
  81. package/dist/review-agents/names.js +55 -0
  82. package/dist/review-agents/names.js.map +1 -0
  83. package/dist/routing/effective-route.d.ts +19 -0
  84. package/dist/routing/effective-route.js +133 -0
  85. package/dist/routing/effective-route.js.map +1 -0
  86. package/dist/routing/model-upgrades.d.ts +5 -0
  87. package/dist/routing/model-upgrades.js +59 -11
  88. package/dist/routing/model-upgrades.js.map +1 -1
  89. package/dist/routing/resolver.d.ts +8 -1
  90. package/dist/routing/resolver.js +29 -9
  91. package/dist/routing/resolver.js.map +1 -1
  92. package/dist/routing/route-registry.d.ts +13 -0
  93. package/dist/routing/route-registry.js +84 -0
  94. package/dist/routing/route-registry.js.map +1 -0
  95. package/dist/routing/variant-translator.js +7 -4
  96. package/dist/routing/variant-translator.js.map +1 -1
  97. package/dist/runtime-fallback/dispatcher.d.ts +1 -0
  98. package/dist/runtime-fallback/dispatcher.js +7 -5
  99. package/dist/runtime-fallback/dispatcher.js.map +1 -1
  100. package/dist/runtime-fallback/error-classifier.d.ts +3 -1
  101. package/dist/runtime-fallback/error-classifier.js +135 -1
  102. package/dist/runtime-fallback/error-classifier.js.map +1 -1
  103. package/dist/runtime-fallback/event-handler-generic-fallback.d.ts +26 -0
  104. package/dist/runtime-fallback/event-handler-generic-fallback.js +54 -0
  105. package/dist/runtime-fallback/event-handler-generic-fallback.js.map +1 -0
  106. package/dist/runtime-fallback/event-handler-idle-continuation.d.ts +9 -0
  107. package/dist/runtime-fallback/event-handler-idle-continuation.js +48 -0
  108. package/dist/runtime-fallback/event-handler-idle-continuation.js.map +1 -0
  109. package/dist/runtime-fallback/event-handler-support.d.ts +39 -0
  110. package/dist/runtime-fallback/event-handler-support.js +194 -0
  111. package/dist/runtime-fallback/event-handler-support.js.map +1 -0
  112. package/dist/runtime-fallback/event-handler-test-fixtures.d.ts +874 -0
  113. package/dist/runtime-fallback/event-handler-test-fixtures.js +150 -0
  114. package/dist/runtime-fallback/event-handler-test-fixtures.js.map +1 -0
  115. package/dist/runtime-fallback/event-handler.d.ts +13 -1
  116. package/dist/runtime-fallback/event-handler.js +334 -192
  117. package/dist/runtime-fallback/event-handler.js.map +1 -1
  118. package/dist/runtime-fallback/fallback-state.d.ts +8 -5
  119. package/dist/runtime-fallback/fallback-state.js +9 -6
  120. package/dist/runtime-fallback/fallback-state.js.map +1 -1
  121. package/dist/runtime-fallback/index.d.ts +21 -1
  122. package/dist/runtime-fallback/index.js +7 -1
  123. package/dist/runtime-fallback/index.js.map +1 -1
  124. package/dist/runtime-fallback/interruption-output-adapter.d.ts +7 -0
  125. package/dist/runtime-fallback/interruption-output-adapter.js +91 -0
  126. package/dist/runtime-fallback/interruption-output-adapter.js.map +1 -0
  127. package/dist/runtime-fallback/subagent-429-controller-fixture.d.ts +105 -0
  128. package/dist/runtime-fallback/subagent-429-controller-fixture.js +116 -0
  129. package/dist/runtime-fallback/subagent-429-controller-fixture.js.map +1 -0
  130. package/dist/runtime-fallback/subagent-429-controller.d.ts +167 -0
  131. package/dist/runtime-fallback/subagent-429-controller.js +334 -0
  132. package/dist/runtime-fallback/subagent-429-controller.js.map +1 -0
  133. package/dist/runtime-fallback/subagent-429-policy.d.ts +13 -0
  134. package/dist/runtime-fallback/subagent-429-policy.js +37 -0
  135. package/dist/runtime-fallback/subagent-429-policy.js.map +1 -0
  136. package/dist/runtime-fallback/subagent-429-session.d.ts +48 -0
  137. package/dist/runtime-fallback/subagent-429-session.js +316 -0
  138. package/dist/runtime-fallback/subagent-429-session.js.map +1 -0
  139. package/dist/shared/opencode-events.d.ts +22 -0
  140. package/dist/shared/opencode-events.js +75 -0
  141. package/dist/shared/opencode-events.js.map +1 -0
  142. package/dist/shared/types.d.ts +12 -1
  143. package/package.json +1 -1
  144. package/plugins/deepwork/.codex-plugin/plugin.json +1 -1
  145. package/plugins/deepwork/README.md +3 -2
  146. package/plugins/deepwork/agents/dw-builder.toml +3 -3
  147. package/plugins/deepwork/agents/dw-clarifier.toml +2 -2
  148. package/plugins/deepwork/agents/dw-code-search.toml +2 -2
  149. package/plugins/deepwork/agents/dw-coding.toml +2 -2
  150. package/plugins/deepwork/agents/dw-complex.toml +2 -2
  151. package/plugins/deepwork/agents/dw-creative.toml +2 -2
  152. package/plugins/deepwork/agents/dw-deep.toml +3 -3
  153. package/plugins/deepwork/agents/dw-doc-search.toml +2 -2
  154. package/plugins/deepwork/agents/dw-documenting.toml +2 -2
  155. package/plugins/deepwork/agents/dw-explore.toml +2 -2
  156. package/plugins/deepwork/agents/dw-frontend.toml +2 -2
  157. package/plugins/deepwork/agents/dw-hard-reasoning.toml +2 -2
  158. package/plugins/deepwork/agents/dw-media-reader.toml +2 -2
  159. package/plugins/deepwork/agents/dw-normal-task.toml +2 -2
  160. package/plugins/deepwork/agents/dw-oracle-2nd.toml +8 -0
  161. package/plugins/deepwork/agents/dw-oracle.toml +3 -3
  162. package/plugins/deepwork/agents/dw-orchestrator.toml +2 -2
  163. package/plugins/deepwork/agents/dw-plan-critic.toml +2 -2
  164. package/plugins/deepwork/agents/dw-planner.toml +3 -3
  165. package/plugins/deepwork/agents/dw-quick.toml +2 -2
  166. package/plugins/deepwork/agents/dw-research.toml +2 -2
  167. package/plugins/deepwork/agents/dw-reviewer.toml +2 -2
  168. package/plugins/deepwork/dist/cli/shim.d.ts +4 -2
  169. package/plugins/deepwork/dist/cli/shim.js +26 -11
  170. package/plugins/deepwork/dist/cli/shim.js.map +1 -1
  171. package/plugins/deepwork/dist/shared/opencode-events.d.ts +22 -0
  172. package/plugins/deepwork/dist/shared/opencode-events.js +75 -0
  173. package/plugins/deepwork/dist/shared/opencode-events.js.map +1 -0
  174. package/plugins/deepwork/dist/shared/types.d.ts +12 -1
  175. package/plugins/deepwork/package.json +1 -1
  176. package/plugins/deepwork/skills/deepwork/SKILL.md +74 -58
  177. package/plugins/deepwork/skills/deepwork-requesting-code-review/SKILL.md +53 -27
  178. package/plugins/deepwork/skills/deepwork-requesting-code-review/code-reviewer.md +11 -7
  179. package/plugins/deepwork/skills/deepwork-subagent-driven-development/SKILL.md +34 -21
  180. package/plugins/deepwork/skills/deepwork-subagent-driven-development/implementer-prompt.md +10 -3
  181. package/prompts/codex/agents/clarifier.md +4 -0
  182. package/prompts/codex/agents/orchestrator.md +12 -2
  183. package/prompts/codex/agents/plan-critic.md +4 -0
  184. package/prompts/codex/agents/planner.md +15 -10
  185. package/prompts/codex/agents/reviewer.md +8 -2
  186. package/prompts/codex/deepwork/gpt-5.6.md +20 -37
  187. package/prompts/omo/agents/clarifier.md +4 -0
  188. package/prompts/omo/agents/orchestrator.md +11 -0
  189. package/prompts/omo/agents/plan-critic.md +4 -0
  190. package/prompts/omo/agents/planner.md +15 -3
  191. package/prompts/omo/agents/reviewer.md +8 -2
  192. package/prompts/omo/deepwork/gpt-5.6.md +20 -37
  193. package/prompts/v1/agents/clarifier.md +4 -0
  194. package/prompts/v1/agents/orchestrator.md +12 -2
  195. package/prompts/v1/agents/plan-critic.md +4 -0
  196. package/prompts/v1/agents/planner.md +15 -10
  197. package/prompts/v1/agents/reviewer.md +8 -2
  198. package/prompts/v1/deepwork/gpt-5.6.md +20 -37
  199. package/skills/v1/requesting-code-review/SKILL.md +53 -27
  200. package/skills/v1/requesting-code-review/code-reviewer.md +11 -7
  201. package/skills/v1/subagent-driven-development/SKILL.md +34 -21
  202. package/skills/v1/subagent-driven-development/implementer-prompt.md +10 -3
@@ -8,9 +8,11 @@ import type { FallbackEntry, ModelRequirement } from "../shared/types.ts";
8
8
  export type FallbackState = {
9
9
  /** The model that originally failed (providerID/modelID). */
10
10
  originalModel: string;
11
+ /** Effective-route snapshot that selected this state machine. */
12
+ snapshotId: number;
11
13
  /** Index into the fallback chain we're currently on (0 = primary). */
12
14
  fallbackIndex: number;
13
- /** Count of fallback attempts dispatched this session. */
15
+ /** Count of committed model switches this session (same-model retries do not count). */
14
16
  attempts: number;
15
17
  /** Map of "providerID/modelID" -> epoch-ms of last failure. */
16
18
  failedModels: Map<string, number>;
@@ -18,7 +20,8 @@ export type FallbackState = {
18
20
  * Used as the failed-model key when an error event carries no model info. */
19
21
  activeModel?: string;
20
22
  };
21
- export declare function createFallbackState(originalModel: string): FallbackState;
23
+ export type FallbackCandidateBlocker = (entry: FallbackEntry) => boolean;
24
+ export declare function createFallbackState(originalModel: string, snapshotId: number): FallbackState;
22
25
  export declare function modelKey(providerID: string, modelID: string): string;
23
26
  export declare function markModelFailed(state: FallbackState, modelKey: string, now?: number): void;
24
27
  export declare function isModelInCooldown(modelKey: string, state: FallbackState, cooldownSeconds: number, now?: number): boolean;
@@ -29,7 +32,7 @@ export declare function isModelInCooldown(modelKey: string, state: FallbackState
29
32
  * unless explicitly included elsewhere). Skips entries whose model is in
30
33
  * cooldown and entries equivalent to the just-failed model.
31
34
  */
32
- export declare function findNextAvailableFallback(state: FallbackState, chain: FallbackEntry[], cooldownSeconds: number, justFailedModelKey: string, now?: number): {
35
+ export declare function findNextAvailableFallback(state: FallbackState, chain: FallbackEntry[], cooldownSeconds: number, justFailedModelKey: string, now?: number, isCandidateBlocked?: FallbackCandidateBlocker): {
33
36
  entry: FallbackEntry;
34
37
  index: number;
35
38
  } | null;
@@ -49,7 +52,7 @@ export type PeekResult = {
49
52
  * After a successful dispatch, call {@link commitFallback} to advance
50
53
  * the state machine.
51
54
  */
52
- export declare function peekNextFallback(state: FallbackState, requirement: ModelRequirement | null, justFailedModelKey: string, maxAttempts: number, cooldownSeconds: number, now?: number): PeekResult;
55
+ export declare function peekNextFallback(state: FallbackState, requirement: ModelRequirement | null, justFailedModelKey: string, maxAttempts: number, cooldownSeconds: number, now?: number, isCandidateBlocked?: FallbackCandidateBlocker): PeekResult;
53
56
  /**
54
57
  * Commit a fallback entry to the state machine after a successful dispatch.
55
58
  *
@@ -58,7 +61,7 @@ export declare function peekNextFallback(state: FallbackState, requirement: Mode
58
61
  */
59
62
  export declare function commitFallback(state: FallbackState, entry: FallbackEntry, index: number): void;
60
63
  /** @deprecated Use {@link peekNextFallback} + {@link commitFallback} instead. */
61
- export declare function prepareFallback(state: FallbackState, requirement: ModelRequirement | null, justFailedModelKey: string, maxAttempts: number, cooldownSeconds: number, now?: number): {
64
+ export declare function prepareFallback(state: FallbackState, requirement: ModelRequirement | null, justFailedModelKey: string, maxAttempts: number, cooldownSeconds: number, now?: number, isCandidateBlocked?: FallbackCandidateBlocker): {
62
65
  ok: true;
63
66
  entry: FallbackEntry;
64
67
  index: number;
@@ -1,6 +1,7 @@
1
- export function createFallbackState(originalModel) {
1
+ export function createFallbackState(originalModel, snapshotId) {
2
2
  return {
3
3
  originalModel,
4
+ snapshotId,
4
5
  fallbackIndex: 0,
5
6
  attempts: 0,
6
7
  failedModels: new Map(),
@@ -25,7 +26,7 @@ export function isModelInCooldown(modelKey, state, cooldownSeconds, now = Date.n
25
26
  * unless explicitly included elsewhere). Skips entries whose model is in
26
27
  * cooldown and entries equivalent to the just-failed model.
27
28
  */
28
- export function findNextAvailableFallback(state, chain, cooldownSeconds, justFailedModelKey, now = Date.now()) {
29
+ export function findNextAvailableFallback(state, chain, cooldownSeconds, justFailedModelKey, now = Date.now(), isCandidateBlocked = () => false) {
29
30
  for (let i = state.fallbackIndex + 1; i < chain.length; i++) {
30
31
  const entry = chain[i];
31
32
  if (!entry)
@@ -36,6 +37,8 @@ export function findNextAvailableFallback(state, chain, cooldownSeconds, justFai
36
37
  continue;
37
38
  if (isModelInCooldown(key, state, cooldownSeconds, now))
38
39
  continue;
40
+ if (isCandidateBlocked(entry))
41
+ continue;
39
42
  return { entry, index: i };
40
43
  }
41
44
  return null;
@@ -47,14 +50,14 @@ export function findNextAvailableFallback(state, chain, cooldownSeconds, justFai
47
50
  * After a successful dispatch, call {@link commitFallback} to advance
48
51
  * the state machine.
49
52
  */
50
- export function peekNextFallback(state, requirement, justFailedModelKey, maxAttempts, cooldownSeconds, now = Date.now()) {
53
+ export function peekNextFallback(state, requirement, justFailedModelKey, maxAttempts, cooldownSeconds, now = Date.now(), isCandidateBlocked = () => false) {
51
54
  if (state.attempts >= maxAttempts) {
52
55
  return { ok: false, reason: "max-attempts" };
53
56
  }
54
57
  if (!requirement || requirement.fallbackChain.length === 0) {
55
58
  return { ok: false, reason: "no-fallback-chain" };
56
59
  }
57
- const next = findNextAvailableFallback(state, requirement.fallbackChain, cooldownSeconds, justFailedModelKey, now);
60
+ const next = findNextAvailableFallback(state, requirement.fallbackChain, cooldownSeconds, justFailedModelKey, now, isCandidateBlocked);
58
61
  if (!next) {
59
62
  return { ok: false, reason: "no-next-model" };
60
63
  }
@@ -72,14 +75,14 @@ export function commitFallback(state, entry, index) {
72
75
  state.activeModel = modelKey(entry.providers[0] ?? "", entry.model);
73
76
  }
74
77
  /** @deprecated Use {@link peekNextFallback} + {@link commitFallback} instead. */
75
- export function prepareFallback(state, requirement, justFailedModelKey, maxAttempts, cooldownSeconds, now = Date.now()) {
78
+ export function prepareFallback(state, requirement, justFailedModelKey, maxAttempts, cooldownSeconds, now = Date.now(), isCandidateBlocked = () => false) {
76
79
  if (state.attempts >= maxAttempts) {
77
80
  return { ok: false, reason: "max-attempts" };
78
81
  }
79
82
  if (!requirement || requirement.fallbackChain.length === 0) {
80
83
  return { ok: false, reason: "no-fallback-chain" };
81
84
  }
82
- const next = findNextAvailableFallback(state, requirement.fallbackChain, cooldownSeconds, justFailedModelKey, now);
85
+ const next = findNextAvailableFallback(state, requirement.fallbackChain, cooldownSeconds, justFailedModelKey, now, isCandidateBlocked);
83
86
  if (!next) {
84
87
  return { ok: false, reason: "no-next-model" };
85
88
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fallback-state.js","sourceRoot":"","sources":["../../src/runtime-fallback/fallback-state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fallback-state.js","sourceRoot":"","sources":["../../src/runtime-fallback/fallback-state.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,24 @@
1
1
  export { classifyError, extractErrorName, extractStatusCode, type ErrorClassification, } from "./error-classifier.ts";
2
2
  export { createFallbackState, findNextAvailableFallback, isModelInCooldown, markModelFailed, modelKey, peekNextFallback, commitFallback, prepareFallback, type FallbackState, type PeekResult, } from "./fallback-state.ts";
3
3
  export { dispatchFallbackRetry, isDispatchInFlight, type DispatchArgs, type OcmmClient, } from "./dispatcher.ts";
4
- export { createRuntimeFallbackEventHandler } from "./event-handler.ts";
4
+ import { type RuntimeFallbackRuntime } from "./event-handler.ts";
5
+ import type { OcmmConfig } from "../config/schema.ts";
6
+ import type { EffectiveRouteRegistry } from "../routing/route-registry.ts";
7
+ import type { OcmmClient } from "./dispatcher.ts";
8
+ import type { IdleContinuationState } from "./idle-state.ts";
9
+ import type { Subagent429Scheduler } from "./subagent-429-controller.ts";
10
+ export type { RuntimeFallbackRuntime } from "./event-handler.ts";
11
+ /** Public runtime contract: failed-model lookup is always route-snapshot based. */
12
+ export type RuntimeFallbackDeps = {
13
+ getConfig: () => OcmmConfig;
14
+ client?: OcmmClient;
15
+ directory?: string;
16
+ idleState?: IdleContinuationState;
17
+ clearSessionIntent?: (sessionID: string) => void;
18
+ routeRegistry?: EffectiveRouteRegistry;
19
+ scheduler?: Subagent429Scheduler;
20
+ clock?: () => number;
21
+ random?: () => number;
22
+ };
23
+ export declare function createRuntimeFallbackRuntime(deps: RuntimeFallbackDeps): RuntimeFallbackRuntime;
24
+ export declare function createRuntimeFallbackEventHandler(deps: RuntimeFallbackDeps): (input: unknown) => Promise<void>;
@@ -1,5 +1,11 @@
1
1
  export { classifyError, extractErrorName, extractStatusCode, } from "./error-classifier.js";
2
2
  export { createFallbackState, findNextAvailableFallback, isModelInCooldown, markModelFailed, modelKey, peekNextFallback, commitFallback, prepareFallback, } from "./fallback-state.js";
3
3
  export { dispatchFallbackRetry, isDispatchInFlight, } from "./dispatcher.js";
4
- export { createRuntimeFallbackEventHandler } from "./event-handler.js";
4
+ import { createRuntimeFallbackRuntime as createRuntimeFallbackRuntimeInternal, createRuntimeFallbackEventHandler as createRuntimeFallbackEventHandlerInternal, } from "./event-handler.js";
5
+ export function createRuntimeFallbackRuntime(deps) {
6
+ return createRuntimeFallbackRuntimeInternal(deps);
7
+ }
8
+ export function createRuntimeFallbackEventHandler(deps) {
9
+ return createRuntimeFallbackEventHandlerInternal(deps);
10
+ }
5
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime-fallback/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,eAAe,GAGhB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GAGnB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime-fallback/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,eAAe,GAGhB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GAGnB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,4BAA4B,IAAI,oCAAoC,EACpE,iCAAiC,IAAI,yCAAyC,GAE/E,MAAM,oBAAoB,CAAA;AAsB3B,MAAM,UAAU,4BAA4B,CAAC,IAAyB;IACpE,OAAO,oCAAoC,CAAC,IAAI,CAAC,CAAA;AACnD,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,IAAyB;IACzE,OAAO,yCAAyC,CAAC,IAAI,CAAC,CAAA;AACxD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { OcmmConfig } from "../config/schema.ts";
2
+ import type { Subagent429Controller } from "./subagent-429-controller.ts";
3
+ export declare const SUBAGENT_CONTINUATION_NOTICE_PREFIX = "[Subagent interruption recovery]";
4
+ export declare function createSubagentInterruptionOutputAdapter(args: {
5
+ getConfig: () => OcmmConfig;
6
+ controller: Pick<Subagent429Controller, "getInterruptionCorrelation" | "claimInterruptionNotice">;
7
+ }): (input: unknown, output: unknown) => Promise<void>;
@@ -0,0 +1,91 @@
1
+ import { isRecord } from "../shared/logger.js";
2
+ export const SUBAGENT_CONTINUATION_NOTICE_PREFIX = "[Subagent interruption recovery]";
3
+ const INTERRUPTION = /tool execution (?:was )?(?:aborted|interrupted)|transport (?:closed|interrupted)|connection (?:closed|reset)|request aborted|request interrupted/i;
4
+ const EXCLUDED = /permission (?:denied|rejected)|unknown agent(?: type)?/i;
5
+ function text(value, keys) {
6
+ if (!isRecord(value))
7
+ return undefined;
8
+ for (const key of keys) {
9
+ const found = value[key];
10
+ if (typeof found === "string" && found.length > 0)
11
+ return found;
12
+ }
13
+ return undefined;
14
+ }
15
+ function bodyTaskID(outputText) {
16
+ const match = /\btask_id\s*(?::=|[:=])\s*["']?([A-Za-z0-9._:-]+)/i.exec(outputText);
17
+ return match?.[1];
18
+ }
19
+ function toolName(input) {
20
+ if (!isRecord(input))
21
+ return "";
22
+ const direct = text(input, ["tool", "toolName", "toolID", "toolId", "name"]);
23
+ if (direct)
24
+ return direct.toLowerCase();
25
+ if (isRecord(input.tool)) {
26
+ const nested = text(input.tool, ["name", "id", "key"]);
27
+ if (nested)
28
+ return nested.toLowerCase();
29
+ }
30
+ return "";
31
+ }
32
+ function taskEvidence(input, output) {
33
+ const metadata = isRecord(output.metadata) ? output.metadata : undefined;
34
+ const args = isRecord(input) && isRecord(input.args) ? input.args : undefined;
35
+ const outputText = typeof output.output === "string" ? output.output : "";
36
+ const childSessionID = text(metadata, ["sessionId", "sessionID"]);
37
+ const taskID = text(metadata, ["task_id", "taskID", "taskId"])
38
+ ?? text(output, ["task_id", "taskID", "taskId"])
39
+ ?? text(args, ["task_id", "taskID", "taskId"])
40
+ ?? bodyTaskID(outputText);
41
+ return {
42
+ ...(childSessionID ? { childSessionID } : {}),
43
+ ...(taskID ? { taskID } : {}),
44
+ };
45
+ }
46
+ export function createSubagentInterruptionOutputAdapter(args) {
47
+ return async (input, rawOutput) => {
48
+ const config = args.getConfig();
49
+ if (config.disabledHooks?.includes("subagent-interruption-recovery"))
50
+ return;
51
+ if (toolName(input) !== "task")
52
+ return;
53
+ if (!isRecord(rawOutput) || typeof rawOutput.output !== "string")
54
+ return;
55
+ const original = rawOutput.output;
56
+ if (!original.trim())
57
+ return;
58
+ if (!INTERRUPTION.test(original))
59
+ return;
60
+ if (EXCLUDED.test(original))
61
+ return;
62
+ if (original.includes(SUBAGENT_CONTINUATION_NOTICE_PREFIX))
63
+ return;
64
+ const evidence = taskEvidence(input, rawOutput);
65
+ const parentSessionID = text(input, ["sessionID", "sessionId", "session_id"]);
66
+ const lookup = {
67
+ ...(evidence.childSessionID ? { childSessionID: evidence.childSessionID } : {}),
68
+ ...(parentSessionID ? { parentSessionID } : {}),
69
+ ...(evidence.taskID ? { taskID: evidence.taskID } : {}),
70
+ };
71
+ const correlation = args.controller.getInterruptionCorrelation(lookup);
72
+ if (!correlation)
73
+ return;
74
+ if (correlation.explicitlyAborted)
75
+ return;
76
+ const resumableTaskID = evidence.taskID ?? correlation.taskID;
77
+ if (!resumableTaskID)
78
+ return;
79
+ if (!args.controller.claimInterruptionNotice({
80
+ ...lookup,
81
+ taskID: resumableTaskID,
82
+ })) {
83
+ return;
84
+ }
85
+ rawOutput.output = `${original}\n\n${SUBAGENT_CONTINUATION_NOTICE_PREFIX}\n` +
86
+ `The task output exposed resumable task identifier "${resumableTaskID}". ` +
87
+ "Preserve that exact value for a manual continuation through the task tool's task_id field. " +
88
+ "This output adapter did not dispatch, create a child, or prompt the parent session.";
89
+ };
90
+ }
91
+ //# sourceMappingURL=interruption-output-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interruption-output-adapter.js","sourceRoot":"","sources":["../../src/runtime-fallback/interruption-output-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ import type { RuntimeFallbackConfig } from "../config/schema.ts";
2
+ import type { FallbackCandidateBlocker } from "./fallback-state.ts";
3
+ import { type Subagent429Controller, type Subagent429DispatchInput, type Subagent429PreparedSwitch, type Subagent429OtherErrorInput, type Subagent429Scheduler, type Subagent429Target } from "./subagent-429-controller.ts";
4
+ export type ScheduledTask = {
5
+ delayMs: number;
6
+ run: () => Promise<void>;
7
+ cancelled: boolean;
8
+ };
9
+ export declare class FakeScheduler implements Subagent429Scheduler {
10
+ readonly tasks: ScheduledTask[];
11
+ schedule(delayMs: number, run: () => Promise<void>): () => void;
12
+ run(index: number, includeCancelled?: boolean): Promise<void>;
13
+ }
14
+ export declare function deferred<T>(): {
15
+ promise: Promise<T>;
16
+ resolve: (value: T) => void;
17
+ };
18
+ export declare function flush(): Promise<void>;
19
+ export declare function target(providerID?: string, modelID?: string): Subagent429Target;
20
+ export declare function runtimeConfig(overrides?: Partial<RuntimeFallbackConfig>): RuntimeFallbackConfig;
21
+ export declare function input(sessionID: string, options?: Partial<Omit<Subagent429DispatchInput, "sessionID" | "target" | "reason" | "snapshotId">> & {
22
+ target?: Subagent429Target;
23
+ reason?: string;
24
+ snapshotId?: number;
25
+ }): {
26
+ agent?: string | undefined;
27
+ sessionID: string;
28
+ snapshotId: number;
29
+ target: Subagent429Target;
30
+ reason: string;
31
+ };
32
+ export declare function errorInput(sessionID: string, options?: {
33
+ target?: Subagent429Target;
34
+ config?: RuntimeFallbackConfig;
35
+ recoveryDelayMs?: number;
36
+ snapshotId?: number;
37
+ prepareSwitch?: (failedTarget: Subagent429Target, blocker: FallbackCandidateBlocker) => {
38
+ ok: true;
39
+ prepared: Subagent429PreparedSwitch;
40
+ } | {
41
+ ok: false;
42
+ reason: "max-attempts" | "no-fallback-chain" | "no-next-model" | "dispatch-failed";
43
+ };
44
+ }): {
45
+ classification: {
46
+ recoveryDelayMs?: number | undefined;
47
+ reason: string;
48
+ };
49
+ runtimeConfig: {
50
+ enabled: boolean;
51
+ dispatch: boolean;
52
+ maxAttempts: number;
53
+ cooldownSeconds: number;
54
+ retryOnStatusCodes: number[];
55
+ retryOnPatterns: string[];
56
+ subagent429: {
57
+ enabled: boolean;
58
+ maxRetries: number;
59
+ providerScopes: Record<string, "model" | "provider">;
60
+ };
61
+ };
62
+ prepareSwitch: (failedTarget: Subagent429Target, blocker: FallbackCandidateBlocker) => {
63
+ ok: false;
64
+ reason: "max-attempts" | "no-fallback-chain" | "no-next-model" | "dispatch-failed";
65
+ } | {
66
+ ok: true;
67
+ prepared: {
68
+ snapshotId: number;
69
+ target: Subagent429Target;
70
+ attempt: number;
71
+ commit: () => void;
72
+ };
73
+ };
74
+ agent?: string | undefined;
75
+ sessionID: string;
76
+ snapshotId: number;
77
+ target: Subagent429Target;
78
+ reason: string;
79
+ };
80
+ type HarnessController = Omit<Subagent429Controller, "onSessionCreated" | "onIdle" | "getActiveDispatchTarget" | "onOtherError"> & {
81
+ onSessionCreated(sessionID: string, isChild: boolean, snapshotId?: number): void;
82
+ onIdle(sessionID: string, snapshotId?: number): ReturnType<Subagent429Controller["onIdle"]>;
83
+ getActiveDispatchTarget(sessionID: string, snapshotId?: number): ReturnType<Subagent429Controller["getActiveDispatchTarget"]>;
84
+ onOtherError(input: Omit<Subagent429OtherErrorInput, "snapshotId"> & {
85
+ snapshotId?: number;
86
+ }): ReturnType<Subagent429Controller["onOtherError"]>;
87
+ };
88
+ export type Harness = {
89
+ scheduler: FakeScheduler;
90
+ dispatches: Subagent429DispatchInput[];
91
+ controller: HarnessController;
92
+ currentSnapshotId: number;
93
+ isCurrentSnapshot: (snapshotId: number) => boolean;
94
+ };
95
+ export declare function createHarness(options?: {
96
+ now?: number;
97
+ random?: number;
98
+ currentSnapshotId?: number;
99
+ dispatchRetry?: (dispatch: Subagent429DispatchInput) => Promise<boolean>;
100
+ }): Harness;
101
+ export declare function idle(kind: string, suppressIdleContinuation: boolean): {
102
+ kind: string;
103
+ suppressIdleContinuation: boolean;
104
+ };
105
+ export {};
@@ -0,0 +1,116 @@
1
+ import assert from "node:assert/strict";
2
+ import { defaultConfig } from "../config/schema.js";
3
+ import { createSubagent429Controller, } from "./subagent-429-controller.js";
4
+ export class FakeScheduler {
5
+ tasks = [];
6
+ schedule(delayMs, run) {
7
+ const task = { delayMs, run, cancelled: false };
8
+ this.tasks.push(task);
9
+ return () => {
10
+ task.cancelled = true;
11
+ };
12
+ }
13
+ async run(index, includeCancelled = false) {
14
+ const task = this.tasks[index];
15
+ assert.ok(task);
16
+ if (!task.cancelled || includeCancelled)
17
+ await task.run();
18
+ }
19
+ }
20
+ export function deferred() {
21
+ let resolve;
22
+ const promise = new Promise((resolvePromise) => {
23
+ resolve = resolvePromise;
24
+ });
25
+ return { promise, resolve };
26
+ }
27
+ export async function flush() {
28
+ await new Promise((resolve) => setImmediate(resolve));
29
+ }
30
+ export function target(providerID = "provider-a", modelID = "model-a") {
31
+ return { providerID, modelID, entry: { providers: [providerID], model: modelID } };
32
+ }
33
+ export function runtimeConfig(overrides = {}) {
34
+ const base = defaultConfig().runtimeFallback;
35
+ return {
36
+ ...base,
37
+ ...overrides,
38
+ subagent429: {
39
+ ...base.subagent429,
40
+ ...overrides.subagent429,
41
+ },
42
+ };
43
+ }
44
+ export function input(sessionID, options = {}) {
45
+ return {
46
+ sessionID,
47
+ snapshotId: options.snapshotId ?? 0,
48
+ target: options.target ?? target(),
49
+ reason: options.reason ?? "status 429",
50
+ ...(options.agent === undefined ? {} : { agent: options.agent }),
51
+ };
52
+ }
53
+ export function errorInput(sessionID, options = {}) {
54
+ const snapshotId = options.snapshotId ?? 0;
55
+ const prepareSwitch = options.prepareSwitch ??
56
+ (() => ({ ok: false, reason: "no-next-model" }));
57
+ return {
58
+ ...input(sessionID, { target: options.target, snapshotId }),
59
+ classification: {
60
+ reason: "status 429",
61
+ ...(options.recoveryDelayMs === undefined ? {} : { recoveryDelayMs: options.recoveryDelayMs }),
62
+ },
63
+ runtimeConfig: options.config ?? runtimeConfig(),
64
+ prepareSwitch: (failedTarget, blocker) => {
65
+ const result = prepareSwitch(failedTarget, blocker);
66
+ if (!result.ok)
67
+ return result;
68
+ return {
69
+ ok: true,
70
+ prepared: {
71
+ ...result.prepared,
72
+ snapshotId: result.prepared.snapshotId ?? snapshotId,
73
+ },
74
+ };
75
+ },
76
+ };
77
+ }
78
+ export function createHarness(options = {}) {
79
+ const scheduler = new FakeScheduler();
80
+ const dispatches = [];
81
+ let currentSnapshotId = options.currentSnapshotId ?? 0;
82
+ const deps = {
83
+ scheduler,
84
+ clock: () => options.now ?? 1_000_000,
85
+ random: () => options.random ?? 0,
86
+ isCurrentSnapshot: (snapshotId) => snapshotId === currentSnapshotId,
87
+ ...(options.dispatchRetry === undefined
88
+ ? {}
89
+ : {
90
+ dispatchRetry: async (dispatch) => {
91
+ dispatches.push(dispatch);
92
+ return options.dispatchRetry(dispatch);
93
+ },
94
+ }),
95
+ };
96
+ const actualController = createSubagent429Controller(deps);
97
+ const controller = {
98
+ ...actualController,
99
+ onSessionCreated: (sessionID, isChild, snapshotId = 0) => actualController.onSessionCreated(sessionID, isChild, snapshotId),
100
+ onIdle: (sessionID, snapshotId = 0) => actualController.onIdle(sessionID, snapshotId),
101
+ getActiveDispatchTarget: (sessionID, snapshotId = 0) => actualController.getActiveDispatchTarget(sessionID, snapshotId),
102
+ onOtherError: (input) => actualController.onOtherError({ ...input, snapshotId: input.snapshotId ?? 0 }),
103
+ };
104
+ return {
105
+ scheduler,
106
+ dispatches,
107
+ controller,
108
+ get currentSnapshotId() { return currentSnapshotId; },
109
+ set currentSnapshotId(snapshotId) { currentSnapshotId = snapshotId; },
110
+ isCurrentSnapshot: (snapshotId) => snapshotId === currentSnapshotId,
111
+ };
112
+ }
113
+ export function idle(kind, suppressIdleContinuation) {
114
+ return { kind, suppressIdleContinuation };
115
+ }
116
+ //# sourceMappingURL=subagent-429-controller-fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-429-controller-fixture.js","sourceRoot":"","sources":["../../src/runtime-fallback/subagent-429-controller-fixture.ts"],"names":[],"mappings":"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"}