@opendash-ai/cli 0.1.0-beta.1

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 (1212) hide show
  1. package/Dockerfile +18 -0
  2. package/README.md +15 -0
  3. package/analysis.py +171 -0
  4. package/bin/opendash +180 -0
  5. package/bunfig.toml +7 -0
  6. package/drizzle.config.ts +10 -0
  7. package/git +0 -0
  8. package/migration/20260127222353_familiar_lady_ursula/migration.sql +90 -0
  9. package/migration/20260127222353_familiar_lady_ursula/snapshot.json +796 -0
  10. package/migration/20260211171708_add_project_commands/migration.sql +1 -0
  11. package/migration/20260211171708_add_project_commands/snapshot.json +806 -0
  12. package/migration/20260213144116_wakeful_the_professor/migration.sql +11 -0
  13. package/migration/20260213144116_wakeful_the_professor/snapshot.json +897 -0
  14. package/migration/20260225215848_workspace/migration.sql +7 -0
  15. package/migration/20260225215848_workspace/snapshot.json +959 -0
  16. package/migration/20260227213759_add_session_workspace_id/migration.sql +2 -0
  17. package/migration/20260227213759_add_session_workspace_id/snapshot.json +983 -0
  18. package/migration/20260228203230_blue_harpoon/migration.sql +17 -0
  19. package/migration/20260228203230_blue_harpoon/snapshot.json +1102 -0
  20. package/migration/20260303231226_add_workspace_fields/migration.sql +5 -0
  21. package/migration/20260303231226_add_workspace_fields/snapshot.json +1013 -0
  22. package/migration/20260309230000_move_org_to_state/migration.sql +3 -0
  23. package/migration/20260309230000_move_org_to_state/snapshot.json +1156 -0
  24. package/migration/20260312043431_session_message_cursor/migration.sql +4 -0
  25. package/migration/20260312043431_session_message_cursor/snapshot.json +1168 -0
  26. package/migration/20260323234822_events/migration.sql +13 -0
  27. package/migration/20260323234822_events/snapshot.json +1271 -0
  28. package/migration/20260410174513_workspace-name/migration.sql +16 -0
  29. package/migration/20260410174513_workspace-name/snapshot.json +1271 -0
  30. package/migration/20260413175956_chief_energizer/migration.sql +13 -0
  31. package/migration/20260413175956_chief_energizer/snapshot.json +1399 -0
  32. package/migration/20260422160000_context_inheritance/migration.sql +3 -0
  33. package/migration/20260422170000_task_registry/migration.sql +18 -0
  34. package/migration/20260423145421_remove_session_entry/migration.sql +4 -0
  35. package/migration/20260515000000_actor_rename/migration.sql +7 -0
  36. package/migration/20260515010000_memory_fts/migration.sql +33 -0
  37. package/migration/20260515020000_user_task/migration.sql +29 -0
  38. package/migration/20260519000000_last_checkpoint_message_id/migration.sql +1 -0
  39. package/migration/20260521000000_message_agent_id/migration.sql +2 -0
  40. package/migration/20260521000100_actor_registry_v6/migration.sql +25 -0
  41. package/migration/20260521010000_memory_fts_v6/migration.sql +33 -0
  42. package/migration/20260521020000_memory_fts_triggers/migration.sql +17 -0
  43. package/migration/20260526000000_agent_id_main/migration.sql +14 -0
  44. package/migration/20260527000000_actor_lifecycle/migration.sql +8 -0
  45. package/migration/20260527000100_inbox/migration.sql +12 -0
  46. package/migration/20260529000000_task_todo_redesign/migration.sql +16 -0
  47. package/migration/20260603000000_task_in_progress_owner/migration.sql +1 -0
  48. package/migration/20260603000000_workflow_run/migration.sql +17 -0
  49. package/migration/20260604000000_workflow_script_sha/migration.sql +1 -0
  50. package/migration/20260608000000_claude_import/migration.sql +7 -0
  51. package/migration/20260608010000_claude_import_message_ids/migration.sql +1 -0
  52. package/migration/20260609000000_history_fts/migration.sql +29 -0
  53. package/migration/20260609230000_workflow_agent_timeout/migration.sql +1 -0
  54. package/migration/20260612000000_external_import/migration.sql +16 -0
  55. package/package.json +218 -0
  56. package/parsers-config.ts +290 -0
  57. package/script/build.ts +337 -0
  58. package/script/build_noinstall.ts +337 -0
  59. package/script/check-migrations.ts +16 -0
  60. package/script/dev.ts +38 -0
  61. package/script/fds-upload.ts +170 -0
  62. package/script/fix-node-pty.ts +28 -0
  63. package/script/generate.ts +23 -0
  64. package/script/postinstall.mjs +102 -0
  65. package/script/publish.ts +75 -0
  66. package/script/run-workspace-server +106 -0
  67. package/script/schema.ts +63 -0
  68. package/script/time.ts +6 -0
  69. package/script/trace-imports.ts +153 -0
  70. package/script/upgrade-opentui.ts +64 -0
  71. package/src/account/account.sql.ts +39 -0
  72. package/src/account/account.ts +456 -0
  73. package/src/account/repo.ts +166 -0
  74. package/src/account/schema.ts +99 -0
  75. package/src/account/url.ts +8 -0
  76. package/src/acp/README.md +174 -0
  77. package/src/acp/agent.ts +1787 -0
  78. package/src/acp/session.ts +116 -0
  79. package/src/acp/types.ts +24 -0
  80. package/src/actor/actor.sql.ts +38 -0
  81. package/src/actor/events.ts +67 -0
  82. package/src/actor/index.ts +2 -0
  83. package/src/actor/registry.ts +412 -0
  84. package/src/actor/return-header.ts +24 -0
  85. package/src/actor/schema.ts +47 -0
  86. package/src/actor/spawn-ref.ts +16 -0
  87. package/src/actor/spawn.ts +756 -0
  88. package/src/actor/turn.ts +49 -0
  89. package/src/actor/waiter.ts +166 -0
  90. package/src/agent/agent.ts +574 -0
  91. package/src/agent/config.ts +5 -0
  92. package/src/agent/generate.txt +75 -0
  93. package/src/agent/prompt/checkpoint-writer.txt +167 -0
  94. package/src/agent/prompt/compaction.txt +9 -0
  95. package/src/agent/prompt/distill.txt +199 -0
  96. package/src/agent/prompt/dream.txt +155 -0
  97. package/src/agent/prompt/explore.txt +18 -0
  98. package/src/agent/prompt/summary.txt +11 -0
  99. package/src/agent/prompt/title.txt +44 -0
  100. package/src/audio.d.ts +9 -0
  101. package/src/auth/index.ts +97 -0
  102. package/src/bus/bus-event.ts +33 -0
  103. package/src/bus/global.ts +12 -0
  104. package/src/bus/index.ts +193 -0
  105. package/src/cli/bootstrap.ts +33 -0
  106. package/src/cli/cmd/account.ts +258 -0
  107. package/src/cli/cmd/acp.ts +70 -0
  108. package/src/cli/cmd/agent.ts +248 -0
  109. package/src/cli/cmd/cmd.ts +7 -0
  110. package/src/cli/cmd/db.ts +120 -0
  111. package/src/cli/cmd/debug/agent.ts +192 -0
  112. package/src/cli/cmd/debug/config.ts +17 -0
  113. package/src/cli/cmd/debug/file.ts +100 -0
  114. package/src/cli/cmd/debug/index.ts +48 -0
  115. package/src/cli/cmd/debug/lsp.ts +61 -0
  116. package/src/cli/cmd/debug/ripgrep.ts +105 -0
  117. package/src/cli/cmd/debug/scrap.ts +16 -0
  118. package/src/cli/cmd/debug/skill.ts +23 -0
  119. package/src/cli/cmd/debug/snapshot.ts +53 -0
  120. package/src/cli/cmd/export.ts +306 -0
  121. package/src/cli/cmd/generate.ts +50 -0
  122. package/src/cli/cmd/github.ts +1647 -0
  123. package/src/cli/cmd/import.ts +208 -0
  124. package/src/cli/cmd/mcp.ts +812 -0
  125. package/src/cli/cmd/models.ts +88 -0
  126. package/src/cli/cmd/plug.ts +233 -0
  127. package/src/cli/cmd/pr.ts +138 -0
  128. package/src/cli/cmd/providers.ts +713 -0
  129. package/src/cli/cmd/run-completion.ts +77 -0
  130. package/src/cli/cmd/run.ts +694 -0
  131. package/src/cli/cmd/serve.ts +30 -0
  132. package/src/cli/cmd/session.ts +181 -0
  133. package/src/cli/cmd/stats.ts +413 -0
  134. package/src/cli/cmd/tui/app.tsx +1140 -0
  135. package/src/cli/cmd/tui/asset/TEN_VAD_LICENSE +12 -0
  136. package/src/cli/cmd/tui/asset/charge.wav +0 -0
  137. package/src/cli/cmd/tui/asset/pulse-a.wav +0 -0
  138. package/src/cli/cmd/tui/asset/pulse-b.wav +0 -0
  139. package/src/cli/cmd/tui/asset/pulse-c.wav +0 -0
  140. package/src/cli/cmd/tui/asset/ten_vad.wasm +0 -0
  141. package/src/cli/cmd/tui/asset/ten_vad_loader.js +30 -0
  142. package/src/cli/cmd/tui/attach.ts +84 -0
  143. package/src/cli/cmd/tui/component/background-image.tsx +150 -0
  144. package/src/cli/cmd/tui/component/bg-pulse.tsx +130 -0
  145. package/src/cli/cmd/tui/component/border.tsx +21 -0
  146. package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
  147. package/src/cli/cmd/tui/component/dialog-agreement.tsx +111 -0
  148. package/src/cli/cmd/tui/component/dialog-command.tsx +219 -0
  149. package/src/cli/cmd/tui/component/dialog-console-org.tsx +103 -0
  150. package/src/cli/cmd/tui/component/dialog-go-upsell.tsx +157 -0
  151. package/src/cli/cmd/tui/component/dialog-image-list.tsx +111 -0
  152. package/src/cli/cmd/tui/component/dialog-logo-design.tsx +37 -0
  153. package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
  154. package/src/cli/cmd/tui/component/dialog-mimo-login.tsx +165 -0
  155. package/src/cli/cmd/tui/component/dialog-model.tsx +335 -0
  156. package/src/cli/cmd/tui/component/dialog-provider.tsx +449 -0
  157. package/src/cli/cmd/tui/component/dialog-session-delete-failed.tsx +101 -0
  158. package/src/cli/cmd/tui/component/dialog-session-list.tsx +269 -0
  159. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
  160. package/src/cli/cmd/tui/component/dialog-skill.tsx +42 -0
  161. package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
  162. package/src/cli/cmd/tui/component/dialog-status.tsx +170 -0
  163. package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
  164. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
  165. package/src/cli/cmd/tui/component/dialog-token-plan.tsx +77 -0
  166. package/src/cli/cmd/tui/component/dialog-variant.tsx +39 -0
  167. package/src/cli/cmd/tui/component/dialog-workflows.tsx +51 -0
  168. package/src/cli/cmd/tui/component/dialog-workspace-create.tsx +289 -0
  169. package/src/cli/cmd/tui/component/dialog-workspace-unavailable.tsx +81 -0
  170. package/src/cli/cmd/tui/component/dialog-worktree.tsx +90 -0
  171. package/src/cli/cmd/tui/component/error-component.tsx +92 -0
  172. package/src/cli/cmd/tui/component/logo.tsx +961 -0
  173. package/src/cli/cmd/tui/component/plugin-route-missing.tsx +14 -0
  174. package/src/cli/cmd/tui/component/prompt/autocomplete-detect.ts +34 -0
  175. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +668 -0
  176. package/src/cli/cmd/tui/component/prompt/cwd.ts +0 -0
  177. package/src/cli/cmd/tui/component/prompt/frecency.tsx +90 -0
  178. package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
  179. package/src/cli/cmd/tui/component/prompt/index.tsx +1917 -0
  180. package/src/cli/cmd/tui/component/prompt/offset.ts +45 -0
  181. package/src/cli/cmd/tui/component/prompt/part.ts +36 -0
  182. package/src/cli/cmd/tui/component/prompt/shimmer.ts +62 -0
  183. package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
  184. package/src/cli/cmd/tui/component/spinner.tsx +24 -0
  185. package/src/cli/cmd/tui/component/starry-background.tsx +305 -0
  186. package/src/cli/cmd/tui/component/startup-loading.tsx +67 -0
  187. package/src/cli/cmd/tui/component/task-item.tsx +63 -0
  188. package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
  189. package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
  190. package/src/cli/cmd/tui/component/workflow-tree.tsx +177 -0
  191. package/src/cli/cmd/tui/config/cwd.ts +5 -0
  192. package/src/cli/cmd/tui/config/tui-migrate.ts +151 -0
  193. package/src/cli/cmd/tui/config/tui-schema.ts +38 -0
  194. package/src/cli/cmd/tui/config/tui.ts +219 -0
  195. package/src/cli/cmd/tui/context/args.tsx +16 -0
  196. package/src/cli/cmd/tui/context/directory.ts +15 -0
  197. package/src/cli/cmd/tui/context/event.ts +45 -0
  198. package/src/cli/cmd/tui/context/exit.tsx +65 -0
  199. package/src/cli/cmd/tui/context/helper.tsx +25 -0
  200. package/src/cli/cmd/tui/context/keybind.tsx +105 -0
  201. package/src/cli/cmd/tui/context/kv.tsx +86 -0
  202. package/src/cli/cmd/tui/context/language.tsx +91 -0
  203. package/src/cli/cmd/tui/context/local.tsx +469 -0
  204. package/src/cli/cmd/tui/context/plugin-keybinds.ts +41 -0
  205. package/src/cli/cmd/tui/context/project.tsx +109 -0
  206. package/src/cli/cmd/tui/context/prompt.tsx +18 -0
  207. package/src/cli/cmd/tui/context/route.tsx +68 -0
  208. package/src/cli/cmd/tui/context/sdk.tsx +150 -0
  209. package/src/cli/cmd/tui/context/sync.tsx +884 -0
  210. package/src/cli/cmd/tui/context/theme/aura.json +69 -0
  211. package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
  212. package/src/cli/cmd/tui/context/theme/carbonfox.json +248 -0
  213. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +230 -0
  214. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +230 -0
  215. package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
  216. package/src/cli/cmd/tui/context/theme/cobalt2.json +225 -0
  217. package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
  218. package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
  219. package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
  220. package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
  221. package/src/cli/cmd/tui/context/theme/github.json +233 -0
  222. package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
  223. package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
  224. package/src/cli/cmd/tui/context/theme/lucent-orng.json +234 -0
  225. package/src/cli/cmd/tui/context/theme/material.json +235 -0
  226. package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
  227. package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
  228. package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
  229. package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
  230. package/src/cli/cmd/tui/context/theme/nord.json +223 -0
  231. package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
  232. package/src/cli/cmd/tui/context/theme/opendash.json +243 -0
  233. package/src/cli/cmd/tui/context/theme/orng.json +249 -0
  234. package/src/cli/cmd/tui/context/theme/osaka-jade.json +93 -0
  235. package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
  236. package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
  237. package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
  238. package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
  239. package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
  240. package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
  241. package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
  242. package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
  243. package/src/cli/cmd/tui/context/theme.tsx +1299 -0
  244. package/src/cli/cmd/tui/context/thinking.ts +48 -0
  245. package/src/cli/cmd/tui/context/tui-config.tsx +9 -0
  246. package/src/cli/cmd/tui/event.ts +56 -0
  247. package/src/cli/cmd/tui/feature-plugins/home/footer.tsx +93 -0
  248. package/src/cli/cmd/tui/feature-plugins/home/tips-view.tsx +194 -0
  249. package/src/cli/cmd/tui/feature-plugins/home/tips.tsx +54 -0
  250. package/src/cli/cmd/tui/feature-plugins/sidebar/context.tsx +114 -0
  251. package/src/cli/cmd/tui/feature-plugins/sidebar/cwd.tsx +45 -0
  252. package/src/cli/cmd/tui/feature-plugins/sidebar/files.tsx +62 -0
  253. package/src/cli/cmd/tui/feature-plugins/sidebar/footer.tsx +93 -0
  254. package/src/cli/cmd/tui/feature-plugins/sidebar/goal.tsx +84 -0
  255. package/src/cli/cmd/tui/feature-plugins/sidebar/instructions.tsx +54 -0
  256. package/src/cli/cmd/tui/feature-plugins/sidebar/lsp.tsx +66 -0
  257. package/src/cli/cmd/tui/feature-plugins/sidebar/mcp.tsx +98 -0
  258. package/src/cli/cmd/tui/feature-plugins/sidebar/task.tsx +95 -0
  259. package/src/cli/cmd/tui/feature-plugins/sidebar/todo.tsx +51 -0
  260. package/src/cli/cmd/tui/feature-plugins/sidebar/tps.ts +31 -0
  261. package/src/cli/cmd/tui/feature-plugins/system/plugins.tsx +274 -0
  262. package/src/cli/cmd/tui/i18n/en.ts +470 -0
  263. package/src/cli/cmd/tui/i18n/es.ts +508 -0
  264. package/src/cli/cmd/tui/i18n/fr.ts +515 -0
  265. package/src/cli/cmd/tui/i18n/ja.ts +463 -0
  266. package/src/cli/cmd/tui/i18n/locales.ts +82 -0
  267. package/src/cli/cmd/tui/i18n/ru.ts +527 -0
  268. package/src/cli/cmd/tui/i18n/slash-command.ts +11 -0
  269. package/src/cli/cmd/tui/i18n/zh.ts +459 -0
  270. package/src/cli/cmd/tui/i18n/zht.ts +430 -0
  271. package/src/cli/cmd/tui/layer.ts +6 -0
  272. package/src/cli/cmd/tui/plugin/api.tsx +402 -0
  273. package/src/cli/cmd/tui/plugin/index.ts +3 -0
  274. package/src/cli/cmd/tui/plugin/internal.ts +35 -0
  275. package/src/cli/cmd/tui/plugin/runtime.ts +1057 -0
  276. package/src/cli/cmd/tui/plugin/slots.tsx +60 -0
  277. package/src/cli/cmd/tui/routes/home.tsx +172 -0
  278. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +76 -0
  279. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +116 -0
  280. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +47 -0
  281. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
  282. package/src/cli/cmd/tui/routes/session/footer.tsx +91 -0
  283. package/src/cli/cmd/tui/routes/session/index.tsx +3087 -0
  284. package/src/cli/cmd/tui/routes/session/permission.tsx +697 -0
  285. package/src/cli/cmd/tui/routes/session/question.tsx +488 -0
  286. package/src/cli/cmd/tui/routes/session/sidebar.tsx +109 -0
  287. package/src/cli/cmd/tui/routes/session/subagent-footer.tsx +143 -0
  288. package/src/cli/cmd/tui/thread.ts +323 -0
  289. package/src/cli/cmd/tui/ui/dialog-alert.tsx +61 -0
  290. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +95 -0
  291. package/src/cli/cmd/tui/ui/dialog-export-options.tsx +223 -0
  292. package/src/cli/cmd/tui/ui/dialog-help.tsx +42 -0
  293. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +123 -0
  294. package/src/cli/cmd/tui/ui/dialog-select.tsx +467 -0
  295. package/src/cli/cmd/tui/ui/dialog.tsx +207 -0
  296. package/src/cli/cmd/tui/ui/link.tsx +28 -0
  297. package/src/cli/cmd/tui/ui/spinner.ts +386 -0
  298. package/src/cli/cmd/tui/ui/toast.tsx +102 -0
  299. package/src/cli/cmd/tui/util/clipboard.ts +203 -0
  300. package/src/cli/cmd/tui/util/editor.ts +36 -0
  301. package/src/cli/cmd/tui/util/image-protocol.ts +35 -0
  302. package/src/cli/cmd/tui/util/index.ts +6 -0
  303. package/src/cli/cmd/tui/util/model.ts +23 -0
  304. package/src/cli/cmd/tui/util/pinyin.ts +20 -0
  305. package/src/cli/cmd/tui/util/provider-origin.ts +7 -0
  306. package/src/cli/cmd/tui/util/revert-diff.ts +18 -0
  307. package/src/cli/cmd/tui/util/scroll.ts +23 -0
  308. package/src/cli/cmd/tui/util/selection.ts +23 -0
  309. package/src/cli/cmd/tui/util/signal.ts +71 -0
  310. package/src/cli/cmd/tui/util/sound.ts +154 -0
  311. package/src/cli/cmd/tui/util/system-locale.ts +209 -0
  312. package/src/cli/cmd/tui/util/terminal.ts +110 -0
  313. package/src/cli/cmd/tui/util/transcript.ts +112 -0
  314. package/src/cli/cmd/tui/util/vad.ts +229 -0
  315. package/src/cli/cmd/tui/util/voice.ts +595 -0
  316. package/src/cli/cmd/tui/win32.ts +130 -0
  317. package/src/cli/cmd/tui/worker.ts +104 -0
  318. package/src/cli/cmd/uninstall.ts +351 -0
  319. package/src/cli/cmd/upgrade.ts +79 -0
  320. package/src/cli/cmd/web.ts +96 -0
  321. package/src/cli/effect/prompt.ts +25 -0
  322. package/src/cli/error.ts +82 -0
  323. package/src/cli/heap.ts +59 -0
  324. package/src/cli/i18n.ts +15 -0
  325. package/src/cli/logo.ts +52 -0
  326. package/src/cli/network.ts +68 -0
  327. package/src/cli/ui.ts +133 -0
  328. package/src/cli/upgrade.ts +41 -0
  329. package/src/command/index.ts +276 -0
  330. package/src/command/template/initialize.txt +66 -0
  331. package/src/command/template/review.txt +101 -0
  332. package/src/config/agent.ts +197 -0
  333. package/src/config/command.ts +69 -0
  334. package/src/config/compose.ts +26 -0
  335. package/src/config/config.ts +1052 -0
  336. package/src/config/console-state.ts +16 -0
  337. package/src/config/entry-name.ts +16 -0
  338. package/src/config/error.ts +21 -0
  339. package/src/config/formatter.ts +17 -0
  340. package/src/config/history.ts +21 -0
  341. package/src/config/index.ts +17 -0
  342. package/src/config/keybinds.ts +127 -0
  343. package/src/config/layout.ts +10 -0
  344. package/src/config/lsp.ts +45 -0
  345. package/src/config/managed.ts +70 -0
  346. package/src/config/markdown.ts +97 -0
  347. package/src/config/mcp.ts +172 -0
  348. package/src/config/model-id.ts +14 -0
  349. package/src/config/parse.ts +44 -0
  350. package/src/config/paths.ts +73 -0
  351. package/src/config/permission.ts +76 -0
  352. package/src/config/plugin.ts +88 -0
  353. package/src/config/provider.ts +118 -0
  354. package/src/config/server.ts +20 -0
  355. package/src/config/skills.ts +16 -0
  356. package/src/config/variable.ts +90 -0
  357. package/src/control-plane/adaptors/index.ts +52 -0
  358. package/src/control-plane/adaptors/worktree.ts +47 -0
  359. package/src/control-plane/dev/debug-workspace-plugin.ts +73 -0
  360. package/src/control-plane/schema.ts +19 -0
  361. package/src/control-plane/sse.ts +66 -0
  362. package/src/control-plane/types.ts +34 -0
  363. package/src/control-plane/util.ts +37 -0
  364. package/src/control-plane/workspace-context.ts +26 -0
  365. package/src/control-plane/workspace.sql.ts +17 -0
  366. package/src/control-plane/workspace.ts +615 -0
  367. package/src/effect/app-runtime.ts +146 -0
  368. package/src/effect/bootstrap-runtime.ts +33 -0
  369. package/src/effect/bridge.ts +48 -0
  370. package/src/effect/cross-spawn-spawner.ts +514 -0
  371. package/src/effect/index.ts +5 -0
  372. package/src/effect/instance-ref.ts +11 -0
  373. package/src/effect/instance-registry.ts +12 -0
  374. package/src/effect/instance-state.ts +81 -0
  375. package/src/effect/logger.ts +73 -0
  376. package/src/effect/memo-map.ts +3 -0
  377. package/src/effect/observability.ts +107 -0
  378. package/src/effect/run-service.ts +52 -0
  379. package/src/effect/runner.ts +210 -0
  380. package/src/effect/runtime.ts +19 -0
  381. package/src/env/index.ts +37 -0
  382. package/src/file/ignore.ts +81 -0
  383. package/src/file/index.ts +664 -0
  384. package/src/file/protected.ts +59 -0
  385. package/src/file/ripgrep.ts +485 -0
  386. package/src/file/watcher.ts +163 -0
  387. package/src/flag/flag.ts +212 -0
  388. package/src/format/formatter.ts +403 -0
  389. package/src/format/index.ts +203 -0
  390. package/src/git/index.ts +260 -0
  391. package/src/global/index.ts +54 -0
  392. package/src/history/backfill.ts +162 -0
  393. package/src/history/extract.ts +67 -0
  394. package/src/history/fts-query.ts +15 -0
  395. package/src/history/fts.sql.ts +20 -0
  396. package/src/history/index.ts +10 -0
  397. package/src/history/resolve.ts +65 -0
  398. package/src/history/service.ts +258 -0
  399. package/src/history/writer.ts +112 -0
  400. package/src/id/id.ts +87 -0
  401. package/src/ide/index.ts +73 -0
  402. package/src/inbox/inbox-ref.ts +38 -0
  403. package/src/inbox/inbox.sql.ts +26 -0
  404. package/src/inbox/inbox.ts +223 -0
  405. package/src/inbox/index.ts +3 -0
  406. package/src/inbox/render.ts +40 -0
  407. package/src/index.ts +261 -0
  408. package/src/installation/index.ts +362 -0
  409. package/src/installation/version.ts +32 -0
  410. package/src/intelligence/AUDIT.md +292 -0
  411. package/src/intelligence/ENTERPRISE-CAPABILITIES.md +317 -0
  412. package/src/intelligence/ENTERPRISE-REVIEW.md +284 -0
  413. package/src/intelligence/IMPLEMENTATION.md +214 -0
  414. package/src/intelligence/PHASE1.md +178 -0
  415. package/src/intelligence/PHASE2.5.md +162 -0
  416. package/src/intelligence/PHASE2.md +150 -0
  417. package/src/intelligence/PHASE3-REFINED.md +257 -0
  418. package/src/intelligence/PHASE3.md +188 -0
  419. package/src/intelligence/README.md +260 -0
  420. package/src/intelligence/analytics/SKILL.md +369 -0
  421. package/src/intelligence/analytics/adapters/index.ts +77 -0
  422. package/src/intelligence/analytics/benchmarks/observable-runner.ts +575 -0
  423. package/src/intelligence/analytics/benchmarks/runner.ts +758 -0
  424. package/src/intelligence/analytics/engine/index.ts +152 -0
  425. package/src/intelligence/analytics/hook.ts +154 -0
  426. package/src/intelligence/analytics/index.ts +194 -0
  427. package/src/intelligence/analytics/loader/index.ts +502 -0
  428. package/src/intelligence/analytics/memory/index.ts +455 -0
  429. package/src/intelligence/analytics/orchestrator/index.ts +329 -0
  430. package/src/intelligence/analytics/planner/index.ts +188 -0
  431. package/src/intelligence/analytics/prompt/index.ts +449 -0
  432. package/src/intelligence/analytics/reasoning/enterprise-capabilities.ts +534 -0
  433. package/src/intelligence/analytics/reasoning/enterprise-prompt.ts +321 -0
  434. package/src/intelligence/analytics/reasoning/index.ts +267 -0
  435. package/src/intelligence/analytics/reasoning/test.ts +166 -0
  436. package/src/intelligence/analytics/reasoning/visible-reasoning.ts +609 -0
  437. package/src/intelligence/analytics/registry/index.ts +176 -0
  438. package/src/intelligence/analytics/router/index.ts +352 -0
  439. package/src/intelligence/analytics/test.ts +127 -0
  440. package/src/intelligence/analytics/workflow/index.ts +375 -0
  441. package/src/intelligence/index.ts +50 -0
  442. package/src/lsp/client.ts +249 -0
  443. package/src/lsp/diagnostic.ts +29 -0
  444. package/src/lsp/index.ts +3 -0
  445. package/src/lsp/language.ts +120 -0
  446. package/src/lsp/launch.ts +21 -0
  447. package/src/lsp/lsp.ts +519 -0
  448. package/src/lsp/server.ts +1956 -0
  449. package/src/mcp/auth.ts +144 -0
  450. package/src/mcp/index.ts +939 -0
  451. package/src/mcp/oauth-callback.ts +236 -0
  452. package/src/mcp/oauth-provider.ts +214 -0
  453. package/src/memory/fts-query.ts +37 -0
  454. package/src/memory/fts.sql.ts +19 -0
  455. package/src/memory/index.ts +1 -0
  456. package/src/memory/paths.ts +116 -0
  457. package/src/memory/reconcile.ts +144 -0
  458. package/src/memory/service.ts +144 -0
  459. package/src/metrics/client.ts +40 -0
  460. package/src/metrics/event.ts +43 -0
  461. package/src/metrics/index.ts +5 -0
  462. package/src/metrics/installation.ts +18 -0
  463. package/src/metrics/subscriber.ts +58 -0
  464. package/src/metrics/util.ts +9 -0
  465. package/src/node.ts +6 -0
  466. package/src/npm/config.ts +0 -0
  467. package/src/npm/index.ts +293 -0
  468. package/src/npmcli-config.d.ts +43 -0
  469. package/src/patch/index.ts +680 -0
  470. package/src/permission/arity.ts +163 -0
  471. package/src/permission/evaluate.ts +15 -0
  472. package/src/permission/index.ts +382 -0
  473. package/src/permission/schema.ts +17 -0
  474. package/src/plugin/checkpoint-splitover.ts +60 -0
  475. package/src/plugin/cloudflare.ts +76 -0
  476. package/src/plugin/codex.ts +611 -0
  477. package/src/plugin/github-copilot/copilot.ts +368 -0
  478. package/src/plugin/github-copilot/models.ts +153 -0
  479. package/src/plugin/index.ts +637 -0
  480. package/src/plugin/install.ts +439 -0
  481. package/src/plugin/loader.ts +216 -0
  482. package/src/plugin/matcher.ts +33 -0
  483. package/src/plugin/meta.ts +188 -0
  484. package/src/plugin/mimo.ts +296 -0
  485. package/src/plugin/shared.ts +323 -0
  486. package/src/plugin/subagent-progress-checker.ts +147 -0
  487. package/src/project/bootstrap.ts +59 -0
  488. package/src/project/index.ts +2 -0
  489. package/src/project/instance.ts +215 -0
  490. package/src/project/project-id.ts +48 -0
  491. package/src/project/project.sql.ts +16 -0
  492. package/src/project/project.ts +522 -0
  493. package/src/project/schema.ts +15 -0
  494. package/src/project/vcs.ts +227 -0
  495. package/src/project/workspace-trust.ts +67 -0
  496. package/src/provider/auth.ts +234 -0
  497. package/src/provider/error.ts +216 -0
  498. package/src/provider/index.ts +5 -0
  499. package/src/provider/models.ts +180 -0
  500. package/src/provider/provider.ts +1788 -0
  501. package/src/provider/schema.ts +36 -0
  502. package/src/provider/sdk/copilot/README.md +5 -0
  503. package/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +170 -0
  504. package/src/provider/sdk/copilot/chat/get-response-metadata.ts +15 -0
  505. package/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +19 -0
  506. package/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts +64 -0
  507. package/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts +815 -0
  508. package/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts +28 -0
  509. package/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +44 -0
  510. package/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts +83 -0
  511. package/src/provider/sdk/copilot/copilot-provider.ts +100 -0
  512. package/src/provider/sdk/copilot/index.ts +2 -0
  513. package/src/provider/sdk/copilot/openai-compatible-error.ts +27 -0
  514. package/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts +335 -0
  515. package/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
  516. package/src/provider/sdk/copilot/responses/openai-config.ts +18 -0
  517. package/src/provider/sdk/copilot/responses/openai-error.ts +22 -0
  518. package/src/provider/sdk/copilot/responses/openai-responses-api-types.ts +214 -0
  519. package/src/provider/sdk/copilot/responses/openai-responses-language-model.ts +1770 -0
  520. package/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts +173 -0
  521. package/src/provider/sdk/copilot/responses/openai-responses-settings.ts +1 -0
  522. package/src/provider/sdk/copilot/responses/tool/code-interpreter.ts +87 -0
  523. package/src/provider/sdk/copilot/responses/tool/file-search.ts +127 -0
  524. package/src/provider/sdk/copilot/responses/tool/image-generation.ts +114 -0
  525. package/src/provider/sdk/copilot/responses/tool/local-shell.ts +64 -0
  526. package/src/provider/sdk/copilot/responses/tool/web-search-preview.ts +103 -0
  527. package/src/provider/sdk/copilot/responses/tool/web-search.ts +102 -0
  528. package/src/provider/transform.ts +1376 -0
  529. package/src/pty/index.ts +364 -0
  530. package/src/pty/pty.bun.ts +26 -0
  531. package/src/pty/pty.node.ts +27 -0
  532. package/src/pty/pty.ts +25 -0
  533. package/src/pty/schema.ts +17 -0
  534. package/src/question/index.ts +252 -0
  535. package/src/question/schema.ts +17 -0
  536. package/src/server/adapter.bun.ts +40 -0
  537. package/src/server/adapter.node.ts +66 -0
  538. package/src/server/adapter.ts +21 -0
  539. package/src/server/auth.ts +16 -0
  540. package/src/server/error.ts +53 -0
  541. package/src/server/event.ts +7 -0
  542. package/src/server/fence.ts +81 -0
  543. package/src/server/mdns.ts +60 -0
  544. package/src/server/middleware.ts +94 -0
  545. package/src/server/projectors.ts +28 -0
  546. package/src/server/proxy.ts +171 -0
  547. package/src/server/pty-ticket.ts +42 -0
  548. package/src/server/rate-limit.ts +38 -0
  549. package/src/server/routes/control/index.ts +160 -0
  550. package/src/server/routes/control/workspace.ts +203 -0
  551. package/src/server/routes/global.ts +367 -0
  552. package/src/server/routes/instance/bash-interactive.ts +82 -0
  553. package/src/server/routes/instance/config.ts +89 -0
  554. package/src/server/routes/instance/event.ts +108 -0
  555. package/src/server/routes/instance/experimental.ts +408 -0
  556. package/src/server/routes/instance/file.ts +190 -0
  557. package/src/server/routes/instance/httpapi/config.ts +51 -0
  558. package/src/server/routes/instance/httpapi/permission.ts +72 -0
  559. package/src/server/routes/instance/httpapi/project.ts +62 -0
  560. package/src/server/routes/instance/httpapi/provider.ts +142 -0
  561. package/src/server/routes/instance/httpapi/question.ts +121 -0
  562. package/src/server/routes/instance/httpapi/server.ts +153 -0
  563. package/src/server/routes/instance/index.ts +301 -0
  564. package/src/server/routes/instance/mcp.ts +260 -0
  565. package/src/server/routes/instance/middleware.ts +44 -0
  566. package/src/server/routes/instance/permission.ts +73 -0
  567. package/src/server/routes/instance/project.ts +122 -0
  568. package/src/server/routes/instance/provider.ts +158 -0
  569. package/src/server/routes/instance/pty.ts +302 -0
  570. package/src/server/routes/instance/question.ts +162 -0
  571. package/src/server/routes/instance/session.ts +1328 -0
  572. package/src/server/routes/instance/sync.ts +143 -0
  573. package/src/server/routes/instance/trace.ts +59 -0
  574. package/src/server/routes/instance/tui.ts +384 -0
  575. package/src/server/routes/instance/workflows.ts +142 -0
  576. package/src/server/routes/ui.ts +37 -0
  577. package/src/server/server.ts +146 -0
  578. package/src/server/workspace.ts +122 -0
  579. package/src/session/auto-dream.ts +123 -0
  580. package/src/session/boundary.ts +77 -0
  581. package/src/session/budgeted-read.ts +118 -0
  582. package/src/session/checkpoint-align.ts +29 -0
  583. package/src/session/checkpoint-context.ts +36 -0
  584. package/src/session/checkpoint-paths.ts +86 -0
  585. package/src/session/checkpoint-progress-reconcile.ts +111 -0
  586. package/src/session/checkpoint-retry.ts +192 -0
  587. package/src/session/checkpoint-templates.ts +114 -0
  588. package/src/session/checkpoint-validator.ts +259 -0
  589. package/src/session/checkpoint.ts +1560 -0
  590. package/src/session/classify.ts +117 -0
  591. package/src/session/claude-import.ts +381 -0
  592. package/src/session/codex-import.ts +416 -0
  593. package/src/session/compaction.ts +545 -0
  594. package/src/session/external-import.sql.ts +18 -0
  595. package/src/session/external-import.ts +136 -0
  596. package/src/session/goal.ts +232 -0
  597. package/src/session/index.ts +1 -0
  598. package/src/session/instruction.ts +276 -0
  599. package/src/session/last-message-info.ts +32 -0
  600. package/src/session/llm-request-prefix.ts +82 -0
  601. package/src/session/llm.ts +734 -0
  602. package/src/session/max-mode.ts +410 -0
  603. package/src/session/message-v2.ts +1138 -0
  604. package/src/session/message.ts +191 -0
  605. package/src/session/opendash-import.ts +281 -0
  606. package/src/session/overflow.ts +53 -0
  607. package/src/session/prefix-capture-ref.ts +48 -0
  608. package/src/session/processor.ts +983 -0
  609. package/src/session/projectors.ts +137 -0
  610. package/src/session/prompt/anthropic.txt +177 -0
  611. package/src/session/prompt/beast.txt +186 -0
  612. package/src/session/prompt/build-switch.txt +5 -0
  613. package/src/session/prompt/codex.txt +108 -0
  614. package/src/session/prompt/compose.txt +119 -0
  615. package/src/session/prompt/copilot-gpt-5.txt +173 -0
  616. package/src/session/prompt/deepseek.txt +156 -0
  617. package/src/session/prompt/default.old.txt +151 -0
  618. package/src/session/prompt/default.txt +209 -0
  619. package/src/session/prompt/gemini.txt +186 -0
  620. package/src/session/prompt/glm.txt +73 -0
  621. package/src/session/prompt/gpt.txt +134 -0
  622. package/src/session/prompt/kimi.txt +117 -0
  623. package/src/session/prompt/max-steps.txt +16 -0
  624. package/src/session/prompt/minimax.txt +165 -0
  625. package/src/session/prompt/text-loop-recovery.ts +40 -0
  626. package/src/session/prompt/text-ngram-detection.ts +116 -0
  627. package/src/session/prompt/trinity.txt +128 -0
  628. package/src/session/prompt.ts +3878 -0
  629. package/src/session/prune.ts +481 -0
  630. package/src/session/retry.ts +178 -0
  631. package/src/session/revert.ts +161 -0
  632. package/src/session/run-state.ts +135 -0
  633. package/src/session/schema.ts +36 -0
  634. package/src/session/session.sql.ts +110 -0
  635. package/src/session/session.ts +908 -0
  636. package/src/session/status.ts +89 -0
  637. package/src/session/summary.ts +163 -0
  638. package/src/session/system.ts +97 -0
  639. package/src/session/todo.ts +77 -0
  640. package/src/session/trajectory.ts +98 -0
  641. package/src/share/index.ts +2 -0
  642. package/src/share/session.ts +57 -0
  643. package/src/share/share-next.ts +381 -0
  644. package/src/share/share.sql.ts +13 -0
  645. package/src/shell/shell.ts +124 -0
  646. package/src/skill/builtin/.bundle/self-extend/SKILL.md +131 -0
  647. package/src/skill/builtin/.bundle/self-extend/reference/hook-api.md +242 -0
  648. package/src/skill/builtin/.bundle/self-extend/reference/skill-api.md +114 -0
  649. package/src/skill/builtin/.bundle/self-extend/reference/tool-api.md +115 -0
  650. package/src/skill/builtin/.bundle/self-extend/reference/tui-api.md +258 -0
  651. package/src/skill/builtin/bundle.macro.ts +30 -0
  652. package/src/skill/builtin/extract.ts +41 -0
  653. package/src/skill/compose/.bundle/ask/SKILL.md +58 -0
  654. package/src/skill/compose/.bundle/brainstorm/SKILL.md +200 -0
  655. package/src/skill/compose/.bundle/brainstorm/scripts/frame-template.html +214 -0
  656. package/src/skill/compose/.bundle/brainstorm/scripts/helper.js +88 -0
  657. package/src/skill/compose/.bundle/brainstorm/scripts/server.cjs +354 -0
  658. package/src/skill/compose/.bundle/brainstorm/scripts/start-server.sh +148 -0
  659. package/src/skill/compose/.bundle/brainstorm/scripts/stop-server.sh +56 -0
  660. package/src/skill/compose/.bundle/brainstorm/spec-document-reviewer-prompt.md +50 -0
  661. package/src/skill/compose/.bundle/brainstorm/visual-companion.md +258 -0
  662. package/src/skill/compose/.bundle/debug/CREATION-LOG.md +119 -0
  663. package/src/skill/compose/.bundle/debug/SKILL.md +297 -0
  664. package/src/skill/compose/.bundle/debug/condition-based-waiting-example.ts +158 -0
  665. package/src/skill/compose/.bundle/debug/condition-based-waiting.md +106 -0
  666. package/src/skill/compose/.bundle/debug/defense-in-depth.md +122 -0
  667. package/src/skill/compose/.bundle/debug/find-polluter.sh +63 -0
  668. package/src/skill/compose/.bundle/debug/root-cause-tracing.md +144 -0
  669. package/src/skill/compose/.bundle/debug/test-academic.md +14 -0
  670. package/src/skill/compose/.bundle/debug/test-pressure-1.md +58 -0
  671. package/src/skill/compose/.bundle/debug/test-pressure-2.md +68 -0
  672. package/src/skill/compose/.bundle/debug/test-pressure-3.md +69 -0
  673. package/src/skill/compose/.bundle/execute/SKILL.md +71 -0
  674. package/src/skill/compose/.bundle/feedback/SKILL.md +214 -0
  675. package/src/skill/compose/.bundle/merge/SKILL.md +252 -0
  676. package/src/skill/compose/.bundle/new-skill/SKILL.md +211 -0
  677. package/src/skill/compose/.bundle/parallel/SKILL.md +168 -0
  678. package/src/skill/compose/.bundle/plan/SKILL.md +183 -0
  679. package/src/skill/compose/.bundle/plan/plan-document-reviewer-prompt.md +50 -0
  680. package/src/skill/compose/.bundle/report/SKILL.md +180 -0
  681. package/src/skill/compose/.bundle/review/SKILL.md +104 -0
  682. package/src/skill/compose/.bundle/review/code-reviewer.md +178 -0
  683. package/src/skill/compose/.bundle/subagent/SKILL.md +325 -0
  684. package/src/skill/compose/.bundle/subagent/code-quality-reviewer-prompt.md +26 -0
  685. package/src/skill/compose/.bundle/subagent/implementer-prompt.md +128 -0
  686. package/src/skill/compose/.bundle/subagent/spec-reviewer-prompt.md +118 -0
  687. package/src/skill/compose/.bundle/tdd/SKILL.md +360 -0
  688. package/src/skill/compose/.bundle/tdd/testing-anti-patterns.md +299 -0
  689. package/src/skill/compose/.bundle/verify/SKILL.md +140 -0
  690. package/src/skill/compose/.bundle/worktree/SKILL.md +234 -0
  691. package/src/skill/compose/LICENSE-karpathy +28 -0
  692. package/src/skill/compose/LICENSE-superpowers +26 -0
  693. package/src/skill/compose/bundle.macro.ts +30 -0
  694. package/src/skill/compose/extract.ts +85 -0
  695. package/src/skill/discovery.ts +116 -0
  696. package/src/skill/index.ts +328 -0
  697. package/src/snapshot/index.ts +777 -0
  698. package/src/sql.d.ts +4 -0
  699. package/src/storage/db.bun.ts +8 -0
  700. package/src/storage/db.node.ts +8 -0
  701. package/src/storage/db.ts +172 -0
  702. package/src/storage/index.ts +26 -0
  703. package/src/storage/json-migration.ts +426 -0
  704. package/src/storage/read-sqlite.bun.ts +11 -0
  705. package/src/storage/read-sqlite.node.ts +13 -0
  706. package/src/storage/read-sqlite.ts +10 -0
  707. package/src/storage/schema.sql.ts +10 -0
  708. package/src/storage/schema.ts +7 -0
  709. package/src/storage/storage.ts +331 -0
  710. package/src/sync/README.md +179 -0
  711. package/src/sync/event.sql.ts +16 -0
  712. package/src/sync/index.ts +278 -0
  713. package/src/sync/schema.ts +14 -0
  714. package/src/task/events.ts +28 -0
  715. package/src/task/gate-state.ts +54 -0
  716. package/src/task/gate.ts +116 -0
  717. package/src/task/index.ts +1 -0
  718. package/src/task/registry.ts +394 -0
  719. package/src/task/schema.ts +43 -0
  720. package/src/task/task.sql.ts +50 -0
  721. package/src/team/events.ts +22 -0
  722. package/src/team/index.ts +113 -0
  723. package/src/team/schema.ts +31 -0
  724. package/src/temporary.ts +33 -0
  725. package/src/tool/actor.shell.txt +72 -0
  726. package/src/tool/actor.ts +804 -0
  727. package/src/tool/actor.txt +103 -0
  728. package/src/tool/apply_patch.ts +308 -0
  729. package/src/tool/apply_patch.txt +33 -0
  730. package/src/tool/bash-interactive.ts +183 -0
  731. package/src/tool/bash.ts +722 -0
  732. package/src/tool/bash.txt +123 -0
  733. package/src/tool/bash_token_efficient_pipeline.ts +189 -0
  734. package/src/tool/change-directory.ts +91 -0
  735. package/src/tool/codesearch.ts +63 -0
  736. package/src/tool/codesearch.txt +12 -0
  737. package/src/tool/edit.ts +752 -0
  738. package/src/tool/edit.txt +10 -0
  739. package/src/tool/external-directory.ts +132 -0
  740. package/src/tool/glob.ts +100 -0
  741. package/src/tool/glob.txt +6 -0
  742. package/src/tool/grep.ts +145 -0
  743. package/src/tool/grep.txt +8 -0
  744. package/src/tool/history.ts +146 -0
  745. package/src/tool/history.txt +17 -0
  746. package/src/tool/index.ts +4 -0
  747. package/src/tool/invalid.ts +20 -0
  748. package/src/tool/invocation-style.ts +17 -0
  749. package/src/tool/lsp.ts +91 -0
  750. package/src/tool/lsp.txt +19 -0
  751. package/src/tool/mcp-exa.ts +78 -0
  752. package/src/tool/memory-path-guard.ts +162 -0
  753. package/src/tool/memory.ts +81 -0
  754. package/src/tool/memory.txt +69 -0
  755. package/src/tool/multiedit.ts +54 -0
  756. package/src/tool/multiedit.txt +41 -0
  757. package/src/tool/notebook-edit.ts +225 -0
  758. package/src/tool/notebook-edit.txt +10 -0
  759. package/src/tool/plan-enter.txt +16 -0
  760. package/src/tool/plan-exit.txt +14 -0
  761. package/src/tool/plan.ts +179 -0
  762. package/src/tool/question.ts +67 -0
  763. package/src/tool/question.txt +10 -0
  764. package/src/tool/read-state.ts +44 -0
  765. package/src/tool/read.ts +327 -0
  766. package/src/tool/read.txt +14 -0
  767. package/src/tool/recoverable.ts +35 -0
  768. package/src/tool/registry.ts +429 -0
  769. package/src/tool/schema.ts +17 -0
  770. package/src/tool/session-cwd.ts +35 -0
  771. package/src/tool/shell-tokenize.ts +374 -0
  772. package/src/tool/shell-wrap.ts +235 -0
  773. package/src/tool/skill.ts +76 -0
  774. package/src/tool/skill.txt +5 -0
  775. package/src/tool/task.shell.txt +57 -0
  776. package/src/tool/task.ts +456 -0
  777. package/src/tool/task.txt +56 -0
  778. package/src/tool/tool.ts +166 -0
  779. package/src/tool/truncate.ts +201 -0
  780. package/src/tool/truncation-dir.ts +4 -0
  781. package/src/tool/webfetch.ts +208 -0
  782. package/src/tool/webfetch.txt +13 -0
  783. package/src/tool/websearch/index.ts +104 -0
  784. package/src/tool/websearch/mimo.ts +118 -0
  785. package/src/tool/websearch/websearch.txt +14 -0
  786. package/src/tool/workflow.ts +357 -0
  787. package/src/tool/workflow.txt +25 -0
  788. package/src/tool/write.ts +88 -0
  789. package/src/tool/write.txt +10 -0
  790. package/src/util/abort.ts +35 -0
  791. package/src/util/archive.ts +15 -0
  792. package/src/util/color.ts +17 -0
  793. package/src/util/data-url.ts +9 -0
  794. package/src/util/defer.ts +10 -0
  795. package/src/util/effect-http-client.ts +11 -0
  796. package/src/util/effect-zod.ts +367 -0
  797. package/src/util/env-info.ts +62 -0
  798. package/src/util/error.ts +78 -0
  799. package/src/util/filesystem.ts +243 -0
  800. package/src/util/fn.ts +21 -0
  801. package/src/util/format.ts +20 -0
  802. package/src/util/iife.ts +3 -0
  803. package/src/util/index.ts +14 -0
  804. package/src/util/keybind.ts +101 -0
  805. package/src/util/lazy.ts +18 -0
  806. package/src/util/local-context.ts +23 -0
  807. package/src/util/locale.ts +79 -0
  808. package/src/util/lock.ts +96 -0
  809. package/src/util/log.ts +234 -0
  810. package/src/util/media.ts +26 -0
  811. package/src/util/network.ts +9 -0
  812. package/src/util/opendash-process.ts +24 -0
  813. package/src/util/process.ts +174 -0
  814. package/src/util/provider-priority.ts +48 -0
  815. package/src/util/queue.ts +60 -0
  816. package/src/util/record.ts +3 -0
  817. package/src/util/rpc.ts +64 -0
  818. package/src/util/schema.ts +53 -0
  819. package/src/util/scrap.ts +10 -0
  820. package/src/util/signal.ts +12 -0
  821. package/src/util/ssrf.ts +116 -0
  822. package/src/util/timeout.ts +14 -0
  823. package/src/util/token.ts +5 -0
  824. package/src/util/tool-compat.ts +144 -0
  825. package/src/util/update-schema.ts +13 -0
  826. package/src/util/which.ts +14 -0
  827. package/src/util/wildcard.ts +57 -0
  828. package/src/workflow/builtin/compose.js +749 -0
  829. package/src/workflow/builtin/deep-research.js +398 -0
  830. package/src/workflow/builtin.ts +59 -0
  831. package/src/workflow/events.ts +72 -0
  832. package/src/workflow/meta.ts +335 -0
  833. package/src/workflow/persistence.ts +312 -0
  834. package/src/workflow/resolve.ts +45 -0
  835. package/src/workflow/runtime-ref.ts +18 -0
  836. package/src/workflow/runtime.ts +1447 -0
  837. package/src/workflow/sandbox.ts +286 -0
  838. package/src/workflow/workflow.sql.ts +31 -0
  839. package/src/workflow/workspace.ts +69 -0
  840. package/src/worktree/index.ts +629 -0
  841. package/sst-env.d.ts +10 -0
  842. package/test/AGENTS.md +133 -0
  843. package/test/account/repo.test.ts +352 -0
  844. package/test/account/service.test.ts +456 -0
  845. package/test/acp/agent-interface.test.ts +51 -0
  846. package/test/acp/event-subscription.test.ts +725 -0
  847. package/test/actor/cancel-cascade.test.ts +432 -0
  848. package/test/actor/no-completion-listener.test.ts +41 -0
  849. package/test/actor/poststop-progress-write-permission.repro.test.ts +414 -0
  850. package/test/actor/registry-render.test.ts +113 -0
  851. package/test/actor/registry-status.test.ts +111 -0
  852. package/test/actor/registry.test.ts +619 -0
  853. package/test/actor/return-header.test.ts +40 -0
  854. package/test/actor/spawn-lifecycle.test.ts +346 -0
  855. package/test/actor/spawn-no-deadlock.test.ts +340 -0
  856. package/test/actor/spawn-notification.test.ts +393 -0
  857. package/test/actor/spawn-task-autostart.test.ts +530 -0
  858. package/test/actor/spawn.test.ts +1106 -0
  859. package/test/actor/status-event-payload.test.ts +132 -0
  860. package/test/actor/terminology.test.ts +39 -0
  861. package/test/actor/turn.test.ts +125 -0
  862. package/test/actor/waiter.test.ts +246 -0
  863. package/test/agent/agent.test.ts +935 -0
  864. package/test/agent/allowlist.test.ts +45 -0
  865. package/test/auth/auth.test.ts +86 -0
  866. package/test/bus/bus-effect.test.ts +162 -0
  867. package/test/bus/bus-integration.test.ts +87 -0
  868. package/test/bus/bus.test.ts +219 -0
  869. package/test/cli/account.test.ts +26 -0
  870. package/test/cli/cmd/tui/autocomplete-detect.test.ts +55 -0
  871. package/test/cli/cmd/tui/extmark-cjk.test.ts +96 -0
  872. package/test/cli/cmd/tui/offset.test.ts +101 -0
  873. package/test/cli/cmd/tui/prompt-part.test.ts +97 -0
  874. package/test/cli/error.test.ts +18 -0
  875. package/test/cli/github-action.test.ts +198 -0
  876. package/test/cli/github-remote.test.ts +80 -0
  877. package/test/cli/import.test.ts +54 -0
  878. package/test/cli/plugin-auth-picker.test.ts +120 -0
  879. package/test/cli/run-completion.test.ts +131 -0
  880. package/test/cli/tui/keybind-plugin.test.ts +90 -0
  881. package/test/cli/tui/plugin-add.test.ts +111 -0
  882. package/test/cli/tui/plugin-install.test.ts +87 -0
  883. package/test/cli/tui/plugin-lifecycle.test.ts +224 -0
  884. package/test/cli/tui/plugin-loader-entrypoint.test.ts +484 -0
  885. package/test/cli/tui/plugin-loader-pure.test.ts +71 -0
  886. package/test/cli/tui/plugin-loader.test.ts +816 -0
  887. package/test/cli/tui/plugin-toggle.test.ts +157 -0
  888. package/test/cli/tui/revert-diff.test.ts +35 -0
  889. package/test/cli/tui/route-agent-id.test.ts +26 -0
  890. package/test/cli/tui/sidebar-tps.test.ts +63 -0
  891. package/test/cli/tui/slot-replace.test.tsx +47 -0
  892. package/test/cli/tui/sync-bucket.test.ts +29 -0
  893. package/test/cli/tui/theme-store.test.ts +51 -0
  894. package/test/cli/tui/thread.test.ts +125 -0
  895. package/test/cli/tui/transcript.test.ts +426 -0
  896. package/test/cli/tui/use-event.test.tsx +175 -0
  897. package/test/cli/tui/voice.test.ts +443 -0
  898. package/test/command/deep-research-command.test.ts +16 -0
  899. package/test/config/agent-color.test.ts +77 -0
  900. package/test/config/checkpoint-fork.test.ts +21 -0
  901. package/test/config/config.test.ts +2577 -0
  902. package/test/config/fixtures/empty-frontmatter.md +4 -0
  903. package/test/config/fixtures/frontmatter.md +28 -0
  904. package/test/config/fixtures/markdown-header.md +11 -0
  905. package/test/config/fixtures/no-frontmatter.md +1 -0
  906. package/test/config/fixtures/weird-model-id.md +13 -0
  907. package/test/config/lsp.test.ts +87 -0
  908. package/test/config/markdown.test.ts +228 -0
  909. package/test/config/plugin.test.ts +0 -0
  910. package/test/config/tui.test.ts +627 -0
  911. package/test/control-plane/adaptors.test.ts +71 -0
  912. package/test/control-plane/sse.test.ts +56 -0
  913. package/test/effect/app-runtime-logger.test.ts +92 -0
  914. package/test/effect/cross-spawn-spawner.test.ts +411 -0
  915. package/test/effect/instance-state.test.ts +482 -0
  916. package/test/effect/observability.test.ts +46 -0
  917. package/test/effect/run-service.test.ts +46 -0
  918. package/test/effect/runner-warn-log.test.ts +111 -0
  919. package/test/effect/runner.test.ts +494 -0
  920. package/test/fake/provider.ts +90 -0
  921. package/test/file/fsmonitor.test.ts +68 -0
  922. package/test/file/ignore.test.ts +10 -0
  923. package/test/file/index.test.ts +963 -0
  924. package/test/file/path-traversal.test.ts +243 -0
  925. package/test/file/ripgrep.test.ts +218 -0
  926. package/test/file/watcher.test.ts +249 -0
  927. package/test/filesystem/filesystem.test.ts +319 -0
  928. package/test/fixture/db.ts +11 -0
  929. package/test/fixture/fixture.test.ts +58 -0
  930. package/test/fixture/fixture.ts +223 -0
  931. package/test/fixture/flock-worker.ts +72 -0
  932. package/test/fixture/lsp/fake-lsp-server.js +75 -0
  933. package/test/fixture/plug-worker.ts +93 -0
  934. package/test/fixture/plugin-meta-worker.ts +19 -0
  935. package/test/fixture/skills/agents-sdk/SKILL.md +152 -0
  936. package/test/fixture/skills/agents-sdk/references/callable.md +92 -0
  937. package/test/fixture/skills/cloudflare/SKILL.md +211 -0
  938. package/test/fixture/skills/index.json +6 -0
  939. package/test/fixture/tui-plugin.ts +328 -0
  940. package/test/fixture/tui-runtime.ts +31 -0
  941. package/test/format/format.test.ts +244 -0
  942. package/test/git/git.test.ts +128 -0
  943. package/test/global/fixture/global-paths-worker.ts +17 -0
  944. package/test/global/mimocode-home.test.ts +143 -0
  945. package/test/history/backfill.test.ts +160 -0
  946. package/test/history/extract.test.ts +106 -0
  947. package/test/history/fts-query.test.ts +30 -0
  948. package/test/history/resolve.test.ts +130 -0
  949. package/test/history/service.test.ts +210 -0
  950. package/test/history/writer.test.ts +163 -0
  951. package/test/ide/ide.test.ts +82 -0
  952. package/test/inbox/drain-in-loop.test.ts +230 -0
  953. package/test/inbox/fork-agent-compat.test.ts +387 -0
  954. package/test/inbox/gc-on-init.test.ts +167 -0
  955. package/test/inbox/send-no-block.test.ts +120 -0
  956. package/test/inbox/sender-cancel-independence.test.ts +160 -0
  957. package/test/inbox/wake-matrix.test.ts +141 -0
  958. package/test/installation/installation.test.ts +255 -0
  959. package/test/keybind.test.ts +421 -0
  960. package/test/lib/effect.ts +53 -0
  961. package/test/lib/filesystem.ts +10 -0
  962. package/test/lib/llm-server.ts +770 -0
  963. package/test/lib/mock-llm.ts +159 -0
  964. package/test/lib/scripted-llm-server.ts +245 -0
  965. package/test/lsp/client.test.ts +98 -0
  966. package/test/lsp/index.test.ts +109 -0
  967. package/test/lsp/launch.test.ts +22 -0
  968. package/test/lsp/lifecycle.test.ts +184 -0
  969. package/test/mcp/headers.test.ts +178 -0
  970. package/test/mcp/lifecycle.test.ts +786 -0
  971. package/test/mcp/oauth-auto-connect.test.ts +281 -0
  972. package/test/mcp/oauth-browser.test.ts +268 -0
  973. package/test/mcp/oauth-callback.test.ts +34 -0
  974. package/test/memory/abort-leak-webfetch.ts +49 -0
  975. package/test/memory/abort-leak.test.ts +127 -0
  976. package/test/memory/cc-frontmatter.test.ts +85 -0
  977. package/test/memory/cc-paths.test.ts +60 -0
  978. package/test/memory/cc-reconcile.test.ts +239 -0
  979. package/test/memory/cc-search.test.ts +151 -0
  980. package/test/memory/fts-query.test.ts +48 -0
  981. package/test/memory/fts-rowid-stability.test.ts +271 -0
  982. package/test/memory/paths.test.ts +210 -0
  983. package/test/memory/reconcile.test.ts +115 -0
  984. package/test/memory/service.test.ts +169 -0
  985. package/test/npm.test.ts +18 -0
  986. package/test/patch/patch.test.ts +348 -0
  987. package/test/permission/abort.test.ts +116 -0
  988. package/test/permission/arity.test.ts +33 -0
  989. package/test/permission/disabled.test.ts +68 -0
  990. package/test/permission/next.test.ts +1116 -0
  991. package/test/permission/non-interactive.test.ts +55 -0
  992. package/test/permission-task.test.ts +326 -0
  993. package/test/plugin/actor-hooks.test.ts +1471 -0
  994. package/test/plugin/auth-override.test.ts +79 -0
  995. package/test/plugin/checkpoint-splitover.test.ts +434 -0
  996. package/test/plugin/cloudflare.test.ts +68 -0
  997. package/test/plugin/codex.test.ts +123 -0
  998. package/test/plugin/github-copilot-models.test.ts +163 -0
  999. package/test/plugin/install-concurrency.test.ts +140 -0
  1000. package/test/plugin/install.test.ts +570 -0
  1001. package/test/plugin/loader-shared.test.ts +1169 -0
  1002. package/test/plugin/matcher.test.ts +97 -0
  1003. package/test/plugin/meta.test.ts +137 -0
  1004. package/test/plugin/mimo.test.ts +259 -0
  1005. package/test/plugin/session-loop-hooks.test.ts +159 -0
  1006. package/test/plugin/shared.test.ts +88 -0
  1007. package/test/plugin/subagent-progress-checker.test.ts +227 -0
  1008. package/test/plugin/trigger.test.ts +116 -0
  1009. package/test/plugin/workspace-adaptor.test.ts +109 -0
  1010. package/test/preload.ts +102 -0
  1011. package/test/project/migrate-global.test.ts +152 -0
  1012. package/test/project/project-id.test.ts +64 -0
  1013. package/test/project/project.test.ts +504 -0
  1014. package/test/project/vcs.test.ts +286 -0
  1015. package/test/project/worktree-remove.test.ts +126 -0
  1016. package/test/project/worktree.test.ts +222 -0
  1017. package/test/provider/amazon-bedrock.test.ts +462 -0
  1018. package/test/provider/copilot/convert-to-copilot-messages.test.ts +523 -0
  1019. package/test/provider/copilot/copilot-chat-model.test.ts +592 -0
  1020. package/test/provider/error.test.ts +160 -0
  1021. package/test/provider/gitlab-duo.test.ts +413 -0
  1022. package/test/provider/model-groups.test.ts +389 -0
  1023. package/test/provider/provider-chunk-timeout.test.ts +23 -0
  1024. package/test/provider/provider.test.ts +2610 -0
  1025. package/test/provider/transform.test.ts +3523 -0
  1026. package/test/pty/pty-output-isolation.test.ts +146 -0
  1027. package/test/pty/pty-session.test.ts +102 -0
  1028. package/test/pty/pty-shell.test.ts +69 -0
  1029. package/test/question/question.test.ts +464 -0
  1030. package/test/server/global-session-list.test.ts +105 -0
  1031. package/test/server/project-init-git.test.ts +137 -0
  1032. package/test/server/rate-limit.test.ts +66 -0
  1033. package/test/server/session-actions.test.ts +49 -0
  1034. package/test/server/session-list.test.ts +110 -0
  1035. package/test/server/session-messages.test.ts +220 -0
  1036. package/test/server/session-prompt-busy.test.ts +146 -0
  1037. package/test/server/session-prompt-heartbeat.test.ts +131 -0
  1038. package/test/server/session-select.test.ts +100 -0
  1039. package/test/server/session-task-route.test.ts +165 -0
  1040. package/test/server/summarize-route-main-slice.test.ts +99 -0
  1041. package/test/server/trace-attributes.test.ts +76 -0
  1042. package/test/server/workflows-route.test.ts +363 -0
  1043. package/test/session/bootstrap-skip-system.test.ts +121 -0
  1044. package/test/session/boundary.test.ts +33 -0
  1045. package/test/session/budgeted-read.test.ts +74 -0
  1046. package/test/session/checkpoint-align.test.ts +58 -0
  1047. package/test/session/checkpoint-boundary.test.ts +186 -0
  1048. package/test/session/checkpoint-child-session.test.ts +509 -0
  1049. package/test/session/checkpoint-context.test.ts +141 -0
  1050. package/test/session/checkpoint-drain.test.ts +189 -0
  1051. package/test/session/checkpoint-extract-titles.test.ts +58 -0
  1052. package/test/session/checkpoint-fork-mode.test.ts +577 -0
  1053. package/test/session/checkpoint-main-slice.test.ts +261 -0
  1054. package/test/session/checkpoint-paths.test.ts +87 -0
  1055. package/test/session/checkpoint-permission.test.ts +136 -0
  1056. package/test/session/checkpoint-progress-reconcile.test.ts +219 -0
  1057. package/test/session/checkpoint-rebuild-unify.test.ts +158 -0
  1058. package/test/session/checkpoint-rebuild-v3.test.ts +259 -0
  1059. package/test/session/checkpoint-render-verify.test.ts +512 -0
  1060. package/test/session/checkpoint-retry.test.ts +150 -0
  1061. package/test/session/checkpoint-splitover-integration.test.ts +533 -0
  1062. package/test/session/checkpoint-templates.test.ts +51 -0
  1063. package/test/session/checkpoint-thresholds.test.ts +120 -0
  1064. package/test/session/checkpoint-validator.test.ts +189 -0
  1065. package/test/session/classify-integration.test.ts +476 -0
  1066. package/test/session/classify.test.ts +390 -0
  1067. package/test/session/codex-import.test.ts +331 -0
  1068. package/test/session/compaction-agent-scope.test.ts +209 -0
  1069. package/test/session/context-inheritance.test.ts +46 -0
  1070. package/test/session/external-import.test.ts +17 -0
  1071. package/test/session/fork-prefix-invariant.test.ts +116 -0
  1072. package/test/session/goal.test.ts +106 -0
  1073. package/test/session/instruction.test.ts +388 -0
  1074. package/test/session/invalid-output-continuation.test.ts +150 -0
  1075. package/test/session/last-message-info.test.ts +47 -0
  1076. package/test/session/length-tool-safety.test.ts +125 -0
  1077. package/test/session/llm-request-prefix.test.ts +197 -0
  1078. package/test/session/llm-retry.test.ts +59 -0
  1079. package/test/session/llm-system-prompt.test.ts +479 -0
  1080. package/test/session/llm.test.ts +1268 -0
  1081. package/test/session/main-lifecycle.test.ts +51 -0
  1082. package/test/session/main-runloop-history-invariant.test.ts +182 -0
  1083. package/test/session/max-mode-econnreset.test.ts +232 -0
  1084. package/test/session/max-mode.test.ts +54 -0
  1085. package/test/session/message-v2-filter.test.ts +197 -0
  1086. package/test/session/message-v2.test.ts +1119 -0
  1087. package/test/session/messages-default-main.test.ts +105 -0
  1088. package/test/session/messages-pagination.test.ts +888 -0
  1089. package/test/session/overflow.test.ts +576 -0
  1090. package/test/session/processor-effect.test.ts +853 -0
  1091. package/test/session/prompt-effect.test.ts +1534 -0
  1092. package/test/session/prompt-rebuild-loop.test.ts +108 -0
  1093. package/test/session/prompt-rebuild-reset.test.ts +67 -0
  1094. package/test/session/prompt-sweep.test.ts +145 -0
  1095. package/test/session/prompt-task-gate.test.ts +127 -0
  1096. package/test/session/prompt.test.ts +827 -0
  1097. package/test/session/prune-main-slice.test.ts +272 -0
  1098. package/test/session/prune-skip-system.test.ts +346 -0
  1099. package/test/session/prune.test.ts +419 -0
  1100. package/test/session/rebuild-microcompact.test.ts +318 -0
  1101. package/test/session/recall-reminder.test.ts +37 -0
  1102. package/test/session/recent-user-msg.test.ts +219 -0
  1103. package/test/session/retry.test.ts +410 -0
  1104. package/test/session/revert-compact.test.ts +639 -0
  1105. package/test/session/run-state-tuple-key.test.ts +152 -0
  1106. package/test/session/session-create-registers-main.test.ts +70 -0
  1107. package/test/session/session.test.ts +181 -0
  1108. package/test/session/snapshot-tool-race.test.ts +301 -0
  1109. package/test/session/structured-output-integration.test.ts +264 -0
  1110. package/test/session/structured-output-retry.test.ts +127 -0
  1111. package/test/session/structured-output.test.ts +397 -0
  1112. package/test/session/summary-main-slice.test.ts +170 -0
  1113. package/test/session/system.test.ts +72 -0
  1114. package/test/session/text-loop-detection.test.ts +185 -0
  1115. package/test/session/text-loop-integration.test.ts +448 -0
  1116. package/test/session/text-ngram-detection.test.ts +169 -0
  1117. package/test/session/trajectory.test.ts +236 -0
  1118. package/test/share/share-next.test.ts +332 -0
  1119. package/test/shell/shell.test.ts +73 -0
  1120. package/test/skill/compose-review.test.ts +174 -0
  1121. package/test/skill/discovery.test.ts +116 -0
  1122. package/test/skill/skill.test.ts +466 -0
  1123. package/test/snapshot/snapshot.test.ts +1531 -0
  1124. package/test/storage/db.test.ts +16 -0
  1125. package/test/storage/json-migration.test.ts +831 -0
  1126. package/test/storage/storage.test.ts +293 -0
  1127. package/test/sync/index.test.ts +237 -0
  1128. package/test/task/gate-state.test.ts +66 -0
  1129. package/test/task/gate.test.ts +167 -0
  1130. package/test/task/registry.test.ts +171 -0
  1131. package/test/task/state-machine.test.ts +292 -0
  1132. package/test/team/migrate-to-inbox.test.ts +124 -0
  1133. package/test/team/team.test.ts +75 -0
  1134. package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
  1135. package/test/tool/actor-cancel.test.ts +211 -0
  1136. package/test/tool/actor-recover.test.ts +50 -0
  1137. package/test/tool/actor-send.test.ts +200 -0
  1138. package/test/tool/actor-status.test.ts +296 -0
  1139. package/test/tool/actor-wait.test.ts +193 -0
  1140. package/test/tool/actor.shell.test.ts +266 -0
  1141. package/test/tool/actor.test.ts +753 -0
  1142. package/test/tool/apply_patch.test.ts +626 -0
  1143. package/test/tool/bash.test.ts +1232 -0
  1144. package/test/tool/bash_token_efficient_pipeline.test.ts +329 -0
  1145. package/test/tool/describe-workflow.test.ts +12 -0
  1146. package/test/tool/edit.test.ts +730 -0
  1147. package/test/tool/external-directory.test.ts +207 -0
  1148. package/test/tool/fixtures/large-image.png +0 -0
  1149. package/test/tool/fixtures/models-api.json +65179 -0
  1150. package/test/tool/glob.test.ts +81 -0
  1151. package/test/tool/grep.test.ts +114 -0
  1152. package/test/tool/history.test.ts +144 -0
  1153. package/test/tool/invocation-style.test.ts +30 -0
  1154. package/test/tool/memory-edit-ask-skip.test.ts +62 -0
  1155. package/test/tool/memory-path-guard.test.ts +594 -0
  1156. package/test/tool/memory.test.ts +71 -0
  1157. package/test/tool/question.test.ts +167 -0
  1158. package/test/tool/read.test.ts +483 -0
  1159. package/test/tool/recoverable.test.ts +36 -0
  1160. package/test/tool/registry-invocation-style.test.ts +121 -0
  1161. package/test/tool/registry.test.ts +164 -0
  1162. package/test/tool/shell-tokenize.test.ts +309 -0
  1163. package/test/tool/shell-wrap-missing-script.test.ts +128 -0
  1164. package/test/tool/shell-wrap.test.ts +345 -0
  1165. package/test/tool/skill.test.ts +99 -0
  1166. package/test/tool/task-recover.test.ts +36 -0
  1167. package/test/tool/task.shell.test.ts +234 -0
  1168. package/test/tool/task.test.ts +296 -0
  1169. package/test/tool/tool-def-shell-shape.test.ts +23 -0
  1170. package/test/tool/tool-define.test.ts +59 -0
  1171. package/test/tool/tool-validation-error.test.ts +25 -0
  1172. package/test/tool/truncation.test.ts +253 -0
  1173. package/test/tool/webfetch.test.ts +103 -0
  1174. package/test/tool/whitelist.test.ts +377 -0
  1175. package/test/tool/write.test.ts +244 -0
  1176. package/test/util/data-url.test.ts +14 -0
  1177. package/test/util/effect-zod.test.ts +869 -0
  1178. package/test/util/env-info.test.ts +26 -0
  1179. package/test/util/error.test.ts +38 -0
  1180. package/test/util/filesystem.test.ts +656 -0
  1181. package/test/util/format.test.ts +59 -0
  1182. package/test/util/glob.test.ts +164 -0
  1183. package/test/util/iife.test.ts +36 -0
  1184. package/test/util/lazy.test.ts +50 -0
  1185. package/test/util/lock.test.ts +72 -0
  1186. package/test/util/log.test.ts +69 -0
  1187. package/test/util/module.test.ts +59 -0
  1188. package/test/util/process.test.ts +128 -0
  1189. package/test/util/queue.test.ts +64 -0
  1190. package/test/util/ssrf.test.ts +115 -0
  1191. package/test/util/timeout.test.ts +21 -0
  1192. package/test/util/tool-compat.test.ts +189 -0
  1193. package/test/util/which.test.ts +100 -0
  1194. package/test/util/wildcard.test.ts +90 -0
  1195. package/test/workflow/builtin.test.ts +36 -0
  1196. package/test/workflow/compose.test.ts +668 -0
  1197. package/test/workflow/deep-research-cluster.test.ts +47 -0
  1198. package/test/workflow/lib.ts +243 -0
  1199. package/test/workflow/meta.test.ts +142 -0
  1200. package/test/workflow/model-routing.test.ts +68 -0
  1201. package/test/workflow/persistence.test.ts +229 -0
  1202. package/test/workflow/resolve.test.ts +37 -0
  1203. package/test/workflow/runtime-nested.test.ts +419 -0
  1204. package/test/workflow/runtime-worktree.test.ts +261 -0
  1205. package/test/workflow/runtime.test.ts +1142 -0
  1206. package/test/workflow/sandbox.test.ts +259 -0
  1207. package/test/workflow/tool.test.ts +487 -0
  1208. package/test/workflow/verify-wow.test.ts +144 -0
  1209. package/test/workflow/workspace.test.ts +88 -0
  1210. package/test/workspace/workspace-restore.test.ts +281 -0
  1211. package/test/worktree/index.test.ts +30 -0
  1212. package/tsconfig.json +24 -0
@@ -0,0 +1,1376 @@
1
+ import type { ModelMessage } from "ai"
2
+ import { mergeDeep, unique } from "remeda"
3
+ import type { JSONSchema7 } from "@ai-sdk/provider"
4
+ import type { JSONSchema } from "zod/v4/core"
5
+ import type * as Provider from "./provider"
6
+ import type * as ModelsDev from "./models"
7
+ import { iife } from "@/util/iife"
8
+ import { Flag } from "@/flag/flag"
9
+
10
+ type Modality = NonNullable<ModelsDev.Model["modalities"]>["input"][number]
11
+
12
+ function mimeToModality(mime: string): Modality | undefined {
13
+ if (mime.startsWith("image/")) return "image"
14
+ if (mime.startsWith("audio/")) return "audio"
15
+ if (mime.startsWith("video/")) return "video"
16
+ if (mime === "application/pdf") return "pdf"
17
+ return undefined
18
+ }
19
+
20
+ // MiMo vision support isn't reflected in models.dev modality data, so the
21
+ // generic capability check would strip images before they reach the model.
22
+ // mimo-auto and mimo-v2.5 accept images; mimo-v2.5-pro is text-only.
23
+ function supportsImageInput(model: Provider.Model): boolean {
24
+ if (model.providerID === "mimo" || model.providerID === "xiaomi") {
25
+ const id = model.id.toLowerCase()
26
+ if (id.includes("v2.5-pro")) return false
27
+ if (id === "mimo-auto" || id.includes("v2.5")) return true
28
+ }
29
+ // Claude and GPT models are all multimodal regardless of catalog data.
30
+ const id = model.id.toLowerCase()
31
+ const apiID = model.api.id.toLowerCase()
32
+ if (id.includes("claude") || apiID.includes("claude") || model.providerID === "anthropic") return true
33
+ if (id.includes("gpt") || apiID.includes("gpt")) return true
34
+ return model.capabilities.input.image
35
+ }
36
+
37
+ export const OUTPUT_TOKEN_MAX = Flag.OPENDASH_EXPERIMENTAL_OUTPUT_TOKEN_MAX || 32_000
38
+ const MIMO_OUTPUT_TOKEN_MAX = 128_000
39
+
40
+ // Maps npm package to the key the AI SDK expects for providerOptions
41
+ function sdkKey(npm: string): string | undefined {
42
+ switch (npm) {
43
+ case "@ai-sdk/github-copilot":
44
+ return "copilot"
45
+ case "@ai-sdk/azure":
46
+ return "azure"
47
+ case "@ai-sdk/openai":
48
+ return "openai"
49
+ case "@ai-sdk/amazon-bedrock":
50
+ return "bedrock"
51
+ case "@ai-sdk/anthropic":
52
+ case "@ai-sdk/google-vertex/anthropic":
53
+ return "anthropic"
54
+ case "@ai-sdk/google-vertex":
55
+ return "vertex"
56
+ case "@ai-sdk/google":
57
+ return "google"
58
+ case "@ai-sdk/gateway":
59
+ return "gateway"
60
+ case "@openrouter/ai-sdk-provider":
61
+ return "openrouter"
62
+ }
63
+ return undefined
64
+ }
65
+
66
+ function normalizeMessages(
67
+ msgs: ModelMessage[],
68
+ model: Provider.Model,
69
+ _options: Record<string, unknown>,
70
+ ): ModelMessage[] {
71
+ // Anthropic rejects messages with empty content - filter out empty string messages
72
+ // and remove empty text/reasoning parts from array content
73
+ if (model.api.npm === "@ai-sdk/anthropic" || model.api.npm === "@ai-sdk/amazon-bedrock") {
74
+ msgs = msgs
75
+ .map((msg) => {
76
+ if (typeof msg.content === "string") {
77
+ if (msg.content === "") return undefined
78
+ return msg
79
+ }
80
+ if (!Array.isArray(msg.content)) return msg
81
+ const filtered = msg.content.filter((part) => {
82
+ if (part.type === "text" || part.type === "reasoning") {
83
+ return part.text !== ""
84
+ }
85
+ return true
86
+ })
87
+ if (filtered.length === 0) return undefined
88
+ return { ...msg, content: filtered }
89
+ })
90
+ .filter((msg): msg is ModelMessage => msg !== undefined && msg.content !== "")
91
+ }
92
+
93
+ if (model.api.id.includes("claude")) {
94
+ const scrub = (id: string) => id.replace(/[^a-zA-Z0-9_-]/g, "_")
95
+ msgs = msgs.map((msg) => {
96
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
97
+ return {
98
+ ...msg,
99
+ content: msg.content.map((part) => {
100
+ if (part.type === "tool-call" || part.type === "tool-result") {
101
+ return { ...part, toolCallId: scrub(part.toolCallId) }
102
+ }
103
+ return part
104
+ }),
105
+ }
106
+ }
107
+ if (msg.role === "tool" && Array.isArray(msg.content)) {
108
+ return {
109
+ ...msg,
110
+ content: msg.content.map((part) => {
111
+ if (part.type === "tool-result") {
112
+ return { ...part, toolCallId: scrub(part.toolCallId) }
113
+ }
114
+ return part
115
+ }),
116
+ }
117
+ }
118
+ return msg
119
+ })
120
+ }
121
+ if (["@ai-sdk/anthropic", "@ai-sdk/google-vertex/anthropic"].includes(model.api.npm)) {
122
+ // Anthropic rejects assistant turns where tool_use blocks are followed by non-tool
123
+ // content, e.g. [tool_use, tool_use, text], with:
124
+ // `tool_use` ids were found without `tool_result` blocks immediately after...
125
+ //
126
+ // Reorder that invalid shape into [text] + [tool_use, tool_use]. Consecutive
127
+ // assistant messages are later merged by the provider/SDK, so preserving the
128
+ // original [tool_use...] then [text] order still produces the invalid payload.
129
+ //
130
+ // The root cause appears to be somewhere upstream where the stream is originally
131
+ // processed. We were unable to locate an exact narrower reproduction elsewhere,
132
+ // so we keep this transform in place for the time being.
133
+ msgs = msgs.flatMap((msg) => {
134
+ if (msg.role !== "assistant" || !Array.isArray(msg.content)) return [msg]
135
+
136
+ const parts = msg.content
137
+ const first = parts.findIndex((part) => part.type === "tool-call")
138
+ if (first === -1) return [msg]
139
+ if (!parts.slice(first).some((part) => part.type !== "tool-call")) return [msg]
140
+ return [
141
+ { ...msg, content: parts.filter((part) => part.type !== "tool-call") },
142
+ { ...msg, content: parts.filter((part) => part.type === "tool-call") },
143
+ ]
144
+ })
145
+ }
146
+ if (
147
+ model.providerID === "mistral" ||
148
+ model.api.id.toLowerCase().includes("mistral") ||
149
+ model.api.id.toLocaleLowerCase().includes("devstral")
150
+ ) {
151
+ const scrub = (id: string) => {
152
+ return id
153
+ .replace(/[^a-zA-Z0-9]/g, "") // Remove non-alphanumeric characters
154
+ .substring(0, 9) // Take first 9 characters
155
+ .padEnd(9, "0") // Pad with zeros if less than 9 characters
156
+ }
157
+ const result: ModelMessage[] = []
158
+ for (let i = 0; i < msgs.length; i++) {
159
+ const msg = msgs[i]
160
+ const nextMsg = msgs[i + 1]
161
+
162
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
163
+ msg.content = msg.content.map((part) => {
164
+ if (part.type === "tool-call" || part.type === "tool-result") {
165
+ return { ...part, toolCallId: scrub(part.toolCallId) }
166
+ }
167
+ return part
168
+ })
169
+ }
170
+ if (msg.role === "tool" && Array.isArray(msg.content)) {
171
+ msg.content = msg.content.map((part) => {
172
+ if (part.type === "tool-result") {
173
+ return { ...part, toolCallId: scrub(part.toolCallId) }
174
+ }
175
+ return part
176
+ })
177
+ }
178
+ result.push(msg)
179
+
180
+ // Fix message sequence: tool messages cannot be followed by user messages
181
+ if (msg.role === "tool" && nextMsg?.role === "user") {
182
+ result.push({
183
+ role: "assistant",
184
+ content: [
185
+ {
186
+ type: "text",
187
+ text: "Done.",
188
+ },
189
+ ],
190
+ })
191
+ }
192
+ }
193
+ return result
194
+ }
195
+
196
+ if (typeof model.capabilities.interleaved === "object" && model.capabilities.interleaved.field) {
197
+ const field = model.capabilities.interleaved.field
198
+ return msgs.map((msg) => {
199
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
200
+ const reasoningParts = msg.content.filter((part: any) => part.type === "reasoning")
201
+ const reasoningText = reasoningParts.map((part: any) => part.text).join("")
202
+
203
+ // Filter out reasoning parts from content
204
+ const filteredContent = msg.content.filter((part: any) => part.type !== "reasoning")
205
+
206
+ // Include reasoning_content | reasoning_details directly on the message for all assistant messages
207
+ if (reasoningText) {
208
+ return {
209
+ ...msg,
210
+ content: filteredContent,
211
+ providerOptions: {
212
+ ...msg.providerOptions,
213
+ openaiCompatible: {
214
+ ...msg.providerOptions?.openaiCompatible,
215
+ [field]: reasoningText,
216
+ },
217
+ },
218
+ }
219
+ }
220
+
221
+ return {
222
+ ...msg,
223
+ content: filteredContent,
224
+ }
225
+ }
226
+
227
+ return msg
228
+ })
229
+ }
230
+
231
+ return msgs
232
+ }
233
+
234
+ // Determines whether a model's provider respects inline cache_control / cachePoint
235
+ // markers. Pure name matching (model.api.id.includes("claude")) is fragile — a Claude
236
+ // model behind an OpenAI-compatible proxy gets matched but markers are silently dropped.
237
+ // See docs/cache-policy.md and upstream opendash#26786.
238
+ function supportsCacheMarkers(model: Provider.Model): boolean {
239
+ // Anthropic-only SDKs — always support inline markers
240
+ if (model.api.npm === "@ai-sdk/anthropic" || model.api.npm === "@ai-sdk/google-vertex/anthropic") return true
241
+ if (model.providerID === "anthropic" || model.providerID === "google-vertex-anthropic") return true
242
+ // Bedrock cachePoint is a Converse API feature, works across model families
243
+ if (model.api.npm === "@ai-sdk/amazon-bedrock") return true
244
+ // Multi-model providers: only Anthropic/Claude models support cache markers
245
+ if (
246
+ model.api.npm === "@openrouter/ai-sdk-provider" ||
247
+ model.api.npm === "@ai-sdk/github-copilot" ||
248
+ model.api.npm === "@ai-sdk/alibaba"
249
+ ) {
250
+ return (
251
+ model.api.id.includes("claude") ||
252
+ model.api.id.includes("anthropic") ||
253
+ model.id.includes("claude") ||
254
+ model.id.includes("anthropic")
255
+ )
256
+ }
257
+ return false
258
+ }
259
+
260
+ // The cache-control marker shape differs per provider/SDK. This is the single
261
+ // source of truth, keyed by the SDK provider-options namespace. `applyCaching`
262
+ // attaches the whole object (keyed by stored providerID) and lets `message()`
263
+ // remap the active provider's namespace to its SDK key; `tools()` (which
264
+ // bypasses that remap) resolves a single namespace up front via `cacheMarkerFor`.
265
+ // Only Anthropic and OpenRouter expose a TTL in their AI SDK — the others ignore
266
+ // an unknown `ttl`, so we thread it only there.
267
+ function cacheMarkerOptions(model: Provider.Model) {
268
+ const ttl = model.cachePromptTTL === "1h" ? { ttl: "1h" as const } : {}
269
+ return {
270
+ anthropic: { cacheControl: { type: "ephemeral", ...ttl } },
271
+ openrouter: { cacheControl: { type: "ephemeral", ...ttl } },
272
+ bedrock: { cachePoint: { type: "default" } },
273
+ openaiCompatible: { cache_control: { type: "ephemeral" } },
274
+ copilot: { copilot_cache_control: { type: "ephemeral" } },
275
+ alibaba: { cacheControl: { type: "ephemeral" } },
276
+ }
277
+ }
278
+
279
+ // Resolve the marker for a single model, already keyed under the SDK namespace
280
+ // the AI SDK expects — i.e. the remap that `message()` performs for messages,
281
+ // done up front. Used by `tools()`, whose tools never pass through `message()`.
282
+ // Returns undefined for providers that don't take inline markers (callers gate
283
+ // on `supportsCacheMarkers` first, so this is just a type-safety fallback).
284
+ function cacheMarkerFor(model: Provider.Model): Record<string, unknown> | undefined {
285
+ const shapes = cacheMarkerOptions(model)
286
+ const ns: keyof typeof shapes | undefined =
287
+ model.api.npm === "@ai-sdk/anthropic" || model.api.npm === "@ai-sdk/google-vertex/anthropic"
288
+ ? "anthropic"
289
+ : model.api.npm === "@openrouter/ai-sdk-provider"
290
+ ? "openrouter"
291
+ : model.api.npm === "@ai-sdk/amazon-bedrock"
292
+ ? "bedrock"
293
+ : model.api.npm === "@ai-sdk/github-copilot"
294
+ ? "copilot"
295
+ : model.api.npm === "@ai-sdk/alibaba"
296
+ ? "alibaba"
297
+ : undefined
298
+ if (!ns) return undefined
299
+ return { [ns]: shapes[ns] }
300
+ }
301
+
302
+ function applyCaching(msgs: ModelMessage[], model: Provider.Model): ModelMessage[] {
303
+ const providerOptions = cacheMarkerOptions(model)
304
+
305
+ // Strategy: prefix caching is longest-common-prefix based with a backward
306
+ // lookback window (Anthropic walks back ~20 blocks from a breakpoint to find
307
+ // a prior write). The markers that grow the cached prefix are pinned to the
308
+ // *tail* of the request. We place up to three stable breakpoints (Anthropic
309
+ // allows max 4):
310
+ // 1. Last system message — the immutable prompt prefix.
311
+ // 2+3. The last TWO messages — a "rolling double buffer". Each turn marks
312
+ // messages[-2] and messages[-1]; next turn the old [-1] is now [-2] and
313
+ // still carries its marker, so the lookback gets a cache READ hit, while
314
+ // the new [-1] is the WRITE for the turn after.
315
+ //
316
+ // Why two and not one: the second (next-to-last) marker is the safety
317
+ // net for the tail boundary. When the last message is removed — a
318
+ // tool-call retry, a Ctrl-C, or the user editing/deleting their latest
319
+ // message — a lone tail marker disappears with it, and how much of the
320
+ // surrounding prefix the provider then evicts depends on the upstream
321
+ // (Anthropic) KV-cache implementation. The next-to-last marker is a
322
+ // still-present, further-back write the next lookback can land on, so the
323
+ // worst case degrades to "recompute only the removed message" instead of
324
+ // "recompute the whole history". It also covers turns that append >20
325
+ // blocks (tool spam pushes the prior write outside the lookback window).
326
+ // Cost is ~equal to a single marker: the two adjacent breakpoints write
327
+ // roughly the same incremental bytes as one, split in two, and a hit
328
+ // never rewrites. A third marker would write a segment never read
329
+ // independently, so two is the minimum that covers the boundary.
330
+ // We deliberately do NOT mark a drifting midpoint or a fixed before-last-user
331
+ // INDEX: those shift every turn without tracking the tail.
332
+ const targets: ModelMessage[] = []
333
+
334
+ const systemMsgs = msgs.filter((msg) => msg.role === "system")
335
+ if (systemMsgs.length > 0) targets.push(systemMsgs[systemMsgs.length - 1])
336
+
337
+ const nonSystem = msgs.filter((msg) => msg.role !== "system")
338
+ for (const msg of nonSystem.slice(-2)) targets.push(msg)
339
+
340
+ for (const msg of unique(targets)) {
341
+ const useMessageLevelOptions =
342
+ model.providerID === "anthropic" ||
343
+ model.providerID.includes("bedrock") ||
344
+ model.api.npm === "@ai-sdk/amazon-bedrock"
345
+ const shouldUseContentOptions = !useMessageLevelOptions && Array.isArray(msg.content) && msg.content.length > 0
346
+
347
+ if (shouldUseContentOptions) {
348
+ const lastContent = msg.content[msg.content.length - 1]
349
+ if (
350
+ lastContent &&
351
+ typeof lastContent === "object" &&
352
+ lastContent.type !== "tool-approval-request" &&
353
+ lastContent.type !== "tool-approval-response"
354
+ ) {
355
+ lastContent.providerOptions = mergeDeep(lastContent.providerOptions ?? {}, providerOptions)
356
+ continue
357
+ }
358
+ }
359
+
360
+ msg.providerOptions = mergeDeep(msg.providerOptions ?? {}, providerOptions)
361
+ }
362
+
363
+ return msgs
364
+ }
365
+
366
+ function unsupportedParts(msgs: ModelMessage[], model: Provider.Model): ModelMessage[] {
367
+ return msgs.map((msg) => {
368
+ if (msg.role !== "user" || !Array.isArray(msg.content)) return msg
369
+
370
+ const filtered = msg.content.map((part) => {
371
+ if (part.type !== "file" && part.type !== "image") return part
372
+
373
+ // Check for empty base64 image data
374
+ if (part.type === "image") {
375
+ const imageStr = String(part.image)
376
+ if (imageStr.startsWith("data:")) {
377
+ const match = imageStr.match(/^data:([^;]+);base64,(.*)$/)
378
+ if (match && (!match[2] || match[2].length === 0)) {
379
+ return {
380
+ type: "text" as const,
381
+ text: "ERROR: Image file is empty or corrupted. Please provide a valid image.",
382
+ }
383
+ }
384
+ }
385
+ }
386
+
387
+ const mime = part.type === "image" ? String(part.image).split(";")[0].replace("data:", "") : part.mediaType
388
+ const filename = part.type === "file" ? part.filename : undefined
389
+ const modality = mimeToModality(mime)
390
+ if (!modality) return part
391
+ const supported = modality === "image" ? supportsImageInput(model) : model.capabilities.input[modality]
392
+ if (supported) return part
393
+
394
+ const name = filename ? `"${filename}"` : modality
395
+ return {
396
+ type: "text" as const,
397
+ text: `ERROR: Cannot read ${name} (this model does not support ${modality} input). Inform the user.`,
398
+ }
399
+ })
400
+
401
+ return { ...msg, content: filtered }
402
+ })
403
+ }
404
+
405
+ // Returns the decoded byte size of a base64 data URL, or undefined for inputs
406
+ // that aren't data URLs (remote URLs, raw binary) and therefore can't be sized.
407
+ function imageByteSize(image: string): number | undefined {
408
+ if (!image.startsWith("data:")) return undefined
409
+ const base64 = image.slice(image.indexOf(",") + 1)
410
+ if (!base64) return 0
411
+ const padding = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0
412
+ return Math.floor((base64.length * 3) / 4) - padding
413
+ }
414
+
415
+ function limitImages(msgs: ModelMessage[]): ModelMessage[] {
416
+ const maxImages = Flag.OPENDASH_MAX_PROMPT_IMAGES
417
+ const maxSize = Flag.OPENDASH_MAX_PROMPT_IMAGE_SIZE
418
+ if (maxImages === undefined && maxSize === undefined) return msgs
419
+
420
+ const total = msgs.reduce(
421
+ (sum, msg) =>
422
+ msg.role === "user" && Array.isArray(msg.content)
423
+ ? sum + msg.content.filter((part) => part.type === "image").length
424
+ : sum,
425
+ 0,
426
+ )
427
+ // Drop the oldest excess images so the most recent ones reach the model.
428
+ let toDrop = maxImages === undefined ? 0 : Math.max(0, total - maxImages)
429
+
430
+ return msgs.map((msg) => {
431
+ if (msg.role !== "user" || !Array.isArray(msg.content)) return msg
432
+ const content = msg.content.map((part) => {
433
+ if (part.type !== "image") return part
434
+ if (toDrop > 0) {
435
+ toDrop--
436
+ return { type: "text" as const, text: `[Image omitted: exceeds the configured limit of ${maxImages} prompt image(s).]` }
437
+ }
438
+ if (maxSize !== undefined) {
439
+ const size = imageByteSize(String(part.image))
440
+ if (size !== undefined && size > maxSize) {
441
+ return { type: "text" as const, text: `[Image omitted: exceeds the configured ${maxSize}-byte prompt image size limit.]` }
442
+ }
443
+ }
444
+ return part
445
+ })
446
+ return { ...msg, content }
447
+ })
448
+ }
449
+
450
+ export function message(msgs: ModelMessage[], model: Provider.Model, options: Record<string, unknown>) {
451
+ msgs = unsupportedParts(msgs, model)
452
+ msgs = limitImages(msgs)
453
+ msgs = normalizeMessages(msgs, model, options)
454
+ if (supportsCacheMarkers(model)) {
455
+ msgs = applyCaching(msgs, model)
456
+ }
457
+
458
+ // Remap providerOptions keys from stored providerID to expected SDK key
459
+ const key = sdkKey(model.api.npm)
460
+ if (key && key !== model.providerID) {
461
+ const remap = (opts: Record<string, any> | undefined) => {
462
+ if (!opts) return opts
463
+ if (!(model.providerID in opts)) return opts
464
+ const result = { ...opts }
465
+ result[key] = result[model.providerID]
466
+ delete result[model.providerID]
467
+ return result
468
+ }
469
+
470
+ msgs = msgs.map((msg) => {
471
+ if (!Array.isArray(msg.content)) return { ...msg, providerOptions: remap(msg.providerOptions) }
472
+ return {
473
+ ...msg,
474
+ providerOptions: remap(msg.providerOptions),
475
+ content: msg.content.map((part) => {
476
+ if (part.type === "tool-approval-request" || part.type === "tool-approval-response") {
477
+ return { ...part }
478
+ }
479
+ return { ...part, providerOptions: remap(part.providerOptions) }
480
+ }),
481
+ } as typeof msg
482
+ })
483
+ }
484
+
485
+ return msgs
486
+ }
487
+
488
+ // Place a cache breakpoint on the tool definitions. The cache hierarchy is
489
+ // `tools` → `system` → `messages`, so marking the LAST tool caches the entire
490
+ // tool-schema block (often several KB) as a stable prefix that sits in front of
491
+ // the system + message caches. Tools are passed to the SDK separately from
492
+ // `message()` and never go through its providerID→SDK-key remap, so we resolve
493
+ // the SDK-keyed marker via `cacheMarkerFor`. Tool registration order is stable
494
+ // (insertion order of the tools record), so "last tool" is deterministic.
495
+ export function tools<T extends Record<string, any>>(tools: T, model: Provider.Model): T {
496
+ if (!supportsCacheMarkers(model)) return tools
497
+ const marker = cacheMarkerFor(model)
498
+ if (!marker) return tools
499
+ const names = Object.keys(tools)
500
+ if (names.length === 0) return tools
501
+
502
+ const last = tools[names[names.length - 1]]
503
+ last.providerOptions = mergeDeep(last.providerOptions ?? {}, marker)
504
+ return tools
505
+ }
506
+
507
+ export function temperature(model: Provider.Model) {
508
+ const id = model.id.toLowerCase()
509
+ if (id.includes("qwen")) return 0.55
510
+ if (id.includes("claude")) return undefined
511
+ if (id.includes("gemini")) return 1.0
512
+ if (id.includes("glm-4.6")) return 1.0
513
+ if (id.includes("glm-4.7")) return 1.0
514
+ if (id.includes("minimax-m2")) return 1.0
515
+ if (id.includes("mimo")) return 1.0
516
+ if (id.includes("kimi-k2")) {
517
+ // kimi-k2-thinking & kimi-k2.5 && kimi-k2p5 && kimi-k2-5
518
+ if (["thinking", "k2.", "k2p", "k2-5"].some((s) => id.includes(s))) {
519
+ return 1.0
520
+ }
521
+ return 0.6
522
+ }
523
+ return undefined
524
+ }
525
+
526
+ export function topP(model: Provider.Model) {
527
+ const id = model.id.toLowerCase()
528
+ if (id.includes("qwen")) return 1
529
+ if (["minimax-m2", "gemini", "kimi-k2.5", "kimi-k2p5", "kimi-k2-5"].some((s) => id.includes(s))) {
530
+ return 0.95
531
+ }
532
+ return undefined
533
+ }
534
+
535
+ export function topK(model: Provider.Model) {
536
+ const id = model.id.toLowerCase()
537
+ if (id.includes("minimax-m2")) {
538
+ if (["m2.", "m25", "m21"].some((s) => id.includes(s))) return 40
539
+ return 20
540
+ }
541
+ if (id.includes("gemini")) return 64
542
+ return undefined
543
+ }
544
+
545
+ const WIDELY_SUPPORTED_EFFORTS = ["low", "medium", "high"]
546
+ const OPENAI_EFFORTS = ["none", "minimal", ...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
547
+
548
+ function anthropicAdaptiveEfforts(apiId: string): string[] | null {
549
+ if (["opus-4-7", "opus-4.7", "opus-4-8", "opus-4.8"].some((v) => apiId.includes(v))) {
550
+ return ["low", "medium", "high", "xhigh", "max"]
551
+ }
552
+ if (["opus-4-6", "opus-4.6", "sonnet-4-6", "sonnet-4.6"].some((v) => apiId.includes(v))) {
553
+ return ["low", "medium", "high", "max"]
554
+ }
555
+ return null
556
+ }
557
+
558
+ export function variants(model: Provider.Model): Record<string, Record<string, any>> {
559
+ if (!model.capabilities.reasoning) return {}
560
+
561
+ const id = model.id.toLowerCase()
562
+ const adaptiveEfforts = anthropicAdaptiveEfforts(model.api.id)
563
+ if (
564
+ id.includes("deepseek") ||
565
+ id.includes("minimax") ||
566
+ id.includes("glm") ||
567
+ id.includes("mistral") ||
568
+ id.includes("kimi") ||
569
+ id.includes("k2p5") ||
570
+ id.includes("qwen") ||
571
+ id.includes("big-pickle")
572
+ )
573
+ return {}
574
+
575
+ // see: https://docs.x.ai/docs/guides/reasoning#control-how-hard-the-model-thinks
576
+ if (id.includes("grok") && id.includes("grok-3-mini")) {
577
+ if (model.api.npm === "@openrouter/ai-sdk-provider") {
578
+ return {
579
+ low: { reasoning: { effort: "low" } },
580
+ high: { reasoning: { effort: "high" } },
581
+ }
582
+ }
583
+ return {
584
+ low: { reasoningEffort: "low" },
585
+ high: { reasoningEffort: "high" },
586
+ }
587
+ }
588
+ if (id.includes("grok")) return {}
589
+
590
+ switch (model.api.npm) {
591
+ case "@openrouter/ai-sdk-provider":
592
+ if (!model.id.includes("gpt") && !model.id.includes("gemini-3") && !model.id.includes("claude")) return {}
593
+ return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoning: { effort } }]))
594
+
595
+ case "@ai-sdk/gateway":
596
+ if (model.id.includes("anthropic")) {
597
+ if (adaptiveEfforts) {
598
+ return Object.fromEntries(
599
+ adaptiveEfforts.map((effort) => [
600
+ effort,
601
+ {
602
+ thinking: {
603
+ type: "adaptive",
604
+ },
605
+ effort,
606
+ },
607
+ ]),
608
+ )
609
+ }
610
+ return {
611
+ high: {
612
+ thinking: {
613
+ type: "enabled",
614
+ budgetTokens: 16000,
615
+ },
616
+ },
617
+ max: {
618
+ thinking: {
619
+ type: "enabled",
620
+ budgetTokens: 31999,
621
+ },
622
+ },
623
+ }
624
+ }
625
+ if (model.id.includes("google")) {
626
+ if (id.includes("2.5")) {
627
+ return {
628
+ high: {
629
+ thinkingConfig: {
630
+ includeThoughts: true,
631
+ thinkingBudget: 16000,
632
+ },
633
+ },
634
+ max: {
635
+ thinkingConfig: {
636
+ includeThoughts: true,
637
+ thinkingBudget: 24576,
638
+ },
639
+ },
640
+ }
641
+ }
642
+ return Object.fromEntries(
643
+ ["low", "high"].map((effort) => [
644
+ effort,
645
+ {
646
+ includeThoughts: true,
647
+ thinkingLevel: effort,
648
+ },
649
+ ]),
650
+ )
651
+ }
652
+ return Object.fromEntries(OPENAI_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }]))
653
+
654
+ case "@ai-sdk/github-copilot":
655
+ if (model.id.includes("gemini")) {
656
+ // currently github copilot only returns thinking
657
+ return {}
658
+ }
659
+ if (model.id.includes("claude")) {
660
+ return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }]))
661
+ }
662
+ const copilotEfforts = iife(() => {
663
+ if (id.includes("5.1-codex-max") || id.includes("5.2") || id.includes("5.3"))
664
+ return [...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
665
+ const arr = [...WIDELY_SUPPORTED_EFFORTS]
666
+ if (id.includes("gpt-5") && model.release_date >= "2025-12-04") arr.push("xhigh")
667
+ return arr
668
+ })
669
+ return Object.fromEntries(
670
+ copilotEfforts.map((effort) => [
671
+ effort,
672
+ {
673
+ reasoningEffort: effort,
674
+ reasoningSummary: "auto",
675
+ include: ["reasoning.encrypted_content"],
676
+ },
677
+ ]),
678
+ )
679
+
680
+ case "@ai-sdk/cerebras":
681
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/cerebras
682
+ case "@ai-sdk/togetherai":
683
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/togetherai
684
+ case "@ai-sdk/xai":
685
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/xai
686
+ case "@ai-sdk/deepinfra":
687
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/deepinfra
688
+ case "venice-ai-sdk-provider":
689
+ // https://docs.venice.ai/overview/guides/reasoning-models#reasoning-effort
690
+ case "@ai-sdk/openai-compatible":
691
+ return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }]))
692
+
693
+ case "@ai-sdk/azure":
694
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/azure
695
+ if (id === "o1-mini") return {}
696
+ const azureEfforts = ["low", "medium", "high"]
697
+ if (id.includes("gpt-5-") || id === "gpt-5") {
698
+ azureEfforts.unshift("minimal")
699
+ }
700
+ return Object.fromEntries(
701
+ azureEfforts.map((effort) => [
702
+ effort,
703
+ {
704
+ reasoningEffort: effort,
705
+ reasoningSummary: "auto",
706
+ include: ["reasoning.encrypted_content"],
707
+ },
708
+ ]),
709
+ )
710
+ case "@ai-sdk/openai":
711
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/openai
712
+ if (id === "gpt-5-pro") return {}
713
+ const openaiEfforts = iife(() => {
714
+ if (id.includes("codex")) {
715
+ if (id.includes("5.2") || id.includes("5.3")) return [...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
716
+ return WIDELY_SUPPORTED_EFFORTS
717
+ }
718
+ const arr = [...WIDELY_SUPPORTED_EFFORTS]
719
+ if (id.includes("gpt-5-") || id === "gpt-5") {
720
+ arr.unshift("minimal")
721
+ }
722
+ if (model.release_date >= "2025-11-13") {
723
+ arr.unshift("none")
724
+ }
725
+ if (model.release_date >= "2025-12-04") {
726
+ arr.push("xhigh")
727
+ }
728
+ return arr
729
+ })
730
+ return Object.fromEntries(
731
+ openaiEfforts.map((effort) => [
732
+ effort,
733
+ {
734
+ reasoningEffort: effort,
735
+ reasoningSummary: "auto",
736
+ include: ["reasoning.encrypted_content"],
737
+ },
738
+ ]),
739
+ )
740
+
741
+ case "@ai-sdk/anthropic":
742
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/anthropic
743
+ case "@ai-sdk/google-vertex/anthropic":
744
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/google-vertex#anthropic-provider
745
+
746
+ if (model.providerID === "github-copilot") {
747
+ if (model.api.id.includes("opus-4.7")) {
748
+ return Object.fromEntries(["medium"].map((effort) => [effort, { reasoningEffort: effort }]))
749
+ }
750
+ }
751
+
752
+ if (adaptiveEfforts) {
753
+ return Object.fromEntries(
754
+ adaptiveEfforts.map((effort) => [
755
+ effort,
756
+ {
757
+ thinking: {
758
+ type: "adaptive",
759
+ ...(["opus-4-7", "opus-4.7", "opus-4-8", "opus-4.8"].some((v) => model.api.id.includes(v))
760
+ ? { display: "summarized" }
761
+ : {}),
762
+ },
763
+ effort,
764
+ },
765
+ ]),
766
+ )
767
+ }
768
+
769
+ return {
770
+ high: {
771
+ thinking: {
772
+ type: "enabled",
773
+ budgetTokens: Math.min(16_000, Math.floor(model.limit.output / 2 - 1)),
774
+ },
775
+ },
776
+ max: {
777
+ thinking: {
778
+ type: "enabled",
779
+ budgetTokens: Math.min(31_999, model.limit.output - 1),
780
+ },
781
+ },
782
+ }
783
+
784
+ case "@ai-sdk/amazon-bedrock":
785
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock
786
+ if (adaptiveEfforts) {
787
+ return Object.fromEntries(
788
+ adaptiveEfforts.map((effort) => [
789
+ effort,
790
+ {
791
+ reasoningConfig: {
792
+ type: "adaptive",
793
+ maxReasoningEffort: effort,
794
+ ...(["opus-4-7", "opus-4.7", "opus-4-8", "opus-4.8"].some((v) => model.api.id.includes(v))
795
+ ? { display: "summarized" }
796
+ : {}),
797
+ },
798
+ },
799
+ ]),
800
+ )
801
+ }
802
+ // For Anthropic models on Bedrock, use reasoningConfig with budgetTokens
803
+ if (model.api.id.includes("anthropic")) {
804
+ return {
805
+ high: {
806
+ reasoningConfig: {
807
+ type: "enabled",
808
+ budgetTokens: 16000,
809
+ },
810
+ },
811
+ max: {
812
+ reasoningConfig: {
813
+ type: "enabled",
814
+ budgetTokens: 31999,
815
+ },
816
+ },
817
+ }
818
+ }
819
+
820
+ // For Amazon Nova models, use reasoningConfig with maxReasoningEffort
821
+ return Object.fromEntries(
822
+ WIDELY_SUPPORTED_EFFORTS.map((effort) => [
823
+ effort,
824
+ {
825
+ reasoningConfig: {
826
+ type: "enabled",
827
+ maxReasoningEffort: effort,
828
+ },
829
+ },
830
+ ]),
831
+ )
832
+
833
+ case "@ai-sdk/google-vertex":
834
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/google-vertex
835
+ case "@ai-sdk/google":
836
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai
837
+ if (id.includes("2.5")) {
838
+ return {
839
+ high: {
840
+ thinkingConfig: {
841
+ includeThoughts: true,
842
+ thinkingBudget: 16000,
843
+ },
844
+ },
845
+ max: {
846
+ thinkingConfig: {
847
+ includeThoughts: true,
848
+ thinkingBudget: 24576,
849
+ },
850
+ },
851
+ }
852
+ }
853
+ let levels = ["low", "high"]
854
+ if (id.includes("3.1")) {
855
+ levels = ["low", "medium", "high"]
856
+ }
857
+
858
+ return Object.fromEntries(
859
+ levels.map((effort) => [
860
+ effort,
861
+ {
862
+ thinkingConfig: {
863
+ includeThoughts: true,
864
+ thinkingLevel: effort,
865
+ },
866
+ },
867
+ ]),
868
+ )
869
+
870
+ case "@ai-sdk/mistral":
871
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/mistral
872
+ return {}
873
+
874
+ case "@ai-sdk/cohere":
875
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/cohere
876
+ return {}
877
+
878
+ case "@ai-sdk/groq":
879
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/groq
880
+ const groqEffort = ["none", ...WIDELY_SUPPORTED_EFFORTS]
881
+ return Object.fromEntries(
882
+ groqEffort.map((effort) => [
883
+ effort,
884
+ {
885
+ reasoningEffort: effort,
886
+ },
887
+ ]),
888
+ )
889
+
890
+ case "@ai-sdk/perplexity":
891
+ // https://v5.ai-sdk.dev/providers/ai-sdk-providers/perplexity
892
+ return {}
893
+
894
+ case "@jerome-benoit/sap-ai-provider-v2":
895
+ if (model.api.id.includes("anthropic")) {
896
+ if (adaptiveEfforts) {
897
+ return Object.fromEntries(
898
+ adaptiveEfforts.map((effort) => [
899
+ effort,
900
+ {
901
+ thinking: {
902
+ type: "adaptive",
903
+ },
904
+ effort,
905
+ },
906
+ ]),
907
+ )
908
+ }
909
+ return {
910
+ high: {
911
+ thinking: {
912
+ type: "enabled",
913
+ budgetTokens: 16000,
914
+ },
915
+ },
916
+ max: {
917
+ thinking: {
918
+ type: "enabled",
919
+ budgetTokens: 31999,
920
+ },
921
+ },
922
+ }
923
+ }
924
+ if (model.api.id.includes("gemini") && id.includes("2.5")) {
925
+ return {
926
+ high: {
927
+ thinkingConfig: {
928
+ includeThoughts: true,
929
+ thinkingBudget: 16000,
930
+ },
931
+ },
932
+ max: {
933
+ thinkingConfig: {
934
+ includeThoughts: true,
935
+ thinkingBudget: 24576,
936
+ },
937
+ },
938
+ }
939
+ }
940
+ if (model.api.id.includes("gpt") || /\bo[1-9]/.test(model.api.id)) {
941
+ return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }]))
942
+ }
943
+ return {}
944
+ }
945
+ return {}
946
+ }
947
+
948
+ export function options(input: {
949
+ model: Provider.Model
950
+ sessionID: string
951
+ providerOptions?: Record<string, any>
952
+ }): Record<string, any> {
953
+ const result: Record<string, any> = {}
954
+
955
+ // openai and providers using openai package should set store to false by default.
956
+ if (
957
+ input.model.providerID === "openai" ||
958
+ input.model.api.npm === "@ai-sdk/openai" ||
959
+ input.model.api.npm === "@ai-sdk/github-copilot"
960
+ ) {
961
+ result["store"] = false
962
+ }
963
+
964
+ if (input.model.api.npm === "@ai-sdk/azure") {
965
+ result["store"] = true
966
+ result["promptCacheKey"] = input.sessionID
967
+ }
968
+
969
+ if (input.model.api.npm === "@openrouter/ai-sdk-provider" || input.model.api.npm === "@llmgateway/ai-sdk-provider") {
970
+ result["usage"] = {
971
+ include: true,
972
+ }
973
+ if (input.model.api.id.includes("gemini-3")) {
974
+ result["reasoning"] = { effort: "high" }
975
+ }
976
+ }
977
+
978
+ if (
979
+ input.model.providerID === "baseten" ||
980
+ (input.model.providerID === "opendash" && ["kimi-k2-thinking", "glm-4.6"].includes(input.model.api.id))
981
+ ) {
982
+ result["chat_template_args"] = { enable_thinking: true }
983
+ }
984
+
985
+ if (
986
+ ["zai", "zhipuai"].some((id) => input.model.providerID.includes(id)) &&
987
+ input.model.api.npm === "@ai-sdk/openai-compatible"
988
+ ) {
989
+ result["thinking"] = {
990
+ type: "enabled",
991
+ clear_thinking: false,
992
+ }
993
+ }
994
+
995
+ if (input.model.providerID === "openai" || input.providerOptions?.setCacheKey) {
996
+ result["promptCacheKey"] = input.sessionID
997
+ }
998
+
999
+ if (input.model.api.npm === "@ai-sdk/google" || input.model.api.npm === "@ai-sdk/google-vertex") {
1000
+ if (input.model.capabilities.reasoning) {
1001
+ result["thinkingConfig"] = {
1002
+ includeThoughts: true,
1003
+ }
1004
+ if (input.model.api.id.includes("gemini-3")) {
1005
+ result["thinkingConfig"]["thinkingLevel"] = "high"
1006
+ }
1007
+ }
1008
+ }
1009
+
1010
+ // Enable thinking by default for kimi-k2.5/k2p5 models using anthropic SDK
1011
+ const modelId = input.model.api.id.toLowerCase()
1012
+ if (
1013
+ (input.model.api.npm === "@ai-sdk/anthropic" || input.model.api.npm === "@ai-sdk/google-vertex/anthropic") &&
1014
+ (modelId.includes("k2p5") || modelId.includes("kimi-k2.5") || modelId.includes("kimi-k2p5"))
1015
+ ) {
1016
+ result["thinking"] = {
1017
+ type: "enabled",
1018
+ budgetTokens: Math.min(16_000, Math.floor(input.model.limit.output / 2 - 1)),
1019
+ }
1020
+ }
1021
+
1022
+ // Enable thinking for reasoning models on alibaba-cn (DashScope).
1023
+ // DashScope's OpenAI-compatible API requires `enable_thinking: true` in the request body
1024
+ // to return reasoning_content. Without it, models like kimi-k2.5, qwen-plus, qwen3, qwq,
1025
+ // deepseek-r1, etc. never output thinking/reasoning tokens.
1026
+ // Note: kimi-k2-thinking is excluded as it returns reasoning_content by default.
1027
+ if (
1028
+ input.model.providerID === "alibaba-cn" &&
1029
+ input.model.capabilities.reasoning &&
1030
+ input.model.api.npm === "@ai-sdk/openai-compatible" &&
1031
+ !modelId.includes("kimi-k2-thinking")
1032
+ ) {
1033
+ result["enable_thinking"] = true
1034
+ }
1035
+
1036
+ if (input.model.api.id.includes("gpt-5") && !input.model.api.id.includes("gpt-5-chat")) {
1037
+ if (!input.model.api.id.includes("gpt-5-pro")) {
1038
+ result["reasoningEffort"] = "medium"
1039
+ // Only inject reasoningSummary for providers that support it natively.
1040
+ // @ai-sdk/openai-compatible proxies (e.g. LiteLLM) do not understand this
1041
+ // parameter and return "Unknown parameter: 'reasoningSummary'".
1042
+ if (
1043
+ input.model.api.npm === "@ai-sdk/openai" ||
1044
+ input.model.api.npm === "@ai-sdk/azure" ||
1045
+ input.model.api.npm === "@ai-sdk/github-copilot"
1046
+ ) {
1047
+ result["reasoningSummary"] = "auto"
1048
+ }
1049
+ }
1050
+
1051
+ // Only set textVerbosity for non-chat gpt-5.x models
1052
+ // Chat models (e.g. gpt-5.2-chat-latest) only support "medium" verbosity
1053
+ if (
1054
+ input.model.api.id.includes("gpt-5.") &&
1055
+ !input.model.api.id.includes("codex") &&
1056
+ !input.model.api.id.includes("-chat") &&
1057
+ input.model.providerID !== "azure"
1058
+ ) {
1059
+ result["textVerbosity"] = "low"
1060
+ }
1061
+
1062
+ if (input.model.providerID.startsWith("opendash")) {
1063
+ result["promptCacheKey"] = input.sessionID
1064
+ result["include"] = ["reasoning.encrypted_content"]
1065
+ result["reasoningSummary"] = "auto"
1066
+ }
1067
+ }
1068
+
1069
+ if (input.model.providerID === "venice") {
1070
+ result["promptCacheKey"] = input.sessionID
1071
+ }
1072
+
1073
+ if (input.model.providerID === "openrouter") {
1074
+ result["prompt_cache_key"] = input.sessionID
1075
+ }
1076
+ if (input.model.api.npm === "@ai-sdk/gateway") {
1077
+ result["gateway"] = {
1078
+ caching: "auto",
1079
+ }
1080
+ }
1081
+
1082
+ return result
1083
+ }
1084
+
1085
+ export function smallOptions(model: Provider.Model) {
1086
+ if (
1087
+ model.providerID === "openai" ||
1088
+ model.api.npm === "@ai-sdk/openai" ||
1089
+ model.api.npm === "@ai-sdk/github-copilot"
1090
+ ) {
1091
+ if (model.api.id.includes("gpt-5")) {
1092
+ if (model.api.id.includes("5.") || model.api.id.includes("5-mini")) {
1093
+ return { store: false, reasoningEffort: "low" }
1094
+ }
1095
+ return { store: false, reasoningEffort: "minimal" }
1096
+ }
1097
+ return { store: false }
1098
+ }
1099
+ if (model.providerID === "google") {
1100
+ // gemini-3 uses thinkingLevel, gemini-2.5 uses thinkingBudget
1101
+ if (model.api.id.includes("gemini-3")) {
1102
+ return { thinkingConfig: { thinkingLevel: "minimal" } }
1103
+ }
1104
+ return { thinkingConfig: { thinkingBudget: 0 } }
1105
+ }
1106
+ if (model.providerID === "openrouter" || model.providerID === "llmgateway") {
1107
+ if (model.api.id.includes("google")) {
1108
+ return { reasoning: { enabled: false } }
1109
+ }
1110
+ return { reasoningEffort: "minimal" }
1111
+ }
1112
+
1113
+ if (model.providerID === "venice") {
1114
+ return { veniceParameters: { disableThinking: true } }
1115
+ }
1116
+
1117
+ return {}
1118
+ }
1119
+
1120
+ // Maps model ID prefix to provider slug used in providerOptions.
1121
+ // Example: "amazon/nova-2-lite" → "bedrock"
1122
+ const SLUG_OVERRIDES: Record<string, string> = {
1123
+ amazon: "bedrock",
1124
+ }
1125
+
1126
+ export function providerOptions(model: Provider.Model, options: { [x: string]: any }) {
1127
+ if (model.api.npm === "@ai-sdk/gateway") {
1128
+ // Gateway providerOptions are split across two namespaces:
1129
+ // - `gateway`: gateway-native routing/caching controls (order, only, byok, etc.)
1130
+ // - `<upstream slug>`: provider-specific model options (anthropic/openai/...)
1131
+ // We keep `gateway` as-is and route every other top-level option under the
1132
+ // model-derived upstream slug.
1133
+ const i = model.api.id.indexOf("/")
1134
+ const rawSlug = i > 0 ? model.api.id.slice(0, i) : undefined
1135
+ const slug = rawSlug ? (SLUG_OVERRIDES[rawSlug] ?? rawSlug) : undefined
1136
+ const gateway = options.gateway
1137
+ const rest = Object.fromEntries(Object.entries(options).filter(([k]) => k !== "gateway"))
1138
+ const has = Object.keys(rest).length > 0
1139
+
1140
+ const result: Record<string, any> = {}
1141
+ if (gateway !== undefined) result.gateway = gateway
1142
+
1143
+ if (has) {
1144
+ if (slug) {
1145
+ // Route model-specific options under the provider slug
1146
+ result[slug] = rest
1147
+ } else if (gateway && typeof gateway === "object" && !Array.isArray(gateway)) {
1148
+ result.gateway = { ...gateway, ...rest }
1149
+ } else {
1150
+ result.gateway = rest
1151
+ }
1152
+ }
1153
+
1154
+ return result
1155
+ }
1156
+
1157
+ const key = sdkKey(model.api.npm) ?? model.providerID
1158
+ // @ai-sdk/azure delegates to OpenAIChatLanguageModel which reads from
1159
+ // providerOptions["openai"], but OpenAIResponsesLanguageModel checks
1160
+ // "azure" first. Pass both so model options work on either code path.
1161
+ if (model.api.npm === "@ai-sdk/azure") {
1162
+ return { openai: options, azure: options }
1163
+ }
1164
+ return { [key]: options }
1165
+ }
1166
+
1167
+ export function maxOutputTokens(model: Provider.Model): number {
1168
+ if (model.providerID === "mimo" || model.providerID === "xiaomi" || model.id.toLowerCase().includes("mimo")) {
1169
+ return MIMO_OUTPUT_TOKEN_MAX
1170
+ }
1171
+ return Math.min(model.limit.output, OUTPUT_TOKEN_MAX) || OUTPUT_TOKEN_MAX
1172
+ }
1173
+
1174
+ // Flatten a root-level `anyOf` / `oneOf` (typically from `z.discriminatedUnion`)
1175
+ // into a single `type: "object"` schema with all variant properties merged at
1176
+ // the root. The discriminator key becomes an `enum`, and per-variant required
1177
+ // fields are encoded as a textual hint on the discriminator's description.
1178
+ //
1179
+ // OpenAI's function-calling validator rejects oneOf/anyOf/allOf/enum/not at the
1180
+ // top level outright, so this is the only shape that gets through. We retain
1181
+ // `additionalProperties: false` to keep the model from inventing fields, and
1182
+ // rely on zod's runtime parse (still using the original discriminated union)
1183
+ // to enforce per-action required fields strictly.
1184
+ function flattenDiscriminatedUnion(schema: JSONSchema.BaseSchema | JSONSchema7): JSONSchema7 {
1185
+ const root = schema as Record<string, any>
1186
+ const variants = (root.anyOf ?? root.oneOf) as Array<Record<string, any>> | undefined
1187
+ if (!variants?.length) return schema as JSONSchema7
1188
+
1189
+ // Find the discriminator: a property whose `const` differs across all variants.
1190
+ const constByKey = new Map<string, Set<unknown>>()
1191
+ for (const v of variants) {
1192
+ if (!v.properties) continue
1193
+ for (const [key, prop] of Object.entries(v.properties as Record<string, any>)) {
1194
+ if (prop && typeof prop === "object" && "const" in prop) {
1195
+ if (!constByKey.has(key)) constByKey.set(key, new Set())
1196
+ constByKey.get(key)!.add(prop.const)
1197
+ }
1198
+ }
1199
+ }
1200
+ let discriminator: string | undefined
1201
+ for (const [key, values] of constByKey) {
1202
+ if (values.size === variants.length) {
1203
+ discriminator = key
1204
+ break
1205
+ }
1206
+ }
1207
+
1208
+ // Merge non-discriminator properties from every variant. Track which variants
1209
+ // each property appeared in so the description can tell the model
1210
+ // "(only when action='X'|'Y')" — flat schemas tempt some models (notably
1211
+ // gpt-5.5) to fill every property regardless of which action they chose.
1212
+ const properties: Record<string, any> = {}
1213
+ const propertyOwners: Record<string, unknown[]> = {}
1214
+ for (const v of variants) {
1215
+ if (!v.properties) continue
1216
+ const variantValue = discriminator
1217
+ ? (v.properties as Record<string, any>)[discriminator]?.const
1218
+ : undefined
1219
+ for (const [key, prop] of Object.entries(v.properties as Record<string, any>)) {
1220
+ if (key === discriminator) continue
1221
+ if (!(key in properties)) properties[key] = prop
1222
+ if (variantValue !== undefined) {
1223
+ if (!propertyOwners[key]) propertyOwners[key] = []
1224
+ propertyOwners[key].push(variantValue)
1225
+ }
1226
+ }
1227
+ }
1228
+ if (discriminator) {
1229
+ for (const [key, owners] of Object.entries(propertyOwners)) {
1230
+ if (owners.length === variants.length) continue // present in every variant — no annotation
1231
+ const tag = `(only when ${discriminator}=${owners.map((o) => JSON.stringify(o)).join("|")})`
1232
+ const original = (properties[key] as Record<string, any>).description as string | undefined
1233
+ properties[key] = {
1234
+ ...properties[key],
1235
+ description: original ? `${tag} ${original}` : tag,
1236
+ }
1237
+ }
1238
+ }
1239
+
1240
+ // Discriminator becomes an enum with per-variant required fields hinted in
1241
+ // its description. Without this hint the model only sees a flat bag of
1242
+ // optional fields and forgets what to provide for each action.
1243
+ if (discriminator) {
1244
+ const proto = (variants[0].properties as Record<string, any>)[discriminator]
1245
+ const enumValues = variants.map((v) => (v.properties as Record<string, any>)[discriminator!]?.const)
1246
+ const baseDescription = (proto?.description as string | undefined) ?? ""
1247
+ const hints = variants
1248
+ .map((v) => {
1249
+ const value = (v.properties as Record<string, any>)[discriminator!]?.const
1250
+ const required = ((v.required as string[] | undefined) ?? []).filter((r) => r !== discriminator)
1251
+ return required.length > 0 ? `${value}: requires ${required.join(", ")}` : `${value}: no extra required fields`
1252
+ })
1253
+ .join("; ")
1254
+ properties[discriminator] = {
1255
+ type: "string",
1256
+ enum: enumValues,
1257
+ description: baseDescription ? `${baseDescription}\n\nPer-${discriminator}: ${hints}.` : `Per-${discriminator}: ${hints}.`,
1258
+ }
1259
+ }
1260
+
1261
+ return {
1262
+ type: "object",
1263
+ properties,
1264
+ required: discriminator ? [discriminator] : [],
1265
+ additionalProperties: false,
1266
+ } as JSONSchema7
1267
+ }
1268
+
1269
+ export function schema(model: Provider.Model, schema: JSONSchema.BaseSchema | JSONSchema7): JSONSchema7 {
1270
+ /*
1271
+ if (["openai", "azure"].includes(providerID)) {
1272
+ if (schema.type === "object" && schema.properties) {
1273
+ for (const [key, value] of Object.entries(schema.properties)) {
1274
+ if (schema.required?.includes(key)) continue
1275
+ schema.properties[key] = {
1276
+ anyOf: [
1277
+ value as JSONSchema.JSONSchema,
1278
+ {
1279
+ type: "null",
1280
+ },
1281
+ ],
1282
+ }
1283
+ }
1284
+ }
1285
+ }
1286
+ */
1287
+
1288
+ // Many providers reject root-level `anyOf`/`oneOf` in tool schemas:
1289
+ // - OpenAI/Azure: "schema must have type 'object' and not have 'oneOf'/'anyOf'"
1290
+ // - Bedrock: "input_schema.type: Field required"
1291
+ // - Anthropic proxies to Bedrock: same Bedrock error
1292
+ // Flatten unconditionally — all providers accept a flat `type: "object"` schema,
1293
+ // and zod's runtime parse still enforces per-variant required fields strictly.
1294
+ schema = flattenDiscriminatedUnion(schema)
1295
+
1296
+ // Convert integer enums to string enums for Google/Gemini
1297
+ if (model.providerID === "google" || model.api.id.includes("gemini")) {
1298
+ const isPlainObject = (node: unknown): node is Record<string, any> =>
1299
+ typeof node === "object" && node !== null && !Array.isArray(node)
1300
+ const hasCombiner = (node: unknown) =>
1301
+ isPlainObject(node) && (Array.isArray(node.anyOf) || Array.isArray(node.oneOf) || Array.isArray(node.allOf))
1302
+ const hasSchemaIntent = (node: unknown) => {
1303
+ if (!isPlainObject(node)) return false
1304
+ if (hasCombiner(node)) return true
1305
+ return [
1306
+ "type",
1307
+ "properties",
1308
+ "items",
1309
+ "prefixItems",
1310
+ "enum",
1311
+ "const",
1312
+ "$ref",
1313
+ "additionalProperties",
1314
+ "patternProperties",
1315
+ "required",
1316
+ "not",
1317
+ "if",
1318
+ "then",
1319
+ "else",
1320
+ ].some((key) => key in node)
1321
+ }
1322
+
1323
+ const sanitizeGemini = (obj: any): any => {
1324
+ if (obj === null || typeof obj !== "object") {
1325
+ return obj
1326
+ }
1327
+
1328
+ if (Array.isArray(obj)) {
1329
+ return obj.map(sanitizeGemini)
1330
+ }
1331
+
1332
+ const result: any = {}
1333
+ for (const [key, value] of Object.entries(obj)) {
1334
+ if (key === "enum" && Array.isArray(value)) {
1335
+ // Convert all enum values to strings
1336
+ result[key] = value.map((v) => String(v))
1337
+ // If we have integer type with enum, change type to string
1338
+ if (result.type === "integer" || result.type === "number") {
1339
+ result.type = "string"
1340
+ }
1341
+ } else if (typeof value === "object" && value !== null) {
1342
+ result[key] = sanitizeGemini(value)
1343
+ } else {
1344
+ result[key] = value
1345
+ }
1346
+ }
1347
+
1348
+ // Filter required array to only include fields that exist in properties
1349
+ if (result.type === "object" && result.properties && Array.isArray(result.required)) {
1350
+ result.required = result.required.filter((field: any) => field in result.properties)
1351
+ }
1352
+
1353
+ if (result.type === "array" && !hasCombiner(result)) {
1354
+ if (result.items == null) {
1355
+ result.items = {}
1356
+ }
1357
+ // Ensure items has a type only when it's still schema-empty.
1358
+ if (isPlainObject(result.items) && !hasSchemaIntent(result.items)) {
1359
+ result.items.type = "string"
1360
+ }
1361
+ }
1362
+
1363
+ // Remove properties/required from non-object types (Gemini rejects these)
1364
+ if (result.type && result.type !== "object" && !hasCombiner(result)) {
1365
+ delete result.properties
1366
+ delete result.required
1367
+ }
1368
+
1369
+ return result
1370
+ }
1371
+
1372
+ schema = sanitizeGemini(schema)
1373
+ }
1374
+
1375
+ return schema as JSONSchema7
1376
+ }