@bastani/atomic 0.9.3 → 0.9.4-alpha.10

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 (312) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/dist/builtin/cursor/CHANGELOG.md +30 -0
  3. package/dist/builtin/cursor/package.json +4 -4
  4. package/dist/builtin/intercom/CHANGELOG.md +30 -0
  5. package/dist/builtin/intercom/package.json +2 -2
  6. package/dist/builtin/mcp/CHANGELOG.md +30 -0
  7. package/dist/builtin/mcp/package.json +4 -4
  8. package/dist/builtin/subagents/CHANGELOG.md +51 -0
  9. package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
  10. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
  11. package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
  12. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
  13. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
  14. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
  15. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
  16. package/dist/builtin/subagents/agents/debugger.md +1 -1
  17. package/dist/builtin/subagents/agents/worker.md +2 -2
  18. package/dist/builtin/subagents/package.json +4 -4
  19. package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +11 -1
  20. package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +11 -1
  21. package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +2 -0
  22. package/dist/builtin/subagents/src/runs/background/subagent-runner-step.ts +27 -4
  23. package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +25 -0
  24. package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
  25. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
  26. package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
  27. package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +1 -0
  28. package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +2 -0
  29. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +3 -1
  30. package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +22 -0
  31. package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +15 -5
  32. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +5 -1
  33. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
  34. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +4 -1
  35. package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +4 -1
  36. package/dist/builtin/subagents/src/runs/shared/attempt-watchdog.ts +126 -0
  37. package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +53 -0
  38. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +52 -53
  39. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +2 -0
  40. package/dist/builtin/subagents/src/shared/model-info.ts +16 -0
  41. package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
  42. package/dist/builtin/web-access/CHANGELOG.md +30 -0
  43. package/dist/builtin/web-access/package.json +2 -2
  44. package/dist/builtin/workflows/CHANGELOG.md +54 -0
  45. package/dist/builtin/workflows/README.md +4 -4
  46. package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +24 -22
  47. package/dist/builtin/workflows/builtin/goal-runner.ts +12 -23
  48. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +4 -4
  49. package/dist/builtin/workflows/builtin/ralph-models.ts +53 -75
  50. package/dist/builtin/workflows/package.json +2 -2
  51. package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +4 -2
  52. package/dist/builtin/workflows/src/engine/run-returned-status.ts +41 -0
  53. package/dist/builtin/workflows/src/engine/run.ts +6 -4
  54. package/dist/builtin/workflows/src/extension/config-file-loader.ts +1 -1
  55. package/dist/builtin/workflows/src/extension/config-loader.ts +1 -1
  56. package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +37 -12
  57. package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +59 -1
  58. package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +1 -1
  59. package/dist/builtin/workflows/src/shared/store-public-types.ts +3 -2
  60. package/dist/builtin/workflows/src/shared/store-run-methods.ts +6 -1
  61. package/dist/bun/cli.d.ts.map +1 -1
  62. package/dist/bun/cli.js +3 -2
  63. package/dist/bun/cli.js.map +1 -1
  64. package/dist/cli/file-processor.d.ts.map +1 -1
  65. package/dist/cli/file-processor.js +13 -25
  66. package/dist/cli/file-processor.js.map +1 -1
  67. package/dist/cli.d.ts.map +1 -1
  68. package/dist/cli.js +15 -5
  69. package/dist/cli.js.map +1 -1
  70. package/dist/config.d.ts +10 -3
  71. package/dist/config.d.ts.map +1 -1
  72. package/dist/config.js +18 -1
  73. package/dist/config.js.map +1 -1
  74. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  75. package/dist/core/agent-session-auto-compaction.js +8 -1
  76. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  77. package/dist/core/agent-session-events.d.ts.map +1 -1
  78. package/dist/core/agent-session-events.js +14 -8
  79. package/dist/core/agent-session-events.js.map +1 -1
  80. package/dist/core/agent-session-export.d.ts.map +1 -1
  81. package/dist/core/agent-session-export.js +4 -2
  82. package/dist/core/agent-session-export.js.map +1 -1
  83. package/dist/core/agent-session-extension-bindings.d.ts +5 -1
  84. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  85. package/dist/core/agent-session-extension-bindings.js +18 -7
  86. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  87. package/dist/core/agent-session-methods.d.ts +9 -2
  88. package/dist/core/agent-session-methods.d.ts.map +1 -1
  89. package/dist/core/agent-session-methods.js.map +1 -1
  90. package/dist/core/agent-session-prompt.d.ts +2 -0
  91. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  92. package/dist/core/agent-session-prompt.js +15 -2
  93. package/dist/core/agent-session-prompt.js.map +1 -1
  94. package/dist/core/agent-session-retry.d.ts +2 -0
  95. package/dist/core/agent-session-retry.d.ts.map +1 -1
  96. package/dist/core/agent-session-retry.js +66 -7
  97. package/dist/core/agent-session-retry.js.map +1 -1
  98. package/dist/core/agent-session-state.d.ts.map +1 -1
  99. package/dist/core/agent-session-state.js +2 -2
  100. package/dist/core/agent-session-state.js.map +1 -1
  101. package/dist/core/agent-session-tool-hooks.d.ts +7 -1
  102. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  103. package/dist/core/agent-session-tool-hooks.js +26 -4
  104. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  105. package/dist/core/agent-session-tree.d.ts.map +1 -1
  106. package/dist/core/agent-session-tree.js +3 -1
  107. package/dist/core/agent-session-tree.js.map +1 -1
  108. package/dist/core/agent-session-types.d.ts +4 -0
  109. package/dist/core/agent-session-types.d.ts.map +1 -1
  110. package/dist/core/agent-session-types.js.map +1 -1
  111. package/dist/core/agent-session.d.ts +1 -0
  112. package/dist/core/agent-session.d.ts.map +1 -1
  113. package/dist/core/agent-session.js +1 -0
  114. package/dist/core/agent-session.js.map +1 -1
  115. package/dist/core/copilot-model-catalog.d.ts +38 -74
  116. package/dist/core/copilot-model-catalog.d.ts.map +1 -1
  117. package/dist/core/copilot-model-catalog.js +177 -68
  118. package/dist/core/copilot-model-catalog.js.map +1 -1
  119. package/dist/core/copilot-model-static-fallbacks.d.ts +43 -0
  120. package/dist/core/copilot-model-static-fallbacks.d.ts.map +1 -0
  121. package/dist/core/copilot-model-static-fallbacks.js +50 -0
  122. package/dist/core/copilot-model-static-fallbacks.js.map +1 -0
  123. package/dist/core/copilot-model-synthesis.d.ts +10 -0
  124. package/dist/core/copilot-model-synthesis.d.ts.map +1 -0
  125. package/dist/core/copilot-model-synthesis.js +89 -0
  126. package/dist/core/copilot-model-synthesis.js.map +1 -0
  127. package/dist/core/extensions/api-types.d.ts +2 -1
  128. package/dist/core/extensions/api-types.d.ts.map +1 -1
  129. package/dist/core/extensions/api-types.js.map +1 -1
  130. package/dist/core/extensions/index.d.ts +1 -1
  131. package/dist/core/extensions/index.d.ts.map +1 -1
  132. package/dist/core/extensions/index.js.map +1 -1
  133. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  134. package/dist/core/extensions/loader-core.js +3 -3
  135. package/dist/core/extensions/loader-core.js.map +1 -1
  136. package/dist/core/extensions/loader-virtual-modules.d.ts +11 -0
  137. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  138. package/dist/core/extensions/loader-virtual-modules.js +79 -11
  139. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  140. package/dist/core/extensions/session-events.d.ts +7 -1
  141. package/dist/core/extensions/session-events.d.ts.map +1 -1
  142. package/dist/core/extensions/session-events.js.map +1 -1
  143. package/dist/core/http-dispatcher.d.ts +5 -3
  144. package/dist/core/http-dispatcher.d.ts.map +1 -1
  145. package/dist/core/http-dispatcher.js +56 -10
  146. package/dist/core/http-dispatcher.js.map +1 -1
  147. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  148. package/dist/core/model-registry-builtins.js +40 -6
  149. package/dist/core/model-registry-builtins.js.map +1 -1
  150. package/dist/core/model-registry.d.ts.map +1 -1
  151. package/dist/core/model-registry.js +4 -3
  152. package/dist/core/model-registry.js.map +1 -1
  153. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  154. package/dist/core/model-resolver-defaults.js +1 -1
  155. package/dist/core/model-resolver-defaults.js.map +1 -1
  156. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  157. package/dist/core/resource-loader-reload.js +6 -3
  158. package/dist/core/resource-loader-reload.js.map +1 -1
  159. package/dist/core/resource-loader-types.d.ts +6 -0
  160. package/dist/core/resource-loader-types.d.ts.map +1 -1
  161. package/dist/core/resource-loader-types.js.map +1 -1
  162. package/dist/core/session-manager-core.d.ts +2 -12
  163. package/dist/core/session-manager-core.d.ts.map +1 -1
  164. package/dist/core/session-manager-core.js +8 -16
  165. package/dist/core/session-manager-core.js.map +1 -1
  166. package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
  167. package/dist/core/settings-manager-basic-accessors.js +1 -1
  168. package/dist/core/settings-manager-basic-accessors.js.map +1 -1
  169. package/dist/core/settings-manager-resource-accessors.d.ts +1 -0
  170. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  171. package/dist/core/settings-manager-resource-accessors.js +11 -0
  172. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  173. package/dist/core/settings-manager-ui-accessors.d.ts +2 -0
  174. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  175. package/dist/core/settings-manager-ui-accessors.js +9 -0
  176. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  177. package/dist/core/settings-types.d.ts +2 -0
  178. package/dist/core/settings-types.d.ts.map +1 -1
  179. package/dist/core/settings-types.js.map +1 -1
  180. package/dist/core/timings.d.ts +7 -5
  181. package/dist/core/timings.d.ts.map +1 -1
  182. package/dist/core/timings.js +42 -24
  183. package/dist/core/timings.js.map +1 -1
  184. package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
  185. package/dist/core/tools/bash-pty-native.js +2 -2
  186. package/dist/core/tools/bash-pty-native.js.map +1 -1
  187. package/dist/core/tools/read-selectors.d.ts.map +1 -1
  188. package/dist/core/tools/read-selectors.js +19 -1
  189. package/dist/core/tools/read-selectors.js.map +1 -1
  190. package/dist/core/tools/read.d.ts.map +1 -1
  191. package/dist/core/tools/read.js +12 -23
  192. package/dist/core/tools/read.js.map +1 -1
  193. package/dist/core/tools/search-native.d.ts.map +1 -1
  194. package/dist/core/tools/search-native.js +2 -2
  195. package/dist/core/tools/search-native.js.map +1 -1
  196. package/dist/index-extensions.d.ts +1 -1
  197. package/dist/index-extensions.d.ts.map +1 -1
  198. package/dist/index-extensions.js.map +1 -1
  199. package/dist/index.d.ts +1 -1
  200. package/dist/index.d.ts.map +1 -1
  201. package/dist/index.js.map +1 -1
  202. package/dist/main-session.d.ts.map +1 -1
  203. package/dist/main-session.js +14 -5
  204. package/dist/main-session.js.map +1 -1
  205. package/dist/main.d.ts.map +1 -1
  206. package/dist/main.js +56 -32
  207. package/dist/main.js.map +1 -1
  208. package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  209. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  210. package/dist/modes/interactive/components/assistant-message.js +22 -15
  211. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  212. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  213. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  214. package/dist/modes/interactive/components/chat-message-renderer.js +5 -5
  215. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  216. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  217. package/dist/modes/interactive/components/chat-session-host-events.js +8 -0
  218. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  219. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  220. package/dist/modes/interactive/components/chat-session-host-rendering.js +1 -0
  221. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  222. package/dist/modes/interactive/components/user-message.d.ts +6 -2
  223. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  224. package/dist/modes/interactive/components/user-message.js +16 -5
  225. package/dist/modes/interactive/components/user-message.js.map +1 -1
  226. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  227. package/dist/modes/interactive/interactive-agent-events.js +6 -1
  228. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  229. package/dist/modes/interactive/interactive-deferred-startup.d.ts +2 -0
  230. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -0
  231. package/dist/modes/interactive/interactive-deferred-startup.js +59 -0
  232. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -0
  233. package/dist/modes/interactive/interactive-editor-actions.d.ts.map +1 -1
  234. package/dist/modes/interactive/interactive-editor-actions.js +1 -0
  235. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  236. package/dist/modes/interactive/interactive-extension-context.d.ts.map +1 -1
  237. package/dist/modes/interactive/interactive-extension-context.js +1 -0
  238. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  239. package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
  240. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  241. package/dist/modes/interactive/interactive-mode-base.js +6 -0
  242. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  243. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
  244. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  245. package/dist/modes/interactive/interactive-mode-deps.js +1 -1
  246. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  247. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -0
  248. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  249. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  250. package/dist/modes/interactive/interactive-mode-types.d.ts +2 -0
  251. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  252. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  253. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  254. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  255. package/dist/modes/interactive/interactive-mode.js +1 -0
  256. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  257. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  258. package/dist/modes/interactive/interactive-model-routing.js +2 -4
  259. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  260. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  261. package/dist/modes/interactive/interactive-render-chat.js +4 -3
  262. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  263. package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
  264. package/dist/modes/interactive/interactive-session-runtime.js +5 -2
  265. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  266. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  267. package/dist/modes/interactive/interactive-startup.js +11 -1
  268. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  269. package/dist/modes/print-mode.d.ts.map +1 -1
  270. package/dist/modes/print-mode.js +15 -13
  271. package/dist/modes/print-mode.js.map +1 -1
  272. package/dist/modes/rpc/rpc-client.d.ts +28 -51
  273. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  274. package/dist/modes/rpc/rpc-client.js +27 -51
  275. package/dist/modes/rpc/rpc-client.js.map +1 -1
  276. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  277. package/dist/modes/rpc/rpc-command-handler.js +19 -0
  278. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  279. package/dist/modes/rpc/rpc-types.d.ts +26 -0
  280. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  281. package/dist/modes/rpc/rpc-types.js.map +1 -1
  282. package/dist/rpc-entry.d.ts +3 -0
  283. package/dist/rpc-entry.d.ts.map +1 -0
  284. package/dist/rpc-entry.js +12 -0
  285. package/dist/rpc-entry.js.map +1 -0
  286. package/dist/utils/image-convert.d.ts +1 -0
  287. package/dist/utils/image-convert.d.ts.map +1 -1
  288. package/dist/utils/image-convert.js +21 -15
  289. package/dist/utils/image-convert.js.map +1 -1
  290. package/dist/utils/image-process.d.ts +18 -0
  291. package/dist/utils/image-process.d.ts.map +1 -0
  292. package/dist/utils/image-process.js +83 -0
  293. package/dist/utils/image-process.js.map +1 -0
  294. package/dist/utils/mime.d.ts.map +1 -1
  295. package/dist/utils/mime.js +41 -0
  296. package/dist/utils/mime.js.map +1 -1
  297. package/dist/utils/module-require.d.ts +11 -0
  298. package/dist/utils/module-require.d.ts.map +1 -0
  299. package/dist/utils/module-require.js +16 -0
  300. package/dist/utils/module-require.js.map +1 -0
  301. package/docs/compaction.md +2 -0
  302. package/docs/development.md +10 -0
  303. package/docs/extensions.md +11 -0
  304. package/docs/models.md +3 -3
  305. package/docs/providers.md +2 -1
  306. package/docs/rpc.md +60 -2
  307. package/docs/sdk.md +1 -1
  308. package/docs/settings.md +8 -5
  309. package/docs/subagents.md +6 -0
  310. package/docs/workflows.md +9 -5
  311. package/npm-shrinkwrap.json +4266 -0
  312. package/package.json +23 -13
@@ -117,6 +117,7 @@ export type ModelFallbackFailureKind =
117
117
  | "provider_unavailable"
118
118
  | "network_timeout"
119
119
  | "model_unavailable"
120
+ | "request_incompatible"
120
121
  | "cancelled"
121
122
  | "task_failure"
122
123
  | "unknown";
@@ -144,6 +145,7 @@ const FALLBACKABLE_FAILURE_KINDS: ReadonlySet<ModelFallbackFailureKind> = new Se
144
145
  "provider_unavailable",
145
146
  "network_timeout",
146
147
  "model_unavailable",
148
+ "request_incompatible",
147
149
  ]);
148
150
 
149
151
  function asRecord(value: unknown): Record<string, unknown> | undefined {
@@ -222,6 +224,9 @@ function normalizeCode(value: string | number | undefined): string | undefined {
222
224
 
223
225
  function kindFromStatus(status: number | undefined): ModelFallbackFailureKind | undefined {
224
226
  switch (status) {
227
+ case 400:
228
+ case 413: case 422:
229
+ return "request_incompatible";
225
230
  case 401:
226
231
  case 403:
227
232
  return "auth_on_candidate_provider";
@@ -237,6 +242,15 @@ function kindFromStatus(status: number | undefined): ModelFallbackFailureKind |
237
242
  }
238
243
  }
239
244
 
245
+ const REQUEST_INCOMPATIBLE_CODES: ReadonlySet<string> = new Set([
246
+ "invalid_request", "invalid_request_error", "bad_request", "context_length_exceeded",
247
+ "request_too_large", "too_large", "request_entity_too_large", "max_tokens",
248
+ "max_context_length", "context_window_exceeded",
249
+ ]);
250
+ function requestIncompatibleKindFromCode(code: string | number | undefined): ModelFallbackFailureKind | undefined {
251
+ const normalizedCode = normalizeCode(code);
252
+ return normalizedCode !== undefined && REQUEST_INCOMPATIBLE_CODES.has(normalizedCode) ? "request_incompatible" : undefined;
253
+ }
240
254
  function refusalKindFromCode(code: string | number | undefined): ModelFallbackFailureKind | undefined {
241
255
  const normalizedCode = normalizeCode(code);
242
256
  if (normalizedCode === undefined) return undefined;
@@ -258,6 +272,14 @@ function refusalKindFromCode(code: string | number | undefined): ModelFallbackFa
258
272
  }
259
273
  }
260
274
 
275
+ const CODE_KINDS_BY_KIND: ReadonlyArray<readonly [ModelFallbackFailureKind, ReadonlySet<string>]> = [
276
+ ["auth_on_candidate_provider", new Set(["auth", "auth_required", "authentication_required", "unauthorized", "forbidden", "invalid_api_key", "missing_api_key", "invalid_key"])],
277
+ ["network_timeout", new Set(["etimedout", "econnreset", "econnrefused", "enotfound", "eai_again", "fetch_failed", "network_error", "timeout", "timeout_error", "und_err_connect_timeout"])],
278
+ ["rate_limit", new Set(["rate_limit", "rate_limit_exceeded", "too_many_requests", "quota_exceeded"])],
279
+ ["cancelled", new Set(["aborterror", "aborted", "cancelled", "canceled"])],
280
+ ["model_unavailable", new Set(["model_not_found", "model_unavailable", "model_disabled", "unknown_model"])],
281
+ ["provider_unavailable", new Set(["provider_error", "api_error", "service_unavailable", "temporarily_unavailable", "overloaded"])],
282
+ ];
261
283
  function kindFromCode(code: string | number | undefined): ModelFallbackFailureKind | undefined {
262
284
  const normalizedCode = normalizeCode(code);
263
285
  if (normalizedCode === undefined) return undefined;
@@ -265,54 +287,19 @@ function kindFromCode(code: string | number | undefined): ModelFallbackFailureKi
265
287
  if (refusalKind !== undefined) return refusalKind;
266
288
  const httpStatusKind = kindFromStatus(integerFrom(code));
267
289
  if (httpStatusKind !== undefined) return httpStatusKind;
268
-
269
- switch (normalizedCode) {
270
- case "auth":
271
- case "auth_required":
272
- case "authentication_required":
273
- case "unauthorized":
274
- case "forbidden":
275
- case "invalid_api_key":
276
- case "missing_api_key":
277
- case "invalid_key":
278
- return "auth_on_candidate_provider";
279
- case "etimedout":
280
- case "econnreset":
281
- case "econnrefused":
282
- case "enotfound":
283
- case "eai_again":
284
- case "fetch_failed":
285
- case "network_error":
286
- case "timeout":
287
- case "timeout_error":
288
- case "und_err_connect_timeout":
289
- return "network_timeout";
290
- case "rate_limit":
291
- case "rate_limit_exceeded":
292
- case "too_many_requests":
293
- case "quota_exceeded":
294
- return "rate_limit";
295
- case "aborterror":
296
- case "aborted":
297
- case "cancelled":
298
- case "canceled":
299
- return "cancelled";
300
- case "model_not_found":
301
- case "model_unavailable":
302
- case "model_disabled":
303
- case "unknown_model":
304
- return "model_unavailable";
305
- case "provider_error":
306
- case "api_error":
307
- case "service_unavailable":
308
- case "temporarily_unavailable":
309
- case "overloaded":
310
- return "provider_unavailable";
311
- default:
312
- return undefined;
313
- }
314
- }
315
-
290
+ const requestIncompatibleKind = requestIncompatibleKindFromCode(code);
291
+ if (requestIncompatibleKind !== undefined) return requestIncompatibleKind;
292
+ return CODE_KINDS_BY_KIND.find(([_, codes]) => codes.has(normalizedCode))?.[0];
293
+ }
294
+
295
+ const REQUEST_INCOMPATIBLE_FAILURE_PATTERNS: readonly RegExp[] = [
296
+ /\bcontext[_\s-]?(?:length|window)(?:[_\s-]?exceeded)?\b/i,
297
+ /\bmax[_\s-]?(?:context|tokens?)\b/i,
298
+ /\b(?:request(?:[_\s-]?entity)?[_\s-]?too|too)[_\s-]?large\b/i,
299
+ /\b(?:unsupported|unknown|invalid)\s+(?:tool|parameter|function)\b/i,
300
+ /\b(?:tool|parameter|function)\s+(?:not\s+(?:supported|found|allowed)|unknown|invalid)\b/i,
301
+ /\b(?:invalid[_\s-]?request(?:[_\s-]?error)?|bad[_\s-]?request)\b/i,
302
+ ];
316
303
  const PROVIDER_REFUSAL_FAILURE_PATTERNS: readonly RegExp[] = [
317
304
  /\bfinish[_\s-]?reason\b[^\n]*\bcontent[_\s-]?filter\b/i,
318
305
  /\bcontent[_\s-]?filter(?:ed|ing)?\b/i,
@@ -335,6 +322,7 @@ function refusalKindFromMessage(message: string): ModelFallbackFailureKind | und
335
322
  function fallbackKindFromMessage(message: string, name: string | undefined): ModelFallbackFailureKind | undefined {
336
323
  const refusalKind = refusalKindFromMessage(message);
337
324
  if (refusalKind !== undefined) return refusalKind;
325
+ if (REQUEST_INCOMPATIBLE_FAILURE_PATTERNS.some((pattern) => pattern.test(message))) return "request_incompatible";
338
326
  const nameKind = kindFromCode(name);
339
327
  if (nameKind !== undefined) return nameKind;
340
328
  if (!RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(message))) return undefined;
@@ -372,15 +360,21 @@ function makeSignal(
372
360
  };
373
361
  }
374
362
 
375
- function fallbackSignalFromMessage(
363
+ function fallbackSignalForMessage(
364
+ message: string | undefined,
376
365
  value: unknown,
377
366
  source: ModelFallbackFailureSource | undefined,
378
367
  ): ModelFallbackFailureSignal | undefined {
379
- const message = modelFailureMessage(value);
380
- if (!message.trim()) return undefined;
368
+ if (message === undefined || message.trim().length === 0) return undefined;
381
369
  const kind = fallbackKindFromMessage(message, errorName(value));
382
370
  return kind === undefined ? undefined : makeSignal(kind, value, source);
383
371
  }
372
+ function fallbackSignalFromMessage(value: unknown, source: ModelFallbackFailureSource | undefined): ModelFallbackFailureSignal | undefined {
373
+ return fallbackSignalForMessage(modelFailureMessage(value), value, source);
374
+ }
375
+ function fallbackSignalFromDirectMessage(value: unknown, source: ModelFallbackFailureSource | undefined): ModelFallbackFailureSignal | undefined {
376
+ return fallbackSignalForMessage(directMessageFrom(value), value, source);
377
+ }
384
378
 
385
379
  function classifyAssistantRefusalSignal(
386
380
  value: unknown,
@@ -433,6 +427,12 @@ function structuredSignal(
433
427
  if (isRefusalSignal(causeSignal)) return causeSignal;
434
428
  firstNestedFallbackSignal ??= causeSignal;
435
429
  }
430
+ // Direct-message classification runs after nested traversal so a generic wrapper
431
+ // ("invalid request"/"400 bad request") cannot mask a non-retryable nested signal.
432
+ // Kept in the same position as the workflows classifier so the two copies stay
433
+ // behaviorally parallel (see test/unit/model-fallback-classifier-conformance.test.ts).
434
+ const directMessageSignal = fallbackSignalFromDirectMessage(value, source);
435
+ if (directMessageSignal !== undefined) return directMessageSignal;
436
436
  const statusKind = kindFromStatus(statusFrom(value));
437
437
  if (statusKind !== undefined) return makeSignal(statusKind, value, source);
438
438
  if (codeKind !== undefined) return makeSignal(codeKind, value, source);
@@ -463,8 +463,7 @@ function messageFromUnknown(value: unknown, seen: Set<unknown>): string | undefi
463
463
  const status = statusFrom(value);
464
464
  if (status !== undefined) return `Model request failed with status ${status}`;
465
465
  const code = codeFrom(value);
466
- if (code !== undefined) return `Model request failed with code ${String(code)}`;
467
- return undefined;
466
+ return code !== undefined ? `Model request failed with code ${String(code)}` : undefined;
468
467
  }
469
468
  export function modelFailureMessage(error: unknown): string {
470
469
  const structuredMessage = messageFromUnknown(error, new Set());
@@ -1,4 +1,5 @@
1
1
  import type { CodexFastModeResolvedSettings, CodexFastModeScope } from "@bastani/atomic";
2
+ import type { ModelAttempt } from "../../shared/types.ts";
2
3
 
3
4
  export interface RunnerSubagentStep {
4
5
  agent: string;
@@ -13,6 +14,7 @@ export interface RunnerSubagentStep {
13
14
  fastMode?: boolean;
14
15
  modelFastModes?: Record<string, boolean>;
15
16
  modelCandidates?: string[];
17
+ modelAttempts?: ModelAttempt[];
16
18
  codexFastModeSettings?: CodexFastModeResolvedSettings;
17
19
  codexFastModeScope?: CodexFastModeScope;
18
20
  tools?: string[];
@@ -27,6 +27,22 @@ export function toModelInfo(model: RegistryModelLike): ModelInfo {
27
27
  };
28
28
  }
29
29
 
30
+ interface KnownProviderRegistryLike {
31
+ getAvailable(): ReadonlyArray<{ provider: string }>;
32
+ /** Older hosts may not expose `getAll()`; callers probe at runtime and fall back
33
+ * to `getAvailable()`. */
34
+ getAll?: () => ReadonlyArray<{ provider: string }>;
35
+ }
36
+
37
+ /** Collect the distinct providers of every model the registry knows about — including
38
+ * providers without configured auth — falling back to `getAvailable()` when the host
39
+ * registry does not expose `getAll()`. Used to pre-filter spawn candidates whose
40
+ * provider is known but keyless. */
41
+ export function collectKnownModelProviders(registry: KnownProviderRegistryLike): string[] {
42
+ const models = typeof registry.getAll === "function" ? registry.getAll() : registry.getAvailable();
43
+ return [...new Set(models.map((model) => model.provider))];
44
+ }
45
+
30
46
  /** Resolve the effective thinking level from a model string (which may contain a known suffix like `:high`)
31
47
  * and an explicit thinking config value. Returns `undefined` when no thinking is applicable
32
48
  * (e.g. no model was specified, or the model has no suffix and no config was provided). */
@@ -80,6 +80,8 @@ export interface RunSyncOptions {
80
80
  modelOverride?: string;
81
81
  /** Registry models available for heuristic bare-model resolution */
82
82
  availableModels?: Array<{ provider: string; id: string; fullId: string }>;
83
+ /** Providers known to the registry before auth filtering */
84
+ knownModelProviders?: string[];
83
85
  /** Current parent-session provider to prefer for ambiguous bare model ids */
84
86
  preferredModelProvider?: string;
85
87
  /** Current parent-session model to try after configured fallback models */
@@ -4,6 +4,36 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.9.4-alpha.6] - 2026-07-01
8
+
9
+ ### Changed
10
+
11
+ - Aligned the web-access extension peer dependency with upstream pi TUI `^0.80.3`; no web-access extension source changes were needed for this metadata sync.
12
+
13
+ ## [0.9.4-alpha.5] - 2026-07-01
14
+
15
+ ### Changed
16
+
17
+ - Published a synchronized Atomic 0.9.4-alpha.5 prerelease for the web-access extension; no web-access extension changes were made after 0.9.4-alpha.1.
18
+
19
+ ## [0.9.4-alpha.4] - 2026-06-30
20
+
21
+ ### Changed
22
+
23
+ - Published a synchronized Atomic 0.9.4-alpha.4 prerelease for the web-access extension; no web-access extension changes were made after 0.9.4-alpha.1.
24
+
25
+ ## [0.9.4-alpha.3] - 2026-06-30
26
+
27
+ ### Changed
28
+
29
+ - Published a synchronized Atomic 0.9.4-alpha.3 prerelease for the web-access extension; no web-access extension changes were made after 0.9.4-alpha.1.
30
+
31
+ ## [0.9.4-alpha.1] - 2026-06-29
32
+
33
+ ### Changed
34
+
35
+ - Published a synchronized Atomic 0.9.4-alpha.1 prerelease for the web-access extension; no web-access extension changes were made after 0.9.3.
36
+
7
37
  ## [0.9.3] - 2026-06-29
8
38
 
9
39
  ### Changed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/web-access",
3
- "version": "0.9.3",
3
+ "version": "0.9.4-alpha.10",
4
4
  "private": true,
5
5
  "description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
6
6
  "contributors": [
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@bastani/atomic": "*",
34
- "@earendil-works/pi-tui": "^0.80.2"
34
+ "@earendil-works/pi-tui": "^0.80.3"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@bastani/atomic": {
@@ -6,6 +6,60 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.9.4-alpha.9] - 2026-07-02
10
+
11
+ ### Changed
12
+
13
+ - Changed the Claude Fable 5 reasoning level back from `high` to `xhigh` across all builtin workflow model chains (`ralph` prompt-engineer/reviewer-a/reviewer-b/reviewer-c, `goal` reviewer, `deep-research-codebase` planner, and `open-claude-design`), covering both the native `anthropic/claude-fable-5` entries and their OpenRouter mirrors; this reverts the `xhigh` → `high` change shipped in 0.9.4-alpha.8.
14
+ - Curated all builtin workflow model chains against Atomic's agentic-coding benchmark (pass@1 / avg cost per task, 2026-07-02) under a role-based placement principle: **reviewers get best-in-class verification quality, every other stage gets the best measured performance-per-dollar**. Reviewer stages keep `anthropic/claude-fable-5:xhigh` (70% / $13.41, `ralph` reviewer-a and the `goal` reviewer), `openai-codex/gpt-5.5:xhigh` (67% / $7.23, reviewer-b), and `zai/glm-5.2:xhigh` (44% / $3.92, reviewer-c for third-family diversity). Non-reviewer stages moved to perf-per-dollar primaries: `ralph` prompt-engineer and the `deep-research-codebase` planner from `claude-fable-5:xhigh` to `openai-codex/gpt-5.5:xhigh` (−3pts for half the cost, with `fable-5:xhigh` as the first cross-family fallback), and the `deep-research-codebase` explorer from unbenchmarked `gpt-5.4-mini:low` to the measured cheap-tier value point `openai-codex/gpt-5.5:low` ($1.20 / task, 28 steps, 9.4k output tokens), backed only by measured fallbacks (`claude-opus-4.8:low` at 41% / $2.29, then `glm-5.2:high`). Unbenchmarked models (`gpt-5.4-mini`, `claude-haiku-4.5`) and unmeasured levels (`gemini-3.5-flash:low`) are removed entirely — every chain entry now corresponds to a benchmark datapoint. Dropped strictly dominated candidates from every chain: `claude-sonnet-5` (40–54% at $4.08–$26.40 per task with up to 268 steps), `claude-sonnet-4.6` (30% / $5.52), `gemini-3.1-pro` (12% / $9.48), and `gemini-3.5-flash` (37% / $7.34 with 276k output tokens). Moved `claude-opus-4.8` fallback entries from `:xhigh` to `:high` — its cost/value point (52% / $4.28 vs 54% / $8.01) — everywhere except `open-claude-design`, which keeps an Anthropic-led chain (`fable-5:xhigh` primary, Opus at `:xhigh`) since design quality, not $/task, is its objective. Added `anthropic/claude-fable-5:low` (60% / $3.76) as the Anthropic candidate in the medium-tier `ralph` research/orchestrator and `goal` worker chains.
15
+ - Normalized all GLM-5.2 chain entries to the model's two real reasoning tiers: GLM-5.2's thinking-level map collapses `minimal`/`low`/`medium`/`high` to its "high" effort and `xhigh` to "max", so the previous `zai/glm-5.2:medium` entries in the `ralph` research/orchestrator and `goal` worker chains silently ran (and billed) at the "high" tier under a misleading label. Native `zai`/`zai-coding-cn` entries in medium-tier chains now say `:high` explicitly, judgment-tier chains keep `:xhigh` (→ "max"), and the `openrouter/z-ai/glm-5.2` mirror — which only maps `:xhigh` — is now always `:xhigh` instead of unsupported `:medium`.
16
+
17
+ ## [0.9.4-alpha.8] - 2026-07-02
18
+
19
+ ### Changed
20
+
21
+ - Changed the Claude Fable 5 reasoning level from `xhigh` to `high` across all builtin workflow model chains (`ralph` prompt-engineer/reviewer-a/reviewer-b/reviewer-c, `goal` reviewer, `deep-research-codebase` planner, and `open-claude-design`), covering both the native `anthropic/claude-fable-5` entries and their OpenRouter mirrors.
22
+
23
+ ### Fixed
24
+
25
+ - Fixed the builtin `goal` reviewer and `deep-research-codebase` planner model fallback chains missing the OpenRouter mirror of their primary model: `openrouter/anthropic/claude-fable-5` is now the first OpenRouter fallback candidate in both chains, matching the ordering already used by the `ralph` prompt-engineer/reviewer and `open-claude-design` chains.
26
+
27
+ ## [0.9.4-alpha.7] - 2026-07-02
28
+
29
+ ### Fixed
30
+
31
+ - Fixed workflow stage model fallback so request/context incompatibility failures (HTTP 400/413/422 bad/unprocessable/payload-too-large request, unsupported tool/parameter, context-length/context-window overflow, `invalid_request`/`bad_request`/`too_large` errors) advance the chain to the next candidate instead of stopping. When none of the configured candidates can serve the request, the stage now falls back to the current user-selected model. Refusals, content-filter/safety blocks, cancellations, and task failures still stop the chain ([#1580](https://github.com/bastani-inc/atomic/issues/1580)).
32
+
33
+ ## [0.9.4-alpha.6] - 2026-07-01
34
+
35
+ ### Changed
36
+
37
+ - Aligned the workflows extension peer dependency with upstream pi TUI `^0.80.3`; no workflows extension source changes were needed for this metadata sync.
38
+
39
+ ## [0.9.4-alpha.5] - 2026-07-01
40
+
41
+ ### Changed
42
+
43
+ - Published a synchronized Atomic 0.9.4-alpha.5 prerelease for the workflows extension; no workflow changes were made after 0.9.4-alpha.3.
44
+
45
+ ## [0.9.4-alpha.4] - 2026-06-30
46
+
47
+ ### Changed
48
+
49
+ - Published a synchronized Atomic 0.9.4-alpha.4 prerelease for the workflows extension; no workflow changes were made after 0.9.4-alpha.3.
50
+
51
+ ## [0.9.4-alpha.3] - 2026-06-30
52
+
53
+ ### Fixed
54
+
55
+ - Classified generic provider `Connection error.` / `fetch failed` transport outages as explicit workflow transport errors so stage fallback metadata can distinguish them from ordinary provider/model outages while preserving the normal next-model fallback order.
56
+
57
+ ## [0.9.4-alpha.1] - 2026-06-29
58
+
59
+ ### Fixed
60
+
61
+ - Fixed workflow lifecycle notices for structured workflow outputs whose returned `status` is `failed` or `blocked`: the runtime now records those runs as failed/blocked instead of successful completions, preserves their returned output, carries blocked summaries into lifecycle notice reasons, marks returned failures non-resumable with explicit terminal failure metadata, and emits failure/blocked lifecycle cards rather than success/checkmark notices.
62
+
9
63
  ## [0.9.3] - 2026-06-29
10
64
 
11
65
  ### Breaking Changes
@@ -31,18 +31,18 @@ Adding workflow files under `.atomic/workflows/` (project scope) or `~/.atomic/a
31
31
 
32
32
  ### Workflow lifecycle notifications
33
33
 
34
- Workflow lifecycle notices are enabled by default. They send steer prompts into the main chat/model context when a run completes or fails. Awaiting-input prompts are tracked for dedupe/restore, but they do not wake the main chat agent. Configure lifecycle tracking in the same extension config file:
34
+ Workflow lifecycle notices are enabled by default. They send steer prompts into the main chat/model context when a run completes, fails, or ends blocked. Awaiting-input prompts are tracked for dedupe/restore, but they do not wake the main chat agent. Configure lifecycle tracking in the same extension config file:
35
35
 
36
36
  ```json
37
37
  {
38
38
  "workflowNotifications": {
39
39
  "enabled": true,
40
- "notifyOn": ["completed", "failed", "awaiting_input"]
40
+ "notifyOn": ["completed", "failed", "blocked", "awaiting_input"]
41
41
  }
42
42
  }
43
43
  ```
44
44
 
45
- Set `enabled` to `false` to disable all lifecycle notices, or narrow `notifyOn` to a non-empty list of selected events. Completion and failure lifecycle notices are emitted for top-level workflow runs, use steer delivery, and wake an idle model so the lifecycle update enters the model context when it happens. Nested child workflow completion/failure is reflected inside the expanded parent graph instead of producing separate top-level completion cards. Awaiting-input states are tracked for dedupe/restore, but workflows do not enqueue main-chat `/workflow connect` cards for them; prompt state remains visible through workflow status/connect surfaces, avoiding stale actionable cards if a prompt resolves while the main chat is streaming.
45
+ Set `enabled` to `false` to disable all lifecycle notices, or narrow `notifyOn` to a non-empty list of selected events. Completion, failure, and blocked lifecycle notices are emitted for top-level workflow runs, use steer delivery, and wake an idle model so the lifecycle update enters the model context when it happens. Nested child workflow completion/failure is reflected inside the expanded parent graph instead of producing separate top-level completion cards. Awaiting-input states are tracked for dedupe/restore, but workflows do not enqueue main-chat `/workflow connect` cards for them; prompt state remains visible through workflow status/connect surfaces, avoiding stale actionable cards if a prompt resolves while the main chat is streaming.
46
46
 
47
47
  When a stage human-in-the-loop prompt is answered from the workflow TUI/stage chat, workflows also emits a separate display-only `workflows:hil-answer-notice` custom message. It records the answer for user-visible audit, but it does not wake the main agent, enter LLM context, or authorize answering later workflow prompts. Answers sent by the main-chat `workflow` tool do not emit this notice because the tool result already tells the main agent what happened.
48
48
 
@@ -736,7 +736,7 @@ Config-based discovery (`~/.atomic/agent/extensions/workflow/config.json` or `.a
736
736
  },
737
737
  "workflowNotifications": {
738
738
  "enabled": true,
739
- "notifyOn": ["completed", "failed", "awaiting_input"]
739
+ "notifyOn": ["completed", "failed", "blocked", "awaiting_input"]
740
740
  }
741
741
  }
742
742
  ```
@@ -31,41 +31,43 @@ export interface DeepResearchCodebaseResult {
31
31
 
32
32
  export const FILE_ONLY_OUTPUT = "file-only" satisfies WorkflowOutputMode;
33
33
 
34
+ // Chains curated from Atomic's agentic-coding benchmark (see ralph-models.ts
35
+ // for the frontier data and placement principle: only reviewers get
36
+ // best-in-class models; the planner is a perf-per-dollar stage).
34
37
  export const PLANNER_MODEL_CONFIG = {
35
- model: "anthropic/claude-fable-5:xhigh",
38
+ model: "openai-codex/gpt-5.5:xhigh",
36
39
  fallbackModels: [
37
- "openai-codex/gpt-5.5:xhigh",
38
40
  "github-copilot/gpt-5.5:xhigh",
39
41
  "openai/gpt-5.5:xhigh",
40
- "github-copilot/claude-opus-4.8 (1m):xhigh",
41
- "anthropic/claude-opus-4-8:xhigh",
42
+ "anthropic/claude-fable-5:xhigh",
43
+ "github-copilot/claude-opus-4.8 (1m):high",
44
+ "anthropic/claude-opus-4-8:high",
42
45
  "zai/glm-5.2:xhigh",
43
46
  "zai-coding-cn/glm-5.2:xhigh",
44
- "github-copilot/gemini-3.5-flash (1m):high",
45
- "google/gemini-3.5-flash:high",
46
- "google-vertex/gemini-3.5-flash:high",
47
- "github-copilot/gemini-3.1-pro-preview (1m):high",
48
- "google/gemini-3.1-pro-preview:high",
49
- "google-vertex/gemini-3.1-pro-preview:high",
50
47
  "openrouter/openai/gpt-5.5:xhigh",
51
- "openrouter/anthropic/claude-opus-4-8:xhigh",
52
- "openrouter/z-ai/glm-5.2:xhigh",
53
- "openrouter/google/gemini-3.5-flash:high",
54
- "openrouter/google/gemini-3.1-pro-preview:high"
48
+ "openrouter/anthropic/claude-fable-5:xhigh",
49
+ "openrouter/anthropic/claude-opus-4-8:high",
50
+ "openrouter/z-ai/glm-5.2:xhigh"
55
51
  ],
56
52
  excludedTools: ["ask_user_question"],
57
53
  } as const;
58
54
 
55
+ // gpt-5.5:low is the measured cheap-tier diamond ($1.20/task, 28 steps, 9.4k
56
+ // output tokens). Benchmark-measured models only: opus-4.8:low (41%/$2.29)
57
+ // and glm-5.2:high (36%/$2.84) back it up; unbenchmarked minis/haiku/flash
58
+ // are excluded.
59
59
  export const EXPLORER_MODEL_CONFIG = {
60
- model: "openai-codex/gpt-5.4-mini:low",
60
+ model: "openai-codex/gpt-5.5:low",
61
61
  fallbackModels: [
62
- "github-copilot/gpt-5.4-mini:low",
63
- "openai/gpt-5.4-mini:low",
64
- "github-copilot/claude-haiku-4.5:low",
65
- "anthropic/claude-haiku-4-5:low",
66
- "github-copilot/gemini-3.5-flash (1m):low",
67
- "google/gemini-3.5-flash:low",
68
- "google-vertex/gemini-3.5-flash:low",
62
+ "github-copilot/gpt-5.5:low",
63
+ "openai/gpt-5.5:low",
64
+ "github-copilot/claude-opus-4.8 (1m):low",
65
+ "anthropic/claude-opus-4-8:low",
66
+ "zai/glm-5.2:high",
67
+ "zai-coding-cn/glm-5.2:high",
68
+ "openrouter/openai/gpt-5.5:low",
69
+ "openrouter/anthropic/claude-opus-4-8:low",
70
+ "openrouter/z-ai/glm-5.2:xhigh",
69
71
  ],
70
72
  excludedTools: ["ask_user_question"],
71
73
  } as const;
@@ -92,26 +92,22 @@ export async function runGoalWorkflow(ctx: GoalRunnerContext, options: GoalWorkf
92
92
  const comparisonBaseBranch = normalizeBranchInput(inputs.base_branch, "origin/main");
93
93
  const { ledger, ledgerPath, artifactDir } = await createGoalLedger(objective);
94
94
 
95
+ // Chains curated from Atomic's agentic-coding benchmark (see
96
+ // ralph-models.ts for the frontier data and drop rationale).
95
97
  const workerModelConfig = {
96
98
  model: "openai-codex/gpt-5.5:medium",
97
99
  fallbackModels: [
98
100
  "github-copilot/gpt-5.5:medium",
99
101
  "openai/gpt-5.5:medium",
102
+ "anthropic/claude-fable-5:low",
100
103
  "github-copilot/claude-opus-4.8 (1m):medium",
101
104
  "anthropic/claude-opus-4-8:medium",
102
- "zai/glm-5.2:medium",
103
- "zai-coding-cn/glm-5.2:medium",
104
- "github-copilot/gemini-3.5-flash (1m):medium",
105
- "google/gemini-3.5-flash:medium",
106
- "google-vertex/gemini-3.5-flash:medium",
107
- "github-copilot/gemini-3.1-pro-preview (1m):medium",
108
- "google/gemini-3.1-pro-preview:medium",
109
- "google-vertex/gemini-3.1-pro-preview:medium",
105
+ "zai/glm-5.2:high",
106
+ "zai-coding-cn/glm-5.2:high",
110
107
  "openrouter/openai/gpt-5.5:medium",
108
+ "openrouter/anthropic/claude-fable-5:low",
111
109
  "openrouter/anthropic/claude-opus-4-8:medium",
112
- "openrouter/z-ai/glm-5.2:medium",
113
- "openrouter/google/gemini-3.5-flash:medium",
114
- "openrouter/google/gemini-3.1-pro-preview:medium"
110
+ "openrouter/z-ai/glm-5.2:xhigh"
115
111
  ],
116
112
  tools: goalRunnerTools,
117
113
  };
@@ -122,21 +118,14 @@ export async function runGoalWorkflow(ctx: GoalRunnerContext, options: GoalWorkf
122
118
  "openai-codex/gpt-5.5:xhigh",
123
119
  "github-copilot/gpt-5.5:xhigh",
124
120
  "openai/gpt-5.5:xhigh",
125
- "github-copilot/claude-opus-4.8 (1m):xhigh",
126
- "anthropic/claude-opus-4-8:xhigh",
121
+ "github-copilot/claude-opus-4.8 (1m):high",
122
+ "anthropic/claude-opus-4-8:high",
127
123
  "zai/glm-5.2:xhigh",
128
124
  "zai-coding-cn/glm-5.2:xhigh",
129
- "github-copilot/gemini-3.5-flash (1m):high",
130
- "google/gemini-3.5-flash:high",
131
- "google-vertex/gemini-3.5-flash:high",
132
- "github-copilot/gemini-3.1-pro-preview (1m):high",
133
- "google/gemini-3.1-pro-preview:high",
134
- "google-vertex/gemini-3.1-pro-preview:high",
125
+ "openrouter/anthropic/claude-fable-5:xhigh",
135
126
  "openrouter/openai/gpt-5.5:xhigh",
136
- "openrouter/anthropic/claude-opus-4-8:xhigh",
137
- "openrouter/z-ai/glm-5.2:xhigh",
138
- "openrouter/google/gemini-3.5-flash:high",
139
- "openrouter/google/gemini-3.1-pro-preview:high"
127
+ "openrouter/anthropic/claude-opus-4-8:high",
128
+ "openrouter/z-ai/glm-5.2:xhigh"
140
129
  ],
141
130
  tools: goalRunnerTools,
142
131
  schema: reviewDecisionSchema,
@@ -74,6 +74,9 @@ export async function runOpenClaudeDesignWorkflow(ctx: OpenClaudeDesignContext):
74
74
  });
75
75
  }
76
76
 
77
+ // Anthropic-heavy chain for design taste; sonnet-5/sonnet-4.6 dropped as
78
+ // strictly dominated in Atomic's benchmark (see ralph-models.ts). Opus stays
79
+ // at :xhigh here — visual quality, not $/task, is the objective for design.
77
80
  const designModelConfig = {
78
81
  model: "anthropic/claude-fable-5:xhigh",
79
82
  fallbackModels: [
@@ -81,12 +84,9 @@ export async function runOpenClaudeDesignWorkflow(ctx: OpenClaudeDesignContext):
81
84
  "anthropic/claude-opus-4-8:xhigh",
82
85
  "zai/glm-5.2:xhigh",
83
86
  "zai-coding-cn/glm-5.2:xhigh",
84
- "github-copilot/claude-sonnet-4.6 (1m):high",
85
- "anthropic/claude-sonnet-4-6:high",
86
87
  "openrouter/anthropic/claude-fable-5:xhigh",
87
88
  "openrouter/anthropic/claude-opus-4-8:xhigh",
88
- "openrouter/z-ai/glm-5.2:xhigh",
89
- "openrouter/anthropic/claude-sonnet-4-6:high"
89
+ "openrouter/z-ai/glm-5.2:xhigh"
90
90
  ],
91
91
  };
92
92
  // Phase 1: combined discovery + init — one stage interviews the user via