@sleepy-ai/cli 0.1.15 → 0.1.16

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