@sleepy-ai/cli 0.1.6 → 0.1.8

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 (799) hide show
  1. package/{src/skill/compose/LICENSE-superpowers → LICENSE} +3 -6
  2. package/README.md +139 -6
  3. package/package.json +35 -199
  4. package/postinstall.mjs +102 -0
  5. package/.sleepycode-test-fixtures-50158/sleepycode-test-eqsxv84ythu/.watcher-b67v64k2mnv +0 -1
  6. package/Dockerfile +0 -18
  7. package/drizzle.config.ts +0 -10
  8. package/git +0 -0
  9. package/migration/20260127222353_familiar_lady_ursula/migration.sql +0 -90
  10. package/migration/20260127222353_familiar_lady_ursula/snapshot.json +0 -796
  11. package/migration/20260211171708_add_project_commands/migration.sql +0 -1
  12. package/migration/20260211171708_add_project_commands/snapshot.json +0 -806
  13. package/migration/20260213144116_wakeful_the_professor/migration.sql +0 -11
  14. package/migration/20260213144116_wakeful_the_professor/snapshot.json +0 -897
  15. package/migration/20260225215848_workspace/migration.sql +0 -7
  16. package/migration/20260225215848_workspace/snapshot.json +0 -959
  17. package/migration/20260227213759_add_session_workspace_id/migration.sql +0 -2
  18. package/migration/20260227213759_add_session_workspace_id/snapshot.json +0 -983
  19. package/migration/20260228203230_blue_harpoon/migration.sql +0 -17
  20. package/migration/20260228203230_blue_harpoon/snapshot.json +0 -1102
  21. package/migration/20260303231226_add_workspace_fields/migration.sql +0 -5
  22. package/migration/20260303231226_add_workspace_fields/snapshot.json +0 -1013
  23. package/migration/20260309230000_move_org_to_state/migration.sql +0 -3
  24. package/migration/20260309230000_move_org_to_state/snapshot.json +0 -1156
  25. package/migration/20260312043431_session_message_cursor/migration.sql +0 -4
  26. package/migration/20260312043431_session_message_cursor/snapshot.json +0 -1168
  27. package/migration/20260323234822_events/migration.sql +0 -13
  28. package/migration/20260323234822_events/snapshot.json +0 -1271
  29. package/migration/20260410174513_workspace-name/migration.sql +0 -16
  30. package/migration/20260410174513_workspace-name/snapshot.json +0 -1271
  31. package/migration/20260413175956_chief_energizer/migration.sql +0 -13
  32. package/migration/20260413175956_chief_energizer/snapshot.json +0 -1399
  33. package/migration/20260422160000_context_inheritance/migration.sql +0 -3
  34. package/migration/20260422170000_task_registry/migration.sql +0 -18
  35. package/migration/20260423145421_remove_session_entry/migration.sql +0 -4
  36. package/migration/20260515000000_actor_rename/migration.sql +0 -7
  37. package/migration/20260515010000_memory_fts/migration.sql +0 -33
  38. package/migration/20260515020000_user_task/migration.sql +0 -29
  39. package/migration/20260519000000_last_checkpoint_message_id/migration.sql +0 -1
  40. package/migration/20260521000000_message_agent_id/migration.sql +0 -2
  41. package/migration/20260521000100_actor_registry_v6/migration.sql +0 -25
  42. package/migration/20260521010000_memory_fts_v6/migration.sql +0 -33
  43. package/migration/20260521020000_memory_fts_triggers/migration.sql +0 -17
  44. package/migration/20260526000000_agent_id_main/migration.sql +0 -14
  45. package/migration/20260527000000_actor_lifecycle/migration.sql +0 -8
  46. package/migration/20260527000100_inbox/migration.sql +0 -12
  47. package/migration/20260529000000_task_todo_redesign/migration.sql +0 -16
  48. package/migration/20260603000000_task_in_progress_owner/migration.sql +0 -1
  49. package/migration/20260603000000_workflow_run/migration.sql +0 -17
  50. package/migration/20260604000000_workflow_script_sha/migration.sql +0 -1
  51. package/migration/20260608000000_claude_import/migration.sql +0 -7
  52. package/migration/20260608010000_claude_import_message_ids/migration.sql +0 -1
  53. package/migration/20260609000000_history_fts/migration.sql +0 -29
  54. package/migration/20260609230000_workflow_agent_timeout/migration.sql +0 -1
  55. package/migration/20260612000000_external_import/migration.sql +0 -16
  56. package/parsers-config.ts +0 -290
  57. package/src/account/account.sql.ts +0 -39
  58. package/src/account/account.ts +0 -456
  59. package/src/account/repo.ts +0 -166
  60. package/src/account/schema.ts +0 -99
  61. package/src/account/url.ts +0 -8
  62. package/src/acp/README.md +0 -174
  63. package/src/acp/agent.ts +0 -1787
  64. package/src/acp/session.ts +0 -116
  65. package/src/acp/types.ts +0 -24
  66. package/src/actor/actor.sql.ts +0 -38
  67. package/src/actor/events.ts +0 -67
  68. package/src/actor/index.ts +0 -2
  69. package/src/actor/registry.ts +0 -412
  70. package/src/actor/return-header.ts +0 -24
  71. package/src/actor/schema.ts +0 -47
  72. package/src/actor/spawn-ref.ts +0 -16
  73. package/src/actor/spawn.ts +0 -756
  74. package/src/actor/turn.ts +0 -49
  75. package/src/actor/waiter.ts +0 -166
  76. package/src/agent/agent.ts +0 -574
  77. package/src/agent/config.ts +0 -5
  78. package/src/agent/generate.txt +0 -75
  79. package/src/agent/prompt/checkpoint-writer.txt +0 -167
  80. package/src/agent/prompt/compaction.txt +0 -9
  81. package/src/agent/prompt/distill.txt +0 -199
  82. package/src/agent/prompt/dream.txt +0 -155
  83. package/src/agent/prompt/explore.txt +0 -18
  84. package/src/agent/prompt/summary.txt +0 -11
  85. package/src/agent/prompt/title.txt +0 -44
  86. package/src/audio.d.ts +0 -9
  87. package/src/auth/index.ts +0 -97
  88. package/src/bus/bus-event.ts +0 -33
  89. package/src/bus/global.ts +0 -12
  90. package/src/bus/index.ts +0 -193
  91. package/src/cli/bootstrap.ts +0 -33
  92. package/src/cli/cmd/account.ts +0 -258
  93. package/src/cli/cmd/acp.ts +0 -70
  94. package/src/cli/cmd/agent.ts +0 -248
  95. package/src/cli/cmd/cmd.ts +0 -7
  96. package/src/cli/cmd/db.ts +0 -120
  97. package/src/cli/cmd/debug/agent.ts +0 -192
  98. package/src/cli/cmd/debug/config.ts +0 -17
  99. package/src/cli/cmd/debug/file.ts +0 -100
  100. package/src/cli/cmd/debug/index.ts +0 -48
  101. package/src/cli/cmd/debug/lsp.ts +0 -61
  102. package/src/cli/cmd/debug/ripgrep.ts +0 -105
  103. package/src/cli/cmd/debug/scrap.ts +0 -16
  104. package/src/cli/cmd/debug/skill.ts +0 -23
  105. package/src/cli/cmd/debug/snapshot.ts +0 -53
  106. package/src/cli/cmd/doctor.ts +0 -116
  107. package/src/cli/cmd/export.ts +0 -306
  108. package/src/cli/cmd/generate.ts +0 -50
  109. package/src/cli/cmd/github.ts +0 -1647
  110. package/src/cli/cmd/import.ts +0 -208
  111. package/src/cli/cmd/init.ts +0 -97
  112. package/src/cli/cmd/login.ts +0 -402
  113. package/src/cli/cmd/mcp.ts +0 -812
  114. package/src/cli/cmd/models.ts +0 -88
  115. package/src/cli/cmd/plug.ts +0 -233
  116. package/src/cli/cmd/pr.ts +0 -138
  117. package/src/cli/cmd/providers.ts +0 -713
  118. package/src/cli/cmd/run-completion.ts +0 -77
  119. package/src/cli/cmd/run.ts +0 -694
  120. package/src/cli/cmd/serve.ts +0 -30
  121. package/src/cli/cmd/session.ts +0 -181
  122. package/src/cli/cmd/stats.ts +0 -413
  123. package/src/cli/cmd/tui/app.tsx +0 -1181
  124. package/src/cli/cmd/tui/asset/TEN_VAD_LICENSE +0 -12
  125. package/src/cli/cmd/tui/asset/charge.wav +0 -0
  126. package/src/cli/cmd/tui/asset/pulse-a.wav +0 -0
  127. package/src/cli/cmd/tui/asset/pulse-b.wav +0 -0
  128. package/src/cli/cmd/tui/asset/pulse-c.wav +0 -0
  129. package/src/cli/cmd/tui/asset/ten_vad.wasm +0 -0
  130. package/src/cli/cmd/tui/asset/ten_vad_loader.js +0 -30
  131. package/src/cli/cmd/tui/attach.ts +0 -84
  132. package/src/cli/cmd/tui/component/background-image.tsx +0 -150
  133. package/src/cli/cmd/tui/component/banner-session-expired.tsx +0 -48
  134. package/src/cli/cmd/tui/component/bg-pulse.tsx +0 -130
  135. package/src/cli/cmd/tui/component/border.tsx +0 -21
  136. package/src/cli/cmd/tui/component/dialog-agent.tsx +0 -31
  137. package/src/cli/cmd/tui/component/dialog-agreement.tsx +0 -111
  138. package/src/cli/cmd/tui/component/dialog-command.tsx +0 -219
  139. package/src/cli/cmd/tui/component/dialog-console-org.tsx +0 -103
  140. package/src/cli/cmd/tui/component/dialog-go-upsell.tsx +0 -157
  141. package/src/cli/cmd/tui/component/dialog-image-list.tsx +0 -111
  142. package/src/cli/cmd/tui/component/dialog-logo-design.tsx +0 -37
  143. package/src/cli/cmd/tui/component/dialog-mcp.tsx +0 -86
  144. package/src/cli/cmd/tui/component/dialog-model.tsx +0 -299
  145. package/src/cli/cmd/tui/component/dialog-provider.tsx +0 -449
  146. package/src/cli/cmd/tui/component/dialog-session-delete-failed.tsx +0 -101
  147. package/src/cli/cmd/tui/component/dialog-session-list.tsx +0 -269
  148. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +0 -31
  149. package/src/cli/cmd/tui/component/dialog-skill.tsx +0 -42
  150. package/src/cli/cmd/tui/component/dialog-sleepy-login.tsx +0 -288
  151. package/src/cli/cmd/tui/component/dialog-stash.tsx +0 -87
  152. package/src/cli/cmd/tui/component/dialog-status.tsx +0 -170
  153. package/src/cli/cmd/tui/component/dialog-tag.tsx +0 -44
  154. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +0 -50
  155. package/src/cli/cmd/tui/component/dialog-token-plan.tsx +0 -77
  156. package/src/cli/cmd/tui/component/dialog-variant.tsx +0 -39
  157. package/src/cli/cmd/tui/component/dialog-workflows.tsx +0 -51
  158. package/src/cli/cmd/tui/component/dialog-workspace-create.tsx +0 -289
  159. package/src/cli/cmd/tui/component/dialog-workspace-unavailable.tsx +0 -81
  160. package/src/cli/cmd/tui/component/dialog-worktree.tsx +0 -90
  161. package/src/cli/cmd/tui/component/error-component.tsx +0 -92
  162. package/src/cli/cmd/tui/component/logo.tsx +0 -961
  163. package/src/cli/cmd/tui/component/plugin-route-missing.tsx +0 -14
  164. package/src/cli/cmd/tui/component/prompt/autocomplete-detect.ts +0 -34
  165. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +0 -668
  166. package/src/cli/cmd/tui/component/prompt/cwd.ts +0 -0
  167. package/src/cli/cmd/tui/component/prompt/frecency.tsx +0 -90
  168. package/src/cli/cmd/tui/component/prompt/history.tsx +0 -108
  169. package/src/cli/cmd/tui/component/prompt/index.tsx +0 -1869
  170. package/src/cli/cmd/tui/component/prompt/offset.ts +0 -45
  171. package/src/cli/cmd/tui/component/prompt/part.ts +0 -36
  172. package/src/cli/cmd/tui/component/prompt/stash.tsx +0 -101
  173. package/src/cli/cmd/tui/component/spinner.tsx +0 -24
  174. package/src/cli/cmd/tui/component/starry-background.tsx +0 -305
  175. package/src/cli/cmd/tui/component/startup-loading.tsx +0 -67
  176. package/src/cli/cmd/tui/component/task-item.tsx +0 -63
  177. package/src/cli/cmd/tui/component/textarea-keybindings.ts +0 -73
  178. package/src/cli/cmd/tui/component/todo-item.tsx +0 -32
  179. package/src/cli/cmd/tui/component/workflow-tree.tsx +0 -177
  180. package/src/cli/cmd/tui/config/cwd.ts +0 -5
  181. package/src/cli/cmd/tui/config/tui-migrate.ts +0 -151
  182. package/src/cli/cmd/tui/config/tui-schema.ts +0 -38
  183. package/src/cli/cmd/tui/config/tui.ts +0 -219
  184. package/src/cli/cmd/tui/context/args.tsx +0 -16
  185. package/src/cli/cmd/tui/context/directory.ts +0 -15
  186. package/src/cli/cmd/tui/context/event.ts +0 -45
  187. package/src/cli/cmd/tui/context/exit.tsx +0 -65
  188. package/src/cli/cmd/tui/context/helper.tsx +0 -25
  189. package/src/cli/cmd/tui/context/keybind.tsx +0 -105
  190. package/src/cli/cmd/tui/context/kv.tsx +0 -86
  191. package/src/cli/cmd/tui/context/language.tsx +0 -91
  192. package/src/cli/cmd/tui/context/local.tsx +0 -469
  193. package/src/cli/cmd/tui/context/plugin-keybinds.ts +0 -41
  194. package/src/cli/cmd/tui/context/project.tsx +0 -109
  195. package/src/cli/cmd/tui/context/prompt.tsx +0 -18
  196. package/src/cli/cmd/tui/context/route.tsx +0 -68
  197. package/src/cli/cmd/tui/context/sdk.tsx +0 -150
  198. package/src/cli/cmd/tui/context/sync.tsx +0 -884
  199. package/src/cli/cmd/tui/context/theme/aura.json +0 -69
  200. package/src/cli/cmd/tui/context/theme/ayu.json +0 -80
  201. package/src/cli/cmd/tui/context/theme/carbonfox.json +0 -248
  202. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +0 -230
  203. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +0 -230
  204. package/src/cli/cmd/tui/context/theme/catppuccin.json +0 -112
  205. package/src/cli/cmd/tui/context/theme/cobalt2.json +0 -225
  206. package/src/cli/cmd/tui/context/theme/cursor.json +0 -249
  207. package/src/cli/cmd/tui/context/theme/dracula.json +0 -219
  208. package/src/cli/cmd/tui/context/theme/everforest.json +0 -241
  209. package/src/cli/cmd/tui/context/theme/flexoki.json +0 -237
  210. package/src/cli/cmd/tui/context/theme/github.json +0 -233
  211. package/src/cli/cmd/tui/context/theme/gruvbox.json +0 -242
  212. package/src/cli/cmd/tui/context/theme/kanagawa.json +0 -77
  213. package/src/cli/cmd/tui/context/theme/lucent-orng.json +0 -234
  214. package/src/cli/cmd/tui/context/theme/material.json +0 -235
  215. package/src/cli/cmd/tui/context/theme/matrix.json +0 -77
  216. package/src/cli/cmd/tui/context/theme/mercury.json +0 -252
  217. package/src/cli/cmd/tui/context/theme/monokai.json +0 -221
  218. package/src/cli/cmd/tui/context/theme/nightowl.json +0 -221
  219. package/src/cli/cmd/tui/context/theme/nord.json +0 -223
  220. package/src/cli/cmd/tui/context/theme/one-dark.json +0 -84
  221. package/src/cli/cmd/tui/context/theme/orng.json +0 -249
  222. package/src/cli/cmd/tui/context/theme/osaka-jade.json +0 -93
  223. package/src/cli/cmd/tui/context/theme/palenight.json +0 -222
  224. package/src/cli/cmd/tui/context/theme/rosepine.json +0 -234
  225. package/src/cli/cmd/tui/context/theme/sleepycode.json +0 -245
  226. package/src/cli/cmd/tui/context/theme/solarized.json +0 -223
  227. package/src/cli/cmd/tui/context/theme/synthwave84.json +0 -226
  228. package/src/cli/cmd/tui/context/theme/tokyonight.json +0 -243
  229. package/src/cli/cmd/tui/context/theme/vercel.json +0 -245
  230. package/src/cli/cmd/tui/context/theme/vesper.json +0 -218
  231. package/src/cli/cmd/tui/context/theme/zenburn.json +0 -223
  232. package/src/cli/cmd/tui/context/theme.tsx +0 -1298
  233. package/src/cli/cmd/tui/context/thinking.ts +0 -48
  234. package/src/cli/cmd/tui/context/tui-config.tsx +0 -9
  235. package/src/cli/cmd/tui/event.ts +0 -62
  236. package/src/cli/cmd/tui/feature-plugins/home/footer.tsx +0 -93
  237. package/src/cli/cmd/tui/feature-plugins/home/tips-view.tsx +0 -193
  238. package/src/cli/cmd/tui/feature-plugins/home/tips.tsx +0 -54
  239. package/src/cli/cmd/tui/feature-plugins/sidebar/context.tsx +0 -267
  240. package/src/cli/cmd/tui/feature-plugins/sidebar/cwd.tsx +0 -45
  241. package/src/cli/cmd/tui/feature-plugins/sidebar/files.tsx +0 -62
  242. package/src/cli/cmd/tui/feature-plugins/sidebar/footer.tsx +0 -93
  243. package/src/cli/cmd/tui/feature-plugins/sidebar/goal.tsx +0 -84
  244. package/src/cli/cmd/tui/feature-plugins/sidebar/instructions.tsx +0 -54
  245. package/src/cli/cmd/tui/feature-plugins/sidebar/lsp.tsx +0 -66
  246. package/src/cli/cmd/tui/feature-plugins/sidebar/mascot.tsx +0 -69
  247. package/src/cli/cmd/tui/feature-plugins/sidebar/mcp.tsx +0 -98
  248. package/src/cli/cmd/tui/feature-plugins/sidebar/task.tsx +0 -95
  249. package/src/cli/cmd/tui/feature-plugins/sidebar/todo.tsx +0 -51
  250. package/src/cli/cmd/tui/feature-plugins/sidebar/tps.ts +0 -31
  251. package/src/cli/cmd/tui/feature-plugins/system/plugins.tsx +0 -274
  252. package/src/cli/cmd/tui/i18n/en.ts +0 -465
  253. package/src/cli/cmd/tui/i18n/es.ts +0 -508
  254. package/src/cli/cmd/tui/i18n/fr.ts +0 -515
  255. package/src/cli/cmd/tui/i18n/ja.ts +0 -463
  256. package/src/cli/cmd/tui/i18n/locales.ts +0 -82
  257. package/src/cli/cmd/tui/i18n/ru.ts +0 -527
  258. package/src/cli/cmd/tui/i18n/slash-command.ts +0 -11
  259. package/src/cli/cmd/tui/i18n/zh.ts +0 -454
  260. package/src/cli/cmd/tui/i18n/zht.ts +0 -430
  261. package/src/cli/cmd/tui/layer.ts +0 -6
  262. package/src/cli/cmd/tui/plugin/api.tsx +0 -402
  263. package/src/cli/cmd/tui/plugin/index.ts +0 -3
  264. package/src/cli/cmd/tui/plugin/internal.ts +0 -37
  265. package/src/cli/cmd/tui/plugin/runtime.ts +0 -1057
  266. package/src/cli/cmd/tui/plugin/slots.tsx +0 -60
  267. package/src/cli/cmd/tui/routes/home.tsx +0 -165
  268. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +0 -76
  269. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +0 -116
  270. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +0 -47
  271. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +0 -47
  272. package/src/cli/cmd/tui/routes/session/footer.tsx +0 -91
  273. package/src/cli/cmd/tui/routes/session/index.tsx +0 -3073
  274. package/src/cli/cmd/tui/routes/session/permission.tsx +0 -697
  275. package/src/cli/cmd/tui/routes/session/question.tsx +0 -488
  276. package/src/cli/cmd/tui/routes/session/sidebar.tsx +0 -97
  277. package/src/cli/cmd/tui/routes/session/subagent-footer.tsx +0 -143
  278. package/src/cli/cmd/tui/thread.ts +0 -324
  279. package/src/cli/cmd/tui/ui/dialog-alert.tsx +0 -61
  280. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +0 -95
  281. package/src/cli/cmd/tui/ui/dialog-export-options.tsx +0 -223
  282. package/src/cli/cmd/tui/ui/dialog-help.tsx +0 -42
  283. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +0 -123
  284. package/src/cli/cmd/tui/ui/dialog-select.tsx +0 -467
  285. package/src/cli/cmd/tui/ui/dialog.tsx +0 -207
  286. package/src/cli/cmd/tui/ui/link.tsx +0 -28
  287. package/src/cli/cmd/tui/ui/spinner.ts +0 -378
  288. package/src/cli/cmd/tui/ui/toast.tsx +0 -102
  289. package/src/cli/cmd/tui/util/clipboard.ts +0 -203
  290. package/src/cli/cmd/tui/util/editor.ts +0 -36
  291. package/src/cli/cmd/tui/util/image-protocol.ts +0 -35
  292. package/src/cli/cmd/tui/util/index.ts +0 -6
  293. package/src/cli/cmd/tui/util/model.ts +0 -23
  294. package/src/cli/cmd/tui/util/pinyin.ts +0 -20
  295. package/src/cli/cmd/tui/util/provider-origin.ts +0 -7
  296. package/src/cli/cmd/tui/util/revert-diff.ts +0 -18
  297. package/src/cli/cmd/tui/util/scroll.ts +0 -23
  298. package/src/cli/cmd/tui/util/selection.ts +0 -23
  299. package/src/cli/cmd/tui/util/signal.ts +0 -41
  300. package/src/cli/cmd/tui/util/sound.ts +0 -154
  301. package/src/cli/cmd/tui/util/system-locale.ts +0 -209
  302. package/src/cli/cmd/tui/util/terminal.ts +0 -110
  303. package/src/cli/cmd/tui/util/transcript.ts +0 -112
  304. package/src/cli/cmd/tui/util/vad.ts +0 -229
  305. package/src/cli/cmd/tui/util/voice.ts +0 -450
  306. package/src/cli/cmd/tui/win32.ts +0 -130
  307. package/src/cli/cmd/tui/worker.ts +0 -104
  308. package/src/cli/cmd/uninstall.ts +0 -351
  309. package/src/cli/cmd/upgrade.ts +0 -79
  310. package/src/cli/cmd/web.ts +0 -96
  311. package/src/cli/effect/prompt.ts +0 -25
  312. package/src/cli/error.ts +0 -82
  313. package/src/cli/heap.ts +0 -59
  314. package/src/cli/i18n.ts +0 -15
  315. package/src/cli/logo.ts +0 -53
  316. package/src/cli/network.ts +0 -68
  317. package/src/cli/ui.ts +0 -133
  318. package/src/cli/upgrade.ts +0 -41
  319. package/src/command/index.ts +0 -276
  320. package/src/command/template/initialize.txt +0 -66
  321. package/src/command/template/review.txt +0 -101
  322. package/src/config/agent.ts +0 -197
  323. package/src/config/command.ts +0 -69
  324. package/src/config/compose.ts +0 -26
  325. package/src/config/config.ts +0 -1047
  326. package/src/config/console-state.ts +0 -16
  327. package/src/config/entry-name.ts +0 -16
  328. package/src/config/error.ts +0 -21
  329. package/src/config/formatter.ts +0 -17
  330. package/src/config/history.ts +0 -21
  331. package/src/config/index.ts +0 -17
  332. package/src/config/keybinds.ts +0 -127
  333. package/src/config/layout.ts +0 -10
  334. package/src/config/lsp.ts +0 -45
  335. package/src/config/managed.ts +0 -70
  336. package/src/config/markdown.ts +0 -97
  337. package/src/config/mcp.ts +0 -172
  338. package/src/config/model-id.ts +0 -14
  339. package/src/config/parse.ts +0 -44
  340. package/src/config/paths.ts +0 -85
  341. package/src/config/permission.ts +0 -76
  342. package/src/config/plugin.ts +0 -88
  343. package/src/config/provider.ts +0 -118
  344. package/src/config/server.ts +0 -20
  345. package/src/config/skills.ts +0 -16
  346. package/src/config/variable.ts +0 -90
  347. package/src/control-plane/adaptors/index.ts +0 -52
  348. package/src/control-plane/adaptors/worktree.ts +0 -47
  349. package/src/control-plane/dev/debug-workspace-plugin.ts +0 -73
  350. package/src/control-plane/schema.ts +0 -19
  351. package/src/control-plane/sse.ts +0 -66
  352. package/src/control-plane/types.ts +0 -34
  353. package/src/control-plane/util.ts +0 -37
  354. package/src/control-plane/workspace-context.ts +0 -26
  355. package/src/control-plane/workspace.sql.ts +0 -17
  356. package/src/control-plane/workspace.ts +0 -615
  357. package/src/effect/app-runtime.ts +0 -146
  358. package/src/effect/bootstrap-runtime.ts +0 -33
  359. package/src/effect/bridge.ts +0 -48
  360. package/src/effect/cross-spawn-spawner.ts +0 -514
  361. package/src/effect/index.ts +0 -5
  362. package/src/effect/instance-ref.ts +0 -11
  363. package/src/effect/instance-registry.ts +0 -12
  364. package/src/effect/instance-state.ts +0 -81
  365. package/src/effect/logger.ts +0 -73
  366. package/src/effect/memo-map.ts +0 -3
  367. package/src/effect/observability.ts +0 -107
  368. package/src/effect/run-service.ts +0 -52
  369. package/src/effect/runner.ts +0 -210
  370. package/src/effect/runtime.ts +0 -19
  371. package/src/env/index.ts +0 -37
  372. package/src/file/ignore.ts +0 -81
  373. package/src/file/index.ts +0 -664
  374. package/src/file/protected.ts +0 -59
  375. package/src/file/ripgrep.ts +0 -485
  376. package/src/file/watcher.ts +0 -163
  377. package/src/flag/flag.ts +0 -185
  378. package/src/format/formatter.ts +0 -403
  379. package/src/format/index.ts +0 -203
  380. package/src/git/index.ts +0 -260
  381. package/src/global/index.ts +0 -54
  382. package/src/history/backfill.ts +0 -162
  383. package/src/history/extract.ts +0 -67
  384. package/src/history/fts-query.ts +0 -15
  385. package/src/history/fts.sql.ts +0 -20
  386. package/src/history/index.ts +0 -10
  387. package/src/history/resolve.ts +0 -65
  388. package/src/history/service.ts +0 -258
  389. package/src/history/writer.ts +0 -112
  390. package/src/id/id.ts +0 -87
  391. package/src/ide/index.ts +0 -73
  392. package/src/inbox/inbox-ref.ts +0 -38
  393. package/src/inbox/inbox.sql.ts +0 -26
  394. package/src/inbox/inbox.ts +0 -223
  395. package/src/inbox/index.ts +0 -3
  396. package/src/inbox/render.ts +0 -40
  397. package/src/index.ts +0 -268
  398. package/src/installation/index.ts +0 -362
  399. package/src/installation/version.ts +0 -8
  400. package/src/lsp/client.ts +0 -249
  401. package/src/lsp/diagnostic.ts +0 -29
  402. package/src/lsp/index.ts +0 -3
  403. package/src/lsp/language.ts +0 -120
  404. package/src/lsp/launch.ts +0 -21
  405. package/src/lsp/lsp.ts +0 -519
  406. package/src/lsp/server.ts +0 -1956
  407. package/src/mcp/auth.ts +0 -144
  408. package/src/mcp/index.ts +0 -939
  409. package/src/mcp/oauth-callback.ts +0 -236
  410. package/src/mcp/oauth-provider.ts +0 -214
  411. package/src/memory/fts-query.ts +0 -37
  412. package/src/memory/fts.sql.ts +0 -19
  413. package/src/memory/index.ts +0 -1
  414. package/src/memory/paths.ts +0 -116
  415. package/src/memory/reconcile.ts +0 -144
  416. package/src/memory/service.ts +0 -144
  417. package/src/metrics/client.ts +0 -40
  418. package/src/metrics/event.ts +0 -43
  419. package/src/metrics/index.ts +0 -5
  420. package/src/metrics/installation.ts +0 -18
  421. package/src/metrics/subscriber.ts +0 -58
  422. package/src/metrics/util.ts +0 -9
  423. package/src/node.ts +0 -6
  424. package/src/npm/config.ts +0 -0
  425. package/src/npm/index.ts +0 -293
  426. package/src/npmcli-config.d.ts +0 -43
  427. package/src/patch/index.ts +0 -680
  428. package/src/permission/arity.ts +0 -163
  429. package/src/permission/evaluate.ts +0 -15
  430. package/src/permission/index.ts +0 -382
  431. package/src/permission/schema.ts +0 -17
  432. package/src/plugin/checkpoint-splitover.ts +0 -60
  433. package/src/plugin/cloudflare.ts +0 -76
  434. package/src/plugin/codex.ts +0 -611
  435. package/src/plugin/github-copilot/copilot.ts +0 -368
  436. package/src/plugin/github-copilot/models.ts +0 -153
  437. package/src/plugin/index.ts +0 -637
  438. package/src/plugin/install.ts +0 -439
  439. package/src/plugin/loader.ts +0 -216
  440. package/src/plugin/matcher.ts +0 -33
  441. package/src/plugin/meta.ts +0 -188
  442. package/src/plugin/shared.ts +0 -323
  443. package/src/plugin/sleepy.ts +0 -244
  444. package/src/plugin/subagent-progress-checker.ts +0 -147
  445. package/src/project/bootstrap.ts +0 -59
  446. package/src/project/index.ts +0 -2
  447. package/src/project/instance.ts +0 -215
  448. package/src/project/project-id.ts +0 -48
  449. package/src/project/project.sql.ts +0 -16
  450. package/src/project/project.ts +0 -522
  451. package/src/project/schema.ts +0 -15
  452. package/src/project/vcs.ts +0 -227
  453. package/src/project/workspace-trust.ts +0 -67
  454. package/src/provider/auth.ts +0 -234
  455. package/src/provider/error.ts +0 -216
  456. package/src/provider/index.ts +0 -5
  457. package/src/provider/models-snapshot.d.ts +0 -2
  458. package/src/provider/models-snapshot.js +0 -3
  459. package/src/provider/models.ts +0 -180
  460. package/src/provider/provider.ts +0 -2098
  461. package/src/provider/schema.ts +0 -36
  462. package/src/provider/sdk/copilot/README.md +0 -5
  463. package/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +0 -170
  464. package/src/provider/sdk/copilot/chat/get-response-metadata.ts +0 -15
  465. package/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +0 -19
  466. package/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts +0 -64
  467. package/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts +0 -815
  468. package/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts +0 -28
  469. package/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +0 -44
  470. package/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts +0 -83
  471. package/src/provider/sdk/copilot/copilot-provider.ts +0 -100
  472. package/src/provider/sdk/copilot/index.ts +0 -2
  473. package/src/provider/sdk/copilot/openai-compatible-error.ts +0 -27
  474. package/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts +0 -335
  475. package/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts +0 -22
  476. package/src/provider/sdk/copilot/responses/openai-config.ts +0 -18
  477. package/src/provider/sdk/copilot/responses/openai-error.ts +0 -22
  478. package/src/provider/sdk/copilot/responses/openai-responses-api-types.ts +0 -214
  479. package/src/provider/sdk/copilot/responses/openai-responses-language-model.ts +0 -1770
  480. package/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts +0 -173
  481. package/src/provider/sdk/copilot/responses/openai-responses-settings.ts +0 -1
  482. package/src/provider/sdk/copilot/responses/tool/code-interpreter.ts +0 -87
  483. package/src/provider/sdk/copilot/responses/tool/file-search.ts +0 -127
  484. package/src/provider/sdk/copilot/responses/tool/image-generation.ts +0 -114
  485. package/src/provider/sdk/copilot/responses/tool/local-shell.ts +0 -64
  486. package/src/provider/sdk/copilot/responses/tool/web-search-preview.ts +0 -103
  487. package/src/provider/sdk/copilot/responses/tool/web-search.ts +0 -102
  488. package/src/provider/session-check.ts +0 -163
  489. package/src/provider/transform.ts +0 -1376
  490. package/src/pty/index.ts +0 -364
  491. package/src/pty/pty.bun.ts +0 -26
  492. package/src/pty/pty.node.ts +0 -27
  493. package/src/pty/pty.ts +0 -25
  494. package/src/pty/schema.ts +0 -17
  495. package/src/question/index.ts +0 -252
  496. package/src/question/schema.ts +0 -17
  497. package/src/server/adapter.bun.ts +0 -40
  498. package/src/server/adapter.node.ts +0 -66
  499. package/src/server/adapter.ts +0 -21
  500. package/src/server/auth.ts +0 -16
  501. package/src/server/error.ts +0 -53
  502. package/src/server/event.ts +0 -7
  503. package/src/server/fence.ts +0 -81
  504. package/src/server/mdns.ts +0 -60
  505. package/src/server/middleware.ts +0 -94
  506. package/src/server/projectors.ts +0 -28
  507. package/src/server/proxy.ts +0 -171
  508. package/src/server/pty-ticket.ts +0 -42
  509. package/src/server/rate-limit.ts +0 -38
  510. package/src/server/routes/control/index.ts +0 -160
  511. package/src/server/routes/control/workspace.ts +0 -203
  512. package/src/server/routes/global.ts +0 -367
  513. package/src/server/routes/instance/bash-interactive.ts +0 -82
  514. package/src/server/routes/instance/config.ts +0 -89
  515. package/src/server/routes/instance/event.ts +0 -108
  516. package/src/server/routes/instance/experimental.ts +0 -408
  517. package/src/server/routes/instance/file.ts +0 -190
  518. package/src/server/routes/instance/httpapi/config.ts +0 -51
  519. package/src/server/routes/instance/httpapi/permission.ts +0 -72
  520. package/src/server/routes/instance/httpapi/project.ts +0 -62
  521. package/src/server/routes/instance/httpapi/provider.ts +0 -142
  522. package/src/server/routes/instance/httpapi/question.ts +0 -121
  523. package/src/server/routes/instance/httpapi/server.ts +0 -153
  524. package/src/server/routes/instance/index.ts +0 -301
  525. package/src/server/routes/instance/mcp.ts +0 -260
  526. package/src/server/routes/instance/middleware.ts +0 -44
  527. package/src/server/routes/instance/permission.ts +0 -73
  528. package/src/server/routes/instance/project.ts +0 -122
  529. package/src/server/routes/instance/provider.ts +0 -158
  530. package/src/server/routes/instance/pty.ts +0 -302
  531. package/src/server/routes/instance/question.ts +0 -162
  532. package/src/server/routes/instance/session.ts +0 -1328
  533. package/src/server/routes/instance/sync.ts +0 -143
  534. package/src/server/routes/instance/trace.ts +0 -59
  535. package/src/server/routes/instance/tui.ts +0 -384
  536. package/src/server/routes/instance/workflows.ts +0 -142
  537. package/src/server/routes/ui.ts +0 -37
  538. package/src/server/server.ts +0 -146
  539. package/src/server/workspace.ts +0 -122
  540. package/src/session/auto-dream.ts +0 -123
  541. package/src/session/boundary.ts +0 -77
  542. package/src/session/budgeted-read.ts +0 -118
  543. package/src/session/checkpoint-align.ts +0 -29
  544. package/src/session/checkpoint-context.ts +0 -36
  545. package/src/session/checkpoint-paths.ts +0 -86
  546. package/src/session/checkpoint-progress-reconcile.ts +0 -111
  547. package/src/session/checkpoint-retry.ts +0 -192
  548. package/src/session/checkpoint-templates.ts +0 -114
  549. package/src/session/checkpoint-validator.ts +0 -259
  550. package/src/session/checkpoint.ts +0 -1560
  551. package/src/session/classify.ts +0 -117
  552. package/src/session/claude-import.ts +0 -381
  553. package/src/session/codex-import.ts +0 -416
  554. package/src/session/compaction.ts +0 -545
  555. package/src/session/external-import.sql.ts +0 -18
  556. package/src/session/external-import.ts +0 -136
  557. package/src/session/goal.ts +0 -232
  558. package/src/session/index.ts +0 -1
  559. package/src/session/instruction.ts +0 -276
  560. package/src/session/last-message-info.ts +0 -32
  561. package/src/session/llm-request-prefix.ts +0 -82
  562. package/src/session/llm.ts +0 -737
  563. package/src/session/max-mode.ts +0 -410
  564. package/src/session/message-v2.ts +0 -1138
  565. package/src/session/message.ts +0 -191
  566. package/src/session/opencode-import.ts +0 -281
  567. package/src/session/overflow.ts +0 -53
  568. package/src/session/prefix-capture-ref.ts +0 -48
  569. package/src/session/processor.ts +0 -983
  570. package/src/session/projectors.ts +0 -137
  571. package/src/session/prompt/anthropic.txt +0 -154
  572. package/src/session/prompt/beast.txt +0 -155
  573. package/src/session/prompt/build-switch.txt +0 -5
  574. package/src/session/prompt/codex.txt +0 -79
  575. package/src/session/prompt/compose.txt +0 -119
  576. package/src/session/prompt/copilot-gpt-5.txt +0 -143
  577. package/src/session/prompt/deepseek.txt +0 -131
  578. package/src/session/prompt/default.old.txt +0 -151
  579. package/src/session/prompt/default.txt +0 -172
  580. package/src/session/prompt/gemini.txt +0 -155
  581. package/src/session/prompt/glm.txt +0 -51
  582. package/src/session/prompt/gpt.txt +0 -107
  583. package/src/session/prompt/kimi.txt +0 -95
  584. package/src/session/prompt/max-steps.txt +0 -16
  585. package/src/session/prompt/minimax.txt +0 -140
  586. package/src/session/prompt/text-loop-recovery.ts +0 -40
  587. package/src/session/prompt/text-ngram-detection.ts +0 -87
  588. package/src/session/prompt/trinity.txt +0 -97
  589. package/src/session/prompt.ts +0 -3878
  590. package/src/session/prune.ts +0 -481
  591. package/src/session/retry.ts +0 -178
  592. package/src/session/revert.ts +0 -161
  593. package/src/session/run-state.ts +0 -135
  594. package/src/session/schema.ts +0 -36
  595. package/src/session/session.sql.ts +0 -110
  596. package/src/session/session.ts +0 -908
  597. package/src/session/status.ts +0 -89
  598. package/src/session/summary.ts +0 -163
  599. package/src/session/system.ts +0 -96
  600. package/src/session/todo.ts +0 -77
  601. package/src/session/trajectory.ts +0 -98
  602. package/src/share/index.ts +0 -2
  603. package/src/share/session.ts +0 -57
  604. package/src/share/share-next.ts +0 -381
  605. package/src/share/share.sql.ts +0 -13
  606. package/src/shell/shell.ts +0 -124
  607. package/src/skill/builtin/.bundle/self-extend/SKILL.md +0 -131
  608. package/src/skill/builtin/.bundle/self-extend/reference/hook-api.md +0 -242
  609. package/src/skill/builtin/.bundle/self-extend/reference/skill-api.md +0 -114
  610. package/src/skill/builtin/.bundle/self-extend/reference/tool-api.md +0 -115
  611. package/src/skill/builtin/.bundle/self-extend/reference/tui-api.md +0 -258
  612. package/src/skill/builtin/bundle.macro.ts +0 -30
  613. package/src/skill/builtin/extract.ts +0 -41
  614. package/src/skill/compose/.bundle/ask/SKILL.md +0 -58
  615. package/src/skill/compose/.bundle/brainstorm/SKILL.md +0 -200
  616. package/src/skill/compose/.bundle/brainstorm/scripts/frame-template.html +0 -214
  617. package/src/skill/compose/.bundle/brainstorm/scripts/helper.js +0 -88
  618. package/src/skill/compose/.bundle/brainstorm/scripts/server.cjs +0 -354
  619. package/src/skill/compose/.bundle/brainstorm/scripts/start-server.sh +0 -148
  620. package/src/skill/compose/.bundle/brainstorm/scripts/stop-server.sh +0 -56
  621. package/src/skill/compose/.bundle/brainstorm/spec-document-reviewer-prompt.md +0 -50
  622. package/src/skill/compose/.bundle/brainstorm/visual-companion.md +0 -258
  623. package/src/skill/compose/.bundle/debug/CREATION-LOG.md +0 -119
  624. package/src/skill/compose/.bundle/debug/SKILL.md +0 -297
  625. package/src/skill/compose/.bundle/debug/condition-based-waiting-example.ts +0 -158
  626. package/src/skill/compose/.bundle/debug/condition-based-waiting.md +0 -106
  627. package/src/skill/compose/.bundle/debug/defense-in-depth.md +0 -122
  628. package/src/skill/compose/.bundle/debug/find-polluter.sh +0 -63
  629. package/src/skill/compose/.bundle/debug/root-cause-tracing.md +0 -144
  630. package/src/skill/compose/.bundle/debug/test-academic.md +0 -14
  631. package/src/skill/compose/.bundle/debug/test-pressure-1.md +0 -58
  632. package/src/skill/compose/.bundle/debug/test-pressure-2.md +0 -68
  633. package/src/skill/compose/.bundle/debug/test-pressure-3.md +0 -69
  634. package/src/skill/compose/.bundle/execute/SKILL.md +0 -71
  635. package/src/skill/compose/.bundle/feedback/SKILL.md +0 -214
  636. package/src/skill/compose/.bundle/merge/SKILL.md +0 -252
  637. package/src/skill/compose/.bundle/new-skill/SKILL.md +0 -211
  638. package/src/skill/compose/.bundle/parallel/SKILL.md +0 -168
  639. package/src/skill/compose/.bundle/plan/SKILL.md +0 -183
  640. package/src/skill/compose/.bundle/plan/plan-document-reviewer-prompt.md +0 -50
  641. package/src/skill/compose/.bundle/report/SKILL.md +0 -180
  642. package/src/skill/compose/.bundle/review/SKILL.md +0 -104
  643. package/src/skill/compose/.bundle/review/code-reviewer.md +0 -178
  644. package/src/skill/compose/.bundle/subagent/SKILL.md +0 -325
  645. package/src/skill/compose/.bundle/subagent/code-quality-reviewer-prompt.md +0 -26
  646. package/src/skill/compose/.bundle/subagent/implementer-prompt.md +0 -128
  647. package/src/skill/compose/.bundle/subagent/spec-reviewer-prompt.md +0 -118
  648. package/src/skill/compose/.bundle/tdd/SKILL.md +0 -360
  649. package/src/skill/compose/.bundle/tdd/testing-anti-patterns.md +0 -299
  650. package/src/skill/compose/.bundle/verify/SKILL.md +0 -140
  651. package/src/skill/compose/.bundle/worktree/SKILL.md +0 -234
  652. package/src/skill/compose/LICENSE-karpathy +0 -28
  653. package/src/skill/compose/bundle.macro.ts +0 -30
  654. package/src/skill/compose/extract.ts +0 -85
  655. package/src/skill/discovery.ts +0 -114
  656. package/src/skill/index.ts +0 -328
  657. package/src/snapshot/index.ts +0 -777
  658. package/src/sql.d.ts +0 -4
  659. package/src/storage/db.bun.ts +0 -8
  660. package/src/storage/db.node.ts +0 -8
  661. package/src/storage/db.ts +0 -172
  662. package/src/storage/index.ts +0 -26
  663. package/src/storage/json-migration.ts +0 -426
  664. package/src/storage/read-sqlite.bun.ts +0 -11
  665. package/src/storage/read-sqlite.node.ts +0 -13
  666. package/src/storage/read-sqlite.ts +0 -10
  667. package/src/storage/schema.sql.ts +0 -10
  668. package/src/storage/schema.ts +0 -7
  669. package/src/storage/storage.ts +0 -331
  670. package/src/sync/README.md +0 -179
  671. package/src/sync/event.sql.ts +0 -16
  672. package/src/sync/index.ts +0 -278
  673. package/src/sync/schema.ts +0 -14
  674. package/src/task/events.ts +0 -28
  675. package/src/task/gate-state.ts +0 -54
  676. package/src/task/gate.ts +0 -116
  677. package/src/task/index.ts +0 -1
  678. package/src/task/registry.ts +0 -394
  679. package/src/task/schema.ts +0 -43
  680. package/src/task/task.sql.ts +0 -50
  681. package/src/team/events.ts +0 -22
  682. package/src/team/index.ts +0 -113
  683. package/src/team/schema.ts +0 -31
  684. package/src/temporary.ts +0 -33
  685. package/src/tool/actor.shell.txt +0 -72
  686. package/src/tool/actor.ts +0 -804
  687. package/src/tool/actor.txt +0 -103
  688. package/src/tool/apply_patch.ts +0 -308
  689. package/src/tool/apply_patch.txt +0 -33
  690. package/src/tool/bash-interactive.ts +0 -183
  691. package/src/tool/bash.ts +0 -704
  692. package/src/tool/bash.txt +0 -123
  693. package/src/tool/change-directory.ts +0 -91
  694. package/src/tool/codesearch.ts +0 -63
  695. package/src/tool/codesearch.txt +0 -12
  696. package/src/tool/edit.ts +0 -693
  697. package/src/tool/edit.txt +0 -10
  698. package/src/tool/external-directory.ts +0 -132
  699. package/src/tool/glob.ts +0 -100
  700. package/src/tool/glob.txt +0 -6
  701. package/src/tool/grep.ts +0 -145
  702. package/src/tool/grep.txt +0 -8
  703. package/src/tool/history.ts +0 -146
  704. package/src/tool/history.txt +0 -17
  705. package/src/tool/index.ts +0 -4
  706. package/src/tool/invalid.ts +0 -20
  707. package/src/tool/invocation-style.ts +0 -17
  708. package/src/tool/lsp.ts +0 -91
  709. package/src/tool/lsp.txt +0 -19
  710. package/src/tool/mcp-exa.ts +0 -78
  711. package/src/tool/memory-path-guard.ts +0 -162
  712. package/src/tool/memory.ts +0 -81
  713. package/src/tool/memory.txt +0 -69
  714. package/src/tool/multiedit.ts +0 -54
  715. package/src/tool/multiedit.txt +0 -41
  716. package/src/tool/notebook-edit.ts +0 -225
  717. package/src/tool/notebook-edit.txt +0 -10
  718. package/src/tool/plan-enter.txt +0 -16
  719. package/src/tool/plan-exit.txt +0 -14
  720. package/src/tool/plan.ts +0 -179
  721. package/src/tool/question.ts +0 -67
  722. package/src/tool/question.txt +0 -10
  723. package/src/tool/read-state.ts +0 -44
  724. package/src/tool/read.ts +0 -327
  725. package/src/tool/read.txt +0 -14
  726. package/src/tool/recoverable.ts +0 -35
  727. package/src/tool/registry.ts +0 -429
  728. package/src/tool/schema.ts +0 -17
  729. package/src/tool/session-cwd.ts +0 -35
  730. package/src/tool/shell-tokenize.ts +0 -374
  731. package/src/tool/shell-wrap.ts +0 -235
  732. package/src/tool/skill.ts +0 -76
  733. package/src/tool/skill.txt +0 -5
  734. package/src/tool/task.shell.txt +0 -57
  735. package/src/tool/task.ts +0 -456
  736. package/src/tool/task.txt +0 -56
  737. package/src/tool/tool.ts +0 -166
  738. package/src/tool/truncate.ts +0 -201
  739. package/src/tool/truncation-dir.ts +0 -4
  740. package/src/tool/webfetch.ts +0 -208
  741. package/src/tool/webfetch.txt +0 -13
  742. package/src/tool/websearch/index.ts +0 -104
  743. package/src/tool/websearch/sleepy.ts +0 -118
  744. package/src/tool/websearch/websearch.txt +0 -14
  745. package/src/tool/workflow.ts +0 -357
  746. package/src/tool/workflow.txt +0 -25
  747. package/src/tool/write.ts +0 -88
  748. package/src/tool/write.txt +0 -10
  749. package/src/util/abort.ts +0 -35
  750. package/src/util/archive.ts +0 -15
  751. package/src/util/color.ts +0 -17
  752. package/src/util/data-url.ts +0 -9
  753. package/src/util/defer.ts +0 -10
  754. package/src/util/effect-http-client.ts +0 -11
  755. package/src/util/effect-zod.ts +0 -367
  756. package/src/util/env-info.ts +0 -62
  757. package/src/util/error.ts +0 -78
  758. package/src/util/filesystem.ts +0 -243
  759. package/src/util/fn.ts +0 -21
  760. package/src/util/format.ts +0 -20
  761. package/src/util/iife.ts +0 -3
  762. package/src/util/index.ts +0 -14
  763. package/src/util/keybind.ts +0 -101
  764. package/src/util/lazy.ts +0 -18
  765. package/src/util/local-context.ts +0 -23
  766. package/src/util/locale.ts +0 -79
  767. package/src/util/lock.ts +0 -96
  768. package/src/util/log.ts +0 -234
  769. package/src/util/media.ts +0 -26
  770. package/src/util/network.ts +0 -9
  771. package/src/util/process.ts +0 -174
  772. package/src/util/provider-priority.ts +0 -48
  773. package/src/util/queue.ts +0 -60
  774. package/src/util/record.ts +0 -3
  775. package/src/util/rpc.ts +0 -64
  776. package/src/util/schema.ts +0 -53
  777. package/src/util/scrap.ts +0 -10
  778. package/src/util/signal.ts +0 -12
  779. package/src/util/sleepy-process.ts +0 -24
  780. package/src/util/ssrf.ts +0 -116
  781. package/src/util/timeout.ts +0 -14
  782. package/src/util/token.ts +0 -5
  783. package/src/util/tool-compat.ts +0 -144
  784. package/src/util/update-schema.ts +0 -13
  785. package/src/util/which.ts +0 -14
  786. package/src/util/wildcard.ts +0 -57
  787. package/src/workflow/builtin/compose.js +0 -749
  788. package/src/workflow/builtin/deep-research.js +0 -398
  789. package/src/workflow/builtin.ts +0 -59
  790. package/src/workflow/events.ts +0 -72
  791. package/src/workflow/meta.ts +0 -335
  792. package/src/workflow/persistence.ts +0 -312
  793. package/src/workflow/resolve.ts +0 -45
  794. package/src/workflow/runtime-ref.ts +0 -18
  795. package/src/workflow/runtime.ts +0 -1447
  796. package/src/workflow/sandbox.ts +0 -286
  797. package/src/workflow/workflow.sql.ts +0 -31
  798. package/src/workflow/workspace.ts +0 -69
  799. package/src/worktree/index.ts +0 -629
@@ -1,2098 +0,0 @@
1
- import z from "zod"
2
- import fsNode from "fs/promises"
3
- import os from "os"
4
- import fuzzysort from "fuzzysort"
5
- import { Config } from "../config"
6
- import { mapValues, mergeDeep, omit, pickBy, sortBy } from "remeda"
7
- import { NoSuchModelError, type Provider as SDK } from "ai"
8
- import { Log } from "../util"
9
- import { Npm } from "../npm"
10
- import { Hash } from "@sleepy-ai/shared/util/hash"
11
- import { Plugin } from "../plugin"
12
- import { NamedError } from "@sleepy-ai/shared/util/error"
13
- import { type LanguageModelV3 } from "@ai-sdk/provider"
14
- import * as ModelsDev from "./models"
15
- import { Auth } from "../auth"
16
- import { Env } from "../env"
17
- import { InstallationVersion } from "../installation/version"
18
- import { Flag } from "../flag/flag"
19
- import { zod } from "@/util/effect-zod"
20
- import { iife } from "@/util/iife"
21
- import { Global } from "../global"
22
- import path from "path"
23
- import { pathToFileURL } from "url"
24
- import { Effect, Layer, Context, Schema, Types } from "effect"
25
- import { EffectBridge } from "@/effect"
26
- import { InstanceState } from "@/effect"
27
- import { AppFileSystem } from "@sleepy-ai/shared/filesystem"
28
- import { isRecord } from "@/util/record"
29
- import { withStatics } from "@/util/schema"
30
-
31
- import * as ProviderTransform from "./transform"
32
- import { ModelID, ProviderID } from "./schema"
33
- import { createSessionChecker } from "./session-check"
34
-
35
- const log = Log.create({ service: "provider" })
36
- const DEFAULT_CONTEXT_WINDOW = 1_000_000
37
- // Reserved built-in model tiers: always resolve, falling back to the default
38
- // model when not configured in `model_groups` (zero-config never errors).
39
- const BUILTIN_TIERS = new Set(["ultra", "standard", "lite"])
40
- // F41: warn once per (providerID, modelID) when limit.context falls back to default
41
- const warnedContextDefaults = new Set<string>()
42
-
43
- export const DEFAULT_CHUNK_TIMEOUT = 480_000 // 8 minutes — bounds single-attempt SSE stall.
44
- // Tuned for sleepy-v2.5-pro on Sleepy Router whose cold-path TTFT after context
45
- // rebuild can dip to ~5 minutes silent. Reasoning models with multi-minute
46
- // thinking still emit partial chunks / heartbeats within this window. Override
47
- // per-provider via sleepycode.json's `chunkTimeout` config for tighter or looser
48
- // bounds.
49
-
50
- function shouldUseCopilotResponsesApi(modelID: string): boolean {
51
- const match = /^gpt-(\d+)/.exec(modelID)
52
- if (!match) return false
53
- return Number(match[1]) >= 5 && !modelID.startsWith("gpt-5-mini")
54
- }
55
-
56
- function wrapSSE(res: Response, ms: number, ctl: AbortController) {
57
- if (typeof ms !== "number" || ms <= 0) return res
58
- if (!res.body) return res
59
- if (!res.headers.get("content-type")?.includes("text/event-stream")) return res
60
-
61
- const reader = res.body.getReader()
62
- const body = new ReadableStream<Uint8Array>({
63
- async pull(ctrl) {
64
- const part = await new Promise<Awaited<ReturnType<typeof reader.read>>>((resolve, reject) => {
65
- const id = setTimeout(() => {
66
- const err = new Error("SSE read timed out")
67
- ctl.abort(err)
68
- void reader.cancel(err)
69
- reject(err)
70
- }, ms)
71
-
72
- reader.read().then(
73
- (part) => {
74
- clearTimeout(id)
75
- resolve(part)
76
- },
77
- (err) => {
78
- clearTimeout(id)
79
- reject(err)
80
- },
81
- )
82
- })
83
-
84
- if (part.done) {
85
- ctrl.close()
86
- return
87
- }
88
-
89
- ctrl.enqueue(part.value)
90
- },
91
- async cancel(reason) {
92
- ctl.abort(reason)
93
- await reader.cancel(reason)
94
- },
95
- })
96
-
97
- return new Response(body, {
98
- headers: new Headers(res.headers),
99
- status: res.status,
100
- statusText: res.statusText,
101
- })
102
- }
103
-
104
- interface GatewayModel {
105
- modelId: string
106
- name: string
107
- omniRouteModelId: string
108
- contextWindow?: number
109
- maxOutputLimit?: number
110
- inputPrice?: number
111
- outputPrice?: number
112
- cacheReadPrice?: number
113
- cacheWritePrice?: number
114
- }
115
-
116
- async function fetchModels(endpoint: string, token: string): Promise<GatewayModel[]> {
117
- try {
118
- const res = await fetch(`${endpoint}/api/v1/models`, {
119
- headers: { Authorization: `Bearer ${token}` },
120
- })
121
- if (!res.ok) return []
122
- const json = await res.json()
123
- if (json && json.data && Array.isArray(json.data)) {
124
- return json.data as GatewayModel[]
125
- }
126
- return []
127
- } catch {
128
- return []
129
- }
130
- }
131
-
132
- type BundledSDK = {
133
- languageModel(modelId: string): LanguageModelV3
134
- }
135
-
136
- const BUNDLED_PROVIDERS: Record<string, () => Promise<(opts: any) => BundledSDK>> = {
137
- "@ai-sdk/amazon-bedrock": () => import("@ai-sdk/amazon-bedrock").then((m) => m.createAmazonBedrock),
138
- "@ai-sdk/anthropic": () => import("@ai-sdk/anthropic").then((m) => m.createAnthropic),
139
- "@ai-sdk/azure": () => import("@ai-sdk/azure").then((m) => m.createAzure),
140
- "@ai-sdk/google": () => import("@ai-sdk/google").then((m) => m.createGoogleGenerativeAI),
141
- "@ai-sdk/google-vertex": () => import("@ai-sdk/google-vertex").then((m) => m.createVertex),
142
- "@ai-sdk/google-vertex/anthropic": () =>
143
- import("@ai-sdk/google-vertex/anthropic").then((m) => m.createVertexAnthropic),
144
- "@ai-sdk/openai": () => import("@ai-sdk/openai").then((m) => m.createOpenAI),
145
- "@ai-sdk/openai-compatible": () => import("@ai-sdk/openai-compatible").then((m) => m.createOpenAICompatible),
146
- "@openrouter/ai-sdk-provider": () => import("@openrouter/ai-sdk-provider").then((m) => m.createOpenRouter),
147
- "@ai-sdk/xai": () => import("@ai-sdk/xai").then((m) => m.createXai),
148
- "@ai-sdk/mistral": () => import("@ai-sdk/mistral").then((m) => m.createMistral),
149
- "@ai-sdk/groq": () => import("@ai-sdk/groq").then((m) => m.createGroq),
150
- "@ai-sdk/deepinfra": () => import("@ai-sdk/deepinfra").then((m) => m.createDeepInfra),
151
- "@ai-sdk/cerebras": () => import("@ai-sdk/cerebras").then((m) => m.createCerebras),
152
- "@ai-sdk/cohere": () => import("@ai-sdk/cohere").then((m) => m.createCohere),
153
- "@ai-sdk/gateway": () => import("@ai-sdk/gateway").then((m) => m.createGateway),
154
- "@ai-sdk/togetherai": () => import("@ai-sdk/togetherai").then((m) => m.createTogetherAI),
155
- "@ai-sdk/perplexity": () => import("@ai-sdk/perplexity").then((m) => m.createPerplexity),
156
- "@ai-sdk/vercel": () => import("@ai-sdk/vercel").then((m) => m.createVercel),
157
- "@ai-sdk/alibaba": () => import("@ai-sdk/alibaba").then((m) => m.createAlibaba),
158
- "gitlab-ai-provider": () => import("gitlab-ai-provider").then((m) => m.createGitLab),
159
- "@ai-sdk/github-copilot": () => import("./sdk/copilot").then((m) => m.createOpenaiCompatible),
160
- "venice-ai-sdk-provider": () => import("venice-ai-sdk-provider").then((m) => m.createVenice),
161
- }
162
-
163
- type CustomModelLoader = (sdk: any, modelID: string, options?: Record<string, any>) => Promise<any>
164
- type CustomVarsLoader = (options: Record<string, any>) => Record<string, string>
165
- type CustomDiscoverModels = () => Promise<Record<string, Model>>
166
- type CustomLoader = (provider: Info) => Effect.Effect<{
167
- autoload: boolean
168
- getModel?: CustomModelLoader
169
- vars?: CustomVarsLoader
170
- options?: Record<string, any>
171
- discoverModels?: CustomDiscoverModels
172
- }>
173
-
174
- type CustomDep = {
175
- auth: (id: string) => Effect.Effect<Auth.Info | undefined>
176
- config: () => Effect.Effect<Config.Info>
177
- env: () => Effect.Effect<Record<string, string | undefined>>
178
- get: (key: string) => Effect.Effect<string | undefined>
179
- }
180
-
181
- function useLanguageModel(sdk: any) {
182
- return sdk.responses === undefined && sdk.chat === undefined
183
- }
184
-
185
- function custom(dep: CustomDep): Record<string, CustomLoader> {
186
- return {
187
- anthropic: () =>
188
- Effect.succeed({
189
- autoload: false,
190
- options: {
191
- headers: {
192
- "anthropic-beta": "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14",
193
- },
194
- },
195
- }),
196
- opencode: Effect.fnUntraced(function* (input: Info) {
197
- const env = yield* dep.env()
198
- const hasKey = iife(() => {
199
- if (input.env.some((item) => env[item])) return true
200
- return false
201
- })
202
- const ok =
203
- hasKey ||
204
- Boolean(yield* dep.auth(input.id)) ||
205
- Boolean((yield* dep.config()).provider?.["opencode"]?.options?.apiKey)
206
-
207
- // Never surface the free/public tier (cost.input === 0). Without a
208
- // subscription/key, hide the remaining (paid) models too — they can't be
209
- // used unauthenticated. So: authenticated -> subscription models only,
210
- // unauthenticated -> nothing.
211
- for (const [key, value] of Object.entries(input.models)) {
212
- if (!ok || value.cost.input === 0) delete input.models[key]
213
- }
214
-
215
- return {
216
- autoload: Object.keys(input.models).length > 0,
217
- options: {},
218
- }
219
- }),
220
- openai: () =>
221
- Effect.succeed({
222
- autoload: false,
223
- async getModel(sdk: any, modelID: string, _options?: Record<string, any>) {
224
- return sdk.responses(modelID)
225
- },
226
- options: {},
227
- }),
228
- xai: () =>
229
- Effect.succeed({
230
- autoload: false,
231
- async getModel(sdk: any, modelID: string, _options?: Record<string, any>) {
232
- return sdk.responses(modelID)
233
- },
234
- options: {},
235
- }),
236
- "github-copilot": () =>
237
- Effect.succeed({
238
- autoload: false,
239
- async getModel(sdk: any, modelID: string, _options?: Record<string, any>) {
240
- if (useLanguageModel(sdk)) return sdk.languageModel(modelID)
241
- return shouldUseCopilotResponsesApi(modelID) ? sdk.responses(modelID) : sdk.chat(modelID)
242
- },
243
- options: {},
244
- }),
245
- azure: Effect.fnUntraced(function* (provider: Info) {
246
- const env = yield* dep.env()
247
- const resource = iife(() => {
248
- const name = provider.options?.resourceName
249
- if (typeof name === "string" && name.trim() !== "") return name
250
- return env["AZURE_RESOURCE_NAME"]
251
- })
252
-
253
- return {
254
- autoload: false,
255
- async getModel(sdk: any, modelID: string, options?: Record<string, any>) {
256
- if (useLanguageModel(sdk)) return sdk.languageModel(modelID)
257
- if (options?.["useCompletionUrls"]) {
258
- return sdk.chat(modelID)
259
- } else {
260
- return sdk.responses(modelID)
261
- }
262
- },
263
- options: {},
264
- vars(_options) {
265
- return {
266
- ...(resource && { AZURE_RESOURCE_NAME: resource }),
267
- }
268
- },
269
- }
270
- }),
271
- "azure-cognitive-services": Effect.fnUntraced(function* () {
272
- const resourceName = yield* dep.get("AZURE_COGNITIVE_SERVICES_RESOURCE_NAME")
273
- return {
274
- autoload: false,
275
- async getModel(sdk: any, modelID: string, options?: Record<string, any>) {
276
- if (useLanguageModel(sdk)) return sdk.languageModel(modelID)
277
- if (options?.["useCompletionUrls"]) {
278
- return sdk.chat(modelID)
279
- } else {
280
- return sdk.responses(modelID)
281
- }
282
- },
283
- options: {
284
- baseURL: resourceName ? `https://${resourceName}.cognitiveservices.azure.com/openai` : undefined,
285
- },
286
- }
287
- }),
288
- "amazon-bedrock": Effect.fnUntraced(function* () {
289
- const providerConfig = (yield* dep.config()).provider?.["amazon-bedrock"]
290
- const auth = yield* dep.auth("amazon-bedrock")
291
- const env = yield* dep.env()
292
-
293
- // Region precedence: 1) config file, 2) env var, 3) default
294
- const configRegion = providerConfig?.options?.region
295
- const envRegion = env["AWS_REGION"]
296
- const defaultRegion = configRegion ?? envRegion ?? "us-east-1"
297
-
298
- // Profile: config file takes precedence over env var
299
- const configProfile = providerConfig?.options?.profile
300
- const envProfile = env["AWS_PROFILE"]
301
- const profile = configProfile ?? envProfile
302
-
303
- const awsAccessKeyId = env["AWS_ACCESS_KEY_ID"]
304
-
305
- // TODO: Using process.env directly because Env.set only updates a process.env shallow copy,
306
- // until the scope of the Env API is clarified (test only or runtime?)
307
- const awsBearerToken = iife(() => {
308
- const envToken = process.env.AWS_BEARER_TOKEN_BEDROCK
309
- if (envToken) return envToken
310
- if (auth?.type === "api") {
311
- process.env.AWS_BEARER_TOKEN_BEDROCK = auth.key
312
- return auth.key
313
- }
314
- return undefined
315
- })
316
-
317
- const awsWebIdentityTokenFile = env["AWS_WEB_IDENTITY_TOKEN_FILE"]
318
-
319
- const containerCreds = Boolean(
320
- process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI || process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI,
321
- )
322
-
323
- if (!profile && !awsAccessKeyId && !awsBearerToken && !awsWebIdentityTokenFile && !containerCreds)
324
- return { autoload: false }
325
-
326
- const { fromNodeProviderChain } = yield* Effect.promise(() => import("@aws-sdk/credential-providers"))
327
-
328
- const providerOptions: Record<string, any> = {
329
- region: defaultRegion,
330
- }
331
-
332
- // Only use credential chain if no bearer token exists
333
- // Bearer token takes precedence over credential chain (profiles, access keys, IAM roles, web identity tokens)
334
- if (!awsBearerToken) {
335
- // Build credential provider options (only pass profile if specified)
336
- const credentialProviderOptions = profile ? { profile } : {}
337
-
338
- providerOptions.credentialProvider = fromNodeProviderChain(credentialProviderOptions)
339
- }
340
-
341
- // Add custom endpoint if specified (endpoint takes precedence over baseURL)
342
- const endpoint = providerConfig?.options?.endpoint ?? providerConfig?.options?.baseURL
343
- if (endpoint) {
344
- providerOptions.baseURL = endpoint
345
- }
346
-
347
- return {
348
- autoload: true,
349
- options: providerOptions,
350
- async getModel(sdk: any, modelID: string, options?: Record<string, any>) {
351
- // Skip region prefixing if model already has a cross-region inference profile prefix
352
- // Models from models.dev may already include prefixes like us., eu., global., etc.
353
- const crossRegionPrefixes = ["global.", "us.", "eu.", "jp.", "apac.", "au."]
354
- if (crossRegionPrefixes.some((prefix) => modelID.startsWith(prefix))) {
355
- return sdk.languageModel(modelID)
356
- }
357
-
358
- // Region resolution precedence (highest to lowest):
359
- // 1. options.region from sleepycode.json provider config
360
- // 2. defaultRegion from AWS_REGION environment variable
361
- // 3. Default "us-east-1" (baked into defaultRegion)
362
- const region = options?.region ?? defaultRegion
363
-
364
- let regionPrefix = region.split("-")[0]
365
-
366
- switch (regionPrefix) {
367
- case "us": {
368
- const modelRequiresPrefix = [
369
- "nova-micro",
370
- "nova-lite",
371
- "nova-pro",
372
- "nova-premier",
373
- "nova-2",
374
- "claude",
375
- "deepseek",
376
- ].some((m) => modelID.includes(m))
377
- const isGovCloud = region.startsWith("us-gov")
378
- if (modelRequiresPrefix && !isGovCloud) {
379
- modelID = `${regionPrefix}.${modelID}`
380
- }
381
- break
382
- }
383
- case "eu": {
384
- const regionRequiresPrefix = [
385
- "eu-west-1",
386
- "eu-west-2",
387
- "eu-west-3",
388
- "eu-north-1",
389
- "eu-central-1",
390
- "eu-south-1",
391
- "eu-south-2",
392
- ].some((r) => region.includes(r))
393
- const modelRequiresPrefix = ["claude", "nova-lite", "nova-micro", "llama3", "pixtral"].some((m) =>
394
- modelID.includes(m),
395
- )
396
- if (regionRequiresPrefix && modelRequiresPrefix) {
397
- modelID = `${regionPrefix}.${modelID}`
398
- }
399
- break
400
- }
401
- case "ap": {
402
- const isAustraliaRegion = ["ap-southeast-2", "ap-southeast-4"].includes(region)
403
- const isTokyoRegion = region === "ap-northeast-1"
404
- if (
405
- isAustraliaRegion &&
406
- ["anthropic.claude-sonnet-4-5", "anthropic.claude-haiku"].some((m) => modelID.includes(m))
407
- ) {
408
- regionPrefix = "au"
409
- modelID = `${regionPrefix}.${modelID}`
410
- } else if (isTokyoRegion) {
411
- // Tokyo region uses jp. prefix for cross-region inference
412
- const modelRequiresPrefix = ["claude", "nova-lite", "nova-micro", "nova-pro"].some((m) =>
413
- modelID.includes(m),
414
- )
415
- if (modelRequiresPrefix) {
416
- regionPrefix = "jp"
417
- modelID = `${regionPrefix}.${modelID}`
418
- }
419
- } else {
420
- // Other APAC regions use apac. prefix
421
- const modelRequiresPrefix = ["claude", "nova-lite", "nova-micro", "nova-pro"].some((m) =>
422
- modelID.includes(m),
423
- )
424
- if (modelRequiresPrefix) {
425
- regionPrefix = "apac"
426
- modelID = `${regionPrefix}.${modelID}`
427
- }
428
- }
429
- break
430
- }
431
- }
432
-
433
- return sdk.languageModel(modelID)
434
- },
435
- }
436
- }),
437
- llmgateway: () =>
438
- Effect.succeed({
439
- autoload: false,
440
- options: {
441
- headers: {
442
- "HTTP-Referer": "https://www.sleepyai.org/",
443
- "X-Title": "sleepy-code",
444
- "X-Source": "sleepycode",
445
- },
446
- },
447
- }),
448
- openrouter: () =>
449
- Effect.succeed({
450
- autoload: false,
451
- options: {
452
- headers: {
453
- "HTTP-Referer": "https://www.sleepyai.org/",
454
- "X-Title": "sleepy-code",
455
- "X-OpenRouter-Categories": "programming,programming-app,cli-agent",
456
- },
457
- },
458
- }),
459
- nvidia: () =>
460
- Effect.succeed({
461
- autoload: false,
462
- options: {
463
- headers: {
464
- "HTTP-Referer": "https://www.sleepyai.org/",
465
- "X-Title": "sleepy-code",
466
- },
467
- },
468
- }),
469
- vercel: () =>
470
- Effect.succeed({
471
- autoload: false,
472
- options: {
473
- headers: {
474
- "http-referer": "https://www.sleepyai.org/",
475
- "x-title": "sleepy-code",
476
- },
477
- },
478
- }),
479
- "google-vertex": Effect.fnUntraced(function* (provider: Info) {
480
- const env = yield* dep.env()
481
- const project =
482
- provider.options?.project ?? env["GOOGLE_CLOUD_PROJECT"] ?? env["GCP_PROJECT"] ?? env["GCLOUD_PROJECT"]
483
-
484
- const location = String(
485
- provider.options?.location ??
486
- env["GOOGLE_VERTEX_LOCATION"] ??
487
- env["GOOGLE_CLOUD_LOCATION"] ??
488
- env["VERTEX_LOCATION"] ??
489
- "us-central1",
490
- )
491
-
492
- const autoload = Boolean(project)
493
- if (!autoload) return { autoload: false }
494
- return {
495
- autoload: true,
496
- vars(_options: Record<string, any>) {
497
- const endpoint = location === "global" ? "aiplatform.googleapis.com" : `${location}-aiplatform.googleapis.com`
498
- return {
499
- ...(project && { GOOGLE_VERTEX_PROJECT: project }),
500
- GOOGLE_VERTEX_LOCATION: location,
501
- GOOGLE_VERTEX_ENDPOINT: endpoint,
502
- }
503
- },
504
- options: {
505
- project,
506
- location,
507
- fetch: async (input: RequestInfo | URL, init?: RequestInit) => {
508
- const { GoogleAuth } = await import("google-auth-library")
509
- const auth = new GoogleAuth()
510
- const client = await auth.getApplicationDefault()
511
- const token = await client.credential.getAccessToken()
512
-
513
- const headers = new Headers(init?.headers)
514
- headers.set("Authorization", `Bearer ${token.token}`)
515
-
516
- return fetch(input, { ...init, headers })
517
- },
518
- },
519
- async getModel(sdk: any, modelID: string) {
520
- const id = String(modelID).trim()
521
- return sdk.languageModel(id)
522
- },
523
- }
524
- }),
525
- "google-vertex-anthropic": Effect.fnUntraced(function* () {
526
- const env = yield* dep.env()
527
- const project = env["GOOGLE_CLOUD_PROJECT"] ?? env["GCP_PROJECT"] ?? env["GCLOUD_PROJECT"]
528
- const location = env["GOOGLE_CLOUD_LOCATION"] ?? env["VERTEX_LOCATION"] ?? "global"
529
- const autoload = Boolean(project)
530
- if (!autoload) return { autoload: false }
531
- return {
532
- autoload: true,
533
- options: {
534
- project,
535
- location,
536
- },
537
- async getModel(sdk: any, modelID) {
538
- const id = String(modelID).trim()
539
- return sdk.languageModel(id)
540
- },
541
- }
542
- }),
543
- "sap-ai-core": Effect.fnUntraced(function* () {
544
- const auth = yield* dep.auth("sap-ai-core")
545
- // TODO: Using process.env directly because Env.set only updates a shallow copy (not process.env),
546
- // until the scope of the Env API is clarified (test only or runtime?)
547
- const envServiceKey = iife(() => {
548
- const envAICoreServiceKey = process.env.AICORE_SERVICE_KEY
549
- if (envAICoreServiceKey) return envAICoreServiceKey
550
- if (auth?.type === "api") {
551
- process.env.AICORE_SERVICE_KEY = auth.key
552
- return auth.key
553
- }
554
- return undefined
555
- })
556
- const deploymentId = process.env.AICORE_DEPLOYMENT_ID
557
- const resourceGroup = process.env.AICORE_RESOURCE_GROUP
558
-
559
- return {
560
- autoload: !!envServiceKey,
561
- options: envServiceKey ? { deploymentId, resourceGroup } : {},
562
- async getModel(sdk: any, modelID: string) {
563
- return sdk(modelID)
564
- },
565
- }
566
- }),
567
- zenmux: () =>
568
- Effect.succeed({
569
- autoload: false,
570
- options: {
571
- headers: {
572
- "HTTP-Referer": "https://www.sleepyai.org/",
573
- "X-Title": "sleepy-code",
574
- },
575
- },
576
- }),
577
- gitlab: Effect.fnUntraced(function* (input: Info) {
578
- const {
579
- VERSION: GITLAB_PROVIDER_VERSION,
580
- isWorkflowModel,
581
- discoverWorkflowModels,
582
- } = yield* Effect.promise(() => import("gitlab-ai-provider"))
583
-
584
- const instanceUrl = (yield* dep.get("GITLAB_INSTANCE_URL")) || "https://gitlab.com"
585
-
586
- const auth = yield* dep.auth(input.id)
587
- const apiKey = yield* Effect.sync(() => {
588
- if (auth?.type === "oauth") return auth.access
589
- if (auth?.type === "api") return auth.key
590
- return undefined
591
- })
592
- const token = apiKey ?? (yield* dep.get("GITLAB_TOKEN"))
593
-
594
- const providerConfig = (yield* dep.config()).provider?.["gitlab"]
595
- const directory = yield* InstanceState.directory
596
-
597
- const aiGatewayHeaders = {
598
- "User-Agent": `sleepycode/${InstallationVersion} gitlab-ai-provider/${GITLAB_PROVIDER_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
599
- "anthropic-beta": "context-1m-2025-08-07",
600
- ...providerConfig?.options?.aiGatewayHeaders,
601
- }
602
-
603
- const featureFlags = {
604
- duo_agent_platform_agentic_chat: true,
605
- duo_agent_platform: true,
606
- ...providerConfig?.options?.featureFlags,
607
- }
608
-
609
- return {
610
- autoload: !!token,
611
- options: {
612
- instanceUrl,
613
- apiKey: token,
614
- aiGatewayHeaders,
615
- featureFlags,
616
- },
617
- async getModel(sdk: any, modelID: string, options?: Record<string, any>) {
618
- if (modelID.startsWith("duo-workflow-")) {
619
- const workflowRef = typeof options?.workflowRef === "string" ? options.workflowRef : undefined
620
- // Use the static mapping if it exists, otherwise use duo-workflow with selectedModelRef
621
- const sdkModelID = isWorkflowModel(modelID) ? modelID : "duo-workflow"
622
- const workflowDefinition =
623
- typeof options?.workflowDefinition === "string" ? options.workflowDefinition : undefined
624
- const model = sdk.workflowChat(sdkModelID, {
625
- featureFlags,
626
- workflowDefinition,
627
- })
628
- if (workflowRef) {
629
- model.selectedModelRef = workflowRef
630
- }
631
- return model
632
- }
633
- return sdk.agenticChat(modelID, {
634
- aiGatewayHeaders,
635
- featureFlags,
636
- })
637
- },
638
- async discoverModels(): Promise<Record<string, Model>> {
639
- if (!apiKey) {
640
- log.info("gitlab model discovery skipped: no apiKey")
641
- return {}
642
- }
643
-
644
- try {
645
- const token = apiKey
646
- const getHeaders = (): Record<string, string> =>
647
- auth?.type === "api" ? { "PRIVATE-TOKEN": token } : { Authorization: `Bearer ${token}` }
648
-
649
- log.info("gitlab model discovery starting", { instanceUrl })
650
- const result = await discoverWorkflowModels({ instanceUrl, getHeaders }, { workingDirectory: directory })
651
-
652
- if (!result.models.length) {
653
- log.info("gitlab model discovery skipped: no models found", {
654
- project: result.project
655
- ? {
656
- id: result.project.id,
657
- path: result.project.pathWithNamespace,
658
- }
659
- : null,
660
- })
661
- return {}
662
- }
663
-
664
- const models: Record<string, Model> = {}
665
- for (const m of result.models) {
666
- if (!input.models[m.id]) {
667
- models[m.id] = {
668
- id: ModelID.make(m.id),
669
- providerID: ProviderID.make("gitlab"),
670
- name: `Agent Platform (${m.name})`,
671
- family: "",
672
- api: {
673
- id: m.id,
674
- url: instanceUrl,
675
- npm: "gitlab-ai-provider",
676
- },
677
- status: "active",
678
- headers: {},
679
- options: { workflowRef: m.ref },
680
- cost: { input: 0, output: 0, cache: { read: 0, write: 0 } },
681
- limit: { context: m.context, output: m.output },
682
- capabilities: {
683
- temperature: false,
684
- reasoning: true,
685
- attachment: true,
686
- toolcall: true,
687
- input: {
688
- text: true,
689
- audio: false,
690
- image: true,
691
- video: false,
692
- pdf: true,
693
- },
694
- output: {
695
- text: true,
696
- audio: false,
697
- image: false,
698
- video: false,
699
- pdf: false,
700
- },
701
- interleaved: false,
702
- },
703
- release_date: "",
704
- variants: {},
705
- }
706
- }
707
- }
708
-
709
- log.info("gitlab model discovery complete", {
710
- count: Object.keys(models).length,
711
- models: Object.keys(models),
712
- })
713
- return models
714
- } catch (e) {
715
- log.warn("gitlab model discovery failed", { error: e })
716
- return {}
717
- }
718
- },
719
- }
720
- }),
721
- "cloudflare-workers-ai": Effect.fnUntraced(function* (input: Info) {
722
- // When baseURL is already configured (e.g. corporate config routing through a proxy/gateway),
723
- // skip the account ID check because the URL is already fully specified.
724
- if (input.options?.baseURL) return { autoload: false }
725
-
726
- const auth = yield* dep.auth(input.id)
727
- const env = yield* dep.env()
728
- const accountId = env["CLOUDFLARE_ACCOUNT_ID"] || (auth?.type === "api" ? auth.metadata?.accountId : undefined)
729
- if (!accountId)
730
- return {
731
- autoload: false,
732
- async getModel() {
733
- throw new Error(
734
- "CLOUDFLARE_ACCOUNT_ID is missing. Set it with: export CLOUDFLARE_ACCOUNT_ID=<your-account-id>",
735
- )
736
- },
737
- }
738
-
739
- const apiKey = yield* Effect.gen(function* () {
740
- const envToken = env["CLOUDFLARE_API_KEY"]
741
- if (envToken) return envToken
742
- if (auth?.type === "api") return auth.key
743
- return undefined
744
- })
745
-
746
- return {
747
- autoload: !!apiKey,
748
- options: {
749
- apiKey,
750
- headers: {
751
- "User-Agent": `sleepycode/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
752
- },
753
- },
754
- async getModel(sdk: any, modelID: string) {
755
- return sdk.languageModel(modelID)
756
- },
757
- vars(_options) {
758
- return {
759
- CLOUDFLARE_ACCOUNT_ID: accountId,
760
- }
761
- },
762
- }
763
- }),
764
- "cloudflare-ai-gateway": Effect.fnUntraced(function* (input: Info) {
765
- // When baseURL is already configured (e.g. corporate config), skip the ID checks.
766
- if (input.options?.baseURL) return { autoload: false }
767
-
768
- const auth = yield* dep.auth(input.id)
769
- const env = yield* dep.env()
770
- const accountId = env["CLOUDFLARE_ACCOUNT_ID"] || (auth?.type === "api" ? auth.metadata?.accountId : undefined)
771
- const gateway = env["CLOUDFLARE_GATEWAY_ID"] || (auth?.type === "api" ? auth.metadata?.gatewayId : undefined)
772
-
773
- if (!accountId || !gateway) {
774
- const missing = [
775
- !accountId ? "CLOUDFLARE_ACCOUNT_ID" : undefined,
776
- !gateway ? "CLOUDFLARE_GATEWAY_ID" : undefined,
777
- ].filter((x): x is string => Boolean(x))
778
- return {
779
- autoload: false,
780
- async getModel() {
781
- throw new Error(
782
- `${missing.join(" and ")} missing. Set with: ${missing.map((x) => `export ${x}=<value>`).join(" && ")}`,
783
- )
784
- },
785
- }
786
- }
787
-
788
- // Get API token from env or auth - required for authenticated gateways
789
- const apiToken = yield* Effect.gen(function* () {
790
- const envToken = env["CLOUDFLARE_API_TOKEN"] || env["CF_AIG_TOKEN"]
791
- if (envToken) return envToken
792
- if (auth?.type === "api") return auth.key
793
- return undefined
794
- })
795
-
796
- if (!apiToken) {
797
- throw new Error(
798
- "CLOUDFLARE_API_TOKEN (or CF_AIG_TOKEN) is required for Cloudflare AI Gateway. " +
799
- "Set it via environment variable or run `sleepycode auth cloudflare-ai-gateway`.",
800
- )
801
- }
802
-
803
- // Use official ai-gateway-provider package (v2.x for AI SDK v5 compatibility)
804
- const { createAiGateway } = yield* Effect.promise(() => import("ai-gateway-provider"))
805
- const { createUnified } = yield* Effect.promise(() => import("ai-gateway-provider/providers/unified"))
806
-
807
- const metadata = iife(() => {
808
- if (input.options?.metadata) return input.options.metadata
809
- try {
810
- return JSON.parse(input.options?.headers?.["cf-aig-metadata"])
811
- } catch {
812
- return undefined
813
- }
814
- })
815
- const opts = {
816
- metadata,
817
- cacheTtl: input.options?.cacheTtl,
818
- cacheKey: input.options?.cacheKey,
819
- skipCache: input.options?.skipCache,
820
- collectLog: input.options?.collectLog,
821
- headers: {
822
- "User-Agent": `sleepycode/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
823
- },
824
- }
825
-
826
- const aigateway = createAiGateway({
827
- accountId,
828
- gateway,
829
- apiKey: apiToken,
830
- ...(Object.values(opts).some((v) => v !== undefined) ? { options: opts } : {}),
831
- })
832
- const unified = createUnified()
833
-
834
- return {
835
- autoload: true,
836
- async getModel(_sdk: any, modelID: string, _options?: Record<string, any>) {
837
- // Model IDs use Unified API format: provider/model (e.g., "anthropic/claude-sonnet-4-5")
838
- return aigateway(unified(modelID))
839
- },
840
- options: {},
841
- }
842
- }),
843
- cerebras: () =>
844
- Effect.succeed({
845
- autoload: false,
846
- options: {
847
- headers: {
848
- "X-Cerebras-3rd-Party-Integration": "sleepycode",
849
- },
850
- },
851
- }),
852
- kilo: () =>
853
- Effect.succeed({
854
- autoload: false,
855
- options: {
856
- headers: {
857
- "HTTP-Referer": "https://www.sleepyai.org/",
858
- "X-Title": "sleepy-code",
859
- },
860
- },
861
- }),
862
- }
863
- }
864
-
865
- const ProviderApiInfo = Schema.Struct({
866
- id: Schema.String,
867
- url: Schema.String,
868
- npm: Schema.String,
869
- })
870
-
871
- const ProviderModalities = Schema.Struct({
872
- text: Schema.Boolean,
873
- audio: Schema.Boolean,
874
- image: Schema.Boolean,
875
- video: Schema.Boolean,
876
- pdf: Schema.Boolean,
877
- })
878
-
879
- const ProviderInterleaved = Schema.Union([
880
- Schema.Boolean,
881
- Schema.Struct({
882
- field: Schema.Literals(["reasoning_content", "reasoning_details"]),
883
- }),
884
- ])
885
-
886
- const ProviderCapabilities = Schema.Struct({
887
- temperature: Schema.Boolean,
888
- reasoning: Schema.Boolean,
889
- attachment: Schema.Boolean,
890
- toolcall: Schema.Boolean,
891
- input: ProviderModalities,
892
- output: ProviderModalities,
893
- interleaved: ProviderInterleaved,
894
- })
895
-
896
- const ProviderCacheCost = Schema.Struct({
897
- read: Schema.Number,
898
- write: Schema.Number,
899
- })
900
-
901
- const ProviderCost = Schema.Struct({
902
- input: Schema.Number,
903
- output: Schema.Number,
904
- cache: ProviderCacheCost,
905
- experimentalOver200K: Schema.optional(
906
- Schema.Struct({
907
- input: Schema.Number,
908
- output: Schema.Number,
909
- cache: ProviderCacheCost,
910
- }),
911
- ),
912
- })
913
-
914
- const ProviderLimit = Schema.Struct({
915
- context: Schema.Number,
916
- input: Schema.optional(Schema.Number),
917
- output: Schema.Number,
918
- })
919
-
920
- export const Model = Schema.Struct({
921
- id: ModelID,
922
- providerID: ProviderID,
923
- api: ProviderApiInfo,
924
- name: Schema.String,
925
- family: Schema.optional(Schema.String),
926
- capabilities: ProviderCapabilities,
927
- cost: ProviderCost,
928
- limit: ProviderLimit,
929
- status: Schema.Literals(["alpha", "beta", "deprecated", "active"]),
930
- options: Schema.Record(Schema.String, Schema.Any),
931
- headers: Schema.Record(Schema.String, Schema.String),
932
- release_date: Schema.String,
933
- variants: Schema.optional(Schema.Record(Schema.String, Schema.Record(Schema.String, Schema.Any))),
934
- cacheTTL: Schema.optional(Schema.Number),
935
- cachePromptTTL: Schema.optional(Schema.Literals(["5m", "1h"])),
936
- })
937
- .annotate({ identifier: "Model" })
938
- .pipe(withStatics((s) => ({ zod: zod(s) })))
939
- export type Model = Types.DeepMutable<Schema.Schema.Type<typeof Model>>
940
-
941
- export const Info = Schema.Struct({
942
- id: ProviderID,
943
- name: Schema.String,
944
- source: Schema.Literals(["env", "config", "custom", "api"]),
945
- env: Schema.Array(Schema.String),
946
- key: Schema.optional(Schema.String),
947
- options: Schema.Record(Schema.String, Schema.Any),
948
- models: Schema.Record(Schema.String, Model),
949
- })
950
- .annotate({ identifier: "Provider" })
951
- .pipe(withStatics((s) => ({ zod: zod(s) })))
952
- export type Info = Types.DeepMutable<Schema.Schema.Type<typeof Info>>
953
-
954
- const DefaultModelIDs = Schema.Record(Schema.String, Schema.String)
955
-
956
- export const ListResult = Schema.Struct({
957
- all: Schema.Array(Info),
958
- default: DefaultModelIDs,
959
- connected: Schema.Array(Schema.String),
960
- }).pipe(withStatics((s) => ({ zod: zod(s) })))
961
- export type ListResult = Types.DeepMutable<Schema.Schema.Type<typeof ListResult>>
962
-
963
- export const ConfigProvidersResult = Schema.Struct({
964
- providers: Schema.Array(Info),
965
- default: DefaultModelIDs,
966
- }).pipe(withStatics((s) => ({ zod: zod(s) })))
967
- export type ConfigProvidersResult = Types.DeepMutable<Schema.Schema.Type<typeof ConfigProvidersResult>>
968
-
969
- export function defaultModelIDs<T extends { models: Record<string, { id: string }> }>(providers: Record<string, T>) {
970
- return mapValues(providers, (item) => sort(Object.values(item.models))[0].id)
971
- }
972
-
973
- export interface Interface {
974
- readonly list: () => Effect.Effect<Record<ProviderID, Info>>
975
- readonly getProvider: (providerID: ProviderID) => Effect.Effect<Info>
976
- readonly getModel: (providerID: ProviderID, modelID: ModelID) => Effect.Effect<Model>
977
- readonly getLanguage: (model: Model) => Effect.Effect<LanguageModelV3>
978
- readonly closest: (
979
- providerID: ProviderID,
980
- query: string[],
981
- ) => Effect.Effect<{ providerID: ProviderID; modelID: string } | undefined>
982
- readonly getSmallModel: (providerID: ProviderID) => Effect.Effect<Model | undefined>
983
- readonly resolveModelRef: (ref: string, contextProviderID?: ProviderID) => Effect.Effect<Model>
984
- readonly defaultModel: () => Effect.Effect<{ providerID: ProviderID; modelID: ModelID }>
985
- }
986
-
987
- interface State {
988
- models: Map<string, LanguageModelV3>
989
- providers: Record<ProviderID, Info>
990
- sdk: Map<string, BundledSDK>
991
- modelLoaders: Record<string, CustomModelLoader>
992
- varsLoaders: Record<string, CustomVarsLoader>
993
- }
994
-
995
- export class Service extends Context.Service<Service, Interface>()("@opencode/Provider") {}
996
-
997
- function cost(c: ModelsDev.Model["cost"]): Model["cost"] {
998
- const result: Model["cost"] = {
999
- input: c?.input ?? 0,
1000
- output: c?.output ?? 0,
1001
- cache: {
1002
- read: c?.cache_read ?? 0,
1003
- write: c?.cache_write ?? 0,
1004
- },
1005
- }
1006
- if (c?.context_over_200k) {
1007
- result.experimentalOver200K = {
1008
- cache: {
1009
- read: c.context_over_200k.cache_read ?? 0,
1010
- write: c.context_over_200k.cache_write ?? 0,
1011
- },
1012
- input: c.context_over_200k.input,
1013
- output: c.context_over_200k.output,
1014
- }
1015
- }
1016
- return result
1017
- }
1018
-
1019
- function fromModelsDevModel(provider: ModelsDev.Provider, model: ModelsDev.Model): Model {
1020
- const base: Model = {
1021
- id: ModelID.make(model.id),
1022
- providerID: ProviderID.make(provider.id),
1023
- name: model.name,
1024
- family: model.family,
1025
- api: {
1026
- id: model.id,
1027
- url: model.provider?.api ?? provider.api ?? "",
1028
- npm: model.provider?.npm ?? provider.npm ?? "@ai-sdk/openai-compatible",
1029
- },
1030
- status: model.status ?? "active",
1031
- headers: {},
1032
- options: {},
1033
- cost: cost(model.cost),
1034
- limit: {
1035
- context: model.limit.context,
1036
- input: model.limit.input,
1037
- output: model.limit.output,
1038
- },
1039
- capabilities: {
1040
- temperature: model.temperature ?? false,
1041
- reasoning: model.reasoning ?? false,
1042
- attachment: model.attachment ?? false,
1043
- toolcall: model.tool_call ?? true,
1044
- input: {
1045
- text: model.modalities?.input?.includes("text") ?? false,
1046
- audio: model.modalities?.input?.includes("audio") ?? false,
1047
- image: model.modalities?.input?.includes("image") ?? false,
1048
- video: model.modalities?.input?.includes("video") ?? false,
1049
- pdf: model.modalities?.input?.includes("pdf") ?? false,
1050
- },
1051
- output: {
1052
- text: model.modalities?.output?.includes("text") ?? false,
1053
- audio: model.modalities?.output?.includes("audio") ?? false,
1054
- image: model.modalities?.output?.includes("image") ?? false,
1055
- video: model.modalities?.output?.includes("video") ?? false,
1056
- pdf: model.modalities?.output?.includes("pdf") ?? false,
1057
- },
1058
- interleaved: model.interleaved ?? false,
1059
- },
1060
- release_date: model.release_date ?? "",
1061
- variants: {},
1062
- }
1063
-
1064
- return {
1065
- ...base,
1066
- variants: mapValues(ProviderTransform.variants(base), (v) => v),
1067
- }
1068
- }
1069
-
1070
- export function fromModelsDevProvider(provider: ModelsDev.Provider): Info {
1071
- const models: Record<string, Model> = {}
1072
- for (const [key, model] of Object.entries(provider.models)) {
1073
- models[key] = fromModelsDevModel(provider, model)
1074
- for (const [mode, opts] of Object.entries(model.experimental?.modes ?? {})) {
1075
- const id = `${model.id}-${mode}`
1076
- const base = fromModelsDevModel(provider, model)
1077
- models[id] = {
1078
- ...base,
1079
- id: ModelID.make(id),
1080
- name: `${model.name} ${mode[0].toUpperCase()}${mode.slice(1)}`,
1081
- cost: opts.cost ? mergeDeep(base.cost, cost(opts.cost)) : base.cost,
1082
- options: opts.provider?.body
1083
- ? Object.fromEntries(
1084
- Object.entries(opts.provider.body).map(([k, v]) => [
1085
- k.replace(/_([a-z])/g, (_, c) => c.toUpperCase()),
1086
- v,
1087
- ]),
1088
- )
1089
- : base.options,
1090
- headers: opts.provider?.headers ?? base.headers,
1091
- }
1092
- }
1093
- }
1094
- return {
1095
- id: ProviderID.make(provider.id),
1096
- source: "custom",
1097
- name: provider.name,
1098
- env: provider.env ?? [],
1099
- options: {},
1100
- models,
1101
- }
1102
- }
1103
-
1104
- const layer: Layer.Layer<
1105
- Service,
1106
- never,
1107
- Config.Service | Auth.Service | Plugin.Service | AppFileSystem.Service | Env.Service
1108
- > = Layer.effect(
1109
- Service,
1110
- Effect.gen(function* () {
1111
- const fs = yield* AppFileSystem.Service
1112
- const config = yield* Config.Service
1113
- const auth = yield* Auth.Service
1114
- const env = yield* Env.Service
1115
- const plugin = yield* Plugin.Service
1116
-
1117
- const state = yield* InstanceState.make<State>(() =>
1118
- Effect.gen(function* () {
1119
- using _ = log.time("state")
1120
- const bridge = yield* EffectBridge.make()
1121
- const cfg = yield* config.get()
1122
- const modelsDev = yield* Effect.promise(() => ModelsDev.get())
1123
- const database = mapValues(modelsDev, fromModelsDevProvider)
1124
-
1125
- let sleepyCredentials: { token: string; dashboardUrl: string } | null = null
1126
-
1127
- // Inject Sleepy Gateway provider from ~/.sleepy/gateway.json if credentials exist
1128
- try {
1129
- const sleepyConfigPath = path.join(Global.Path.config, "gateway.json")
1130
- const sleepyConfigRaw = yield* Effect.promise(() =>
1131
- fsNode.readFile(sleepyConfigPath, "utf-8").catch(() => null as string | null),
1132
- )
1133
- if (sleepyConfigRaw) {
1134
- const sleepyConfig = JSON.parse(sleepyConfigRaw)
1135
- const endpoint = sleepyConfig.endpoint
1136
- let token = sleepyConfig.access_token || sleepyConfig.token
1137
- const dashboardUrl = sleepyConfig.dashboard_url || "https://www.sleepyai.org"
1138
-
1139
- if (token && sleepyConfig.refresh_token && sleepyConfig.expires_at && Date.now() > sleepyConfig.expires_at) {
1140
- try {
1141
- const refreshRes = yield* Effect.promise(() =>
1142
- fetch(`${dashboardUrl}/api/auth/token/refresh`, {
1143
- method: "POST",
1144
- headers: { "Content-Type": "application/json" },
1145
- body: JSON.stringify({ refresh_token: sleepyConfig.refresh_token }),
1146
- }).then(async (r) => (r.ok ? r.json() : null)),
1147
- )
1148
- if (refreshRes) {
1149
- token = refreshRes.access_token
1150
- const updated = {
1151
- ...sleepyConfig,
1152
- access_token: refreshRes.access_token,
1153
- refresh_token: refreshRes.refresh_token,
1154
- expires_at: Date.now() + (refreshRes.expires_in ?? 3600) * 1000,
1155
- }
1156
- const tmpPath = sleepyConfigPath + ".tmp"
1157
- yield* Effect.promise(() =>
1158
- fsNode.writeFile(tmpPath, JSON.stringify(updated, null, 2)).then(() => fsNode.rename(tmpPath, sleepyConfigPath)).catch((err) => {
1159
- log.error("failed to persist refreshed token — next startup will re-refresh", { error: err.message })
1160
- }),
1161
- )
1162
- }
1163
- } catch {}
1164
- }
1165
-
1166
- if (endpoint && token) {
1167
- sleepyCredentials = { token, dashboardUrl }
1168
- const sleepyProviderID = ProviderID.make("sleepy")
1169
- const baseUrl = `${dashboardUrl}/api/v1`
1170
- const authHeader = `Bearer ${token}`
1171
-
1172
- const fetchedModels = yield* Effect.promise(() => fetchModels(dashboardUrl, token))
1173
-
1174
- let sleepyModels: Record<string, Model> = {}
1175
-
1176
- if (fetchedModels.length > 0) {
1177
- for (const m of fetchedModels) {
1178
- sleepyModels[m.modelId] = {
1179
- id: ModelID.make(m.modelId),
1180
- providerID: sleepyProviderID,
1181
- name: m.name,
1182
- family: "sleepy",
1183
- api: {
1184
- id: m.omniRouteModelId,
1185
- url: baseUrl,
1186
- npm: "@ai-sdk/openai-compatible",
1187
- },
1188
- status: "active",
1189
- headers: { Authorization: authHeader },
1190
- options: {},
1191
- cost: {
1192
- input: m.inputPrice ?? 0.0015,
1193
- output: m.outputPrice ?? 0.005,
1194
- cache: {
1195
- read: m.cacheReadPrice ?? 0.00075,
1196
- write: m.cacheWritePrice ?? 0.0015,
1197
- },
1198
- },
1199
- limit: {
1200
- context: m.contextWindow ?? 128000,
1201
- output: m.maxOutputLimit ?? 4096,
1202
- },
1203
- capabilities: {
1204
- temperature: true,
1205
- reasoning: true,
1206
- attachment: true,
1207
- toolcall: true,
1208
- input: { text: true, audio: false, image: true, video: false, pdf: true },
1209
- output: { text: true, audio: false, image: false, video: false, pdf: false },
1210
- interleaved: false,
1211
- },
1212
- release_date: "",
1213
- variants: {},
1214
- }
1215
- }
1216
- } else {
1217
- sleepyModels = {
1218
- smart: {
1219
- id: ModelID.make("smart"),
1220
- providerID: sleepyProviderID,
1221
- name: "Sleepy Smart Routing (Auto)",
1222
- family: "sleepy",
1223
- api: { id: "smart", url: baseUrl, npm: "@ai-sdk/openai-compatible" },
1224
- status: "active",
1225
- headers: { Authorization: authHeader },
1226
- options: {},
1227
- cost: { input: 0.0015, output: 0.005, cache: { read: 0, write: 0 } },
1228
- limit: { context: 128000, output: 4096 },
1229
- capabilities: {
1230
- temperature: true, reasoning: true, attachment: true, toolcall: true,
1231
- input: { text: true, audio: false, image: true, video: false, pdf: true },
1232
- output: { text: true, audio: false, image: false, video: false, pdf: false },
1233
- interleaved: false,
1234
- },
1235
- release_date: "",
1236
- variants: {},
1237
- },
1238
- cheap: {
1239
- id: ModelID.make("cheap"),
1240
- providerID: sleepyProviderID,
1241
- name: "Sleepy Eco Route (Low Cost)",
1242
- family: "sleepy",
1243
- api: { id: "cheap", url: baseUrl, npm: "@ai-sdk/openai-compatible" },
1244
- status: "active",
1245
- headers: { Authorization: authHeader },
1246
- options: {},
1247
- cost: { input: 0.00015, output: 0.0006, cache: { read: 0, write: 0 } },
1248
- limit: { context: 128000, output: 4096 },
1249
- capabilities: {
1250
- temperature: true, reasoning: false, attachment: true, toolcall: true,
1251
- input: { text: true, audio: false, image: true, video: false, pdf: true },
1252
- output: { text: true, audio: false, image: false, video: false, pdf: false },
1253
- interleaved: false,
1254
- },
1255
- release_date: "",
1256
- variants: {},
1257
- },
1258
- fast: {
1259
- id: ModelID.make("fast"),
1260
- providerID: sleepyProviderID,
1261
- name: "Sleepy Sprint Route (Low Latency)",
1262
- family: "sleepy",
1263
- api: { id: "fast", url: baseUrl, npm: "@ai-sdk/openai-compatible" },
1264
- status: "active",
1265
- headers: { Authorization: authHeader },
1266
- options: {},
1267
- cost: { input: 0.00015, output: 0.0006, cache: { read: 0, write: 0 } },
1268
- limit: { context: 128000, output: 4096 },
1269
- capabilities: {
1270
- temperature: true, reasoning: false, attachment: true, toolcall: true,
1271
- input: { text: true, audio: false, image: true, video: false, pdf: true },
1272
- output: { text: true, audio: false, image: false, video: false, pdf: false },
1273
- interleaved: false,
1274
- },
1275
- release_date: "",
1276
- variants: {},
1277
- },
1278
- high: {
1279
- id: ModelID.make("high"),
1280
- providerID: sleepyProviderID,
1281
- name: "Sleepy Reasoning Route (High Quality)",
1282
- family: "sleepy",
1283
- api: { id: "high", url: baseUrl, npm: "@ai-sdk/openai-compatible" },
1284
- status: "active",
1285
- headers: { Authorization: authHeader },
1286
- options: {},
1287
- cost: { input: 0.003, output: 0.015, cache: { read: 0, write: 0 } },
1288
- limit: { context: 128000, output: 4096 },
1289
- capabilities: {
1290
- temperature: true, reasoning: true, attachment: true, toolcall: true,
1291
- input: { text: true, audio: false, image: true, video: false, pdf: true },
1292
- output: { text: true, audio: false, image: false, video: false, pdf: false },
1293
- interleaved: false,
1294
- },
1295
- release_date: "",
1296
- variants: {},
1297
- },
1298
- }
1299
- }
1300
-
1301
- database[sleepyProviderID] = {
1302
- id: sleepyProviderID,
1303
- source: "config",
1304
- name: "Sleepy Gateway",
1305
- env: [],
1306
- options: {
1307
- baseURL: baseUrl,
1308
- headers: {
1309
- Authorization: authHeader,
1310
- },
1311
- },
1312
- models: sleepyModels,
1313
- }
1314
- log.info("sleepy provider injected from config", { endpoint, dashboardUrl })
1315
-
1316
- // Start background session polling — checks every 5 minutes if the session is still valid.
1317
- // Network errors are ignored (offline = still valid). 401/403 = session revoked/expired.
1318
- // Proactively refreshes tokens before expiry to prevent mid-session logouts.
1319
- const checker = createSessionChecker({ dashboardUrl, token, configPath: sleepyConfigPath })
1320
- checker.start()
1321
- }
1322
- }
1323
- } catch {
1324
- // Config file missing or malformed — silently skip sleepy provider injection
1325
- }
1326
-
1327
- const providers: Record<ProviderID, Info> = {} as Record<ProviderID, Info>
1328
- const languages = new Map<string, LanguageModelV3>()
1329
- const modelLoaders: {
1330
- [providerID: string]: CustomModelLoader
1331
- } = {}
1332
- const varsLoaders: {
1333
- [providerID: string]: CustomVarsLoader
1334
- } = {}
1335
- const sdk = new Map<string, BundledSDK>()
1336
- const discoveryLoaders: {
1337
- [providerID: string]: CustomDiscoverModels
1338
- } = {}
1339
- const dep = {
1340
- auth: (id: string) => auth.get(id).pipe(Effect.orDie),
1341
- config: () => config.get(),
1342
- env: () => env.all(),
1343
- get: (key: string) => env.get(key),
1344
- }
1345
-
1346
- log.info("init")
1347
-
1348
- function mergeProvider(providerID: ProviderID, provider: Partial<Info>) {
1349
- const existing = providers[providerID]
1350
- if (existing) {
1351
- // @ts-expect-error
1352
- providers[providerID] = mergeDeep(existing, provider)
1353
- return
1354
- }
1355
- const match = database[providerID]
1356
- if (!match) return
1357
- // @ts-expect-error
1358
- providers[providerID] = mergeDeep(match, provider)
1359
- }
1360
-
1361
- // load plugins first so config() hook runs before reading cfg.provider
1362
- const plugins = yield* plugin.list()
1363
-
1364
- // promote sleepy provider from database to providers if injected
1365
- if (database[ProviderID.make("sleepy")]) {
1366
- mergeProvider(ProviderID.make("sleepy"), {})
1367
- }
1368
-
1369
- // now read config providers - includes any modifications from plugin config() hook
1370
- const configProviders = Object.entries(cfg.provider ?? {})
1371
- const disabled = new Set(cfg.disabled_providers ?? [])
1372
- const enabled = cfg.enabled_providers ? new Set(cfg.enabled_providers) : null
1373
-
1374
- function isProviderAllowed(providerID: ProviderID): boolean {
1375
- if (enabled && !enabled.has(providerID)) return false
1376
- if (disabled.has(providerID)) return false
1377
- return true
1378
- }
1379
-
1380
- // extend database from config
1381
- for (const [providerID, provider] of configProviders) {
1382
- const existing = database[providerID]
1383
- const parsed: Info = {
1384
- id: ProviderID.make(providerID),
1385
- name: provider.name ?? existing?.name ?? providerID,
1386
- env: provider.env ?? existing?.env ?? [],
1387
- options: mergeDeep(existing?.options ?? {}, provider.options ?? {}),
1388
- source: "config",
1389
- models: existing?.models ?? {},
1390
- }
1391
-
1392
- for (const [modelID, model] of Object.entries(provider.models ?? {})) {
1393
- const existingModel = parsed.models[model.id ?? modelID]
1394
- const apiID = model.id ?? existingModel?.api.id ?? modelID
1395
- const apiNpm =
1396
- model.provider?.npm ??
1397
- provider.npm ??
1398
- existingModel?.api.npm ??
1399
- modelsDev[providerID]?.npm ??
1400
- "@ai-sdk/openai-compatible"
1401
- const name = iife(() => {
1402
- if (model.name) return model.name
1403
- if (model.id && model.id !== modelID) return modelID
1404
- return existingModel?.name ?? modelID
1405
- })
1406
- const parsedModel: Model = {
1407
- id: ModelID.make(modelID),
1408
- api: {
1409
- id: apiID,
1410
- npm: apiNpm,
1411
- url: model.provider?.api ?? provider?.api ?? existingModel?.api.url ?? modelsDev[providerID]?.api ?? "",
1412
- },
1413
- status: model.status ?? existingModel?.status ?? "active",
1414
- name,
1415
- providerID: ProviderID.make(providerID),
1416
- capabilities: {
1417
- temperature: model.temperature ?? existingModel?.capabilities.temperature ?? false,
1418
- reasoning: model.reasoning ?? existingModel?.capabilities.reasoning ?? false,
1419
- attachment: model.attachment ?? existingModel?.capabilities.attachment ?? false,
1420
- toolcall: model.tool_call ?? existingModel?.capabilities.toolcall ?? true,
1421
- input: {
1422
- text: model.modalities?.input?.includes("text") ?? existingModel?.capabilities.input.text ?? true,
1423
- audio: model.modalities?.input?.includes("audio") ?? existingModel?.capabilities.input.audio ?? false,
1424
- image: model.modalities?.input?.includes("image") ?? existingModel?.capabilities.input.image ?? false,
1425
- video: model.modalities?.input?.includes("video") ?? existingModel?.capabilities.input.video ?? false,
1426
- pdf: model.modalities?.input?.includes("pdf") ?? existingModel?.capabilities.input.pdf ?? false,
1427
- },
1428
- output: {
1429
- text: model.modalities?.output?.includes("text") ?? existingModel?.capabilities.output.text ?? true,
1430
- audio:
1431
- model.modalities?.output?.includes("audio") ?? existingModel?.capabilities.output.audio ?? false,
1432
- image:
1433
- model.modalities?.output?.includes("image") ?? existingModel?.capabilities.output.image ?? false,
1434
- video:
1435
- model.modalities?.output?.includes("video") ?? existingModel?.capabilities.output.video ?? false,
1436
- pdf: model.modalities?.output?.includes("pdf") ?? existingModel?.capabilities.output.pdf ?? false,
1437
- },
1438
- interleaved:
1439
- model.interleaved ??
1440
- existingModel?.capabilities.interleaved ??
1441
- (!existingModel && apiNpm === "@ai-sdk/openai-compatible" && apiID.includes("deepseek")
1442
- ? { field: "reasoning_content" }
1443
- : false),
1444
- },
1445
- cost: {
1446
- input: model?.cost?.input ?? existingModel?.cost?.input ?? 0,
1447
- output: model?.cost?.output ?? existingModel?.cost?.output ?? 0,
1448
- cache: {
1449
- read: model?.cost?.cache_read ?? existingModel?.cost?.cache.read ?? 0,
1450
- write: model?.cost?.cache_write ?? existingModel?.cost?.cache.write ?? 0,
1451
- },
1452
- },
1453
- options: mergeDeep(existingModel?.options ?? {}, model.options ?? {}),
1454
- limit: {
1455
- context: (() => {
1456
- const explicit = model.limit?.context ?? existingModel?.limit?.context
1457
- if (explicit !== undefined) return explicit
1458
- const key = `${providerID}/${modelID}`
1459
- if (!warnedContextDefaults.has(key)) {
1460
- warnedContextDefaults.add(key)
1461
- log.warn("limit.context not configured and not found in models.dev", {
1462
- providerID,
1463
- modelID,
1464
- defaulting_to: DEFAULT_CONTEXT_WINDOW,
1465
- fix: `Set limit.context explicitly in sleepycode.json under provider.${providerID}.models.${modelID}`,
1466
- })
1467
- }
1468
- return DEFAULT_CONTEXT_WINDOW
1469
- })(),
1470
- input: model.limit?.input ?? existingModel?.limit?.input,
1471
- output: model.limit?.output ?? existingModel?.limit?.output ?? 0,
1472
- },
1473
- headers: mergeDeep(existingModel?.headers ?? {}, model.headers ?? {}),
1474
- family: model.family ?? existingModel?.family ?? "",
1475
- release_date: model.release_date ?? existingModel?.release_date ?? "",
1476
- cachePromptTTL: model.cachePromptTTL ?? existingModel?.cachePromptTTL,
1477
- variants: {},
1478
- }
1479
- const merged = mergeDeep(ProviderTransform.variants(parsedModel), model.variants ?? {})
1480
- parsedModel.variants = mapValues(
1481
- pickBy(merged, (v) => !v.disabled),
1482
- (v) => omit(v, ["disabled"]),
1483
- )
1484
- parsed.models[modelID] = parsedModel
1485
- }
1486
- database[providerID] = parsed
1487
- }
1488
-
1489
- // load env (skipped in sleepy-only mode so ANTHROPIC_API_KEY etc. don't auto-light other providers)
1490
- if (!Flag.SLEEPYCODE_DISABLE_PROVIDER_ENV) {
1491
- const envs = yield* env.all()
1492
- for (const [id, provider] of Object.entries(database)) {
1493
- const providerID = ProviderID.make(id)
1494
- if (disabled.has(providerID)) continue
1495
- const apiKey = provider.env.map((item) => envs[item]).find(Boolean)
1496
- if (!apiKey) continue
1497
- mergeProvider(providerID, {
1498
- source: "env",
1499
- key: provider.env.length === 1 ? apiKey : undefined,
1500
- })
1501
- }
1502
- }
1503
-
1504
- // load apikeys
1505
- const auths = yield* auth.all().pipe(Effect.orDie)
1506
- for (const [id, provider] of Object.entries(auths)) {
1507
- const providerID = ProviderID.make(id)
1508
- if (disabled.has(providerID)) continue
1509
- if (provider.type === "api") {
1510
- mergeProvider(providerID, {
1511
- source: "api",
1512
- key: provider.key,
1513
- })
1514
- }
1515
- }
1516
-
1517
- // plugin auth loader - database now has entries for config providers
1518
- for (const plugin of plugins) {
1519
- if (!plugin.auth) continue
1520
- const providerID = ProviderID.make(plugin.auth.provider)
1521
- if (disabled.has(providerID)) continue
1522
-
1523
- const stored = yield* auth.get(providerID).pipe(Effect.orDie)
1524
- if (!stored) continue
1525
- if (!plugin.auth.loader) continue
1526
-
1527
- const options = yield* Effect.promise(() =>
1528
- plugin.auth!.loader!(
1529
- () => bridge.promise(auth.get(providerID).pipe(Effect.orDie)) as any,
1530
- database[plugin.auth!.provider],
1531
- ),
1532
- )
1533
- const opts = options ?? {}
1534
- const patch: Partial<Info> = providers[providerID] ? { options: opts } : { source: "custom", options: opts }
1535
- mergeProvider(providerID, patch)
1536
- }
1537
-
1538
- for (const [id, fn] of Object.entries(custom(dep))) {
1539
- const providerID = ProviderID.make(id)
1540
- if (disabled.has(providerID)) continue
1541
- const data = database[providerID]
1542
- if (!data) {
1543
- log.error("Provider does not exist in model list " + providerID)
1544
- continue
1545
- }
1546
- const result = yield* fn(data)
1547
- if (result && (result.autoload || providers[providerID])) {
1548
- if (result.getModel) modelLoaders[providerID] = result.getModel
1549
- if (result.vars) varsLoaders[providerID] = result.vars
1550
- if (result.discoverModels) discoveryLoaders[providerID] = result.discoverModels
1551
- const opts = result.options ?? {}
1552
- const patch: Partial<Info> = providers[providerID] ? { options: opts } : { source: "custom", options: opts }
1553
- mergeProvider(providerID, patch)
1554
- }
1555
- }
1556
-
1557
- // load config - re-apply with updated data
1558
- for (const [id, provider] of configProviders) {
1559
- const providerID = ProviderID.make(id)
1560
- const partial: Partial<Info> = { source: "config" }
1561
- if (provider.env) partial.env = provider.env
1562
- if (provider.name) partial.name = provider.name
1563
- if (provider.options) partial.options = provider.options
1564
- mergeProvider(providerID, partial)
1565
- }
1566
-
1567
- const gitlab = ProviderID.make("gitlab")
1568
- if (discoveryLoaders[gitlab] && providers[gitlab] && isProviderAllowed(gitlab)) {
1569
- yield* Effect.promise(async () => {
1570
- try {
1571
- const discovered = await discoveryLoaders[gitlab]()
1572
- for (const [modelID, model] of Object.entries(discovered)) {
1573
- if (!providers[gitlab].models[modelID]) {
1574
- providers[gitlab].models[modelID] = model
1575
- }
1576
- }
1577
- } catch (e) {
1578
- log.warn("state discovery error", { id: "gitlab", error: e })
1579
- }
1580
- })
1581
- }
1582
-
1583
- for (const hook of plugins) {
1584
- const p = hook.provider
1585
- const models = p?.models
1586
- if (!p || !models) continue
1587
-
1588
- const providerID = ProviderID.make(p.id)
1589
- if (disabled.has(providerID)) continue
1590
-
1591
- const provider = providers[providerID]
1592
- if (!provider) continue
1593
- const pluginAuth = yield* auth.get(providerID).pipe(Effect.orDie)
1594
-
1595
- provider.models = yield* Effect.promise(async () => {
1596
- const next = await models(provider, { auth: pluginAuth })
1597
- return Object.fromEntries(
1598
- Object.entries(next).map(([id, model]) => [
1599
- id,
1600
- {
1601
- ...model,
1602
- id: ModelID.make(id),
1603
- providerID,
1604
- },
1605
- ]),
1606
- )
1607
- })
1608
- }
1609
-
1610
- for (const [id, provider] of Object.entries(providers)) {
1611
- const providerID = ProviderID.make(id)
1612
- if (!isProviderAllowed(providerID)) {
1613
- delete providers[providerID]
1614
- continue
1615
- }
1616
-
1617
- const configProvider = cfg.provider?.[providerID]
1618
-
1619
- for (const [modelID, model] of Object.entries(provider.models)) {
1620
- model.api.id = model.api.id ?? model.id ?? modelID
1621
- if (
1622
- modelID === "gpt-5-chat-latest" ||
1623
- (providerID === ProviderID.openrouter && modelID === "openai/gpt-5-chat")
1624
- )
1625
- delete provider.models[modelID]
1626
- if (model.status === "alpha" && !Flag.SLEEPYCODE_ENABLE_EXPERIMENTAL_MODELS) delete provider.models[modelID]
1627
- if (model.status === "deprecated") delete provider.models[modelID]
1628
- if (
1629
- (configProvider?.blacklist && configProvider.blacklist.includes(modelID)) ||
1630
- (configProvider?.whitelist && !configProvider.whitelist.includes(modelID))
1631
- )
1632
- delete provider.models[modelID]
1633
-
1634
- model.variants = mapValues(ProviderTransform.variants(model), (v) => v)
1635
-
1636
- const configVariants = configProvider?.models?.[modelID]?.variants
1637
- if (configVariants && model.variants) {
1638
- const merged = mergeDeep(model.variants, configVariants)
1639
- model.variants = mapValues(
1640
- pickBy(merged, (v) => !v.disabled),
1641
- (v) => omit(v, ["disabled"]),
1642
- )
1643
- }
1644
- }
1645
-
1646
- if (Object.keys(provider.models).length === 0) {
1647
- delete providers[providerID]
1648
- continue
1649
- }
1650
-
1651
- log.info("found", { providerID })
1652
- }
1653
-
1654
- if (sleepyCredentials) {
1655
- const { token, dashboardUrl } = sleepyCredentials
1656
- setInterval(async () => {
1657
- const freshModels = await fetchModels(dashboardUrl, token)
1658
- if (freshModels.length === 0) return
1659
-
1660
- const sleepy = providers[ProviderID.make("sleepy")]
1661
- if (!sleepy) return
1662
-
1663
- const sleepyProviderID = ProviderID.make("sleepy")
1664
- const baseUrl = `${dashboardUrl}/api/v1`
1665
- const authHeader = `Bearer ${token}`
1666
-
1667
- for (const m of freshModels) {
1668
- const existing = sleepy.models[m.modelId]
1669
- if (existing) {
1670
- existing.name = m.name
1671
- existing.api.id = m.omniRouteModelId
1672
- existing.cost = {
1673
- input: m.inputPrice ?? 0.0015,
1674
- output: m.outputPrice ?? 0.005,
1675
- cache: {
1676
- read: m.cacheReadPrice ?? 0.00075,
1677
- write: m.cacheWritePrice ?? 0.0015,
1678
- },
1679
- }
1680
- existing.limit = {
1681
- context: m.contextWindow ?? 128000,
1682
- output: m.maxOutputLimit ?? 4096,
1683
- }
1684
- } else {
1685
- sleepy.models[m.modelId] = {
1686
- id: ModelID.make(m.modelId),
1687
- providerID: sleepyProviderID,
1688
- name: m.name,
1689
- family: "sleepy",
1690
- api: {
1691
- id: m.omniRouteModelId,
1692
- url: baseUrl,
1693
- npm: "@ai-sdk/openai-compatible",
1694
- },
1695
- status: "active",
1696
- headers: { Authorization: authHeader },
1697
- options: {},
1698
- cost: {
1699
- input: m.inputPrice ?? 0.0015,
1700
- output: m.outputPrice ?? 0.005,
1701
- cache: {
1702
- read: m.cacheReadPrice ?? 0.00075,
1703
- write: m.cacheWritePrice ?? 0.0015,
1704
- },
1705
- },
1706
- limit: {
1707
- context: m.contextWindow ?? 128000,
1708
- output: m.maxOutputLimit ?? 4096,
1709
- },
1710
- capabilities: {
1711
- temperature: true,
1712
- reasoning: true,
1713
- attachment: true,
1714
- toolcall: true,
1715
- input: { text: true, audio: false, image: true, video: false, pdf: true },
1716
- output: { text: true, audio: false, image: false, video: false, pdf: false },
1717
- interleaved: false,
1718
- },
1719
- release_date: "",
1720
- variants: {},
1721
- }
1722
- }
1723
- }
1724
- }, 30 * 1000).unref()
1725
- }
1726
-
1727
- return {
1728
- models: languages,
1729
- providers,
1730
- sdk,
1731
- modelLoaders,
1732
- varsLoaders,
1733
- }
1734
- }),
1735
- )
1736
-
1737
- const list = Effect.fn("Provider.list")(() => InstanceState.use(state, (s) => s.providers))
1738
-
1739
- async function resolveSDK(model: Model, s: State, envs: Record<string, string | undefined>) {
1740
- try {
1741
- using _ = log.time("getSDK", {
1742
- providerID: model.providerID,
1743
- })
1744
- const provider = s.providers[model.providerID]
1745
- const options = { ...provider.options }
1746
-
1747
- if (model.providerID === "google-vertex" && !model.api.npm.includes("@ai-sdk/openai-compatible")) {
1748
- delete options.fetch
1749
- }
1750
-
1751
- if (model.api.npm.includes("@ai-sdk/openai-compatible") && options["includeUsage"] !== false) {
1752
- options["includeUsage"] = true
1753
- }
1754
-
1755
- const baseURL = iife(() => {
1756
- let url =
1757
- typeof options["baseURL"] === "string" && options["baseURL"] !== "" ? options["baseURL"] : model.api.url
1758
- if (!url) return
1759
-
1760
- const loader = s.varsLoaders[model.providerID]
1761
- if (loader) {
1762
- const vars = loader(options)
1763
- for (const [key, value] of Object.entries(vars)) {
1764
- const field = "${" + key + "}"
1765
- url = url.replaceAll(field, value)
1766
- }
1767
- }
1768
-
1769
- url = url.replace(/\$\{([^}]+)\}/g, (item, key) => {
1770
- const val = envs[String(key)]
1771
- return val ?? item
1772
- })
1773
- return url
1774
- })
1775
-
1776
- if (baseURL !== undefined) options["baseURL"] = baseURL
1777
- if (options["apiKey"] === undefined && provider.key) options["apiKey"] = provider.key
1778
- if (model.headers)
1779
- options["headers"] = {
1780
- ...options["headers"],
1781
- ...model.headers,
1782
- }
1783
-
1784
- const key = Hash.fast(
1785
- JSON.stringify({
1786
- providerID: model.providerID,
1787
- npm: model.api.npm,
1788
- options,
1789
- }),
1790
- )
1791
- const existing = s.sdk.get(key)
1792
- if (existing) return existing
1793
-
1794
- const customFetch = options["fetch"]
1795
- const userChunkTimeout = options["chunkTimeout"]
1796
- const chunkTimeout =
1797
- typeof userChunkTimeout === "number"
1798
- ? userChunkTimeout // user-set value (incl. 0 / negative to disable)
1799
- : DEFAULT_CHUNK_TIMEOUT
1800
- delete options["chunkTimeout"]
1801
-
1802
- options["fetch"] = async (input: any, init?: BunFetchRequestInit) => {
1803
- const fetchFn = customFetch ?? fetch
1804
- const opts = init ?? {}
1805
- const chunkAbortCtl = typeof chunkTimeout === "number" && chunkTimeout > 0 ? new AbortController() : undefined
1806
- const signals: AbortSignal[] = []
1807
-
1808
- if (opts.signal) signals.push(opts.signal)
1809
- if (chunkAbortCtl) signals.push(chunkAbortCtl.signal)
1810
- if (options["timeout"] !== undefined && options["timeout"] !== null && options["timeout"] !== false)
1811
- signals.push(AbortSignal.timeout(options["timeout"]))
1812
-
1813
- const combined = signals.length === 0 ? null : signals.length === 1 ? signals[0] : AbortSignal.any(signals)
1814
- if (combined) opts.signal = combined
1815
-
1816
- // Strip openai itemId metadata following what codex does
1817
- if (model.api.npm === "@ai-sdk/openai" && opts.body && opts.method === "POST") {
1818
- const body = JSON.parse(opts.body as string)
1819
- const isAzure = model.providerID.includes("azure")
1820
- const keepIds = isAzure && body.store === true
1821
- if (!keepIds && Array.isArray(body.input)) {
1822
- for (const item of body.input) {
1823
- if ("id" in item) {
1824
- delete item.id
1825
- }
1826
- }
1827
- opts.body = JSON.stringify(body)
1828
- }
1829
- }
1830
-
1831
- const res = await fetchFn(input, {
1832
- ...opts,
1833
- // @ts-ignore see here: https://github.com/oven-sh/bun/issues/16682
1834
- timeout: false,
1835
- })
1836
-
1837
- if (!chunkAbortCtl) return res
1838
- return wrapSSE(res, chunkTimeout, chunkAbortCtl)
1839
- }
1840
-
1841
- const bundledLoader = BUNDLED_PROVIDERS[model.api.npm]
1842
- if (bundledLoader) {
1843
- log.info("using bundled provider", {
1844
- providerID: model.providerID,
1845
- pkg: model.api.npm,
1846
- })
1847
- const factory = await bundledLoader()
1848
- const loaded = factory({
1849
- name: model.providerID,
1850
- ...options,
1851
- })
1852
- s.sdk.set(key, loaded)
1853
- return loaded as SDK
1854
- }
1855
-
1856
- let installedPath: string
1857
- if (!model.api.npm.startsWith("file://")) {
1858
- const item = await Npm.add(model.api.npm)
1859
- if (!item.entrypoint) throw new Error(`Package ${model.api.npm} has no import entrypoint`)
1860
- installedPath = item.entrypoint
1861
- } else {
1862
- log.info("loading local provider", { pkg: model.api.npm })
1863
- installedPath = model.api.npm
1864
- }
1865
-
1866
- // `installedPath` is a local entry path or an existing `file://` URL. Normalize
1867
- // only path inputs so Node on Windows accepts the dynamic import.
1868
- const importSpec = installedPath.startsWith("file://") ? installedPath : pathToFileURL(installedPath).href
1869
- const mod = await import(importSpec)
1870
-
1871
- const fn = mod[Object.keys(mod).find((key) => key.startsWith("create"))!]
1872
- const loaded = fn({
1873
- name: model.providerID,
1874
- ...options,
1875
- })
1876
- s.sdk.set(key, loaded)
1877
- return loaded as SDK
1878
- } catch (e) {
1879
- throw new InitError({ providerID: model.providerID }, { cause: e })
1880
- }
1881
- }
1882
-
1883
- const getProvider = Effect.fn("Provider.getProvider")((providerID: ProviderID) =>
1884
- InstanceState.use(state, (s) => s.providers[providerID]),
1885
- )
1886
-
1887
- const getModel = Effect.fn("Provider.getModel")(function* (providerID: ProviderID, modelID: ModelID) {
1888
- const s = yield* InstanceState.get(state)
1889
- const provider = s.providers[providerID]
1890
- if (!provider) {
1891
- const available = Object.keys(s.providers)
1892
- const matches = fuzzysort.go(providerID, available, { limit: 3, threshold: -10000 })
1893
- throw new ModelNotFoundError({ providerID, modelID, suggestions: matches.map((m) => m.target) })
1894
- }
1895
-
1896
- const info = provider.models[modelID]
1897
- if (!info) {
1898
- const available = Object.keys(provider.models)
1899
- const matches = fuzzysort.go(modelID, available, { limit: 3, threshold: -10000 })
1900
- throw new ModelNotFoundError({ providerID, modelID, suggestions: matches.map((m) => m.target) })
1901
- }
1902
- return info
1903
- })
1904
-
1905
- const getLanguage = Effect.fn("Provider.getLanguage")(function* (model: Model) {
1906
- const s = yield* InstanceState.get(state)
1907
- const envs = yield* env.all()
1908
- const key = `${model.providerID}/${model.id}`
1909
- if (s.models.has(key)) return s.models.get(key)!
1910
-
1911
- return yield* Effect.promise(async () => {
1912
- const provider = s.providers[model.providerID]
1913
- const sdk = await resolveSDK(model, s, envs)
1914
-
1915
- try {
1916
- const language = s.modelLoaders[model.providerID]
1917
- ? await s.modelLoaders[model.providerID](sdk, model.api.id, {
1918
- ...provider.options,
1919
- ...model.options,
1920
- })
1921
- : sdk.languageModel(model.api.id)
1922
- s.models.set(key, language)
1923
- return language
1924
- } catch (e) {
1925
- if (e instanceof NoSuchModelError)
1926
- throw new ModelNotFoundError(
1927
- {
1928
- modelID: model.id,
1929
- providerID: model.providerID,
1930
- },
1931
- { cause: e },
1932
- )
1933
- throw e
1934
- }
1935
- })
1936
- })
1937
-
1938
- const closest = Effect.fn("Provider.closest")(function* (providerID: ProviderID, query: string[]) {
1939
- const s = yield* InstanceState.get(state)
1940
- const provider = s.providers[providerID]
1941
- if (!provider) return undefined
1942
- for (const item of query) {
1943
- for (const modelID of Object.keys(provider.models)) {
1944
- if (modelID.includes(item)) return { providerID, modelID }
1945
- }
1946
- }
1947
- return undefined
1948
- })
1949
-
1950
- const resolveModelRef = Effect.fn("Provider.resolveModelRef")(function* (
1951
- ref: string,
1952
- contextProviderID?: ProviderID,
1953
- ) {
1954
- // Literal "provider/model" — unchanged path.
1955
- if (ref.includes("/")) {
1956
- const parsed = parseModel(ref)
1957
- return yield* getModel(parsed.providerID, parsed.modelID)
1958
- }
1959
-
1960
- // Otherwise it's a group name.
1961
- const cfg = yield* config.get()
1962
- const group = cfg.model_groups?.[ref]
1963
- if (!group) {
1964
- if (BUILTIN_TIERS.has(ref)) {
1965
- const fallback = yield* defaultModel()
1966
- return yield* getModel(fallback.providerID, fallback.modelID)
1967
- }
1968
- const names = Object.keys(cfg.model_groups ?? {})
1969
- const matches = fuzzysort.go(ref, names, { limit: 3, threshold: -10000 })
1970
- throw new ModelGroupNotFoundError({ group: ref, suggestions: matches.map((m) => m.target) })
1971
- }
1972
-
1973
- const def = typeof group === "string" ? group : group.default
1974
- const members = typeof group === "string" ? [group] : (group.models ?? [group.default])
1975
-
1976
- // Provider-aware: prefer a member on the caller's provider.
1977
- if (contextProviderID) {
1978
- for (const member of members) {
1979
- const parsed = parseModel(member)
1980
- if (parsed.providerID !== contextProviderID) continue
1981
- const resolved = yield* getModel(parsed.providerID, parsed.modelID).pipe(Effect.exit)
1982
- if (resolved._tag === "Success") return resolved.value
1983
- }
1984
- }
1985
-
1986
- // Fall back to the group default.
1987
- const parsedDefault = parseModel(def)
1988
- return yield* getModel(parsedDefault.providerID, parsedDefault.modelID)
1989
- })
1990
-
1991
- const getSmallModel = Effect.fn("Provider.getSmallModel")(function* (providerID: ProviderID) {
1992
- const cfg = yield* config.get()
1993
-
1994
- // Explicit small_model literal wins (back-compat).
1995
- if (cfg.small_model) {
1996
- const parsed = parseModel(cfg.small_model)
1997
- return yield* getModel(parsed.providerID, parsed.modelID)
1998
- }
1999
-
2000
- // Otherwise route through the `lite` tier: configured lite group
2001
- // (provider-aware) → else the built-in tier fallback to defaultModel().
2002
- return yield* resolveModelRef("lite", providerID)
2003
- })
2004
-
2005
- const defaultModel = Effect.fn("Provider.defaultModel")(function* () {
2006
- const cfg = yield* config.get()
2007
- if (cfg.model) return parseModel(cfg.model)
2008
-
2009
- const s = yield* InstanceState.get(state)
2010
- const recent = yield* fs.readJson(path.join(Global.Path.state, "model.json")).pipe(
2011
- Effect.map((x): { providerID: ProviderID; modelID: ModelID }[] => {
2012
- if (!isRecord(x) || !Array.isArray(x.recent)) return []
2013
- return x.recent.flatMap((item) => {
2014
- if (!isRecord(item)) return []
2015
- if (typeof item.providerID !== "string") return []
2016
- if (typeof item.modelID !== "string") return []
2017
- return [{ providerID: ProviderID.make(item.providerID), modelID: ModelID.make(item.modelID) }]
2018
- })
2019
- }),
2020
- Effect.catch(() => Effect.succeed([] as { providerID: ProviderID; modelID: ModelID }[])),
2021
- )
2022
- for (const entry of recent) {
2023
- const provider = s.providers[entry.providerID]
2024
- if (!provider) continue
2025
- if (!provider.models[entry.modelID]) continue
2026
- return { providerID: entry.providerID, modelID: entry.modelID }
2027
- }
2028
-
2029
- const sleepy = s.providers[ProviderID.make("sleepy")]
2030
- if (sleepy?.models[ModelID.make("smart")]) {
2031
- return { providerID: sleepy.id, modelID: ModelID.make("smart") }
2032
- }
2033
-
2034
- const provider = Object.values(s.providers).find((p) => !cfg.provider || Object.keys(cfg.provider).includes(p.id))
2035
- if (!provider) throw new Error("no providers found")
2036
- const [model] = sort(Object.values(provider.models))
2037
- if (!model) throw new Error("no models found")
2038
- return {
2039
- providerID: provider.id,
2040
- modelID: model.id,
2041
- }
2042
- })
2043
-
2044
- return Service.of({ list, getProvider, getModel, getLanguage, closest, getSmallModel, defaultModel, resolveModelRef })
2045
- }),
2046
- )
2047
-
2048
- export const defaultLayer = Layer.suspend(() =>
2049
- layer.pipe(
2050
- Layer.provide(AppFileSystem.defaultLayer),
2051
- Layer.provide(Env.defaultLayer),
2052
- Layer.provide(Config.defaultLayer),
2053
- Layer.provide(Auth.defaultLayer),
2054
- Layer.provide(Plugin.defaultLayer),
2055
- ),
2056
- )
2057
-
2058
- const priority = ["gpt-5", "claude-sonnet-4", "big-pickle", "gemini-3-pro"]
2059
- export function sort<T extends { id: string }>(models: T[]) {
2060
- return sortBy(
2061
- models,
2062
- [(model) => priority.findIndex((filter) => model.id.includes(filter)), "desc"],
2063
- [(model) => (model.id.includes("latest") ? 0 : 1), "asc"],
2064
- [(model) => model.id, "desc"],
2065
- )
2066
- }
2067
-
2068
- export function parseModel(model: string) {
2069
- const [providerID, ...rest] = model.split("/")
2070
- return {
2071
- providerID: ProviderID.make(providerID),
2072
- modelID: ModelID.make(rest.join("/")),
2073
- }
2074
- }
2075
-
2076
- export const ModelNotFoundError = NamedError.create(
2077
- "ProviderModelNotFoundError",
2078
- z.object({
2079
- providerID: ProviderID.zod,
2080
- modelID: ModelID.zod,
2081
- suggestions: z.array(z.string()).optional(),
2082
- }),
2083
- )
2084
-
2085
- export const ModelGroupNotFoundError = NamedError.create(
2086
- "ProviderModelGroupNotFoundError",
2087
- z.object({
2088
- group: z.string(),
2089
- suggestions: z.array(z.string()).optional(),
2090
- }),
2091
- )
2092
-
2093
- export const InitError = NamedError.create(
2094
- "ProviderInitError",
2095
- z.object({
2096
- providerID: ProviderID.zod,
2097
- }),
2098
- )