agent-bober 0.15.0 → 0.17.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 (301) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/CHANGELOG.md +30 -0
  4. package/README.md +127 -3
  5. package/agents/bober-architect.md +34 -0
  6. package/agents/bober-code-reviewer.md +2 -0
  7. package/agents/bober-curator.md +12 -0
  8. package/agents/bober-documenter.md +129 -0
  9. package/agents/bober-evaluator.md +46 -0
  10. package/agents/bober-generator.md +12 -0
  11. package/agents/bober-planner.md +8 -1
  12. package/dist/cli/commands/graph.js +3 -3
  13. package/dist/cli/commands/graph.js.map +1 -1
  14. package/dist/cli/commands/init.js +4 -0
  15. package/dist/cli/commands/init.js.map +1 -1
  16. package/dist/cli/commands/memory.d.ts +14 -0
  17. package/dist/cli/commands/memory.d.ts.map +1 -0
  18. package/dist/cli/commands/memory.js +132 -0
  19. package/dist/cli/commands/memory.js.map +1 -0
  20. package/dist/cli/index.js +6 -0
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/config/defaults.d.ts.map +1 -1
  23. package/dist/config/defaults.js +14 -3
  24. package/dist/config/defaults.js.map +1 -1
  25. package/dist/config/loader.d.ts.map +1 -1
  26. package/dist/config/loader.js +7 -0
  27. package/dist/config/loader.js.map +1 -1
  28. package/dist/config/role-providers.d.ts +29 -0
  29. package/dist/config/role-providers.d.ts.map +1 -0
  30. package/dist/config/role-providers.js +115 -0
  31. package/dist/config/role-providers.js.map +1 -0
  32. package/dist/config/schema.d.ts +383 -14
  33. package/dist/config/schema.d.ts.map +1 -1
  34. package/dist/config/schema.js +42 -0
  35. package/dist/config/schema.js.map +1 -1
  36. package/dist/contracts/eval-result.d.ts +112 -56
  37. package/dist/contracts/eval-result.d.ts.map +1 -1
  38. package/dist/contracts/eval-result.js +3 -0
  39. package/dist/contracts/eval-result.js.map +1 -1
  40. package/dist/contracts/sprint-contract.d.ts +30 -30
  41. package/dist/fleet/aggregator.d.ts +5 -0
  42. package/dist/fleet/aggregator.d.ts.map +1 -0
  43. package/dist/fleet/aggregator.js +39 -0
  44. package/dist/fleet/aggregator.js.map +1 -0
  45. package/dist/fleet/child-config.d.ts +12 -0
  46. package/dist/fleet/child-config.d.ts.map +1 -0
  47. package/dist/fleet/child-config.js +38 -0
  48. package/dist/fleet/child-config.js.map +1 -0
  49. package/dist/fleet/coordinator.d.ts +25 -0
  50. package/dist/fleet/coordinator.d.ts.map +1 -0
  51. package/dist/fleet/coordinator.js +40 -0
  52. package/dist/fleet/coordinator.js.map +1 -0
  53. package/dist/fleet/index.d.ts +40 -0
  54. package/dist/fleet/index.d.ts.map +1 -0
  55. package/dist/fleet/index.js +117 -0
  56. package/dist/fleet/index.js.map +1 -0
  57. package/dist/fleet/manifest.d.ts +51 -0
  58. package/dist/fleet/manifest.d.ts.map +1 -0
  59. package/dist/fleet/manifest.js +32 -0
  60. package/dist/fleet/manifest.js.map +1 -0
  61. package/dist/fleet/reporter.d.ts +32 -0
  62. package/dist/fleet/reporter.d.ts.map +1 -0
  63. package/dist/fleet/reporter.js +71 -0
  64. package/dist/fleet/reporter.js.map +1 -0
  65. package/dist/fleet/runner.d.ts +48 -0
  66. package/dist/fleet/runner.d.ts.map +1 -0
  67. package/dist/fleet/runner.js +104 -0
  68. package/dist/fleet/runner.js.map +1 -0
  69. package/dist/fleet/scaffolder.d.ts +12 -0
  70. package/dist/fleet/scaffolder.d.ts.map +1 -0
  71. package/dist/fleet/scaffolder.js +82 -0
  72. package/dist/fleet/scaffolder.js.map +1 -0
  73. package/dist/fleet/types.d.ts +21 -0
  74. package/dist/fleet/types.d.ts.map +1 -0
  75. package/dist/fleet/types.js +2 -0
  76. package/dist/fleet/types.js.map +1 -0
  77. package/dist/graph/cli.d.ts +6 -2
  78. package/dist/graph/cli.d.ts.map +1 -1
  79. package/dist/graph/cli.js +53 -12
  80. package/dist/graph/cli.js.map +1 -1
  81. package/dist/graph/pipeline-lifecycle.d.ts +9 -0
  82. package/dist/graph/pipeline-lifecycle.d.ts.map +1 -1
  83. package/dist/graph/pipeline-lifecycle.js +12 -0
  84. package/dist/graph/pipeline-lifecycle.js.map +1 -1
  85. package/dist/graph/preflight-injector.d.ts +14 -0
  86. package/dist/graph/preflight-injector.d.ts.map +1 -1
  87. package/dist/graph/preflight-injector.js +84 -4
  88. package/dist/graph/preflight-injector.js.map +1 -1
  89. package/dist/incident/types.d.ts +24 -24
  90. package/dist/mcp/tools/graph-schemas.d.ts +7 -7
  91. package/dist/mcp/tools/init.d.ts.map +1 -1
  92. package/dist/mcp/tools/init.js +2 -0
  93. package/dist/mcp/tools/init.js.map +1 -1
  94. package/dist/orchestrator/agent-loader.d.ts.map +1 -1
  95. package/dist/orchestrator/agent-loader.js +15 -1
  96. package/dist/orchestrator/agent-loader.js.map +1 -1
  97. package/dist/orchestrator/agentic-loop.d.ts +51 -0
  98. package/dist/orchestrator/agentic-loop.d.ts.map +1 -1
  99. package/dist/orchestrator/agentic-loop.js +123 -4
  100. package/dist/orchestrator/agentic-loop.js.map +1 -1
  101. package/dist/orchestrator/arch-lenses.d.ts +7 -0
  102. package/dist/orchestrator/arch-lenses.d.ts.map +1 -0
  103. package/dist/orchestrator/arch-lenses.js +22 -0
  104. package/dist/orchestrator/arch-lenses.js.map +1 -0
  105. package/dist/orchestrator/architect-agent.d.ts +16 -0
  106. package/dist/orchestrator/architect-agent.d.ts.map +1 -1
  107. package/dist/orchestrator/architect-agent.js +509 -1
  108. package/dist/orchestrator/architect-agent.js.map +1 -1
  109. package/dist/orchestrator/curator-agent.js +1 -1
  110. package/dist/orchestrator/curator-agent.js.map +1 -1
  111. package/dist/orchestrator/deploy/types.d.ts +2 -2
  112. package/dist/orchestrator/documenter-agent.d.ts +57 -0
  113. package/dist/orchestrator/documenter-agent.d.ts.map +1 -0
  114. package/dist/orchestrator/documenter-agent.js +195 -0
  115. package/dist/orchestrator/documenter-agent.js.map +1 -0
  116. package/dist/orchestrator/environment.d.ts +45 -0
  117. package/dist/orchestrator/environment.d.ts.map +1 -0
  118. package/dist/orchestrator/environment.js +151 -0
  119. package/dist/orchestrator/environment.js.map +1 -0
  120. package/dist/orchestrator/eval-lenses.d.ts +7 -0
  121. package/dist/orchestrator/eval-lenses.d.ts.map +1 -0
  122. package/dist/orchestrator/eval-lenses.js +19 -0
  123. package/dist/orchestrator/eval-lenses.js.map +1 -0
  124. package/dist/orchestrator/eval-persist.d.ts +25 -0
  125. package/dist/orchestrator/eval-persist.d.ts.map +1 -0
  126. package/dist/orchestrator/eval-persist.js +74 -0
  127. package/dist/orchestrator/eval-persist.js.map +1 -0
  128. package/dist/orchestrator/evaluator-agent.d.ts +23 -0
  129. package/dist/orchestrator/evaluator-agent.d.ts.map +1 -1
  130. package/dist/orchestrator/evaluator-agent.js +60 -3
  131. package/dist/orchestrator/evaluator-agent.js.map +1 -1
  132. package/dist/orchestrator/generator-agent.d.ts.map +1 -1
  133. package/dist/orchestrator/generator-agent.js +32 -0
  134. package/dist/orchestrator/generator-agent.js.map +1 -1
  135. package/dist/orchestrator/memory/distill.d.ts +60 -0
  136. package/dist/orchestrator/memory/distill.d.ts.map +1 -0
  137. package/dist/orchestrator/memory/distill.js +177 -0
  138. package/dist/orchestrator/memory/distill.js.map +1 -0
  139. package/dist/orchestrator/memory/eval-source.d.ts +20 -0
  140. package/dist/orchestrator/memory/eval-source.d.ts.map +1 -0
  141. package/dist/orchestrator/memory/eval-source.js +88 -0
  142. package/dist/orchestrator/memory/eval-source.js.map +1 -0
  143. package/dist/orchestrator/memory/retrieve.d.ts +45 -0
  144. package/dist/orchestrator/memory/retrieve.d.ts.map +1 -0
  145. package/dist/orchestrator/memory/retrieve.js +102 -0
  146. package/dist/orchestrator/memory/retrieve.js.map +1 -0
  147. package/dist/orchestrator/model-resolver.d.ts.map +1 -1
  148. package/dist/orchestrator/model-resolver.js +12 -0
  149. package/dist/orchestrator/model-resolver.js.map +1 -1
  150. package/dist/orchestrator/pipeline.d.ts +10 -0
  151. package/dist/orchestrator/pipeline.d.ts.map +1 -1
  152. package/dist/orchestrator/pipeline.js +111 -3
  153. package/dist/orchestrator/pipeline.js.map +1 -1
  154. package/dist/orchestrator/planner-agent.d.ts +22 -1
  155. package/dist/orchestrator/planner-agent.d.ts.map +1 -1
  156. package/dist/orchestrator/planner-agent.js +160 -4
  157. package/dist/orchestrator/planner-agent.js.map +1 -1
  158. package/dist/orchestrator/research-agent.js +2 -2
  159. package/dist/orchestrator/research-agent.js.map +1 -1
  160. package/dist/orchestrator/tools/handlers.d.ts +14 -0
  161. package/dist/orchestrator/tools/handlers.d.ts.map +1 -1
  162. package/dist/orchestrator/tools/handlers.js +29 -4
  163. package/dist/orchestrator/tools/handlers.js.map +1 -1
  164. package/dist/orchestrator/tools/schemas.js +5 -5
  165. package/dist/orchestrator/tools/schemas.js.map +1 -1
  166. package/dist/orchestrator/workflow/args-builder.d.ts +35 -0
  167. package/dist/orchestrator/workflow/args-builder.d.ts.map +1 -0
  168. package/dist/orchestrator/workflow/args-builder.js +142 -0
  169. package/dist/orchestrator/workflow/args-builder.js.map +1 -0
  170. package/dist/orchestrator/workflow/budget.d.ts +57 -0
  171. package/dist/orchestrator/workflow/budget.d.ts.map +1 -0
  172. package/dist/orchestrator/workflow/budget.js +80 -0
  173. package/dist/orchestrator/workflow/budget.js.map +1 -0
  174. package/dist/orchestrator/workflow/conformance.d.ts +27 -0
  175. package/dist/orchestrator/workflow/conformance.d.ts.map +1 -0
  176. package/dist/orchestrator/workflow/conformance.js +111 -0
  177. package/dist/orchestrator/workflow/conformance.js.map +1 -0
  178. package/dist/orchestrator/workflow/eligibility.d.ts +8 -0
  179. package/dist/orchestrator/workflow/eligibility.d.ts.map +1 -0
  180. package/dist/orchestrator/workflow/eligibility.js +10 -0
  181. package/dist/orchestrator/workflow/eligibility.js.map +1 -0
  182. package/dist/orchestrator/workflow/engine.d.ts +10 -0
  183. package/dist/orchestrator/workflow/engine.d.ts.map +1 -0
  184. package/dist/orchestrator/workflow/engine.js +2 -0
  185. package/dist/orchestrator/workflow/engine.js.map +1 -0
  186. package/dist/orchestrator/workflow/errors.d.ts +13 -0
  187. package/dist/orchestrator/workflow/errors.d.ts.map +1 -0
  188. package/dist/orchestrator/workflow/errors.js +26 -0
  189. package/dist/orchestrator/workflow/errors.js.map +1 -0
  190. package/dist/orchestrator/workflow/flusher.d.ts +19 -0
  191. package/dist/orchestrator/workflow/flusher.d.ts.map +1 -0
  192. package/dist/orchestrator/workflow/flusher.js +81 -0
  193. package/dist/orchestrator/workflow/flusher.js.map +1 -0
  194. package/dist/orchestrator/workflow/interpreter.d.ts +48 -0
  195. package/dist/orchestrator/workflow/interpreter.d.ts.map +1 -0
  196. package/dist/orchestrator/workflow/interpreter.js +92 -0
  197. package/dist/orchestrator/workflow/interpreter.js.map +1 -0
  198. package/dist/orchestrator/workflow/pure-sprint.d.ts +65 -0
  199. package/dist/orchestrator/workflow/pure-sprint.d.ts.map +1 -0
  200. package/dist/orchestrator/workflow/pure-sprint.js +82 -0
  201. package/dist/orchestrator/workflow/pure-sprint.js.map +1 -0
  202. package/dist/orchestrator/workflow/reconciler.d.ts +15 -0
  203. package/dist/orchestrator/workflow/reconciler.d.ts.map +1 -0
  204. package/dist/orchestrator/workflow/reconciler.js +65 -0
  205. package/dist/orchestrator/workflow/reconciler.js.map +1 -0
  206. package/dist/orchestrator/workflow/resume-cursor.d.ts +10 -0
  207. package/dist/orchestrator/workflow/resume-cursor.d.ts.map +1 -0
  208. package/dist/orchestrator/workflow/resume-cursor.js +25 -0
  209. package/dist/orchestrator/workflow/resume-cursor.js.map +1 -0
  210. package/dist/orchestrator/workflow/retry.d.ts +50 -0
  211. package/dist/orchestrator/workflow/retry.d.ts.map +1 -0
  212. package/dist/orchestrator/workflow/retry.js +100 -0
  213. package/dist/orchestrator/workflow/retry.js.map +1 -0
  214. package/dist/orchestrator/workflow/scheduler.d.ts +87 -0
  215. package/dist/orchestrator/workflow/scheduler.d.ts.map +1 -0
  216. package/dist/orchestrator/workflow/scheduler.js +158 -0
  217. package/dist/orchestrator/workflow/scheduler.js.map +1 -0
  218. package/dist/orchestrator/workflow/selector.d.ts +26 -0
  219. package/dist/orchestrator/workflow/selector.d.ts.map +1 -0
  220. package/dist/orchestrator/workflow/selector.js +54 -0
  221. package/dist/orchestrator/workflow/selector.js.map +1 -0
  222. package/dist/orchestrator/workflow/synthesizer.d.ts +52 -0
  223. package/dist/orchestrator/workflow/synthesizer.d.ts.map +1 -0
  224. package/dist/orchestrator/workflow/synthesizer.js +75 -0
  225. package/dist/orchestrator/workflow/synthesizer.js.map +1 -0
  226. package/dist/orchestrator/workflow/ts-engine.d.ts +13 -0
  227. package/dist/orchestrator/workflow/ts-engine.d.ts.map +1 -0
  228. package/dist/orchestrator/workflow/ts-engine.js +14 -0
  229. package/dist/orchestrator/workflow/ts-engine.js.map +1 -0
  230. package/dist/orchestrator/workflow/types.d.ts +55 -0
  231. package/dist/orchestrator/workflow/types.d.ts.map +1 -0
  232. package/dist/orchestrator/workflow/types.js +3 -0
  233. package/dist/orchestrator/workflow/types.js.map +1 -0
  234. package/dist/orchestrator/workflow/workflow-engine.d.ts +31 -0
  235. package/dist/orchestrator/workflow/workflow-engine.d.ts.map +1 -0
  236. package/dist/orchestrator/workflow/workflow-engine.js +70 -0
  237. package/dist/orchestrator/workflow/workflow-engine.js.map +1 -0
  238. package/dist/providers/anthropic.d.ts.map +1 -1
  239. package/dist/providers/anthropic.js +49 -6
  240. package/dist/providers/anthropic.js.map +1 -1
  241. package/dist/providers/claude-code.d.ts +44 -0
  242. package/dist/providers/claude-code.d.ts.map +1 -0
  243. package/dist/providers/claude-code.js +143 -0
  244. package/dist/providers/claude-code.js.map +1 -0
  245. package/dist/providers/factory.d.ts +16 -2
  246. package/dist/providers/factory.d.ts.map +1 -1
  247. package/dist/providers/factory.js +66 -12
  248. package/dist/providers/factory.js.map +1 -1
  249. package/dist/providers/google.d.ts.map +1 -1
  250. package/dist/providers/google.js +27 -3
  251. package/dist/providers/google.js.map +1 -1
  252. package/dist/providers/index.d.ts +3 -1
  253. package/dist/providers/index.d.ts.map +1 -1
  254. package/dist/providers/index.js +3 -1
  255. package/dist/providers/index.js.map +1 -1
  256. package/dist/providers/openai.d.ts.map +1 -1
  257. package/dist/providers/openai.js +24 -3
  258. package/dist/providers/openai.js.map +1 -1
  259. package/dist/providers/preflight.d.ts +22 -0
  260. package/dist/providers/preflight.d.ts.map +1 -0
  261. package/dist/providers/preflight.js +54 -0
  262. package/dist/providers/preflight.js.map +1 -0
  263. package/dist/providers/structured.d.ts +130 -0
  264. package/dist/providers/structured.d.ts.map +1 -0
  265. package/dist/providers/structured.js +205 -0
  266. package/dist/providers/structured.js.map +1 -0
  267. package/dist/providers/types.d.ts +28 -0
  268. package/dist/providers/types.d.ts.map +1 -1
  269. package/dist/state/history-rotation.d.ts +17 -0
  270. package/dist/state/history-rotation.d.ts.map +1 -0
  271. package/dist/state/history-rotation.js +84 -0
  272. package/dist/state/history-rotation.js.map +1 -0
  273. package/dist/state/history.d.ts +16 -4
  274. package/dist/state/history.d.ts.map +1 -1
  275. package/dist/state/history.js +62 -20
  276. package/dist/state/history.js.map +1 -1
  277. package/dist/state/index.d.ts +1 -1
  278. package/dist/state/index.d.ts.map +1 -1
  279. package/dist/state/index.js +1 -1
  280. package/dist/state/index.js.map +1 -1
  281. package/dist/state/memory.d.ts +60 -0
  282. package/dist/state/memory.d.ts.map +1 -0
  283. package/dist/state/memory.js +242 -0
  284. package/dist/state/memory.js.map +1 -0
  285. package/hooks/hooks.json +12 -2
  286. package/package.json +9 -5
  287. package/scripts/spike-claude-code-provider.mjs +66 -0
  288. package/scripts/spike-deepseek.mjs +63 -0
  289. package/scripts/sync-targets.json +12 -0
  290. package/scripts/update-all.mjs +255 -0
  291. package/skills/bober.architect/SKILL.md +13 -0
  292. package/skills/bober.architect/references/arch-lens-panel.md +126 -0
  293. package/skills/bober.eval/SKILL.md +9 -0
  294. package/skills/bober.eval/references/lens-panel.md +115 -0
  295. package/skills/bober.plan/SKILL.md +6 -0
  296. package/skills/bober.run/SKILL.md +23 -4
  297. package/skills/bober.run/references/lens-panel.md +115 -0
  298. package/skills/bober.sprint/SKILL.md +44 -2
  299. package/skills/bober.sprint/references/lens-panel.md +115 -0
  300. package/skills/shared/arch-lens-panel.md +126 -0
  301. package/skills/shared/lens-panel.md +115 -0
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Exponential-backoff retry for transient provider failures.
3
+ *
4
+ * Today the agentic loop ends on the first `client.chat()` error
5
+ * (agentic-loop.ts), which is fragile when hammering a single local model
6
+ * server (Ollama/vLLM return 429/503 under load). `withRetry` wraps a call in
7
+ * bounded exponential backoff with jitter, retrying only TRANSIENT failures
8
+ * (rate limits, overload, timeouts, network resets) and surfacing everything
9
+ * else immediately.
10
+ *
11
+ * The scheduler / interpreter wraps each provider call in this, so every
12
+ * provider benefits without per-adapter changes. `sleep` and `jitter` are
13
+ * injectable so tests are deterministic and instant.
14
+ */
15
+ // ── Transient classification ────────────────────────────────────────
16
+ function asRecord(err) {
17
+ return typeof err === "object" && err !== null
18
+ ? err
19
+ : undefined;
20
+ }
21
+ function getStatus(err) {
22
+ const e = asRecord(err);
23
+ if (!e)
24
+ return undefined;
25
+ const s = e["status"] ?? e["statusCode"];
26
+ return typeof s === "number" ? s : undefined;
27
+ }
28
+ function getCode(err) {
29
+ const e = asRecord(err);
30
+ const c = e?.["code"];
31
+ return typeof c === "string" ? c : undefined;
32
+ }
33
+ function getMessage(err) {
34
+ if (err instanceof Error)
35
+ return err.message;
36
+ const e = asRecord(err);
37
+ const m = e?.["message"];
38
+ return typeof m === "string" ? m : String(err);
39
+ }
40
+ const TRANSIENT_CODES = new Set([
41
+ "ETIMEDOUT",
42
+ "ECONNRESET",
43
+ "ECONNREFUSED",
44
+ "ENOTFOUND",
45
+ "EAI_AGAIN",
46
+ "EPIPE",
47
+ "ECONNABORTED",
48
+ ]);
49
+ const TRANSIENT_MESSAGE = /rate.?limit|too many requests|overloaded|overload|temporarily|try again|timed? ?out|service unavailable|ECONNRESET|ETIMEDOUT|\b(?:429|500|502|503|504|529)\b/i;
50
+ /**
51
+ * Heuristic: is this error worth retrying? True for HTTP 408/429 and 5xx,
52
+ * known transient network codes, and overload/rate-limit/timeout messages.
53
+ */
54
+ export function classifyTransient(err) {
55
+ const status = getStatus(err);
56
+ if (status !== undefined) {
57
+ if (status === 408 || status === 429)
58
+ return true;
59
+ if (status >= 500 && status < 600)
60
+ return true;
61
+ }
62
+ const code = getCode(err);
63
+ if (code && TRANSIENT_CODES.has(code))
64
+ return true;
65
+ return TRANSIENT_MESSAGE.test(getMessage(err));
66
+ }
67
+ const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
68
+ /**
69
+ * Run `fn`, retrying TRANSIENT failures with exponential backoff + jitter.
70
+ * Non-transient errors and the final exhausted error are rethrown.
71
+ *
72
+ * Backoff for retry `n` (0-based): `min(maxDelayMs, baseDelayMs * factor**n)`,
73
+ * then jittered to 50–100% of that value (decorrelated, avoids thundering herd).
74
+ */
75
+ export async function withRetry(fn, opts = {}) {
76
+ const maxRetries = opts.maxRetries ?? 3;
77
+ const baseDelayMs = opts.baseDelayMs ?? 500;
78
+ const maxDelayMs = opts.maxDelayMs ?? 30_000;
79
+ const factor = opts.factor ?? 2;
80
+ const jitter = opts.jitter ?? Math.random;
81
+ const sleep = opts.sleep ?? defaultSleep;
82
+ const isTransient = opts.isTransient ?? classifyTransient;
83
+ for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
84
+ try {
85
+ return await fn();
86
+ }
87
+ catch (error) {
88
+ if (attempt === maxRetries || !isTransient(error)) {
89
+ throw error;
90
+ }
91
+ const raw = Math.min(maxDelayMs, baseDelayMs * Math.pow(factor, attempt));
92
+ const delayMs = raw * (0.5 + 0.5 * jitter());
93
+ opts.onRetry?.({ attempt: attempt + 1, delayMs, error });
94
+ await sleep(delayMs);
95
+ }
96
+ }
97
+ // Unreachable: the loop either returns or throws on the final attempt.
98
+ throw new Error("withRetry: retry loop exited unexpectedly.");
99
+ }
100
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/orchestrator/workflow/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Concurrency scheduler for the local-model workflow runtime.
3
+ *
4
+ * Mirrors the execution model of Claude Code's dynamic-workflow runtime:
5
+ * - `parallel(thunks)` — barrier; runs all thunks with bounded concurrency
6
+ * and awaits them all (order-preserving). Use for lens panels / N skeptics.
7
+ * - `pipeline(items, ...stages)` — per-item, NO barrier between stages; each
8
+ * item flows through every stage independently, so item A can be in stage 3
9
+ * while item B is still in stage 1. Total concurrent stage executions are
10
+ * bounded by the same cap.
11
+ *
12
+ * Concurrency is enforced by a hand-off semaphore (true bounded concurrency,
13
+ * unlike chunk-batching which idles fast tasks waiting on a slow one). A live
14
+ * agent counter caps total executions over the scheduler's lifetime (the
15
+ * runaway guard — Claude Code uses 1000/run).
16
+ */
17
+ /** Raised when a scheduler exceeds its lifetime agent-execution cap. */
18
+ export declare class AgentCapError extends Error {
19
+ /** The cap that was hit. */
20
+ readonly cap: number;
21
+ constructor(message: string,
22
+ /** The cap that was hit. */
23
+ cap: number);
24
+ }
25
+ /**
26
+ * The default concurrency cap: `min(16, cores - 2)`, floored at 1. Matches the
27
+ * Claude Code dynamic-workflow runtime. For local model servers the real bound
28
+ * is usually the server's slot count (e.g. Ollama's OLLAMA_NUM_PARALLEL), so
29
+ * callers should override `maxConcurrent` to match their backend.
30
+ */
31
+ export declare function defaultConcurrency(): number;
32
+ /**
33
+ * A counting semaphore with FIFO hand-off: when a holder releases and a waiter
34
+ * is queued, the slot transfers directly to that waiter (the active count never
35
+ * dips), giving true peak-concurrency === cap regardless of task duration.
36
+ */
37
+ export declare class Semaphore {
38
+ private readonly cap;
39
+ private active;
40
+ private readonly waiters;
41
+ constructor(cap: number);
42
+ acquire(): Promise<void>;
43
+ release(): void;
44
+ /** Number of currently-held slots (for tests / introspection). */
45
+ get inFlight(): number;
46
+ }
47
+ export interface SchedulerOptions {
48
+ /** Max concurrent task executions. Default {@link defaultConcurrency}. */
49
+ maxConcurrent?: number;
50
+ /** Hard ceiling on total executions over this scheduler's lifetime. Default 1000. */
51
+ maxAgents?: number;
52
+ }
53
+ /** A pipeline stage: receives the previous stage's output, the original item, and its index. */
54
+ export type Stage<I> = (prev: unknown, item: I, index: number) => Promise<unknown>;
55
+ export declare class Scheduler {
56
+ readonly maxConcurrent: number;
57
+ readonly maxAgents: number;
58
+ private readonly sem;
59
+ private agentsStarted;
60
+ constructor(opts?: SchedulerOptions);
61
+ /** Total task executions started over this scheduler's lifetime. */
62
+ get agentsRun(): number;
63
+ /** Acquire a slot, run, release — counting the execution against the cap. */
64
+ private run;
65
+ /**
66
+ * Run all thunks concurrently (bounded by the cap) and await them all.
67
+ * Results are index-aligned with `thunks`. A thunk that throws rejects the
68
+ * whole call (use try/catch inside the thunk for {@link Promise.allSettled}-style
69
+ * tolerance).
70
+ */
71
+ parallel<T>(thunks: ReadonlyArray<() => Promise<T>>): Promise<T[]>;
72
+ /**
73
+ * Run each item through every stage independently — no barrier between
74
+ * stages. Returns an array index-aligned with `items`. A stage that throws
75
+ * (other than {@link AgentCapError}) drops that item to `null` and skips its
76
+ * remaining stages; the runaway-cap error propagates.
77
+ */
78
+ pipeline<I>(items: ReadonlyArray<I>, ...stages: Array<Stage<I>>): Promise<unknown[]>;
79
+ }
80
+ /**
81
+ * Map over `items` applying `fn` with at most `cap` concurrent calls, preserving
82
+ * input order. Backed by a hand-off {@link Semaphore} (true bounded concurrency,
83
+ * superseding the chunk-batching copies previously duplicated in the evaluator
84
+ * and architect agents).
85
+ */
86
+ export declare function mapBounded<T, R>(items: ReadonlyArray<T>, cap: number, fn: (x: T) => Promise<R>): Promise<R[]>;
87
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/workflow/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,wEAAwE;AACxE,qBAAa,aAAc,SAAQ,KAAK;IAGpC,4BAA4B;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM;gBAFpB,OAAO,EAAE,MAAM;IACf,4BAA4B;IACnB,GAAG,EAAE,MAAM;CAKvB;AAID;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C;AAID;;;;GAIG;AACH,qBAAa,SAAS;IAIR,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;gBAEpB,GAAG,EAAE,MAAM;IAIlC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9B,OAAO,IAAI,IAAI;IASf,kEAAkE;IAClE,IAAI,QAAQ,IAAI,MAAM,CAErB;CACF;AAID,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,gGAAgG;AAChG,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnF,qBAAa,SAAS;IACpB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAChC,OAAO,CAAC,aAAa,CAAK;gBAEd,IAAI,GAAE,gBAAqB;IAMvC,oEAAoE;IACpE,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,6EAA6E;YAC/D,GAAG;IAgBjB;;;;;OAKG;IACG,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAIxE;;;;;OAKG;IACG,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAgB3F;AAID;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,CAAC,EACnC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,EAAE,CAAC,CAYd"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Concurrency scheduler for the local-model workflow runtime.
3
+ *
4
+ * Mirrors the execution model of Claude Code's dynamic-workflow runtime:
5
+ * - `parallel(thunks)` — barrier; runs all thunks with bounded concurrency
6
+ * and awaits them all (order-preserving). Use for lens panels / N skeptics.
7
+ * - `pipeline(items, ...stages)` — per-item, NO barrier between stages; each
8
+ * item flows through every stage independently, so item A can be in stage 3
9
+ * while item B is still in stage 1. Total concurrent stage executions are
10
+ * bounded by the same cap.
11
+ *
12
+ * Concurrency is enforced by a hand-off semaphore (true bounded concurrency,
13
+ * unlike chunk-batching which idles fast tasks waiting on a slow one). A live
14
+ * agent counter caps total executions over the scheduler's lifetime (the
15
+ * runaway guard — Claude Code uses 1000/run).
16
+ */
17
+ import * as os from "node:os";
18
+ // ── Errors ──────────────────────────────────────────────────────────
19
+ /** Raised when a scheduler exceeds its lifetime agent-execution cap. */
20
+ export class AgentCapError extends Error {
21
+ cap;
22
+ constructor(message,
23
+ /** The cap that was hit. */
24
+ cap) {
25
+ super(message);
26
+ this.cap = cap;
27
+ this.name = "AgentCapError";
28
+ }
29
+ }
30
+ // ── Default concurrency ─────────────────────────────────────────────
31
+ /**
32
+ * The default concurrency cap: `min(16, cores - 2)`, floored at 1. Matches the
33
+ * Claude Code dynamic-workflow runtime. For local model servers the real bound
34
+ * is usually the server's slot count (e.g. Ollama's OLLAMA_NUM_PARALLEL), so
35
+ * callers should override `maxConcurrent` to match their backend.
36
+ */
37
+ export function defaultConcurrency() {
38
+ const cores = os.cpus().length;
39
+ return Math.max(1, Math.min(16, cores - 2));
40
+ }
41
+ // ── Hand-off semaphore ──────────────────────────────────────────────
42
+ /**
43
+ * A counting semaphore with FIFO hand-off: when a holder releases and a waiter
44
+ * is queued, the slot transfers directly to that waiter (the active count never
45
+ * dips), giving true peak-concurrency === cap regardless of task duration.
46
+ */
47
+ export class Semaphore {
48
+ cap;
49
+ active = 0;
50
+ waiters = [];
51
+ constructor(cap) {
52
+ this.cap = cap;
53
+ if (cap < 1)
54
+ throw new Error(`Semaphore cap must be >= 1 (got ${String(cap)}).`);
55
+ }
56
+ async acquire() {
57
+ if (this.active < this.cap) {
58
+ this.active += 1;
59
+ return;
60
+ }
61
+ // Full: queue and wait. release() hands us the slot (active stays at cap),
62
+ // so we do NOT increment when resumed.
63
+ await new Promise((resolve) => this.waiters.push(resolve));
64
+ }
65
+ release() {
66
+ const next = this.waiters.shift();
67
+ if (next) {
68
+ next(); // hand the slot over; active unchanged
69
+ }
70
+ else {
71
+ this.active -= 1;
72
+ }
73
+ }
74
+ /** Number of currently-held slots (for tests / introspection). */
75
+ get inFlight() {
76
+ return this.active;
77
+ }
78
+ }
79
+ export class Scheduler {
80
+ maxConcurrent;
81
+ maxAgents;
82
+ sem;
83
+ agentsStarted = 0;
84
+ constructor(opts = {}) {
85
+ this.maxConcurrent = opts.maxConcurrent ?? defaultConcurrency();
86
+ this.maxAgents = opts.maxAgents ?? 1000;
87
+ this.sem = new Semaphore(Math.max(1, this.maxConcurrent));
88
+ }
89
+ /** Total task executions started over this scheduler's lifetime. */
90
+ get agentsRun() {
91
+ return this.agentsStarted;
92
+ }
93
+ /** Acquire a slot, run, release — counting the execution against the cap. */
94
+ async run(thunk) {
95
+ if (this.agentsStarted >= this.maxAgents) {
96
+ throw new AgentCapError(`Scheduler agent cap exceeded (${String(this.maxAgents)} executions).`, this.maxAgents);
97
+ }
98
+ this.agentsStarted += 1;
99
+ await this.sem.acquire();
100
+ try {
101
+ return await thunk();
102
+ }
103
+ finally {
104
+ this.sem.release();
105
+ }
106
+ }
107
+ /**
108
+ * Run all thunks concurrently (bounded by the cap) and await them all.
109
+ * Results are index-aligned with `thunks`. A thunk that throws rejects the
110
+ * whole call (use try/catch inside the thunk for {@link Promise.allSettled}-style
111
+ * tolerance).
112
+ */
113
+ async parallel(thunks) {
114
+ return Promise.all(thunks.map((t) => this.run(t)));
115
+ }
116
+ /**
117
+ * Run each item through every stage independently — no barrier between
118
+ * stages. Returns an array index-aligned with `items`. A stage that throws
119
+ * (other than {@link AgentCapError}) drops that item to `null` and skips its
120
+ * remaining stages; the runaway-cap error propagates.
121
+ */
122
+ async pipeline(items, ...stages) {
123
+ return Promise.all(items.map(async (item, index) => {
124
+ let acc = item;
125
+ for (const stage of stages) {
126
+ try {
127
+ acc = await this.run(() => stage(acc, item, index));
128
+ }
129
+ catch (e) {
130
+ if (e instanceof AgentCapError)
131
+ throw e;
132
+ return null;
133
+ }
134
+ }
135
+ return acc;
136
+ }));
137
+ }
138
+ }
139
+ // ── mapBounded (drop-in for the legacy panel helper) ────────────────
140
+ /**
141
+ * Map over `items` applying `fn` with at most `cap` concurrent calls, preserving
142
+ * input order. Backed by a hand-off {@link Semaphore} (true bounded concurrency,
143
+ * superseding the chunk-batching copies previously duplicated in the evaluator
144
+ * and architect agents).
145
+ */
146
+ export async function mapBounded(items, cap, fn) {
147
+ const sem = new Semaphore(Math.max(1, cap));
148
+ return Promise.all(items.map(async (item) => {
149
+ await sem.acquire();
150
+ try {
151
+ return await fn(item);
152
+ }
153
+ finally {
154
+ sem.release();
155
+ }
156
+ }));
157
+ }
158
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/orchestrator/workflow/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,uEAAuE;AAEvE,wEAAwE;AACxE,MAAM,OAAO,aAAc,SAAQ,KAAK;IAI3B;IAHX,YACE,OAAe;IACf,4BAA4B;IACnB,GAAW;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,QAAG,GAAH,GAAG,CAAQ;QAGpB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,uEAAuE;AAEvE;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC;IAC/B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,uEAAuE;AAEvE;;;;GAIG;AACH,MAAM,OAAO,SAAS;IAIS;IAHrB,MAAM,GAAG,CAAC,CAAC;IACF,OAAO,GAAsB,EAAE,CAAC;IAEjD,YAA6B,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;QACtC,IAAI,GAAG,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnF,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;QACD,2EAA2E;QAC3E,uCAAuC;QACvC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,EAAE,CAAC,CAAC,uCAAuC;QACjD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AAcD,MAAM,OAAO,SAAS;IACX,aAAa,CAAS;IACtB,SAAS,CAAS;IACV,GAAG,CAAY;IACxB,aAAa,GAAG,CAAC,CAAC;IAE1B,YAAY,OAAyB,EAAE;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,kBAAkB,EAAE,CAAC;QAChE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,oEAAoE;IACpE,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,6EAA6E;IACrE,KAAK,CAAC,GAAG,CAAI,KAAuB;QAC1C,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACzC,MAAM,IAAI,aAAa,CACrB,iCAAiC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,EACtE,IAAI,CAAC,SAAS,CACf,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;QACxB,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,EAAE,CAAC;QACvB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAI,MAAuC;QACvD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAI,KAAuB,EAAE,GAAG,MAAuB;QACnE,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YAC9B,IAAI,GAAG,GAAY,IAAI,CAAC;YACxB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;gBACtD,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAI,CAAC,YAAY,aAAa;wBAAE,MAAM,CAAC,CAAC;oBACxC,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AAED,uEAAuE;AAEvE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAuB,EACvB,GAAW,EACX,EAAwB;IAExB,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;gBAAS,CAAC;YACT,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { BoberConfig } from "../../config/schema.js";
2
+ import type { PipelineEngine, PipelineEngineName } from "./engine.js";
3
+ /**
4
+ * Pure resolver — returns the engine name without instantiating an engine.
5
+ *
6
+ * Resolution branches:
7
+ * - engine unset → 'ts'
8
+ * - engine === 'workflow' && ineligible → 'ts' (one downgrade log line)
9
+ * - engine === 'workflow' && mode === 'careful' → 'ts' (one downgrade log line)
10
+ * - else → engine verbatim ('ts' | 'skill' | 'workflow')
11
+ *
12
+ * Mirrors the pure-resolver pattern of resolveCheckpointMechanismName
13
+ * (src/orchestrator/checkpoints/registry.ts:65).
14
+ */
15
+ export declare function resolveEngineName(config: BoberConfig): PipelineEngineName;
16
+ /**
17
+ * Resolve config.pipeline.engine to a PipelineEngine instance.
18
+ *
19
+ * Belt-and-suspenders per ADR-6:
20
+ * - resolveEngineName (above) ALREADY downgrades workflow→ts when ineligible/careful.
21
+ * - In the eligible case, WorkflowEngine is returned; its run() has a second guard
22
+ * that catches WorkflowUnavailableError from the dormant invoke and re-dispatches TS.
23
+ * - 'skill' remains on TsPipelineEngine (no skill engine this sprint — non-goal).
24
+ */
25
+ export declare function selectPipelineEngine(config: BoberConfig): PipelineEngine;
26
+ //# sourceMappingURL=selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/workflow/selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAOtE;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,kBAAkB,CAezE;AAID;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,CAaxE"}
@@ -0,0 +1,54 @@
1
+ import { logger } from "../../utils/logger.js";
2
+ import { isWorkflowEligible } from "./eligibility.js";
3
+ import { TsPipelineEngine } from "./ts-engine.js";
4
+ import { WorkflowEngine } from "./workflow-engine.js";
5
+ // ── Resolver ───────────────────────────────────────────────────────
6
+ /**
7
+ * Pure resolver — returns the engine name without instantiating an engine.
8
+ *
9
+ * Resolution branches:
10
+ * - engine unset → 'ts'
11
+ * - engine === 'workflow' && ineligible → 'ts' (one downgrade log line)
12
+ * - engine === 'workflow' && mode === 'careful' → 'ts' (one downgrade log line)
13
+ * - else → engine verbatim ('ts' | 'skill' | 'workflow')
14
+ *
15
+ * Mirrors the pure-resolver pattern of resolveCheckpointMechanismName
16
+ * (src/orchestrator/checkpoints/registry.ts:65).
17
+ */
18
+ export function resolveEngineName(config) {
19
+ const requested = config.pipeline?.engine ?? "ts";
20
+ if (requested === "workflow") {
21
+ const eligible = isWorkflowEligible(config);
22
+ const careful = config.pipeline?.mode === "careful";
23
+ if (!eligible || careful) {
24
+ logger.info(`Workflow engine requested but ${!eligible ? "ineligible" : "mode='careful'"}; downgrading to 'ts'.`);
25
+ return "ts";
26
+ }
27
+ }
28
+ return requested;
29
+ }
30
+ // ── Selector ───────────────────────────────────────────────────────
31
+ /**
32
+ * Resolve config.pipeline.engine to a PipelineEngine instance.
33
+ *
34
+ * Belt-and-suspenders per ADR-6:
35
+ * - resolveEngineName (above) ALREADY downgrades workflow→ts when ineligible/careful.
36
+ * - In the eligible case, WorkflowEngine is returned; its run() has a second guard
37
+ * that catches WorkflowUnavailableError from the dormant invoke and re-dispatches TS.
38
+ * - 'skill' remains on TsPipelineEngine (no skill engine this sprint — non-goal).
39
+ */
40
+ export function selectPipelineEngine(config) {
41
+ const name = resolveEngineName(config);
42
+ switch (name) {
43
+ case "ts":
44
+ return new TsPipelineEngine();
45
+ case "skill":
46
+ // Skill engine deferred (non-goal this sprint); falls through to TS.
47
+ return new TsPipelineEngine();
48
+ case "workflow":
49
+ // Reachable only when resolveEngineName returns 'workflow' (eligible + not careful).
50
+ // WorkflowEngine.run has a belt-and-suspenders catch for WorkflowUnavailableError.
51
+ return new WorkflowEngine();
52
+ }
53
+ }
54
+ //# sourceMappingURL=selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.js","sourceRoot":"","sources":["../../../src/orchestrator/workflow/selector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,sEAAsE;AAEtE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,MAAM,SAAS,GAAuB,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,IAAI,CAAC;IAEtE,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,KAAK,SAAS,CAAC;QACpD,IAAI,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CACT,iCAAiC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,wBAAwB,CACrG,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,sEAAsE;AAEtE;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,IAAI;YACP,OAAO,IAAI,gBAAgB,EAAE,CAAC;QAChC,KAAK,OAAO;YACV,qEAAqE;YACrE,OAAO,IAAI,gBAAgB,EAAE,CAAC;QAChC,KAAK,UAAU;YACb,qFAAqF;YACrF,mFAAmF;YACnF,OAAO,IAAI,cAAc,EAAE,CAAC;IAChC,CAAC;AACH,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * SynthesisResult: the ranked output of synthesize() (ranking shape, not
3
+ * pass/fail — contrast with EvalResult returned by reconcile()).
4
+ */
5
+ export interface SynthesisResult {
6
+ /** The approach with the highest aggregate score across all lenses. */
7
+ winner: string;
8
+ /**
9
+ * All approaches ordered descending by total score.
10
+ * Deterministic tie-break: lower original index in `approaches` wins
11
+ * when two approaches have equal totals (i.e. the approach that appeared
12
+ * earlier in the caller's list is ranked higher).
13
+ */
14
+ ranking: Array<{
15
+ approach: string;
16
+ perLensScores: Record<string, number>;
17
+ total: number;
18
+ }>;
19
+ /**
20
+ * Placeholder collection slot for cross-approach ideas worth grafting into
21
+ * the winner. This sprint uses runner-up approach names as a simple default;
22
+ * future sprints may populate this with extracted proposal fragments.
23
+ */
24
+ graftedIdeas: string[];
25
+ /**
26
+ * Lenses whose individual top-scored approach differs from the overall winner.
27
+ * Each entry is a human-readable string identifying the lens and its preferred
28
+ * approach, e.g. "scalability: prefers approach-B".
29
+ */
30
+ dissent: string[];
31
+ }
32
+ /**
33
+ * Pure ranking reducer over per-lens approach scores (sibling of reconcile()).
34
+ * No Date.now / new Date / Math.random / fs — this function is deterministic
35
+ * given the same inputs.
36
+ *
37
+ * Tie-break rule (documented): when two approaches have equal aggregate totals,
38
+ * the approach whose index is LOWER in the original `approaches` array wins.
39
+ * This is achieved by capturing original indices before sorting and using them
40
+ * as a stable comparator secondary key.
41
+ *
42
+ * @param approaches - Ordered list of approach identifiers to rank.
43
+ * @param lensScores - Per-lens score maps: each entry has a lens name and a
44
+ * `scores` record mapping approach → numeric score. Missing approach keys
45
+ * contribute 0 for that lens.
46
+ * @throws {Error} if `approaches` is empty (mirrors reconcile() guard).
47
+ */
48
+ export declare function synthesize(approaches: string[], lensScores: Array<{
49
+ lens: string;
50
+ scores: Record<string, number>;
51
+ }>): SynthesisResult;
52
+ //# sourceMappingURL=synthesizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesizer.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/workflow/synthesizer.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,OAAO,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtC,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IACH;;;;OAIG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;;;;OAIG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAID;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,GAClE,eAAe,CA4EjB"}
@@ -0,0 +1,75 @@
1
+ // ── Synthesizer ─────────────────────────────────────────────────────
2
+ // ── synthesize ──────────────────────────────────────────────────────
3
+ /**
4
+ * Pure ranking reducer over per-lens approach scores (sibling of reconcile()).
5
+ * No Date.now / new Date / Math.random / fs — this function is deterministic
6
+ * given the same inputs.
7
+ *
8
+ * Tie-break rule (documented): when two approaches have equal aggregate totals,
9
+ * the approach whose index is LOWER in the original `approaches` array wins.
10
+ * This is achieved by capturing original indices before sorting and using them
11
+ * as a stable comparator secondary key.
12
+ *
13
+ * @param approaches - Ordered list of approach identifiers to rank.
14
+ * @param lensScores - Per-lens score maps: each entry has a lens name and a
15
+ * `scores` record mapping approach → numeric score. Missing approach keys
16
+ * contribute 0 for that lens.
17
+ * @throws {Error} if `approaches` is empty (mirrors reconcile() guard).
18
+ */
19
+ export function synthesize(approaches, lensScores) {
20
+ if (approaches.length === 0) {
21
+ throw new Error("synthesize: approaches must be non-empty");
22
+ }
23
+ // ── Build per-approach aggregates ───────────────────────────────────
24
+ // Capture original indices for deterministic tie-breaking before sort
25
+ const indexed = approaches.map((approach, originalIndex) => {
26
+ const perLensScores = {};
27
+ let total = 0;
28
+ for (const { lens, scores } of lensScores) {
29
+ const s = scores[approach] ?? 0;
30
+ perLensScores[lens] = s;
31
+ total = total + s;
32
+ }
33
+ return { approach, perLensScores, total, originalIndex };
34
+ });
35
+ // ── Sort descending by total; tie-break: lower original index wins ──
36
+ const sorted = indexed.slice().sort((a, b) => {
37
+ if (b.total !== a.total) {
38
+ return b.total - a.total; // higher total ranks first
39
+ }
40
+ return a.originalIndex - b.originalIndex; // lower index ranks first on tie
41
+ });
42
+ const ranking = sorted.map(({ approach, perLensScores, total }) => ({
43
+ approach,
44
+ perLensScores,
45
+ total,
46
+ }));
47
+ const winner = ranking[0].approach;
48
+ // ── Compute dissent ─────────────────────────────────────────────────
49
+ // A lens dissents when its own top-scored approach differs from winner.
50
+ // Tie-break within a single lens also uses lower original index.
51
+ const approachToIndex = new Map(approaches.map((a, i) => [a, i]));
52
+ const dissent = [];
53
+ for (const { lens, scores } of lensScores) {
54
+ let lensWinner;
55
+ let lensMax = -Infinity;
56
+ for (const approach of approaches) {
57
+ const s = scores[approach] ?? 0;
58
+ const idx = approachToIndex.get(approach) ?? 0;
59
+ if (s > lensMax ||
60
+ (s === lensMax &&
61
+ lensWinner !== undefined &&
62
+ idx < (approachToIndex.get(lensWinner) ?? 0))) {
63
+ lensMax = s;
64
+ lensWinner = approach;
65
+ }
66
+ }
67
+ if (lensWinner !== undefined && lensWinner !== winner) {
68
+ dissent.push(`${lens}: prefers ${lensWinner}`);
69
+ }
70
+ }
71
+ // ── Compute graftedIdeas (runner-up approaches as placeholder) ──────
72
+ const graftedIdeas = ranking.slice(1).map((r) => r.approach);
73
+ return { winner, ranking, graftedIdeas, dissent };
74
+ }
75
+ //# sourceMappingURL=synthesizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesizer.js","sourceRoot":"","sources":["../../../src/orchestrator/workflow/synthesizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { BoberConfig } from "../../config/schema.js";
2
+ import type { PipelineResult } from "../pipeline.js";
3
+ import type { PipelineEngine, PipelineEngineName } from "./engine.js";
4
+ /**
5
+ * Engine adapter that wraps the original TypeScript pipeline implementation.
6
+ * Delegates to runTsPipeline — the extracted former runPipeline body — with
7
+ * ZERO behaviour change on the default 'ts' path.
8
+ */
9
+ export declare class TsPipelineEngine implements PipelineEngine {
10
+ readonly name: PipelineEngineName;
11
+ run(userPrompt: string, projectRoot: string, config: BoberConfig): Promise<PipelineResult>;
12
+ }
13
+ //# sourceMappingURL=ts-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-engine.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/workflow/ts-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAItE;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IACrD,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAQ;IAEzC,GAAG,CACD,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,cAAc,CAAC;CAG3B"}
@@ -0,0 +1,14 @@
1
+ import { runTsPipeline } from "../pipeline.js";
2
+ // ── TsPipelineEngine ───────────────────────────────────────────────
3
+ /**
4
+ * Engine adapter that wraps the original TypeScript pipeline implementation.
5
+ * Delegates to runTsPipeline — the extracted former runPipeline body — with
6
+ * ZERO behaviour change on the default 'ts' path.
7
+ */
8
+ export class TsPipelineEngine {
9
+ name = "ts";
10
+ run(userPrompt, projectRoot, config) {
11
+ return runTsPipeline(userPrompt, projectRoot, config);
12
+ }
13
+ }
14
+ //# sourceMappingURL=ts-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-engine.js","sourceRoot":"","sources":["../../../src/orchestrator/workflow/ts-engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI/C,sEAAsE;AAEtE;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAClB,IAAI,GAAuB,IAAI,CAAC;IAEzC,GAAG,CACD,UAAkB,EAClB,WAAmB,EACnB,MAAmB;QAEnB,OAAO,aAAa,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;CACF"}