@prometheus-ai/agent 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1954) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +36 -0
  3. package/dist/types/async/index.d.ts +2 -0
  4. package/dist/types/async/job-manager.d.ts +88 -0
  5. package/dist/types/async/support.d.ts +2 -0
  6. package/dist/types/auto-thinking/classifier.d.ts +35 -0
  7. package/dist/types/autoresearch/dashboard.d.ts +4 -0
  8. package/dist/types/autoresearch/git.d.ts +36 -0
  9. package/dist/types/autoresearch/helpers.d.ts +24 -0
  10. package/dist/types/autoresearch/index.d.ts +2 -0
  11. package/dist/types/autoresearch/state.d.ts +17 -0
  12. package/dist/types/autoresearch/storage.d.ts +142 -0
  13. package/dist/types/autoresearch/tools/init-experiment.d.ts +31 -0
  14. package/dist/types/autoresearch/tools/log-experiment.d.ts +23 -0
  15. package/dist/types/autoresearch/tools/run-experiment.d.ts +8 -0
  16. package/dist/types/autoresearch/tools/update-notes.d.ts +12 -0
  17. package/dist/types/autoresearch/types.d.ts +154 -0
  18. package/dist/types/capability/context-file.d.ts +30 -0
  19. package/dist/types/capability/extension-module.d.ts +15 -0
  20. package/dist/types/capability/extension.d.ts +28 -0
  21. package/dist/types/capability/fs.d.ts +20 -0
  22. package/dist/types/capability/hook.d.ts +19 -0
  23. package/dist/types/capability/index.d.ts +80 -0
  24. package/dist/types/capability/instruction.d.ts +17 -0
  25. package/dist/types/capability/mcp.d.ts +45 -0
  26. package/dist/types/capability/prompt.d.ts +15 -0
  27. package/dist/types/capability/rule-buckets.d.ts +30 -0
  28. package/dist/types/capability/rule.d.ts +68 -0
  29. package/dist/types/capability/settings.d.ts +15 -0
  30. package/dist/types/capability/skill.d.ts +43 -0
  31. package/dist/types/capability/slash-command.d.ts +17 -0
  32. package/dist/types/capability/ssh.d.ts +23 -0
  33. package/dist/types/capability/system-prompt.d.ts +15 -0
  34. package/dist/types/capability/tool.d.ts +19 -0
  35. package/dist/types/capability/types.d.ts +158 -0
  36. package/dist/types/cli/agents-cli.d.ts +12 -0
  37. package/dist/types/cli/args.d.ts +55 -0
  38. package/dist/types/cli/auth-broker-cli.d.ts +25 -0
  39. package/dist/types/cli/auth-gateway-cli.d.ts +26 -0
  40. package/dist/types/cli/classify-install-target.d.ts +12 -0
  41. package/dist/types/cli/claude-trace-cli.d.ts +52 -0
  42. package/dist/types/cli/commands/init-xdg.d.ts +1 -0
  43. package/dist/types/cli/completion-gen.d.ts +80 -0
  44. package/dist/types/cli/config-cli.d.ts +22 -0
  45. package/dist/types/cli/dry-balance-cli.d.ts +104 -0
  46. package/dist/types/cli/extension-flags.d.ts +36 -0
  47. package/dist/types/cli/file-processor.d.ts +11 -0
  48. package/dist/types/cli/gateway-cli.d.ts +95 -0
  49. package/dist/types/cli/grep-cli.d.ts +17 -0
  50. package/dist/types/cli/grievances-cli.d.ts +37 -0
  51. package/dist/types/cli/initial-message.d.ts +17 -0
  52. package/dist/types/cli/list-models.d.ts +30 -0
  53. package/dist/types/cli/plugin-cli.d.ts +32 -0
  54. package/dist/types/cli/read-cli.d.ts +4 -0
  55. package/dist/types/cli/session-picker.d.ts +10 -0
  56. package/dist/types/cli/setup-cli.d.ts +24 -0
  57. package/dist/types/cli/shell-cli.d.ts +8 -0
  58. package/dist/types/cli/ssh-cli.d.ts +21 -0
  59. package/dist/types/cli/stats-cli.d.ts +17 -0
  60. package/dist/types/cli/tiny-models-cli.d.ts +9 -0
  61. package/dist/types/cli/update-cli.d.ts +106 -0
  62. package/dist/types/cli/web-search-cli.d.ts +20 -0
  63. package/dist/types/cli/worktree-cli.d.ts +26 -0
  64. package/dist/types/cli-commands.d.ts +19 -0
  65. package/dist/types/cli.d.ts +3 -0
  66. package/dist/types/commands/acp.d.ts +12 -0
  67. package/dist/types/commands/agents.d.ts +34 -0
  68. package/dist/types/commands/auth-broker.d.ts +54 -0
  69. package/dist/types/commands/auth-gateway.d.ts +35 -0
  70. package/dist/types/commands/commit.d.ts +27 -0
  71. package/dist/types/commands/complete.d.ts +6 -0
  72. package/dist/types/commands/completions.d.ts +13 -0
  73. package/dist/types/commands/config.d.ts +30 -0
  74. package/dist/types/commands/dry-balance.d.ts +31 -0
  75. package/dist/types/commands/gateway.d.ts +69 -0
  76. package/dist/types/commands/grep.d.ts +42 -0
  77. package/dist/types/commands/grievances.d.ts +40 -0
  78. package/dist/types/commands/install.d.ts +51 -0
  79. package/dist/types/commands/launch.d.ts +129 -0
  80. package/dist/types/commands/plugin.d.ts +52 -0
  81. package/dist/types/commands/read.d.ts +15 -0
  82. package/dist/types/commands/setup.d.ts +34 -0
  83. package/dist/types/commands/shell.d.ts +21 -0
  84. package/dist/types/commands/ssh.d.ts +48 -0
  85. package/dist/types/commands/stats.d.ts +25 -0
  86. package/dist/types/commands/tiny-models.d.ts +22 -0
  87. package/dist/types/commands/update.d.ts +20 -0
  88. package/dist/types/commands/web-search.d.ts +33 -0
  89. package/dist/types/commands/worktree.d.ts +34 -0
  90. package/dist/types/commit/agentic/agent.d.ts +31 -0
  91. package/dist/types/commit/agentic/fallback.d.ts +5 -0
  92. package/dist/types/commit/agentic/index.d.ts +2 -0
  93. package/dist/types/commit/agentic/state.d.ts +58 -0
  94. package/dist/types/commit/agentic/tools/analyze-file.d.ts +19 -0
  95. package/dist/types/commit/agentic/tools/git-file-diff.d.ts +10 -0
  96. package/dist/types/commit/agentic/tools/git-hunk.d.ts +9 -0
  97. package/dist/types/commit/agentic/tools/git-overview.d.ts +9 -0
  98. package/dist/types/commit/agentic/tools/index.d.ts +16 -0
  99. package/dist/types/commit/agentic/tools/propose-changelog.d.ts +28 -0
  100. package/dist/types/commit/agentic/tools/propose-commit.d.ts +36 -0
  101. package/dist/types/commit/agentic/tools/recent-commits.d.ts +7 -0
  102. package/dist/types/commit/agentic/tools/schemas.d.ts +27 -0
  103. package/dist/types/commit/agentic/tools/split-commit.d.ts +53 -0
  104. package/dist/types/commit/agentic/topo-sort.d.ts +4 -0
  105. package/dist/types/commit/agentic/trivial.d.ts +7 -0
  106. package/dist/types/commit/agentic/validation.d.ts +20 -0
  107. package/dist/types/commit/analysis/conventional.d.ts +22 -0
  108. package/dist/types/commit/analysis/index.d.ts +4 -0
  109. package/dist/types/commit/analysis/scope.d.ts +6 -0
  110. package/dist/types/commit/analysis/summary.d.ts +19 -0
  111. package/dist/types/commit/analysis/validation.d.ts +8 -0
  112. package/dist/types/commit/changelog/detect.d.ts +2 -0
  113. package/dist/types/commit/changelog/generate.d.ts +30 -0
  114. package/dist/types/commit/changelog/index.d.ts +30 -0
  115. package/dist/types/commit/changelog/parse.d.ts +2 -0
  116. package/dist/types/commit/cli.d.ts +3 -0
  117. package/dist/types/commit/git/diff.d.ts +5 -0
  118. package/dist/types/commit/index.d.ts +4 -0
  119. package/dist/types/commit/map-reduce/index.d.ts +28 -0
  120. package/dist/types/commit/map-reduce/map-phase.d.ts +17 -0
  121. package/dist/types/commit/map-reduce/reduce-phase.d.ts +13 -0
  122. package/dist/types/commit/map-reduce/utils.d.ts +2 -0
  123. package/dist/types/commit/message.d.ts +2 -0
  124. package/dist/types/commit/model-selection.d.ts +15 -0
  125. package/dist/types/commit/pipeline.d.ts +5 -0
  126. package/dist/types/commit/shared-llm.d.ts +54 -0
  127. package/dist/types/commit/types.d.ts +78 -0
  128. package/dist/types/commit/utils/exclusions.d.ts +4 -0
  129. package/dist/types/commit/utils.d.ts +20 -0
  130. package/dist/types/config/append-only-context-mode.d.ts +8 -0
  131. package/dist/types/config/config-file.d.ts +62 -0
  132. package/dist/types/config/file-lock.d.ts +29 -0
  133. package/dist/types/config/keybindings.d.ts +352 -0
  134. package/dist/types/config/model-equivalence.d.ts +24 -0
  135. package/dist/types/config/model-id-affixes.d.ts +10 -0
  136. package/dist/types/config/model-registry.d.ts +400 -0
  137. package/dist/types/config/model-resolver.d.ts +230 -0
  138. package/dist/types/config/models-config-schema.d.ts +523 -0
  139. package/dist/types/config/prompt-templates.d.ts +32 -0
  140. package/dist/types/config/resolve-config-value.d.ts +17 -0
  141. package/dist/types/config/settings-schema.d.ts +4352 -0
  142. package/dist/types/config/settings.d.ts +156 -0
  143. package/dist/types/config.d.ts +92 -0
  144. package/dist/types/cursor.d.ts +22 -0
  145. package/dist/types/dap/client.d.ts +38 -0
  146. package/dist/types/dap/config.d.ts +6 -0
  147. package/dist/types/dap/index.d.ts +4 -0
  148. package/dist/types/dap/session.d.ts +108 -0
  149. package/dist/types/dap/types.d.ts +524 -0
  150. package/dist/types/debug/index.d.ts +15 -0
  151. package/dist/types/debug/log-formatting.d.ts +4 -0
  152. package/dist/types/debug/log-viewer.d.ts +68 -0
  153. package/dist/types/debug/profiler.d.ts +24 -0
  154. package/dist/types/debug/protocol-probe.d.ts +38 -0
  155. package/dist/types/debug/raw-sse-buffer.d.ts +44 -0
  156. package/dist/types/debug/raw-sse.d.ts +18 -0
  157. package/dist/types/debug/report-bundle.d.ts +55 -0
  158. package/dist/types/debug/system-info.d.ts +26 -0
  159. package/dist/types/debug/terminal-info.d.ts +34 -0
  160. package/dist/types/discovery/agents-md.d.ts +1 -0
  161. package/dist/types/discovery/agents.d.ts +12 -0
  162. package/dist/types/discovery/builtin-defaults.d.ts +1 -0
  163. package/dist/types/discovery/builtin-rules/index.d.ts +7 -0
  164. package/dist/types/discovery/builtin.d.ts +1 -0
  165. package/dist/types/discovery/claude-plugins.d.ts +1 -0
  166. package/dist/types/discovery/claude.d.ts +1 -0
  167. package/dist/types/discovery/cline.d.ts +1 -0
  168. package/dist/types/discovery/codex.d.ts +1 -0
  169. package/dist/types/discovery/context-files.d.ts +17 -0
  170. package/dist/types/discovery/cursor.d.ts +16 -0
  171. package/dist/types/discovery/gemini.d.ts +1 -0
  172. package/dist/types/discovery/github.d.ts +1 -0
  173. package/dist/types/discovery/helpers.d.ts +269 -0
  174. package/dist/types/discovery/index.d.ts +53 -0
  175. package/dist/types/discovery/mcp-json.d.ts +1 -0
  176. package/dist/types/discovery/opencode.d.ts +1 -0
  177. package/dist/types/discovery/plugin-dir-roots.d.ts +15 -0
  178. package/dist/types/discovery/prometheus-extension-roots.d.ts +43 -0
  179. package/dist/types/discovery/prometheus-plugins.d.ts +1 -0
  180. package/dist/types/discovery/ssh.d.ts +1 -0
  181. package/dist/types/discovery/substitute-plugin-root.d.ts +1 -0
  182. package/dist/types/discovery/vscode.d.ts +1 -0
  183. package/dist/types/discovery/windsurf.d.ts +13 -0
  184. package/dist/types/edit/apply-patch/index.d.ts +35 -0
  185. package/dist/types/edit/apply-patch/parser.d.ts +34 -0
  186. package/dist/types/edit/diff.d.ts +59 -0
  187. package/dist/types/edit/file-snapshot-store.d.ts +40 -0
  188. package/dist/types/edit/hashline/block-resolver.d.ts +9 -0
  189. package/dist/types/edit/hashline/diff.d.ts +40 -0
  190. package/dist/types/edit/hashline/execute.d.ts +28 -0
  191. package/dist/types/edit/hashline/filesystem.d.ts +57 -0
  192. package/dist/types/edit/hashline/index.d.ts +5 -0
  193. package/dist/types/edit/hashline/params.d.ts +11 -0
  194. package/dist/types/edit/index.d.ts +62 -0
  195. package/dist/types/edit/modes/apply-patch.d.ts +24 -0
  196. package/dist/types/edit/modes/patch.d.ts +99 -0
  197. package/dist/types/edit/modes/replace.d.ts +142 -0
  198. package/dist/types/edit/normalize.d.ts +31 -0
  199. package/dist/types/edit/notebook.d.ts +23 -0
  200. package/dist/types/edit/read-file.d.ts +2 -0
  201. package/dist/types/edit/renderer.d.ts +109 -0
  202. package/dist/types/edit/streaming.d.ts +75 -0
  203. package/dist/types/eval/__tests__/agent-bridge.test.d.ts +1 -0
  204. package/dist/types/eval/__tests__/bridge-timeout.test.d.ts +1 -0
  205. package/dist/types/eval/__tests__/budget-bridge.test.d.ts +1 -0
  206. package/dist/types/eval/__tests__/idle-timeout.test.d.ts +1 -0
  207. package/dist/types/eval/__tests__/kernel-spawn.test.d.ts +1 -0
  208. package/dist/types/eval/__tests__/llm-bridge.test.d.ts +1 -0
  209. package/dist/types/eval/__tests__/shared-executors.test.d.ts +1 -0
  210. package/dist/types/eval/agent-bridge.d.ts +25 -0
  211. package/dist/types/eval/backend.d.ts +55 -0
  212. package/dist/types/eval/bridge-timeout.d.ts +27 -0
  213. package/dist/types/eval/budget-bridge.d.ts +29 -0
  214. package/dist/types/eval/concurrency-bridge.d.ts +26 -0
  215. package/dist/types/eval/idle-timeout.d.ts +30 -0
  216. package/dist/types/eval/index.d.ts +4 -0
  217. package/dist/types/eval/js/context-manager.d.ts +24 -0
  218. package/dist/types/eval/js/executor.d.ts +36 -0
  219. package/dist/types/eval/js/index.d.ts +10 -0
  220. package/dist/types/eval/js/shared/helpers.d.ts +38 -0
  221. package/dist/types/eval/js/shared/indirect-eval.d.ts +14 -0
  222. package/dist/types/eval/js/shared/local-module-loader.d.ts +16 -0
  223. package/dist/types/eval/js/shared/prelude.d.ts +1 -0
  224. package/dist/types/eval/js/shared/rewrite-imports.d.ts +25 -0
  225. package/dist/types/eval/js/shared/runtime.d.ts +53 -0
  226. package/dist/types/eval/js/shared/types.d.ts +24 -0
  227. package/dist/types/eval/js/tool-bridge.d.ts +20 -0
  228. package/dist/types/eval/js/worker-core.d.ts +5 -0
  229. package/dist/types/eval/js/worker-entry.d.ts +1 -0
  230. package/dist/types/eval/js/worker-protocol.d.ts +77 -0
  231. package/dist/types/eval/llm-bridge.d.ts +25 -0
  232. package/dist/types/eval/py/display.d.ts +25 -0
  233. package/dist/types/eval/py/executor.d.ts +95 -0
  234. package/dist/types/eval/py/index.d.ts +11 -0
  235. package/dist/types/eval/py/kernel.d.ts +70 -0
  236. package/dist/types/eval/py/prelude.d.ts +1 -0
  237. package/dist/types/eval/py/runtime.d.ts +31 -0
  238. package/dist/types/eval/py/spawn-options.d.ts +58 -0
  239. package/dist/types/eval/py/tool-bridge.d.ts +16 -0
  240. package/dist/types/eval/session-id.d.ts +3 -0
  241. package/dist/types/eval/types.d.ts +52 -0
  242. package/dist/types/exa/factory.d.ts +13 -0
  243. package/dist/types/exa/index.d.ts +20 -0
  244. package/dist/types/exa/mcp-client.d.ts +46 -0
  245. package/dist/types/exa/render.d.ts +19 -0
  246. package/dist/types/exa/researcher.d.ts +9 -0
  247. package/dist/types/exa/search.d.ts +9 -0
  248. package/dist/types/exa/types.d.ts +155 -0
  249. package/dist/types/exa/websets.d.ts +9 -0
  250. package/dist/types/exec/bash-executor.d.ts +42 -0
  251. package/dist/types/exec/exec.d.ts +25 -0
  252. package/dist/types/exec/idle-timeout-watchdog.d.ts +18 -0
  253. package/dist/types/exec/non-interactive-env.d.ts +1 -0
  254. package/dist/types/export/custom-share.d.ts +20 -0
  255. package/dist/types/export/html/index.d.ts +10 -0
  256. package/dist/types/export/html/template.generated.d.ts +1 -0
  257. package/dist/types/export/html/template.macro.d.ts +5 -0
  258. package/dist/types/export/ttsr.d.ts +53 -0
  259. package/dist/types/extensibility/custom-commands/bundled/ci-green/index.d.ts +9 -0
  260. package/dist/types/extensibility/custom-commands/bundled/review/index.d.ts +10 -0
  261. package/dist/types/extensibility/custom-commands/index.d.ts +2 -0
  262. package/dist/types/extensibility/custom-commands/loader.d.ts +29 -0
  263. package/dist/types/extensibility/custom-commands/types.d.ts +106 -0
  264. package/dist/types/extensibility/custom-tools/index.d.ts +6 -0
  265. package/dist/types/extensibility/custom-tools/loader.d.ts +69 -0
  266. package/dist/types/extensibility/custom-tools/types.d.ts +232 -0
  267. package/dist/types/extensibility/custom-tools/wrapper.d.ts +23 -0
  268. package/dist/types/extensibility/extensions/compact-handler.d.ts +26 -0
  269. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +29 -0
  270. package/dist/types/extensibility/extensions/index.d.ts +8 -0
  271. package/dist/types/extensibility/extensions/loader.d.ts +43 -0
  272. package/dist/types/extensibility/extensions/runner.d.ts +142 -0
  273. package/dist/types/extensibility/extensions/types.d.ts +892 -0
  274. package/dist/types/extensibility/extensions/wrapper.d.ts +54 -0
  275. package/dist/types/extensibility/hooks/index.d.ts +5 -0
  276. package/dist/types/extensibility/hooks/loader.d.ts +89 -0
  277. package/dist/types/extensibility/hooks/runner.d.ts +126 -0
  278. package/dist/types/extensibility/hooks/tool-wrapper.d.ts +25 -0
  279. package/dist/types/extensibility/hooks/types.d.ts +435 -0
  280. package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +23 -0
  281. package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +14 -0
  282. package/dist/types/extensibility/plugins/doctor.d.ts +3 -0
  283. package/dist/types/extensibility/plugins/git-url.d.ts +44 -0
  284. package/dist/types/extensibility/plugins/index.d.ts +7 -0
  285. package/dist/types/extensibility/plugins/installer.d.ts +5 -0
  286. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +29 -0
  287. package/dist/types/extensibility/plugins/loader.d.ts +41 -0
  288. package/dist/types/extensibility/plugins/manager.d.ts +76 -0
  289. package/dist/types/extensibility/plugins/marketplace/cache.d.ts +41 -0
  290. package/dist/types/extensibility/plugins/marketplace/fetcher.d.ts +48 -0
  291. package/dist/types/extensibility/plugins/marketplace/index.d.ts +6 -0
  292. package/dist/types/extensibility/plugins/marketplace/manager.d.ts +57 -0
  293. package/dist/types/extensibility/plugins/marketplace/registry.d.ts +34 -0
  294. package/dist/types/extensibility/plugins/marketplace/source-resolver.d.ts +28 -0
  295. package/dist/types/extensibility/plugins/marketplace/types.d.ts +130 -0
  296. package/dist/types/extensibility/plugins/parser.d.ts +52 -0
  297. package/dist/types/extensibility/plugins/types.d.ts +149 -0
  298. package/dist/types/extensibility/shared-events.d.ts +279 -0
  299. package/dist/types/extensibility/skills.d.ts +57 -0
  300. package/dist/types/extensibility/slash-commands.d.ts +48 -0
  301. package/dist/types/extensibility/tool-proxy.d.ts +4 -0
  302. package/dist/types/extensibility/typebox.d.ts +155 -0
  303. package/dist/types/extensibility/utils.d.ts +12 -0
  304. package/dist/types/gateway/adapters/telegram/access.d.ts +11 -0
  305. package/dist/types/gateway/adapters/telegram/commands.d.ts +41 -0
  306. package/dist/types/gateway/adapters/telegram/expressions.d.ts +60 -0
  307. package/dist/types/gateway/adapters/telegram/media.d.ts +58 -0
  308. package/dist/types/gateway/adapters/telegram/native-command-policy.d.ts +6 -0
  309. package/dist/types/gateway/adapters/telegram/native-commands.d.ts +23 -0
  310. package/dist/types/gateway/adapters/telegram/normalize.d.ts +8 -0
  311. package/dist/types/gateway/adapters/telegram/send-message.d.ts +388 -0
  312. package/dist/types/gateway/adapters/telegram/service.d.ts +65 -0
  313. package/dist/types/gateway/adapters/telegram/setup-api.d.ts +39 -0
  314. package/dist/types/gateway/adapters/telegram/setup-config.d.ts +11 -0
  315. package/dist/types/gateway/adapters/telegram/types.d.ts +187 -0
  316. package/dist/types/gateway/adapters/telegram/webhook.d.ts +53 -0
  317. package/dist/types/gateway/commands.d.ts +33 -0
  318. package/dist/types/gateway/context.d.ts +30 -0
  319. package/dist/types/gateway/native-slash-policy.d.ts +12 -0
  320. package/dist/types/gateway/prometheus-dispatch.d.ts +29 -0
  321. package/dist/types/gateway/router.d.ts +52 -0
  322. package/dist/types/gateway/session-key.d.ts +3 -0
  323. package/dist/types/gateway/types.d.ts +98 -0
  324. package/dist/types/goals/index.d.ts +3 -0
  325. package/dist/types/goals/runtime.d.ts +67 -0
  326. package/dist/types/goals/state.d.ts +35 -0
  327. package/dist/types/goals/tools/goal-tool.d.ts +66 -0
  328. package/dist/types/hindsight/backend.d.ts +13 -0
  329. package/dist/types/hindsight/bank.d.ts +62 -0
  330. package/dist/types/hindsight/client.d.ts +224 -0
  331. package/dist/types/hindsight/config.d.ts +51 -0
  332. package/dist/types/hindsight/content.d.ts +70 -0
  333. package/dist/types/hindsight/index.d.ts +8 -0
  334. package/dist/types/hindsight/mental-models.d.ts +125 -0
  335. package/dist/types/hindsight/state.d.ts +105 -0
  336. package/dist/types/hindsight/transcript.d.ts +28 -0
  337. package/dist/types/index.d.ts +36 -0
  338. package/dist/types/internal-urls/agent-protocol.d.ts +13 -0
  339. package/dist/types/internal-urls/artifact-protocol.d.ts +7 -0
  340. package/dist/types/internal-urls/docs-index.generated.d.ts +2 -0
  341. package/dist/types/internal-urls/index.d.ts +23 -0
  342. package/dist/types/internal-urls/issue-pr-protocol.d.ts +17 -0
  343. package/dist/types/internal-urls/json-query.d.ts +30 -0
  344. package/dist/types/internal-urls/local-protocol.d.ts +50 -0
  345. package/dist/types/internal-urls/mcp-protocol.d.ts +12 -0
  346. package/dist/types/internal-urls/memory-protocol.d.ts +24 -0
  347. package/dist/types/internal-urls/parse.d.ts +19 -0
  348. package/dist/types/internal-urls/prometheus-protocol.d.ts +13 -0
  349. package/dist/types/internal-urls/registry-helpers.d.ts +10 -0
  350. package/dist/types/internal-urls/router.d.ts +21 -0
  351. package/dist/types/internal-urls/rule-protocol.d.ts +7 -0
  352. package/dist/types/internal-urls/skill-protocol.d.ts +14 -0
  353. package/dist/types/internal-urls/types.d.ts +145 -0
  354. package/dist/types/internal-urls/vault-protocol.d.ts +93 -0
  355. package/dist/types/lib/xai-http.d.ts +40 -0
  356. package/dist/types/lsp/client.d.ts +68 -0
  357. package/dist/types/lsp/clients/biome-client.d.ts +16 -0
  358. package/dist/types/lsp/clients/index.d.ts +19 -0
  359. package/dist/types/lsp/clients/lsp-linter-client.d.ts +16 -0
  360. package/dist/types/lsp/clients/swiftlint-client.d.ts +20 -0
  361. package/dist/types/lsp/config.d.ts +65 -0
  362. package/dist/types/lsp/diagnostics-ledger.d.ts +10 -0
  363. package/dist/types/lsp/edits.d.ts +23 -0
  364. package/dist/types/lsp/index.d.ts +140 -0
  365. package/dist/types/lsp/lspmux.d.ts +58 -0
  366. package/dist/types/lsp/render.d.ts +32 -0
  367. package/dist/types/lsp/startup-events.d.ts +11 -0
  368. package/dist/types/lsp/types.d.ts +302 -0
  369. package/dist/types/lsp/utils.d.ts +112 -0
  370. package/dist/types/main.d.ts +56 -0
  371. package/dist/types/mcp/client.d.ts +75 -0
  372. package/dist/types/mcp/config-writer.d.ts +53 -0
  373. package/dist/types/mcp/config.d.ts +75 -0
  374. package/dist/types/mcp/index.d.ts +18 -0
  375. package/dist/types/mcp/json-rpc.d.ts +27 -0
  376. package/dist/types/mcp/loader.d.ts +43 -0
  377. package/dist/types/mcp/manager.d.ts +202 -0
  378. package/dist/types/mcp/oauth-discovery.d.ts +41 -0
  379. package/dist/types/mcp/oauth-flow.d.ts +59 -0
  380. package/dist/types/mcp/render.d.ts +25 -0
  381. package/dist/types/mcp/smithery-auth.d.ts +16 -0
  382. package/dist/types/mcp/smithery-connect.d.ts +38 -0
  383. package/dist/types/mcp/smithery-registry.d.ts +51 -0
  384. package/dist/types/mcp/timeout.d.ts +9 -0
  385. package/dist/types/mcp/tool-bridge.d.ts +90 -0
  386. package/dist/types/mcp/tool-cache.d.ts +8 -0
  387. package/dist/types/mcp/transports/http.d.ts +45 -0
  388. package/dist/types/mcp/transports/index.d.ts +5 -0
  389. package/dist/types/mcp/transports/stdio.d.ts +60 -0
  390. package/dist/types/mcp/types.d.ts +333 -0
  391. package/dist/types/memories/index.d.ts +43 -0
  392. package/dist/types/memories/storage.d.ts +120 -0
  393. package/dist/types/memory-backend/index.d.ts +5 -0
  394. package/dist/types/memory-backend/local-backend.d.ts +9 -0
  395. package/dist/types/memory-backend/off-backend.d.ts +7 -0
  396. package/dist/types/memory-backend/resolve.d.ts +16 -0
  397. package/dist/types/memory-backend/types.d.ts +67 -0
  398. package/dist/types/mnemopi/backend.d.ts +4 -0
  399. package/dist/types/mnemopi/config.d.ts +29 -0
  400. package/dist/types/mnemopi/index.d.ts +3 -0
  401. package/dist/types/mnemopi/state.d.ts +72 -0
  402. package/dist/types/modes/acp/acp-agent.d.ts +61 -0
  403. package/dist/types/modes/acp/acp-client-bridge.d.ts +9 -0
  404. package/dist/types/modes/acp/acp-event-mapper.d.ts +32 -0
  405. package/dist/types/modes/acp/acp-mode.d.ts +5 -0
  406. package/dist/types/modes/acp/index.d.ts +2 -0
  407. package/dist/types/modes/acp/terminal-auth.d.ts +6 -0
  408. package/dist/types/modes/components/agent-dashboard.d.ts +22 -0
  409. package/dist/types/modes/components/assistant-message.d.ts +35 -0
  410. package/dist/types/modes/components/bash-execution.d.ts +29 -0
  411. package/dist/types/modes/components/bordered-loader.d.ts +11 -0
  412. package/dist/types/modes/components/branch-summary-message.d.ts +13 -0
  413. package/dist/types/modes/components/btw-panel.d.ts +16 -0
  414. package/dist/types/modes/components/compaction-summary-message.d.ts +13 -0
  415. package/dist/types/modes/components/copy-selector.d.ts +22 -0
  416. package/dist/types/modes/components/countdown-timer.d.ts +14 -0
  417. package/dist/types/modes/components/custom-editor.d.ts +53 -0
  418. package/dist/types/modes/components/custom-message.d.ts +15 -0
  419. package/dist/types/modes/components/diff.d.ts +11 -0
  420. package/dist/types/modes/components/dynamic-border.d.ts +14 -0
  421. package/dist/types/modes/components/error-banner.d.ts +11 -0
  422. package/dist/types/modes/components/eval-execution.d.ts +23 -0
  423. package/dist/types/modes/components/execution-shared.d.ts +46 -0
  424. package/dist/types/modes/components/extensions/extension-dashboard.d.ts +27 -0
  425. package/dist/types/modes/components/extensions/extension-list.d.ts +39 -0
  426. package/dist/types/modes/components/extensions/index.d.ts +8 -0
  427. package/dist/types/modes/components/extensions/inspector-panel.d.ts +8 -0
  428. package/dist/types/modes/components/extensions/state-manager.d.ts +50 -0
  429. package/dist/types/modes/components/extensions/types.d.ts +147 -0
  430. package/dist/types/modes/components/footer.d.ts +30 -0
  431. package/dist/types/modes/components/history-search.d.ts +7 -0
  432. package/dist/types/modes/components/hook-editor.d.ts +18 -0
  433. package/dist/types/modes/components/hook-input.d.ts +15 -0
  434. package/dist/types/modes/components/hook-message.d.ts +15 -0
  435. package/dist/types/modes/components/hook-selector.d.ts +70 -0
  436. package/dist/types/modes/components/index.d.ts +37 -0
  437. package/dist/types/modes/components/keybinding-hints.d.ts +40 -0
  438. package/dist/types/modes/components/login-dialog.d.ts +32 -0
  439. package/dist/types/modes/components/mcp-add-wizard.d.ts +25 -0
  440. package/dist/types/modes/components/message-frame.d.ts +42 -0
  441. package/dist/types/modes/components/model-selector.d.ts +28 -0
  442. package/dist/types/modes/components/oauth-selector.d.ts +14 -0
  443. package/dist/types/modes/components/omfg-panel.d.ts +19 -0
  444. package/dist/types/modes/components/plugin-selector.d.ts +26 -0
  445. package/dist/types/modes/components/plugin-settings.d.ts +98 -0
  446. package/dist/types/modes/components/queue-mode-selector.d.ts +9 -0
  447. package/dist/types/modes/components/read-tool-group.d.ts +30 -0
  448. package/dist/types/modes/components/segment-track.d.ts +22 -0
  449. package/dist/types/modes/components/session-observer-overlay.d.ts +11 -0
  450. package/dist/types/modes/components/session-selector.d.ts +62 -0
  451. package/dist/types/modes/components/settings-defs.d.ts +50 -0
  452. package/dist/types/modes/components/settings-selector.d.ts +54 -0
  453. package/dist/types/modes/components/show-images-selector.d.ts +9 -0
  454. package/dist/types/modes/components/skill-message.d.ts +9 -0
  455. package/dist/types/modes/components/status-line/context-thresholds.d.ts +10 -0
  456. package/dist/types/modes/components/status-line/git-utils.d.ts +22 -0
  457. package/dist/types/modes/components/status-line/index.d.ts +4 -0
  458. package/dist/types/modes/components/status-line/presets.d.ts +3 -0
  459. package/dist/types/modes/components/status-line/segments.d.ts +5 -0
  460. package/dist/types/modes/components/status-line/separators.d.ts +3 -0
  461. package/dist/types/modes/components/status-line/token-rate.d.ts +10 -0
  462. package/dist/types/modes/components/status-line/types.d.ts +80 -0
  463. package/dist/types/modes/components/status-line.d.ts +77 -0
  464. package/dist/types/modes/components/theme-selector.d.ts +10 -0
  465. package/dist/types/modes/components/thinking-selector.d.ts +10 -0
  466. package/dist/types/modes/components/tiny-title-download-progress.d.ts +11 -0
  467. package/dist/types/modes/components/todo-reminder.d.ts +13 -0
  468. package/dist/types/modes/components/tool-execution.d.ts +77 -0
  469. package/dist/types/modes/components/transcript-container.d.ts +38 -0
  470. package/dist/types/modes/components/tree-selector.d.ts +31 -0
  471. package/dist/types/modes/components/ttsr-notification.d.ts +13 -0
  472. package/dist/types/modes/components/user-message-selector.d.ts +28 -0
  473. package/dist/types/modes/components/user-message.d.ts +8 -0
  474. package/dist/types/modes/components/visual-truncate.d.ts +19 -0
  475. package/dist/types/modes/components/welcome.d.ts +55 -0
  476. package/dist/types/modes/controllers/btw-controller.d.ts +10 -0
  477. package/dist/types/modes/controllers/command-controller-shared.d.ts +47 -0
  478. package/dist/types/modes/controllers/command-controller.d.ts +41 -0
  479. package/dist/types/modes/controllers/event-controller.d.ts +12 -0
  480. package/dist/types/modes/controllers/extension-ui-controller.d.ts +83 -0
  481. package/dist/types/modes/controllers/input-controller.d.ts +34 -0
  482. package/dist/types/modes/controllers/mcp-command-controller.d.ts +10 -0
  483. package/dist/types/modes/controllers/omfg-controller.d.ts +10 -0
  484. package/dist/types/modes/controllers/omfg-rule.d.ts +26 -0
  485. package/dist/types/modes/controllers/selector-controller.d.ts +46 -0
  486. package/dist/types/modes/controllers/ssh-command-controller.d.ts +10 -0
  487. package/dist/types/modes/controllers/todo-command-controller.d.ts +7 -0
  488. package/dist/types/modes/emoji-autocomplete.d.ts +16 -0
  489. package/dist/types/modes/gradient-highlight.d.ts +27 -0
  490. package/dist/types/modes/image-references.d.ts +17 -0
  491. package/dist/types/modes/index.d.ts +9 -0
  492. package/dist/types/modes/interactive-mode.d.ts +291 -0
  493. package/dist/types/modes/internal-url-autocomplete.d.ts +43 -0
  494. package/dist/types/modes/loop-limit.d.ts +22 -0
  495. package/dist/types/modes/magic-keywords.d.ts +14 -0
  496. package/dist/types/modes/markdown-prose.d.ts +27 -0
  497. package/dist/types/modes/oauth-manual-input.d.ts +8 -0
  498. package/dist/types/modes/orchestrate.d.ts +15 -0
  499. package/dist/types/modes/print-mode.d.ts +27 -0
  500. package/dist/types/modes/prompt-action-autocomplete.d.ts +46 -0
  501. package/dist/types/modes/rpc/host-tools.d.ts +16 -0
  502. package/dist/types/modes/rpc/host-uris.d.ts +38 -0
  503. package/dist/types/modes/rpc/rpc-client.d.ts +249 -0
  504. package/dist/types/modes/rpc/rpc-mode.d.ts +17 -0
  505. package/dist/types/modes/rpc/rpc-types.d.ts +586 -0
  506. package/dist/types/modes/runtime-init.d.ts +21 -0
  507. package/dist/types/modes/session-observer-registry.d.ts +26 -0
  508. package/dist/types/modes/setup-wizard/index.d.ts +16 -0
  509. package/dist/types/modes/setup-wizard/scenes/channels.d.ts +14 -0
  510. package/dist/types/modes/setup-wizard/scenes/glyph.d.ts +2 -0
  511. package/dist/types/modes/setup-wizard/scenes/outro.d.ts +2 -0
  512. package/dist/types/modes/setup-wizard/scenes/providers.d.ts +2 -0
  513. package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +19 -0
  514. package/dist/types/modes/setup-wizard/scenes/splash.d.ts +11 -0
  515. package/dist/types/modes/setup-wizard/scenes/telegram.d.ts +20 -0
  516. package/dist/types/modes/setup-wizard/scenes/theme.d.ts +2 -0
  517. package/dist/types/modes/setup-wizard/scenes/types.d.ts +43 -0
  518. package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +19 -0
  519. package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +14 -0
  520. package/dist/types/modes/shared.d.ts +15 -0
  521. package/dist/types/modes/theme/defaults/index.d.ts +9436 -0
  522. package/dist/types/modes/theme/mermaid-cache.d.ts +9 -0
  523. package/dist/types/modes/theme/shimmer.d.ts +40 -0
  524. package/dist/types/modes/theme/theme.d.ts +305 -0
  525. package/dist/types/modes/turn-budget.d.ts +18 -0
  526. package/dist/types/modes/types.d.ts +294 -0
  527. package/dist/types/modes/ultrathink.d.ts +15 -0
  528. package/dist/types/modes/utils/context-usage.d.ts +47 -0
  529. package/dist/types/modes/utils/copy-targets.d.ts +53 -0
  530. package/dist/types/modes/utils/hotkeys-markdown.d.ts +5 -0
  531. package/dist/types/modes/utils/keybinding-matchers.d.ts +19 -0
  532. package/dist/types/modes/utils/tools-markdown.d.ts +5 -0
  533. package/dist/types/modes/utils/ui-helpers.d.ts +55 -0
  534. package/dist/types/modes/workflow.d.ts +15 -0
  535. package/dist/types/plan-mode/approved-plan.d.ts +49 -0
  536. package/dist/types/plan-mode/plan-handoff.d.ts +20 -0
  537. package/dist/types/plan-mode/plan-protection.d.ts +12 -0
  538. package/dist/types/plan-mode/state.d.ts +6 -0
  539. package/dist/types/registry/agent-registry.d.ts +62 -0
  540. package/dist/types/sdk.d.ts +271 -0
  541. package/dist/types/secrets/index.d.ts +9 -0
  542. package/dist/types/secrets/obfuscator.d.ts +23 -0
  543. package/dist/types/secrets/regex.d.ts +2 -0
  544. package/dist/types/session/agent-session.d.ts +1032 -0
  545. package/dist/types/session/agent-storage.d.ts +94 -0
  546. package/dist/types/session/artifacts.d.ts +61 -0
  547. package/dist/types/session/auth-broker-config.d.ts +13 -0
  548. package/dist/types/session/auth-storage.d.ts +6 -0
  549. package/dist/types/session/blob-store.d.ts +64 -0
  550. package/dist/types/session/client-bridge.d.ts +88 -0
  551. package/dist/types/session/history-storage.d.ts +30 -0
  552. package/dist/types/session/indexed-session-storage.d.ts +59 -0
  553. package/dist/types/session/messages.d.ts +173 -0
  554. package/dist/types/session/redis-session-storage.d.ts +51 -0
  555. package/dist/types/session/session-dump-format.d.ts +22 -0
  556. package/dist/types/session/session-manager.d.ts +594 -0
  557. package/dist/types/session/session-storage.d.ts +86 -0
  558. package/dist/types/session/shake-types.d.ts +24 -0
  559. package/dist/types/session/sql-session-storage.d.ts +72 -0
  560. package/dist/types/session/streaming-output.d.ts +185 -0
  561. package/dist/types/session/tool-choice-queue.d.ts +78 -0
  562. package/dist/types/session/yield-queue.d.ts +24 -0
  563. package/dist/types/slash-commands/acp-builtins.d.ts +18 -0
  564. package/dist/types/slash-commands/builtin-registry.d.ts +23 -0
  565. package/dist/types/slash-commands/headless-plan.d.ts +3 -0
  566. package/dist/types/slash-commands/helpers/context-report.d.ts +7 -0
  567. package/dist/types/slash-commands/helpers/format.d.ts +10 -0
  568. package/dist/types/slash-commands/helpers/marketplace-manager.d.ts +8 -0
  569. package/dist/types/slash-commands/helpers/mcp.d.ts +3 -0
  570. package/dist/types/slash-commands/helpers/parse.d.ts +33 -0
  571. package/dist/types/slash-commands/helpers/ssh.d.ts +3 -0
  572. package/dist/types/slash-commands/helpers/todo.d.ts +3 -0
  573. package/dist/types/slash-commands/helpers/usage-report.d.ts +7 -0
  574. package/dist/types/slash-commands/marketplace-install-parser.d.ts +33 -0
  575. package/dist/types/slash-commands/types.d.ts +129 -0
  576. package/dist/types/ssh/config-writer.d.ts +49 -0
  577. package/dist/types/ssh/connection-manager.d.ts +33 -0
  578. package/dist/types/ssh/ssh-executor.d.ts +37 -0
  579. package/dist/types/ssh/sshfs-mount.d.ts +6 -0
  580. package/dist/types/ssh/utils.d.ts +2 -0
  581. package/dist/types/stt/downloader.d.ts +9 -0
  582. package/dist/types/stt/index.d.ts +3 -0
  583. package/dist/types/stt/recorder.d.ts +13 -0
  584. package/dist/types/stt/setup.d.ts +18 -0
  585. package/dist/types/stt/stt-controller.d.ts +16 -0
  586. package/dist/types/stt/transcriber.d.ts +16 -0
  587. package/dist/types/system-prompt.d.ts +97 -0
  588. package/dist/types/task/agents.d.ts +28 -0
  589. package/dist/types/task/commands.d.ts +35 -0
  590. package/dist/types/task/discovery.d.ts +18 -0
  591. package/dist/types/task/executor.d.ts +121 -0
  592. package/dist/types/task/index.d.ts +42 -0
  593. package/dist/types/task/name-generator.d.ts +16 -0
  594. package/dist/types/task/output-manager.d.ts +27 -0
  595. package/dist/types/task/parallel.d.ts +34 -0
  596. package/dist/types/task/prometheus-command.d.ts +7 -0
  597. package/dist/types/task/render.d.ts +26 -0
  598. package/dist/types/task/repair-args.d.ts +52 -0
  599. package/dist/types/task/simple-mode.d.ts +8 -0
  600. package/dist/types/task/subprocess-tool-registry.d.ts +72 -0
  601. package/dist/types/task/types.d.ts +300 -0
  602. package/dist/types/task/worktree.d.ts +94 -0
  603. package/dist/types/telemetry-export.d.ts +43 -0
  604. package/dist/types/thinking.d.ts +68 -0
  605. package/dist/types/tiny/compiled-runtime.d.ts +35 -0
  606. package/dist/types/tiny/device.d.ts +78 -0
  607. package/dist/types/tiny/dtype.d.ts +85 -0
  608. package/dist/types/tiny/models.d.ts +204 -0
  609. package/dist/types/tiny/text.d.ts +36 -0
  610. package/dist/types/tiny/title-client.d.ts +73 -0
  611. package/dist/types/tiny/title-protocol.d.ts +77 -0
  612. package/dist/types/tiny/worker.d.ts +2 -0
  613. package/dist/types/tool-discovery/mode.d.ts +8 -0
  614. package/dist/types/tool-discovery/tool-index.d.ts +57 -0
  615. package/dist/types/tools/approval.d.ts +46 -0
  616. package/dist/types/tools/archive-reader.d.ts +44 -0
  617. package/dist/types/tools/ask.d.ts +113 -0
  618. package/dist/types/tools/ast-edit.d.ts +79 -0
  619. package/dist/types/tools/ast-grep.d.ts +70 -0
  620. package/dist/types/tools/auto-generated-guard.d.ts +17 -0
  621. package/dist/types/tools/bash-command-fixup.d.ts +11 -0
  622. package/dist/types/tools/bash-interactive.d.ts +16 -0
  623. package/dist/types/tools/bash-interceptor.d.ts +24 -0
  624. package/dist/types/tools/bash-pty-selection.d.ts +7 -0
  625. package/dist/types/tools/bash-skill-urls.d.ts +31 -0
  626. package/dist/types/tools/bash.d.ts +142 -0
  627. package/dist/types/tools/browser/attach.d.ts +34 -0
  628. package/dist/types/tools/browser/launch.d.ts +62 -0
  629. package/dist/types/tools/browser/readable.d.ts +17 -0
  630. package/dist/types/tools/browser/registry.d.ts +42 -0
  631. package/dist/types/tools/browser/render.d.ts +50 -0
  632. package/dist/types/tools/browser/tab-protocol.d.ts +144 -0
  633. package/dist/types/tools/browser/tab-supervisor.d.ts +63 -0
  634. package/dist/types/tools/browser/tab-worker-entry.d.ts +1 -0
  635. package/dist/types/tools/browser/tab-worker.d.ts +19 -0
  636. package/dist/types/tools/browser.d.ts +116 -0
  637. package/dist/types/tools/checkpoint.d.ts +65 -0
  638. package/dist/types/tools/conflict-detect.d.ts +205 -0
  639. package/dist/types/tools/context.d.ts +19 -0
  640. package/dist/types/tools/debug.d.ts +217 -0
  641. package/dist/types/tools/eval-backends.d.ts +12 -0
  642. package/dist/types/tools/eval-render.d.ts +60 -0
  643. package/dist/types/tools/eval.d.ts +77 -0
  644. package/dist/types/tools/fetch.d.ts +80 -0
  645. package/dist/types/tools/file-recorder.d.ts +13 -0
  646. package/dist/types/tools/find.d.ts +103 -0
  647. package/dist/types/tools/fs-cache-invalidation.d.ts +15 -0
  648. package/dist/types/tools/gh-format.d.ts +6 -0
  649. package/dist/types/tools/gh-renderer.d.ts +25 -0
  650. package/dist/types/tools/gh.d.ts +357 -0
  651. package/dist/types/tools/github-cache.d.ts +103 -0
  652. package/dist/types/tools/grouped-file-output.d.ts +36 -0
  653. package/dist/types/tools/image-gen.d.ts +82 -0
  654. package/dist/types/tools/index.d.ts +269 -0
  655. package/dist/types/tools/inspect-image-renderer.d.ts +26 -0
  656. package/dist/types/tools/inspect-image.d.ts +32 -0
  657. package/dist/types/tools/irc.d.ts +80 -0
  658. package/dist/types/tools/job.d.ts +66 -0
  659. package/dist/types/tools/json-tree.d.ts +23 -0
  660. package/dist/types/tools/jtd-to-json-schema.d.ts +29 -0
  661. package/dist/types/tools/jtd-to-typescript.d.ts +26 -0
  662. package/dist/types/tools/jtd-utils.d.ts +42 -0
  663. package/dist/types/tools/list-limit.d.ts +12 -0
  664. package/dist/types/tools/match-line-format.d.ts +11 -0
  665. package/dist/types/tools/memory-edit.d.ts +40 -0
  666. package/dist/types/tools/memory-recall.d.ts +24 -0
  667. package/dist/types/tools/memory-reflect.d.ts +26 -0
  668. package/dist/types/tools/memory-render.d.ts +60 -0
  669. package/dist/types/tools/memory-retain.d.ts +30 -0
  670. package/dist/types/tools/output-meta.d.ts +204 -0
  671. package/dist/types/tools/output-schema-validator.d.ts +64 -0
  672. package/dist/types/tools/path-utils.d.ts +199 -0
  673. package/dist/types/tools/plan-mode-guard.d.ts +17 -0
  674. package/dist/types/tools/read.d.ts +86 -0
  675. package/dist/types/tools/render-mermaid.d.ts +38 -0
  676. package/dist/types/tools/render-utils.d.ts +185 -0
  677. package/dist/types/tools/renderers.d.ts +26 -0
  678. package/dist/types/tools/report-tool-issue.d.ts +123 -0
  679. package/dist/types/tools/resolve.d.ts +91 -0
  680. package/dist/types/tools/review.d.ts +63 -0
  681. package/dist/types/tools/search-tool-bm25.d.ts +66 -0
  682. package/dist/types/tools/search.d.ts +95 -0
  683. package/dist/types/tools/sqlite-reader.d.ts +110 -0
  684. package/dist/types/tools/ssh.d.ts +69 -0
  685. package/dist/types/tools/todo.d.ts +159 -0
  686. package/dist/types/tools/tool-errors.d.ts +33 -0
  687. package/dist/types/tools/tool-result.d.ts +32 -0
  688. package/dist/types/tools/tool-timeouts.d.ts +51 -0
  689. package/dist/types/tools/tts.d.ts +18 -0
  690. package/dist/types/tools/write.d.ts +65 -0
  691. package/dist/types/tools/yield.d.ts +26 -0
  692. package/dist/types/tui/code-cell.d.ts +40 -0
  693. package/dist/types/tui/file-list.d.ts +22 -0
  694. package/dist/types/tui/hyperlink.d.ts +54 -0
  695. package/dist/types/tui/index.d.ts +11 -0
  696. package/dist/types/tui/output-block.d.ts +57 -0
  697. package/dist/types/tui/status-line.d.ts +18 -0
  698. package/dist/types/tui/tree-list.d.ts +19 -0
  699. package/dist/types/tui/types.d.ts +13 -0
  700. package/dist/types/tui/utils.d.ts +36 -0
  701. package/dist/types/utils/changelog.d.ts +25 -0
  702. package/dist/types/utils/clipboard.d.ts +26 -0
  703. package/dist/types/utils/command-args.d.ts +9 -0
  704. package/dist/types/utils/commit-message-generator.d.ts +7 -0
  705. package/dist/types/utils/edit-mode.d.ts +13 -0
  706. package/dist/types/utils/event-bus.d.ts +6 -0
  707. package/dist/types/utils/external-editor.d.ts +17 -0
  708. package/dist/types/utils/file-display-mode.d.ts +27 -0
  709. package/dist/types/utils/file-mentions.d.ts +13 -0
  710. package/dist/types/utils/git.d.ts +361 -0
  711. package/dist/types/utils/image-loading.d.ts +26 -0
  712. package/dist/types/utils/image-resize.d.ts +39 -0
  713. package/dist/types/utils/jj.d.ts +49 -0
  714. package/dist/types/utils/lang-from-path.d.ts +8 -0
  715. package/dist/types/utils/markit.d.ts +7 -0
  716. package/dist/types/utils/open.d.ts +2 -0
  717. package/dist/types/utils/session-color.d.ts +15 -0
  718. package/dist/types/utils/shell-snapshot.d.ts +5 -0
  719. package/dist/types/utils/sixel.d.ts +21 -0
  720. package/dist/types/utils/title-generator.d.ts +34 -0
  721. package/dist/types/utils/tool-choice.d.ts +7 -0
  722. package/dist/types/utils/tools-manager.d.ts +9 -0
  723. package/dist/types/web/kagi.d.ts +99 -0
  724. package/dist/types/web/parallel.d.ts +58 -0
  725. package/dist/types/web/scrapers/artifacthub.d.ts +6 -0
  726. package/dist/types/web/scrapers/arxiv.d.ts +5 -0
  727. package/dist/types/web/scrapers/aur.d.ts +5 -0
  728. package/dist/types/web/scrapers/biorxiv.d.ts +5 -0
  729. package/dist/types/web/scrapers/bluesky.d.ts +5 -0
  730. package/dist/types/web/scrapers/brew.d.ts +5 -0
  731. package/dist/types/web/scrapers/cheatsh.d.ts +8 -0
  732. package/dist/types/web/scrapers/chocolatey.d.ts +5 -0
  733. package/dist/types/web/scrapers/choosealicense.d.ts +2 -0
  734. package/dist/types/web/scrapers/cisa-kev.d.ts +5 -0
  735. package/dist/types/web/scrapers/clojars.d.ts +5 -0
  736. package/dist/types/web/scrapers/coingecko.d.ts +5 -0
  737. package/dist/types/web/scrapers/crates-io.d.ts +5 -0
  738. package/dist/types/web/scrapers/crossref.d.ts +2 -0
  739. package/dist/types/web/scrapers/devto.d.ts +5 -0
  740. package/dist/types/web/scrapers/discogs.d.ts +8 -0
  741. package/dist/types/web/scrapers/discourse.d.ts +5 -0
  742. package/dist/types/web/scrapers/dockerhub.d.ts +5 -0
  743. package/dist/types/web/scrapers/docs-rs.d.ts +2 -0
  744. package/dist/types/web/scrapers/fdroid.d.ts +5 -0
  745. package/dist/types/web/scrapers/firefox-addons.d.ts +2 -0
  746. package/dist/types/web/scrapers/flathub.d.ts +2 -0
  747. package/dist/types/web/scrapers/github-gist.d.ts +5 -0
  748. package/dist/types/web/scrapers/github.d.ts +12 -0
  749. package/dist/types/web/scrapers/gitlab.d.ts +5 -0
  750. package/dist/types/web/scrapers/go-pkg.d.ts +5 -0
  751. package/dist/types/web/scrapers/hackage.d.ts +5 -0
  752. package/dist/types/web/scrapers/hackernews.d.ts +2 -0
  753. package/dist/types/web/scrapers/hex.d.ts +5 -0
  754. package/dist/types/web/scrapers/huggingface.d.ts +2 -0
  755. package/dist/types/web/scrapers/iacr.d.ts +5 -0
  756. package/dist/types/web/scrapers/index.d.ts +84 -0
  757. package/dist/types/web/scrapers/jetbrains-marketplace.d.ts +2 -0
  758. package/dist/types/web/scrapers/lemmy.d.ts +2 -0
  759. package/dist/types/web/scrapers/lobsters.d.ts +5 -0
  760. package/dist/types/web/scrapers/mastodon.d.ts +5 -0
  761. package/dist/types/web/scrapers/maven.d.ts +6 -0
  762. package/dist/types/web/scrapers/mdn.d.ts +2 -0
  763. package/dist/types/web/scrapers/metacpan.d.ts +5 -0
  764. package/dist/types/web/scrapers/musicbrainz.d.ts +5 -0
  765. package/dist/types/web/scrapers/npm.d.ts +5 -0
  766. package/dist/types/web/scrapers/nuget.d.ts +5 -0
  767. package/dist/types/web/scrapers/nvd.d.ts +5 -0
  768. package/dist/types/web/scrapers/ollama.d.ts +2 -0
  769. package/dist/types/web/scrapers/open-vsx.d.ts +5 -0
  770. package/dist/types/web/scrapers/opencorporates.d.ts +5 -0
  771. package/dist/types/web/scrapers/openlibrary.d.ts +5 -0
  772. package/dist/types/web/scrapers/orcid.d.ts +5 -0
  773. package/dist/types/web/scrapers/osv.d.ts +5 -0
  774. package/dist/types/web/scrapers/packagist.d.ts +5 -0
  775. package/dist/types/web/scrapers/pub-dev.d.ts +5 -0
  776. package/dist/types/web/scrapers/pubmed.d.ts +5 -0
  777. package/dist/types/web/scrapers/pypi.d.ts +5 -0
  778. package/dist/types/web/scrapers/rawg.d.ts +2 -0
  779. package/dist/types/web/scrapers/readthedocs.d.ts +2 -0
  780. package/dist/types/web/scrapers/reddit.d.ts +5 -0
  781. package/dist/types/web/scrapers/repology.d.ts +5 -0
  782. package/dist/types/web/scrapers/rfc.d.ts +5 -0
  783. package/dist/types/web/scrapers/rubygems.d.ts +5 -0
  784. package/dist/types/web/scrapers/searchcode.d.ts +2 -0
  785. package/dist/types/web/scrapers/sec-edgar.d.ts +5 -0
  786. package/dist/types/web/scrapers/semantic-scholar.d.ts +2 -0
  787. package/dist/types/web/scrapers/snapcraft.d.ts +2 -0
  788. package/dist/types/web/scrapers/sourcegraph.d.ts +2 -0
  789. package/dist/types/web/scrapers/spdx.d.ts +5 -0
  790. package/dist/types/web/scrapers/spotify.d.ts +8 -0
  791. package/dist/types/web/scrapers/stackoverflow.d.ts +6 -0
  792. package/dist/types/web/scrapers/terraform.d.ts +5 -0
  793. package/dist/types/web/scrapers/tldr.d.ts +7 -0
  794. package/dist/types/web/scrapers/twitter.d.ts +5 -0
  795. package/dist/types/web/scrapers/types.d.ts +78 -0
  796. package/dist/types/web/scrapers/utils.d.ts +26 -0
  797. package/dist/types/web/scrapers/vimeo.d.ts +5 -0
  798. package/dist/types/web/scrapers/vscode-marketplace.d.ts +5 -0
  799. package/dist/types/web/scrapers/w3c.d.ts +2 -0
  800. package/dist/types/web/scrapers/wikidata.d.ts +5 -0
  801. package/dist/types/web/scrapers/wikipedia.d.ts +5 -0
  802. package/dist/types/web/scrapers/youtube.d.ts +5 -0
  803. package/dist/types/web/search/index.d.ts +85 -0
  804. package/dist/types/web/search/provider.d.ts +21 -0
  805. package/dist/types/web/search/providers/anthropic.d.ts +32 -0
  806. package/dist/types/web/search/providers/base.d.ts +81 -0
  807. package/dist/types/web/search/providers/brave.d.ts +27 -0
  808. package/dist/types/web/search/providers/codex.d.ts +35 -0
  809. package/dist/types/web/search/providers/exa.d.ts +67 -0
  810. package/dist/types/web/search/providers/gemini.d.ts +57 -0
  811. package/dist/types/web/search/providers/jina.d.ts +26 -0
  812. package/dist/types/web/search/providers/kagi.d.ts +25 -0
  813. package/dist/types/web/search/providers/kimi.d.ts +27 -0
  814. package/dist/types/web/search/providers/parallel.d.ts +15 -0
  815. package/dist/types/web/search/providers/perplexity.d.ts +38 -0
  816. package/dist/types/web/search/providers/searxng.d.ts +44 -0
  817. package/dist/types/web/search/providers/synthetic.d.ts +21 -0
  818. package/dist/types/web/search/providers/tavily.d.ts +29 -0
  819. package/dist/types/web/search/providers/utils.d.ts +52 -0
  820. package/dist/types/web/search/providers/zai.d.ts +28 -0
  821. package/dist/types/web/search/render.d.ts +34 -0
  822. package/dist/types/web/search/types.d.ts +409 -0
  823. package/dist/types/web/search/utils.d.ts +4 -0
  824. package/dist/types/workspace-tree.d.ts +42 -0
  825. package/examples/README.md +21 -0
  826. package/examples/custom-tools/README.md +104 -0
  827. package/examples/custom-tools/hello/index.ts +20 -0
  828. package/examples/extensions/README.md +142 -0
  829. package/examples/extensions/api-demo.ts +79 -0
  830. package/examples/extensions/chalk-logger.ts +25 -0
  831. package/examples/extensions/hello.ts +31 -0
  832. package/examples/extensions/pirate.ts +43 -0
  833. package/examples/extensions/plan-mode.ts +549 -0
  834. package/examples/extensions/reload-runtime.ts +38 -0
  835. package/examples/extensions/thinking-note.ts +13 -0
  836. package/examples/extensions/tools.ts +144 -0
  837. package/examples/extensions/with-deps/index.ts +36 -0
  838. package/examples/extensions/with-deps/package-lock.json +31 -0
  839. package/examples/extensions/with-deps/package.json +16 -0
  840. package/examples/hooks/README.md +56 -0
  841. package/examples/hooks/auto-commit-on-exit.ts +48 -0
  842. package/examples/hooks/confirm-destructive.ts +58 -0
  843. package/examples/hooks/custom-compaction.ts +116 -0
  844. package/examples/hooks/dirty-repo-guard.ts +51 -0
  845. package/examples/hooks/file-trigger.ts +40 -0
  846. package/examples/hooks/git-checkpoint.ts +52 -0
  847. package/examples/hooks/handoff.ts +150 -0
  848. package/examples/hooks/permission-gate.ts +33 -0
  849. package/examples/hooks/protected-paths.ts +29 -0
  850. package/examples/hooks/qna.ts +119 -0
  851. package/examples/hooks/status-line.ts +39 -0
  852. package/examples/sdk/01-minimal.ts +21 -0
  853. package/examples/sdk/02-custom-model.ts +50 -0
  854. package/examples/sdk/03-custom-prompt.ts +46 -0
  855. package/examples/sdk/04-skills.ts +43 -0
  856. package/examples/sdk/06-extensions.ts +82 -0
  857. package/examples/sdk/06-hooks.ts +61 -0
  858. package/examples/sdk/07-context-files.ts +35 -0
  859. package/examples/sdk/08-prompt-templates.ts +36 -0
  860. package/examples/sdk/08-slash-commands.ts +41 -0
  861. package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
  862. package/examples/sdk/11-sessions.ts +47 -0
  863. package/examples/sdk/12-redis-sessions.ts +54 -0
  864. package/examples/sdk/13-sql-sessions.ts +61 -0
  865. package/examples/sdk/README.md +172 -0
  866. package/package.json +548 -0
  867. package/scripts/build-binary.ts +105 -0
  868. package/scripts/format-prompts.ts +68 -0
  869. package/scripts/generate-docs-index.ts +40 -0
  870. package/scripts/generate-template.ts +33 -0
  871. package/src/async/index.ts +2 -0
  872. package/src/async/job-manager.ts +571 -0
  873. package/src/async/support.ts +5 -0
  874. package/src/auto-thinking/classifier.ts +180 -0
  875. package/src/autoresearch/command-resume.md +14 -0
  876. package/src/autoresearch/dashboard.ts +436 -0
  877. package/src/autoresearch/git.ts +319 -0
  878. package/src/autoresearch/helpers.ts +218 -0
  879. package/src/autoresearch/index.ts +536 -0
  880. package/src/autoresearch/prompt-setup.md +43 -0
  881. package/src/autoresearch/prompt.md +103 -0
  882. package/src/autoresearch/resume-message.md +10 -0
  883. package/src/autoresearch/state.ts +273 -0
  884. package/src/autoresearch/storage.ts +699 -0
  885. package/src/autoresearch/tools/init-experiment.ts +272 -0
  886. package/src/autoresearch/tools/log-experiment.ts +524 -0
  887. package/src/autoresearch/tools/run-experiment.ts +407 -0
  888. package/src/autoresearch/tools/update-notes.ts +109 -0
  889. package/src/autoresearch/types.ts +168 -0
  890. package/src/bun-imports.d.ts +28 -0
  891. package/src/capability/context-file.ts +58 -0
  892. package/src/capability/extension-module.ts +34 -0
  893. package/src/capability/extension.ts +47 -0
  894. package/src/capability/fs.ts +107 -0
  895. package/src/capability/hook.ts +40 -0
  896. package/src/capability/index.ts +441 -0
  897. package/src/capability/instruction.ts +37 -0
  898. package/src/capability/mcp.ts +74 -0
  899. package/src/capability/prompt.ts +35 -0
  900. package/src/capability/rule-buckets.ts +64 -0
  901. package/src/capability/rule.ts +252 -0
  902. package/src/capability/settings.ts +34 -0
  903. package/src/capability/skill.ts +63 -0
  904. package/src/capability/slash-command.ts +40 -0
  905. package/src/capability/ssh.ts +41 -0
  906. package/src/capability/system-prompt.ts +34 -0
  907. package/src/capability/tool.ts +38 -0
  908. package/src/capability/types.ts +172 -0
  909. package/src/cli/agents-cli.ts +138 -0
  910. package/src/cli/args.ts +335 -0
  911. package/src/cli/auth-broker-cli.ts +898 -0
  912. package/src/cli/auth-gateway-cli.ts +612 -0
  913. package/src/cli/classify-install-target.ts +76 -0
  914. package/src/cli/claude-trace-cli.ts +813 -0
  915. package/src/cli/commands/init-xdg.ts +27 -0
  916. package/src/cli/completion-gen.ts +550 -0
  917. package/src/cli/config-cli.ts +418 -0
  918. package/src/cli/dry-balance-cli.ts +823 -0
  919. package/src/cli/extension-flags.ts +48 -0
  920. package/src/cli/file-processor.ts +133 -0
  921. package/src/cli/gateway-cli.ts +664 -0
  922. package/src/cli/grep-cli.ts +160 -0
  923. package/src/cli/grievances-cli.ts +260 -0
  924. package/src/cli/initial-message.ts +58 -0
  925. package/src/cli/list-models.ts +194 -0
  926. package/src/cli/plugin-cli.ts +996 -0
  927. package/src/cli/read-cli.ts +57 -0
  928. package/src/cli/session-picker.ts +79 -0
  929. package/src/cli/setup-cli.ts +231 -0
  930. package/src/cli/shell-cli.ts +176 -0
  931. package/src/cli/ssh-cli.ts +181 -0
  932. package/src/cli/stats-cli.ts +238 -0
  933. package/src/cli/tiny-models-cli.ts +127 -0
  934. package/src/cli/update-cli.ts +739 -0
  935. package/src/cli/web-search-cli.ts +132 -0
  936. package/src/cli/worktree-cli.ts +291 -0
  937. package/src/cli-commands.ts +49 -0
  938. package/src/cli.ts +123 -0
  939. package/src/commands/acp.ts +24 -0
  940. package/src/commands/agents.ts +57 -0
  941. package/src/commands/auth-broker.ts +99 -0
  942. package/src/commands/auth-gateway.ts +69 -0
  943. package/src/commands/commit.ts +46 -0
  944. package/src/commands/complete.ts +66 -0
  945. package/src/commands/completions.ts +60 -0
  946. package/src/commands/config.ts +51 -0
  947. package/src/commands/dry-balance.ts +43 -0
  948. package/src/commands/gateway.ts +103 -0
  949. package/src/commands/grep.ts +48 -0
  950. package/src/commands/grievances.ts +51 -0
  951. package/src/commands/install.ts +107 -0
  952. package/src/commands/launch.ts +162 -0
  953. package/src/commands/plugin.ts +78 -0
  954. package/src/commands/read.ts +35 -0
  955. package/src/commands/setup.ts +67 -0
  956. package/src/commands/shell.ts +29 -0
  957. package/src/commands/ssh.ts +60 -0
  958. package/src/commands/stats.ts +29 -0
  959. package/src/commands/tiny-models.ts +36 -0
  960. package/src/commands/update.ts +21 -0
  961. package/src/commands/web-search.ts +42 -0
  962. package/src/commands/worktree.ts +56 -0
  963. package/src/commit/agentic/agent.ts +316 -0
  964. package/src/commit/agentic/fallback.ts +96 -0
  965. package/src/commit/agentic/index.ts +355 -0
  966. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  967. package/src/commit/agentic/prompts/session-user.md +25 -0
  968. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  969. package/src/commit/agentic/prompts/system.md +38 -0
  970. package/src/commit/agentic/state.ts +60 -0
  971. package/src/commit/agentic/tools/analyze-file.ts +127 -0
  972. package/src/commit/agentic/tools/git-file-diff.ts +191 -0
  973. package/src/commit/agentic/tools/git-hunk.ts +50 -0
  974. package/src/commit/agentic/tools/git-overview.ts +81 -0
  975. package/src/commit/agentic/tools/index.ts +54 -0
  976. package/src/commit/agentic/tools/propose-changelog.ts +144 -0
  977. package/src/commit/agentic/tools/propose-commit.ts +109 -0
  978. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  979. package/src/commit/agentic/tools/schemas.ts +23 -0
  980. package/src/commit/agentic/tools/split-commit.ts +238 -0
  981. package/src/commit/agentic/topo-sort.ts +44 -0
  982. package/src/commit/agentic/trivial.ts +51 -0
  983. package/src/commit/agentic/validation.ts +183 -0
  984. package/src/commit/analysis/conventional.ts +64 -0
  985. package/src/commit/analysis/index.ts +4 -0
  986. package/src/commit/analysis/scope.ts +242 -0
  987. package/src/commit/analysis/summary.ts +105 -0
  988. package/src/commit/analysis/validation.ts +66 -0
  989. package/src/commit/changelog/detect.ts +40 -0
  990. package/src/commit/changelog/generate.ts +97 -0
  991. package/src/commit/changelog/index.ts +234 -0
  992. package/src/commit/changelog/parse.ts +44 -0
  993. package/src/commit/cli.ts +85 -0
  994. package/src/commit/git/diff.ts +148 -0
  995. package/src/commit/index.ts +5 -0
  996. package/src/commit/map-reduce/index.ts +69 -0
  997. package/src/commit/map-reduce/map-phase.ts +193 -0
  998. package/src/commit/map-reduce/reduce-phase.ts +49 -0
  999. package/src/commit/map-reduce/utils.ts +9 -0
  1000. package/src/commit/message.ts +11 -0
  1001. package/src/commit/model-selection.ts +66 -0
  1002. package/src/commit/pipeline.ts +243 -0
  1003. package/src/commit/prompts/analysis-system.md +148 -0
  1004. package/src/commit/prompts/analysis-user.md +38 -0
  1005. package/src/commit/prompts/changelog-system.md +50 -0
  1006. package/src/commit/prompts/changelog-user.md +18 -0
  1007. package/src/commit/prompts/file-observer-system.md +24 -0
  1008. package/src/commit/prompts/file-observer-user.md +8 -0
  1009. package/src/commit/prompts/reduce-system.md +50 -0
  1010. package/src/commit/prompts/reduce-user.md +17 -0
  1011. package/src/commit/prompts/summary-retry.md +3 -0
  1012. package/src/commit/prompts/summary-system.md +38 -0
  1013. package/src/commit/prompts/summary-user.md +13 -0
  1014. package/src/commit/prompts/types-description.md +2 -0
  1015. package/src/commit/shared-llm.ts +77 -0
  1016. package/src/commit/types.ts +118 -0
  1017. package/src/commit/utils/exclusions.ts +42 -0
  1018. package/src/commit/utils.ts +58 -0
  1019. package/src/config/append-only-context-mode.ts +37 -0
  1020. package/src/config/config-file.ts +317 -0
  1021. package/src/config/file-lock.ts +164 -0
  1022. package/src/config/keybindings.ts +623 -0
  1023. package/src/config/mcp-schema.json +230 -0
  1024. package/src/config/model-equivalence.ts +852 -0
  1025. package/src/config/model-id-affixes.ts +64 -0
  1026. package/src/config/model-registry.ts +2650 -0
  1027. package/src/config/model-resolver.ts +1402 -0
  1028. package/src/config/models-config-schema.ts +177 -0
  1029. package/src/config/prompt-templates.ts +185 -0
  1030. package/src/config/resolve-config-value.ts +94 -0
  1031. package/src/config/settings-schema.ts +3752 -0
  1032. package/src/config/settings.ts +1017 -0
  1033. package/src/config.ts +242 -0
  1034. package/src/cursor.ts +340 -0
  1035. package/src/dap/client.ts +675 -0
  1036. package/src/dap/config.ts +150 -0
  1037. package/src/dap/defaults.json +211 -0
  1038. package/src/dap/index.ts +4 -0
  1039. package/src/dap/session.ts +1339 -0
  1040. package/src/dap/types.ts +600 -0
  1041. package/src/debug/index.ts +525 -0
  1042. package/src/debug/log-formatting.ts +58 -0
  1043. package/src/debug/log-viewer.ts +908 -0
  1044. package/src/debug/profiler.ts +162 -0
  1045. package/src/debug/protocol-probe.ts +267 -0
  1046. package/src/debug/raw-sse-buffer.ts +270 -0
  1047. package/src/debug/raw-sse.ts +292 -0
  1048. package/src/debug/report-bundle.ts +365 -0
  1049. package/src/debug/system-info.ts +111 -0
  1050. package/src/debug/terminal-info.ts +127 -0
  1051. package/src/discovery/agents-md.ts +63 -0
  1052. package/src/discovery/agents.ts +236 -0
  1053. package/src/discovery/builtin-defaults.ts +39 -0
  1054. package/src/discovery/builtin-rules/index.ts +50 -0
  1055. package/src/discovery/builtin-rules/rs-box-leak.md +48 -0
  1056. package/src/discovery/builtin-rules/rs-future-prelude.md +23 -0
  1057. package/src/discovery/builtin-rules/rs-lazylock.md +51 -0
  1058. package/src/discovery/builtin-rules/rs-match-ergonomics.md +67 -0
  1059. package/src/discovery/builtin-rules/rs-parking-lot.md +44 -0
  1060. package/src/discovery/builtin-rules/rs-result-type.md +19 -0
  1061. package/src/discovery/builtin-rules/ts-bare-catch.md +38 -0
  1062. package/src/discovery/builtin-rules/ts-import-type.md +42 -0
  1063. package/src/discovery/builtin-rules/ts-no-any.md +56 -0
  1064. package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +44 -0
  1065. package/src/discovery/builtin-rules/ts-no-dynamic-import.md +39 -0
  1066. package/src/discovery/builtin-rules/ts-no-return-type.md +45 -0
  1067. package/src/discovery/builtin-rules/ts-no-tiny-functions.md +51 -0
  1068. package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +65 -0
  1069. package/src/discovery/builtin-rules/ts-set-map.md +28 -0
  1070. package/src/discovery/builtin.ts +906 -0
  1071. package/src/discovery/claude-plugins.ts +386 -0
  1072. package/src/discovery/claude.ts +584 -0
  1073. package/src/discovery/cline.ts +83 -0
  1074. package/src/discovery/codex.ts +522 -0
  1075. package/src/discovery/context-files.ts +49 -0
  1076. package/src/discovery/cursor.ts +220 -0
  1077. package/src/discovery/gemini.ts +383 -0
  1078. package/src/discovery/github.ts +154 -0
  1079. package/src/discovery/helpers.ts +1015 -0
  1080. package/src/discovery/index.ts +81 -0
  1081. package/src/discovery/mcp-json.ts +171 -0
  1082. package/src/discovery/opencode.ts +398 -0
  1083. package/src/discovery/plugin-dir-roots.ts +28 -0
  1084. package/src/discovery/prometheus-extension-roots.ts +190 -0
  1085. package/src/discovery/prometheus-plugins.ts +385 -0
  1086. package/src/discovery/ssh.ts +153 -0
  1087. package/src/discovery/substitute-plugin-root.ts +29 -0
  1088. package/src/discovery/vscode.ts +105 -0
  1089. package/src/discovery/windsurf.ts +147 -0
  1090. package/src/edit/apply-patch/index.ts +87 -0
  1091. package/src/edit/apply-patch/parser.ts +174 -0
  1092. package/src/edit/diff.ts +812 -0
  1093. package/src/edit/file-snapshot-store.ts +59 -0
  1094. package/src/edit/hashline/block-resolver.ts +14 -0
  1095. package/src/edit/hashline/diff.ts +169 -0
  1096. package/src/edit/hashline/execute.ts +187 -0
  1097. package/src/edit/hashline/filesystem.ts +129 -0
  1098. package/src/edit/hashline/index.ts +5 -0
  1099. package/src/edit/hashline/params.ts +18 -0
  1100. package/src/edit/index.ts +542 -0
  1101. package/src/edit/modes/apply-patch.lark +19 -0
  1102. package/src/edit/modes/apply-patch.ts +53 -0
  1103. package/src/edit/modes/patch.ts +1835 -0
  1104. package/src/edit/modes/replace.ts +1103 -0
  1105. package/src/edit/normalize.ts +345 -0
  1106. package/src/edit/notebook.ts +222 -0
  1107. package/src/edit/read-file.ts +25 -0
  1108. package/src/edit/renderer.ts +660 -0
  1109. package/src/edit/streaming.ts +517 -0
  1110. package/src/eval/__tests__/agent-bridge.test.ts +650 -0
  1111. package/src/eval/__tests__/bridge-timeout.test.ts +64 -0
  1112. package/src/eval/__tests__/budget-bridge.test.ts +69 -0
  1113. package/src/eval/__tests__/idle-timeout.test.ts +80 -0
  1114. package/src/eval/__tests__/kernel-spawn.test.ts +103 -0
  1115. package/src/eval/__tests__/llm-bridge.test.ts +327 -0
  1116. package/src/eval/__tests__/shared-executors.test.ts +609 -0
  1117. package/src/eval/agent-bridge.ts +303 -0
  1118. package/src/eval/backend.ts +58 -0
  1119. package/src/eval/bridge-timeout.ts +44 -0
  1120. package/src/eval/budget-bridge.ts +48 -0
  1121. package/src/eval/concurrency-bridge.ts +34 -0
  1122. package/src/eval/idle-timeout.ts +98 -0
  1123. package/src/eval/index.ts +4 -0
  1124. package/src/eval/js/context-manager.ts +425 -0
  1125. package/src/eval/js/executor.ts +166 -0
  1126. package/src/eval/js/index.ts +47 -0
  1127. package/src/eval/js/shared/helpers.ts +237 -0
  1128. package/src/eval/js/shared/indirect-eval.ts +30 -0
  1129. package/src/eval/js/shared/local-module-loader.ts +342 -0
  1130. package/src/eval/js/shared/prelude.ts +2 -0
  1131. package/src/eval/js/shared/prelude.txt +169 -0
  1132. package/src/eval/js/shared/rewrite-imports.ts +508 -0
  1133. package/src/eval/js/shared/runtime.ts +344 -0
  1134. package/src/eval/js/shared/types.ts +18 -0
  1135. package/src/eval/js/tool-bridge.ts +162 -0
  1136. package/src/eval/js/worker-core.ts +131 -0
  1137. package/src/eval/js/worker-entry.ts +24 -0
  1138. package/src/eval/js/worker-protocol.ts +41 -0
  1139. package/src/eval/llm-bridge.ts +186 -0
  1140. package/src/eval/py/display.ts +71 -0
  1141. package/src/eval/py/executor.ts +698 -0
  1142. package/src/eval/py/index.ts +59 -0
  1143. package/src/eval/py/kernel.ts +709 -0
  1144. package/src/eval/py/prelude.py +620 -0
  1145. package/src/eval/py/prelude.ts +3 -0
  1146. package/src/eval/py/runner.py +1028 -0
  1147. package/src/eval/py/runtime.ts +239 -0
  1148. package/src/eval/py/spawn-options.ts +126 -0
  1149. package/src/eval/py/tool-bridge.ts +182 -0
  1150. package/src/eval/session-id.ts +8 -0
  1151. package/src/eval/types.ts +48 -0
  1152. package/src/exa/factory.ts +60 -0
  1153. package/src/exa/index.ts +27 -0
  1154. package/src/exa/mcp-client.ts +370 -0
  1155. package/src/exa/render.ts +244 -0
  1156. package/src/exa/researcher.ts +36 -0
  1157. package/src/exa/search.ts +47 -0
  1158. package/src/exa/types.ts +166 -0
  1159. package/src/exa/websets.ts +248 -0
  1160. package/src/exec/bash-executor.ts +338 -0
  1161. package/src/exec/exec.ts +53 -0
  1162. package/src/exec/idle-timeout-watchdog.ts +126 -0
  1163. package/src/exec/non-interactive-env.ts +48 -0
  1164. package/src/export/custom-share.ts +65 -0
  1165. package/src/export/html/index.ts +164 -0
  1166. package/src/export/html/template.css +1051 -0
  1167. package/src/export/html/template.generated.ts +2 -0
  1168. package/src/export/html/template.html +46 -0
  1169. package/src/export/html/template.js +2244 -0
  1170. package/src/export/html/template.macro.ts +25 -0
  1171. package/src/export/html/vendor/highlight.min.js +1213 -0
  1172. package/src/export/html/vendor/marked.min.js +6 -0
  1173. package/src/export/ttsr.ts +462 -0
  1174. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
  1175. package/src/extensibility/custom-commands/bundled/review/index.ts +489 -0
  1176. package/src/extensibility/custom-commands/index.ts +2 -0
  1177. package/src/extensibility/custom-commands/loader.ts +238 -0
  1178. package/src/extensibility/custom-commands/types.ts +113 -0
  1179. package/src/extensibility/custom-tools/index.ts +7 -0
  1180. package/src/extensibility/custom-tools/loader.ts +240 -0
  1181. package/src/extensibility/custom-tools/types.ts +268 -0
  1182. package/src/extensibility/custom-tools/wrapper.ts +47 -0
  1183. package/src/extensibility/extensions/compact-handler.ts +40 -0
  1184. package/src/extensibility/extensions/get-commands-handler.ts +77 -0
  1185. package/src/extensibility/extensions/index.ts +15 -0
  1186. package/src/extensibility/extensions/loader.ts +552 -0
  1187. package/src/extensibility/extensions/runner.ts +917 -0
  1188. package/src/extensibility/extensions/types.ts +1303 -0
  1189. package/src/extensibility/extensions/wrapper.ts +223 -0
  1190. package/src/extensibility/hooks/index.ts +5 -0
  1191. package/src/extensibility/hooks/loader.ts +257 -0
  1192. package/src/extensibility/hooks/runner.ts +425 -0
  1193. package/src/extensibility/hooks/tool-wrapper.ts +107 -0
  1194. package/src/extensibility/hooks/types.ts +606 -0
  1195. package/src/extensibility/legacy-pi-ai-shim.ts +24 -0
  1196. package/src/extensibility/legacy-pi-coding-agent-shim.ts +15 -0
  1197. package/src/extensibility/plugins/doctor.ts +66 -0
  1198. package/src/extensibility/plugins/git-url.ts +367 -0
  1199. package/src/extensibility/plugins/index.ts +9 -0
  1200. package/src/extensibility/plugins/installer.ts +192 -0
  1201. package/src/extensibility/plugins/legacy-pi-compat.ts +661 -0
  1202. package/src/extensibility/plugins/loader.ts +313 -0
  1203. package/src/extensibility/plugins/manager.ts +827 -0
  1204. package/src/extensibility/plugins/marketplace/cache.ts +136 -0
  1205. package/src/extensibility/plugins/marketplace/fetcher.ts +317 -0
  1206. package/src/extensibility/plugins/marketplace/index.ts +6 -0
  1207. package/src/extensibility/plugins/marketplace/manager.ts +770 -0
  1208. package/src/extensibility/plugins/marketplace/registry.ts +196 -0
  1209. package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
  1210. package/src/extensibility/plugins/marketplace/types.ts +191 -0
  1211. package/src/extensibility/plugins/parser.ts +105 -0
  1212. package/src/extensibility/plugins/types.ts +194 -0
  1213. package/src/extensibility/shared-events.ts +343 -0
  1214. package/src/extensibility/skills.ts +312 -0
  1215. package/src/extensibility/slash-commands.ts +227 -0
  1216. package/src/extensibility/tool-proxy.ts +25 -0
  1217. package/src/extensibility/typebox.ts +418 -0
  1218. package/src/extensibility/utils.ts +44 -0
  1219. package/src/gateway/adapters/telegram/access.ts +53 -0
  1220. package/src/gateway/adapters/telegram/commands.ts +206 -0
  1221. package/src/gateway/adapters/telegram/expressions.ts +678 -0
  1222. package/src/gateway/adapters/telegram/media.ts +831 -0
  1223. package/src/gateway/adapters/telegram/native-command-policy.ts +83 -0
  1224. package/src/gateway/adapters/telegram/native-commands.ts +197 -0
  1225. package/src/gateway/adapters/telegram/normalize.ts +593 -0
  1226. package/src/gateway/adapters/telegram/send-message.ts +1465 -0
  1227. package/src/gateway/adapters/telegram/service.ts +577 -0
  1228. package/src/gateway/adapters/telegram/setup-api.ts +196 -0
  1229. package/src/gateway/adapters/telegram/setup-config.ts +72 -0
  1230. package/src/gateway/adapters/telegram/types.ts +206 -0
  1231. package/src/gateway/adapters/telegram/webhook.ts +364 -0
  1232. package/src/gateway/commands.ts +196 -0
  1233. package/src/gateway/context.ts +276 -0
  1234. package/src/gateway/native-slash-policy.ts +19 -0
  1235. package/src/gateway/prometheus-dispatch.ts +362 -0
  1236. package/src/gateway/router.ts +123 -0
  1237. package/src/gateway/session-key.ts +55 -0
  1238. package/src/gateway/types.ts +119 -0
  1239. package/src/goals/index.ts +3 -0
  1240. package/src/goals/runtime.ts +528 -0
  1241. package/src/goals/state.ts +37 -0
  1242. package/src/goals/tools/goal-tool.ts +241 -0
  1243. package/src/hindsight/backend.ts +354 -0
  1244. package/src/hindsight/bank.ts +141 -0
  1245. package/src/hindsight/client.ts +598 -0
  1246. package/src/hindsight/config.ts +175 -0
  1247. package/src/hindsight/content.ts +210 -0
  1248. package/src/hindsight/index.ts +8 -0
  1249. package/src/hindsight/mental-models.ts +382 -0
  1250. package/src/hindsight/seeds.json +32 -0
  1251. package/src/hindsight/state.ts +483 -0
  1252. package/src/hindsight/transcript.ts +71 -0
  1253. package/src/index.ts +59 -0
  1254. package/src/internal-urls/agent-protocol.ts +146 -0
  1255. package/src/internal-urls/artifact-protocol.ts +98 -0
  1256. package/src/internal-urls/docs-index.generated.ts +107 -0
  1257. package/src/internal-urls/index.ts +24 -0
  1258. package/src/internal-urls/issue-pr-protocol.ts +577 -0
  1259. package/src/internal-urls/json-query.ts +126 -0
  1260. package/src/internal-urls/local-protocol.ts +274 -0
  1261. package/src/internal-urls/mcp-protocol.ts +151 -0
  1262. package/src/internal-urls/memory-protocol.ts +196 -0
  1263. package/src/internal-urls/parse.ts +72 -0
  1264. package/src/internal-urls/prometheus-protocol.ts +93 -0
  1265. package/src/internal-urls/registry-helpers.ts +25 -0
  1266. package/src/internal-urls/router.ts +103 -0
  1267. package/src/internal-urls/rule-protocol.ts +45 -0
  1268. package/src/internal-urls/skill-protocol.ts +96 -0
  1269. package/src/internal-urls/types.ts +152 -0
  1270. package/src/internal-urls/vault-protocol.ts +936 -0
  1271. package/src/lib/xai-http.ts +124 -0
  1272. package/src/lsp/client.ts +1052 -0
  1273. package/src/lsp/clients/biome-client.ts +202 -0
  1274. package/src/lsp/clients/index.ts +50 -0
  1275. package/src/lsp/clients/lsp-linter-client.ts +93 -0
  1276. package/src/lsp/clients/swiftlint-client.ts +120 -0
  1277. package/src/lsp/config.ts +492 -0
  1278. package/src/lsp/defaults.json +493 -0
  1279. package/src/lsp/diagnostics-ledger.ts +51 -0
  1280. package/src/lsp/edits.ts +219 -0
  1281. package/src/lsp/index.ts +2340 -0
  1282. package/src/lsp/lspmux.ts +233 -0
  1283. package/src/lsp/render.ts +692 -0
  1284. package/src/lsp/startup-events.ts +13 -0
  1285. package/src/lsp/types.ts +443 -0
  1286. package/src/lsp/utils.ts +699 -0
  1287. package/src/main.ts +1167 -0
  1288. package/src/mcp/client.ts +484 -0
  1289. package/src/mcp/config-writer.ts +225 -0
  1290. package/src/mcp/config.ts +365 -0
  1291. package/src/mcp/index.ts +29 -0
  1292. package/src/mcp/json-rpc.ts +92 -0
  1293. package/src/mcp/loader.ts +124 -0
  1294. package/src/mcp/manager.ts +1274 -0
  1295. package/src/mcp/oauth-discovery.ts +437 -0
  1296. package/src/mcp/oauth-flow.ts +435 -0
  1297. package/src/mcp/render.ts +126 -0
  1298. package/src/mcp/smithery-auth.ts +104 -0
  1299. package/src/mcp/smithery-connect.ts +145 -0
  1300. package/src/mcp/smithery-registry.ts +477 -0
  1301. package/src/mcp/timeout.ts +59 -0
  1302. package/src/mcp/tool-bridge.ts +424 -0
  1303. package/src/mcp/tool-cache.ts +117 -0
  1304. package/src/mcp/transports/http.ts +519 -0
  1305. package/src/mcp/transports/index.ts +6 -0
  1306. package/src/mcp/transports/stdio.ts +386 -0
  1307. package/src/mcp/types.ts +423 -0
  1308. package/src/memories/index.ts +2227 -0
  1309. package/src/memories/storage.ts +617 -0
  1310. package/src/memory-backend/index.ts +5 -0
  1311. package/src/memory-backend/local-backend.ts +30 -0
  1312. package/src/memory-backend/off-backend.ts +16 -0
  1313. package/src/memory-backend/resolve.ts +27 -0
  1314. package/src/memory-backend/types.ts +86 -0
  1315. package/src/mnemopi/backend.ts +374 -0
  1316. package/src/mnemopi/config.ts +160 -0
  1317. package/src/mnemopi/index.ts +3 -0
  1318. package/src/mnemopi/state.ts +549 -0
  1319. package/src/modes/acp/acp-agent.ts +2292 -0
  1320. package/src/modes/acp/acp-client-bridge.ts +154 -0
  1321. package/src/modes/acp/acp-event-mapper.ts +929 -0
  1322. package/src/modes/acp/acp-mode.ts +23 -0
  1323. package/src/modes/acp/index.ts +2 -0
  1324. package/src/modes/acp/terminal-auth.ts +37 -0
  1325. package/src/modes/components/agent-dashboard.ts +1201 -0
  1326. package/src/modes/components/assistant-message.ts +309 -0
  1327. package/src/modes/components/bash-execution.ts +220 -0
  1328. package/src/modes/components/bordered-loader.ts +41 -0
  1329. package/src/modes/components/branch-summary-message.ts +45 -0
  1330. package/src/modes/components/btw-panel.ts +104 -0
  1331. package/src/modes/components/compaction-summary-message.ts +51 -0
  1332. package/src/modes/components/copy-selector.ts +249 -0
  1333. package/src/modes/components/countdown-timer.ts +75 -0
  1334. package/src/modes/components/custom-editor.ts +267 -0
  1335. package/src/modes/components/custom-message.ts +65 -0
  1336. package/src/modes/components/diff.ts +266 -0
  1337. package/src/modes/components/dynamic-border.ts +25 -0
  1338. package/src/modes/components/error-banner.ts +33 -0
  1339. package/src/modes/components/eval-execution.ts +158 -0
  1340. package/src/modes/components/execution-shared.ts +102 -0
  1341. package/src/modes/components/extensions/extension-dashboard.ts +396 -0
  1342. package/src/modes/components/extensions/extension-list.ts +502 -0
  1343. package/src/modes/components/extensions/index.ts +9 -0
  1344. package/src/modes/components/extensions/inspector-panel.ts +317 -0
  1345. package/src/modes/components/extensions/state-manager.ts +632 -0
  1346. package/src/modes/components/extensions/types.ts +186 -0
  1347. package/src/modes/components/footer.ts +272 -0
  1348. package/src/modes/components/history-search.ts +280 -0
  1349. package/src/modes/components/hook-editor.ts +159 -0
  1350. package/src/modes/components/hook-input.ts +79 -0
  1351. package/src/modes/components/hook-message.ts +68 -0
  1352. package/src/modes/components/hook-selector.ts +660 -0
  1353. package/src/modes/components/index.ts +38 -0
  1354. package/src/modes/components/keybinding-hints.ts +65 -0
  1355. package/src/modes/components/login-dialog.ts +164 -0
  1356. package/src/modes/components/mcp-add-wizard.ts +1340 -0
  1357. package/src/modes/components/message-frame.ts +88 -0
  1358. package/src/modes/components/model-selector.ts +1213 -0
  1359. package/src/modes/components/oauth-selector.ts +342 -0
  1360. package/src/modes/components/omfg-panel.ts +141 -0
  1361. package/src/modes/components/plugin-selector.ts +95 -0
  1362. package/src/modes/components/plugin-settings.ts +728 -0
  1363. package/src/modes/components/queue-mode-selector.ts +56 -0
  1364. package/src/modes/components/read-tool-group.ts +267 -0
  1365. package/src/modes/components/segment-track.ts +52 -0
  1366. package/src/modes/components/session-observer-overlay.ts +852 -0
  1367. package/src/modes/components/session-selector.ts +571 -0
  1368. package/src/modes/components/settings-defs.ts +189 -0
  1369. package/src/modes/components/settings-selector.ts +647 -0
  1370. package/src/modes/components/show-images-selector.ts +45 -0
  1371. package/src/modes/components/skill-message.ts +90 -0
  1372. package/src/modes/components/status-line/context-thresholds.ts +79 -0
  1373. package/src/modes/components/status-line/git-utils.ts +42 -0
  1374. package/src/modes/components/status-line/index.ts +4 -0
  1375. package/src/modes/components/status-line/presets.ts +106 -0
  1376. package/src/modes/components/status-line/segments.ts +590 -0
  1377. package/src/modes/components/status-line/separators.ts +55 -0
  1378. package/src/modes/components/status-line/token-rate.ts +66 -0
  1379. package/src/modes/components/status-line/types.ts +93 -0
  1380. package/src/modes/components/status-line.ts +794 -0
  1381. package/src/modes/components/theme-selector.ts +63 -0
  1382. package/src/modes/components/thinking-selector.ts +52 -0
  1383. package/src/modes/components/tiny-title-download-progress.ts +90 -0
  1384. package/src/modes/components/tips.txt +18 -0
  1385. package/src/modes/components/todo-reminder.ts +40 -0
  1386. package/src/modes/components/tool-execution.ts +1017 -0
  1387. package/src/modes/components/transcript-container.ts +181 -0
  1388. package/src/modes/components/tree-selector.ts +978 -0
  1389. package/src/modes/components/ttsr-notification.ts +80 -0
  1390. package/src/modes/components/user-message-selector.ts +227 -0
  1391. package/src/modes/components/user-message.ts +52 -0
  1392. package/src/modes/components/visual-truncate.ts +63 -0
  1393. package/src/modes/components/welcome.ts +435 -0
  1394. package/src/modes/controllers/btw-controller.ts +105 -0
  1395. package/src/modes/controllers/command-controller-shared.ts +108 -0
  1396. package/src/modes/controllers/command-controller.ts +1546 -0
  1397. package/src/modes/controllers/event-controller.ts +926 -0
  1398. package/src/modes/controllers/extension-ui-controller.ts +933 -0
  1399. package/src/modes/controllers/input-controller.ts +947 -0
  1400. package/src/modes/controllers/mcp-command-controller.ts +1938 -0
  1401. package/src/modes/controllers/omfg-controller.ts +283 -0
  1402. package/src/modes/controllers/omfg-rule.ts +647 -0
  1403. package/src/modes/controllers/selector-controller.ts +1117 -0
  1404. package/src/modes/controllers/ssh-command-controller.ts +384 -0
  1405. package/src/modes/controllers/todo-command-controller.ts +485 -0
  1406. package/src/modes/data/emojis.json +1 -0
  1407. package/src/modes/emoji-autocomplete.ts +285 -0
  1408. package/src/modes/gradient-highlight.ts +87 -0
  1409. package/src/modes/image-references.ts +111 -0
  1410. package/src/modes/index.ts +34 -0
  1411. package/src/modes/interactive-mode.ts +3151 -0
  1412. package/src/modes/internal-url-autocomplete.ts +143 -0
  1413. package/src/modes/loop-limit.ts +140 -0
  1414. package/src/modes/magic-keywords.ts +20 -0
  1415. package/src/modes/markdown-prose.ts +247 -0
  1416. package/src/modes/oauth-manual-input.ts +42 -0
  1417. package/src/modes/orchestrate.ts +42 -0
  1418. package/src/modes/print-mode.ts +126 -0
  1419. package/src/modes/prompt-action-autocomplete.ts +260 -0
  1420. package/src/modes/rpc/host-tools.ts +186 -0
  1421. package/src/modes/rpc/host-uris.ts +235 -0
  1422. package/src/modes/rpc/rpc-client.ts +812 -0
  1423. package/src/modes/rpc/rpc-mode.ts +862 -0
  1424. package/src/modes/rpc/rpc-types.ts +378 -0
  1425. package/src/modes/runtime-init.ts +116 -0
  1426. package/src/modes/session-observer-registry.ts +146 -0
  1427. package/src/modes/setup-wizard/index.ts +88 -0
  1428. package/src/modes/setup-wizard/scenes/channels.ts +104 -0
  1429. package/src/modes/setup-wizard/scenes/glyph.ts +96 -0
  1430. package/src/modes/setup-wizard/scenes/outro.ts +35 -0
  1431. package/src/modes/setup-wizard/scenes/providers.ts +70 -0
  1432. package/src/modes/setup-wizard/scenes/sign-in.ts +213 -0
  1433. package/src/modes/setup-wizard/scenes/splash.ts +201 -0
  1434. package/src/modes/setup-wizard/scenes/telegram.ts +695 -0
  1435. package/src/modes/setup-wizard/scenes/theme.ts +299 -0
  1436. package/src/modes/setup-wizard/scenes/types.ts +48 -0
  1437. package/src/modes/setup-wizard/scenes/web-search.ts +128 -0
  1438. package/src/modes/setup-wizard/wizard-overlay.ts +275 -0
  1439. package/src/modes/shared.ts +47 -0
  1440. package/src/modes/theme/dark.json +95 -0
  1441. package/src/modes/theme/defaults/alabaster.json +93 -0
  1442. package/src/modes/theme/defaults/amethyst.json +96 -0
  1443. package/src/modes/theme/defaults/anthracite.json +93 -0
  1444. package/src/modes/theme/defaults/basalt.json +91 -0
  1445. package/src/modes/theme/defaults/birch.json +95 -0
  1446. package/src/modes/theme/defaults/dark-abyss.json +91 -0
  1447. package/src/modes/theme/defaults/dark-arctic.json +104 -0
  1448. package/src/modes/theme/defaults/dark-aurora.json +95 -0
  1449. package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
  1450. package/src/modes/theme/defaults/dark-cavern.json +91 -0
  1451. package/src/modes/theme/defaults/dark-copper.json +95 -0
  1452. package/src/modes/theme/defaults/dark-cosmos.json +90 -0
  1453. package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
  1454. package/src/modes/theme/defaults/dark-dracula.json +98 -0
  1455. package/src/modes/theme/defaults/dark-eclipse.json +91 -0
  1456. package/src/modes/theme/defaults/dark-ember.json +95 -0
  1457. package/src/modes/theme/defaults/dark-equinox.json +90 -0
  1458. package/src/modes/theme/defaults/dark-forest.json +96 -0
  1459. package/src/modes/theme/defaults/dark-github.json +105 -0
  1460. package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
  1461. package/src/modes/theme/defaults/dark-lavender.json +95 -0
  1462. package/src/modes/theme/defaults/dark-lunar.json +89 -0
  1463. package/src/modes/theme/defaults/dark-midnight.json +95 -0
  1464. package/src/modes/theme/defaults/dark-monochrome.json +94 -0
  1465. package/src/modes/theme/defaults/dark-monokai.json +98 -0
  1466. package/src/modes/theme/defaults/dark-nebula.json +90 -0
  1467. package/src/modes/theme/defaults/dark-nord.json +97 -0
  1468. package/src/modes/theme/defaults/dark-ocean.json +101 -0
  1469. package/src/modes/theme/defaults/dark-one.json +100 -0
  1470. package/src/modes/theme/defaults/dark-poimandres.json +142 -0
  1471. package/src/modes/theme/defaults/dark-rainforest.json +91 -0
  1472. package/src/modes/theme/defaults/dark-reef.json +91 -0
  1473. package/src/modes/theme/defaults/dark-retro.json +92 -0
  1474. package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
  1475. package/src/modes/theme/defaults/dark-sakura.json +95 -0
  1476. package/src/modes/theme/defaults/dark-slate.json +95 -0
  1477. package/src/modes/theme/defaults/dark-solarized.json +97 -0
  1478. package/src/modes/theme/defaults/dark-solstice.json +90 -0
  1479. package/src/modes/theme/defaults/dark-starfall.json +91 -0
  1480. package/src/modes/theme/defaults/dark-sunset.json +99 -0
  1481. package/src/modes/theme/defaults/dark-swamp.json +90 -0
  1482. package/src/modes/theme/defaults/dark-synthwave.json +103 -0
  1483. package/src/modes/theme/defaults/dark-taiga.json +91 -0
  1484. package/src/modes/theme/defaults/dark-terminal.json +95 -0
  1485. package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
  1486. package/src/modes/theme/defaults/dark-tundra.json +91 -0
  1487. package/src/modes/theme/defaults/dark-twilight.json +91 -0
  1488. package/src/modes/theme/defaults/dark-volcanic.json +91 -0
  1489. package/src/modes/theme/defaults/graphite.json +92 -0
  1490. package/src/modes/theme/defaults/index.ts +199 -0
  1491. package/src/modes/theme/defaults/light-arctic.json +107 -0
  1492. package/src/modes/theme/defaults/light-aurora-day.json +91 -0
  1493. package/src/modes/theme/defaults/light-canyon.json +91 -0
  1494. package/src/modes/theme/defaults/light-catppuccin.json +106 -0
  1495. package/src/modes/theme/defaults/light-cirrus.json +90 -0
  1496. package/src/modes/theme/defaults/light-coral.json +95 -0
  1497. package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
  1498. package/src/modes/theme/defaults/light-dawn.json +90 -0
  1499. package/src/modes/theme/defaults/light-dunes.json +91 -0
  1500. package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
  1501. package/src/modes/theme/defaults/light-forest.json +100 -0
  1502. package/src/modes/theme/defaults/light-frost.json +95 -0
  1503. package/src/modes/theme/defaults/light-github.json +115 -0
  1504. package/src/modes/theme/defaults/light-glacier.json +91 -0
  1505. package/src/modes/theme/defaults/light-gruvbox.json +108 -0
  1506. package/src/modes/theme/defaults/light-haze.json +90 -0
  1507. package/src/modes/theme/defaults/light-honeycomb.json +95 -0
  1508. package/src/modes/theme/defaults/light-lagoon.json +91 -0
  1509. package/src/modes/theme/defaults/light-lavender.json +95 -0
  1510. package/src/modes/theme/defaults/light-meadow.json +91 -0
  1511. package/src/modes/theme/defaults/light-mint.json +95 -0
  1512. package/src/modes/theme/defaults/light-monochrome.json +101 -0
  1513. package/src/modes/theme/defaults/light-ocean.json +99 -0
  1514. package/src/modes/theme/defaults/light-one.json +99 -0
  1515. package/src/modes/theme/defaults/light-opal.json +91 -0
  1516. package/src/modes/theme/defaults/light-orchard.json +91 -0
  1517. package/src/modes/theme/defaults/light-paper.json +95 -0
  1518. package/src/modes/theme/defaults/light-poimandres.json +142 -0
  1519. package/src/modes/theme/defaults/light-prism.json +90 -0
  1520. package/src/modes/theme/defaults/light-retro.json +98 -0
  1521. package/src/modes/theme/defaults/light-sand.json +95 -0
  1522. package/src/modes/theme/defaults/light-savanna.json +91 -0
  1523. package/src/modes/theme/defaults/light-solarized.json +102 -0
  1524. package/src/modes/theme/defaults/light-soleil.json +90 -0
  1525. package/src/modes/theme/defaults/light-sunset.json +99 -0
  1526. package/src/modes/theme/defaults/light-synthwave.json +98 -0
  1527. package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
  1528. package/src/modes/theme/defaults/light-wetland.json +91 -0
  1529. package/src/modes/theme/defaults/light-zenith.json +89 -0
  1530. package/src/modes/theme/defaults/limestone.json +94 -0
  1531. package/src/modes/theme/defaults/mahogany.json +97 -0
  1532. package/src/modes/theme/defaults/marble.json +93 -0
  1533. package/src/modes/theme/defaults/obsidian.json +91 -0
  1534. package/src/modes/theme/defaults/onyx.json +91 -0
  1535. package/src/modes/theme/defaults/pearl.json +93 -0
  1536. package/src/modes/theme/defaults/porcelain.json +91 -0
  1537. package/src/modes/theme/defaults/quartz.json +96 -0
  1538. package/src/modes/theme/defaults/sandstone.json +95 -0
  1539. package/src/modes/theme/defaults/titanium.json +90 -0
  1540. package/src/modes/theme/light.json +93 -0
  1541. package/src/modes/theme/mermaid-cache.ts +29 -0
  1542. package/src/modes/theme/shimmer.ts +224 -0
  1543. package/src/modes/theme/theme-schema.json +459 -0
  1544. package/src/modes/theme/theme.ts +2569 -0
  1545. package/src/modes/turn-budget.ts +31 -0
  1546. package/src/modes/types.ts +338 -0
  1547. package/src/modes/ultrathink.ts +41 -0
  1548. package/src/modes/utils/context-usage.ts +335 -0
  1549. package/src/modes/utils/copy-targets.ts +254 -0
  1550. package/src/modes/utils/hotkeys-markdown.ts +60 -0
  1551. package/src/modes/utils/keybinding-matchers.ts +51 -0
  1552. package/src/modes/utils/tools-markdown.ts +27 -0
  1553. package/src/modes/utils/ui-helpers.ts +772 -0
  1554. package/src/modes/workflow.ts +42 -0
  1555. package/src/plan-mode/approved-plan.ts +163 -0
  1556. package/src/plan-mode/plan-handoff.ts +37 -0
  1557. package/src/plan-mode/plan-protection.ts +31 -0
  1558. package/src/plan-mode/state.ts +6 -0
  1559. package/src/priority.json +41 -0
  1560. package/src/prompts/agents/designer.md +66 -0
  1561. package/src/prompts/agents/explore.md +58 -0
  1562. package/src/prompts/agents/frontmatter.md +11 -0
  1563. package/src/prompts/agents/init.md +33 -0
  1564. package/src/prompts/agents/librarian.md +120 -0
  1565. package/src/prompts/agents/oracle.md +55 -0
  1566. package/src/prompts/agents/plan.md +48 -0
  1567. package/src/prompts/agents/reviewer.md +140 -0
  1568. package/src/prompts/agents/task.md +16 -0
  1569. package/src/prompts/ci-green-request.md +38 -0
  1570. package/src/prompts/dry-balance-bench.md +8 -0
  1571. package/src/prompts/goals/goal-budget-limit.md +16 -0
  1572. package/src/prompts/goals/goal-continuation.md +28 -0
  1573. package/src/prompts/goals/goal-mode-active.md +23 -0
  1574. package/src/prompts/memories/consolidation.md +35 -0
  1575. package/src/prompts/memories/identity_review.md +38 -0
  1576. package/src/prompts/memories/post_turn_review.md +37 -0
  1577. package/src/prompts/memories/read-path.md +16 -0
  1578. package/src/prompts/memories/stage_one_input.md +6 -0
  1579. package/src/prompts/memories/stage_one_system.md +21 -0
  1580. package/src/prompts/review-custom-request.md +22 -0
  1581. package/src/prompts/review-headless-request.md +16 -0
  1582. package/src/prompts/review-request.md +69 -0
  1583. package/src/prompts/steering/user-interjection.md +10 -0
  1584. package/src/prompts/system/agent-creation-architect.md +50 -0
  1585. package/src/prompts/system/agent-creation-user.md +6 -0
  1586. package/src/prompts/system/auto-continue.md +1 -0
  1587. package/src/prompts/system/auto-thinking-difficulty-local.md +14 -0
  1588. package/src/prompts/system/auto-thinking-difficulty.md +12 -0
  1589. package/src/prompts/system/btw-user.md +8 -0
  1590. package/src/prompts/system/commit-message-system.md +2 -0
  1591. package/src/prompts/system/custom-system-prompt.md +64 -0
  1592. package/src/prompts/system/eager-todo.md +13 -0
  1593. package/src/prompts/system/empty-stop-retry.md +6 -0
  1594. package/src/prompts/system/irc-incoming.md +8 -0
  1595. package/src/prompts/system/memory-consolidation-system.md +8 -0
  1596. package/src/prompts/system/memory-extraction-system.md +26 -0
  1597. package/src/prompts/system/omfg-user.md +51 -0
  1598. package/src/prompts/system/orchestrate-notice.md +40 -0
  1599. package/src/prompts/system/plan-mode-active.md +116 -0
  1600. package/src/prompts/system/plan-mode-approved.md +25 -0
  1601. package/src/prompts/system/plan-mode-compact-instructions.md +16 -0
  1602. package/src/prompts/system/plan-mode-reference.md +11 -0
  1603. package/src/prompts/system/plan-mode-subagent.md +34 -0
  1604. package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
  1605. package/src/prompts/system/project-prompt.md +52 -0
  1606. package/src/prompts/system/subagent-system-prompt.md +69 -0
  1607. package/src/prompts/system/subagent-user-prompt.md +3 -0
  1608. package/src/prompts/system/subagent-yield-reminder.md +12 -0
  1609. package/src/prompts/system/system-prompt.md +275 -0
  1610. package/src/prompts/system/tiny-title-system.md +8 -0
  1611. package/src/prompts/system/title-system.md +3 -0
  1612. package/src/prompts/system/ttsr-interrupt.md +7 -0
  1613. package/src/prompts/system/ttsr-tool-reminder.md +5 -0
  1614. package/src/prompts/system/ultrathink-notice.md +3 -0
  1615. package/src/prompts/system/web-search.md +25 -0
  1616. package/src/prompts/system/workflow-notice.md +70 -0
  1617. package/src/prompts/tools/apply-patch.md +65 -0
  1618. package/src/prompts/tools/ask.md +30 -0
  1619. package/src/prompts/tools/ast-edit.md +39 -0
  1620. package/src/prompts/tools/ast-grep.md +42 -0
  1621. package/src/prompts/tools/async-result.md +8 -0
  1622. package/src/prompts/tools/bash.md +39 -0
  1623. package/src/prompts/tools/browser.md +73 -0
  1624. package/src/prompts/tools/checkpoint.md +16 -0
  1625. package/src/prompts/tools/debug.md +34 -0
  1626. package/src/prompts/tools/eval.md +89 -0
  1627. package/src/prompts/tools/find.md +37 -0
  1628. package/src/prompts/tools/github.md +20 -0
  1629. package/src/prompts/tools/goal.md +18 -0
  1630. package/src/prompts/tools/image-gen.md +7 -0
  1631. package/src/prompts/tools/inspect-image-system.md +20 -0
  1632. package/src/prompts/tools/inspect-image.md +32 -0
  1633. package/src/prompts/tools/irc.md +49 -0
  1634. package/src/prompts/tools/job.md +19 -0
  1635. package/src/prompts/tools/lsp.md +42 -0
  1636. package/src/prompts/tools/memory-edit.md +8 -0
  1637. package/src/prompts/tools/patch.md +70 -0
  1638. package/src/prompts/tools/read.md +86 -0
  1639. package/src/prompts/tools/recall.md +5 -0
  1640. package/src/prompts/tools/reflect.md +5 -0
  1641. package/src/prompts/tools/render-mermaid.md +9 -0
  1642. package/src/prompts/tools/replace.md +36 -0
  1643. package/src/prompts/tools/resolve.md +9 -0
  1644. package/src/prompts/tools/retain.md +6 -0
  1645. package/src/prompts/tools/rewind.md +13 -0
  1646. package/src/prompts/tools/search-tool-bm25.md +40 -0
  1647. package/src/prompts/tools/search.md +25 -0
  1648. package/src/prompts/tools/ssh.md +35 -0
  1649. package/src/prompts/tools/task-summary.md +28 -0
  1650. package/src/prompts/tools/task.md +80 -0
  1651. package/src/prompts/tools/todo.md +58 -0
  1652. package/src/prompts/tools/web-search.md +10 -0
  1653. package/src/prompts/tools/write.md +14 -0
  1654. package/src/registry/agent-registry.ts +140 -0
  1655. package/src/sdk.ts +2374 -0
  1656. package/src/secrets/index.ts +116 -0
  1657. package/src/secrets/obfuscator.ts +277 -0
  1658. package/src/secrets/regex.ts +21 -0
  1659. package/src/session/agent-session.ts +9765 -0
  1660. package/src/session/agent-storage.ts +455 -0
  1661. package/src/session/artifacts.ts +135 -0
  1662. package/src/session/auth-broker-config.ts +102 -0
  1663. package/src/session/auth-storage.ts +27 -0
  1664. package/src/session/blob-store.ts +255 -0
  1665. package/src/session/client-bridge.ts +85 -0
  1666. package/src/session/history-storage.ts +348 -0
  1667. package/src/session/indexed-session-storage.ts +430 -0
  1668. package/src/session/messages.ts +575 -0
  1669. package/src/session/redis-session-storage.ts +170 -0
  1670. package/src/session/session-dump-format.ts +209 -0
  1671. package/src/session/session-manager.ts +3541 -0
  1672. package/src/session/session-storage.ts +529 -0
  1673. package/src/session/shake-types.ts +43 -0
  1674. package/src/session/sql-session-storage.ts +314 -0
  1675. package/src/session/streaming-output.ts +1093 -0
  1676. package/src/session/tool-choice-queue.ts +213 -0
  1677. package/src/session/yield-queue.ts +155 -0
  1678. package/src/slash-commands/acp-builtins.ts +46 -0
  1679. package/src/slash-commands/builtin-registry.ts +1726 -0
  1680. package/src/slash-commands/headless-plan.ts +142 -0
  1681. package/src/slash-commands/helpers/context-report.ts +39 -0
  1682. package/src/slash-commands/helpers/format.ts +46 -0
  1683. package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
  1684. package/src/slash-commands/helpers/mcp.ts +532 -0
  1685. package/src/slash-commands/helpers/parse.ts +85 -0
  1686. package/src/slash-commands/helpers/ssh.ts +195 -0
  1687. package/src/slash-commands/helpers/todo.ts +279 -0
  1688. package/src/slash-commands/helpers/usage-report.ts +93 -0
  1689. package/src/slash-commands/marketplace-install-parser.ts +99 -0
  1690. package/src/slash-commands/types.ts +139 -0
  1691. package/src/ssh/config-writer.ts +183 -0
  1692. package/src/ssh/connection-manager.ts +482 -0
  1693. package/src/ssh/ssh-executor.ts +133 -0
  1694. package/src/ssh/sshfs-mount.ts +140 -0
  1695. package/src/ssh/utils.ts +8 -0
  1696. package/src/stt/downloader.ts +71 -0
  1697. package/src/stt/index.ts +3 -0
  1698. package/src/stt/recorder.ts +351 -0
  1699. package/src/stt/setup.ts +52 -0
  1700. package/src/stt/stt-controller.ts +160 -0
  1701. package/src/stt/transcribe.py +70 -0
  1702. package/src/stt/transcriber.ts +91 -0
  1703. package/src/system-prompt.ts +591 -0
  1704. package/src/task/agents.ts +167 -0
  1705. package/src/task/commands.ts +131 -0
  1706. package/src/task/discovery.ts +129 -0
  1707. package/src/task/executor.ts +1659 -0
  1708. package/src/task/index.ts +1401 -0
  1709. package/src/task/name-generator.ts +1577 -0
  1710. package/src/task/output-manager.ts +99 -0
  1711. package/src/task/parallel.ts +116 -0
  1712. package/src/task/prometheus-command.ts +26 -0
  1713. package/src/task/render.ts +1211 -0
  1714. package/src/task/repair-args.ts +117 -0
  1715. package/src/task/simple-mode.ts +27 -0
  1716. package/src/task/subprocess-tool-registry.ts +88 -0
  1717. package/src/task/types.ts +320 -0
  1718. package/src/task/worktree.ts +506 -0
  1719. package/src/telemetry-export.ts +127 -0
  1720. package/src/thinking.ts +165 -0
  1721. package/src/tiny/compiled-runtime.ts +179 -0
  1722. package/src/tiny/device.ts +111 -0
  1723. package/src/tiny/dtype.ts +101 -0
  1724. package/src/tiny/models.ts +242 -0
  1725. package/src/tiny/text.ts +165 -0
  1726. package/src/tiny/title-client.ts +491 -0
  1727. package/src/tiny/title-protocol.ts +56 -0
  1728. package/src/tiny/worker.ts +566 -0
  1729. package/src/tool-discovery/mode.ts +24 -0
  1730. package/src/tool-discovery/tool-index.ts +256 -0
  1731. package/src/tools/approval.ts +189 -0
  1732. package/src/tools/archive-reader.ts +629 -0
  1733. package/src/tools/ask.ts +879 -0
  1734. package/src/tools/ast-edit.ts +595 -0
  1735. package/src/tools/ast-grep.ts +458 -0
  1736. package/src/tools/auto-generated-guard.ts +305 -0
  1737. package/src/tools/bash-command-fixup.ts +37 -0
  1738. package/src/tools/bash-interactive.ts +388 -0
  1739. package/src/tools/bash-interceptor.ts +67 -0
  1740. package/src/tools/bash-pty-selection.ts +14 -0
  1741. package/src/tools/bash-skill-urls.ts +248 -0
  1742. package/src/tools/bash.ts +1238 -0
  1743. package/src/tools/browser/attach.ts +175 -0
  1744. package/src/tools/browser/launch.ts +651 -0
  1745. package/src/tools/browser/readable.ts +95 -0
  1746. package/src/tools/browser/registry.ts +194 -0
  1747. package/src/tools/browser/render.ts +213 -0
  1748. package/src/tools/browser/tab-protocol.ts +105 -0
  1749. package/src/tools/browser/tab-supervisor.ts +577 -0
  1750. package/src/tools/browser/tab-worker-entry.ts +21 -0
  1751. package/src/tools/browser/tab-worker.ts +1058 -0
  1752. package/src/tools/browser.ts +316 -0
  1753. package/src/tools/checkpoint.ts +136 -0
  1754. package/src/tools/conflict-detect.ts +672 -0
  1755. package/src/tools/context.ts +39 -0
  1756. package/src/tools/debug.ts +1052 -0
  1757. package/src/tools/eval-backends.ts +27 -0
  1758. package/src/tools/eval-render.ts +765 -0
  1759. package/src/tools/eval.ts +568 -0
  1760. package/src/tools/fetch.ts +1586 -0
  1761. package/src/tools/file-recorder.ts +35 -0
  1762. package/src/tools/find.ts +571 -0
  1763. package/src/tools/fs-cache-invalidation.ts +28 -0
  1764. package/src/tools/gh-format.ts +12 -0
  1765. package/src/tools/gh-renderer.ts +428 -0
  1766. package/src/tools/gh.ts +3582 -0
  1767. package/src/tools/github-cache.ts +548 -0
  1768. package/src/tools/grouped-file-output.ts +103 -0
  1769. package/src/tools/image-gen.ts +1448 -0
  1770. package/src/tools/index.ts +516 -0
  1771. package/src/tools/inspect-image-renderer.ts +103 -0
  1772. package/src/tools/inspect-image.ts +166 -0
  1773. package/src/tools/irc.ts +294 -0
  1774. package/src/tools/job.ts +521 -0
  1775. package/src/tools/json-tree.ts +243 -0
  1776. package/src/tools/jtd-to-json-schema.ts +219 -0
  1777. package/src/tools/jtd-to-typescript.ts +136 -0
  1778. package/src/tools/jtd-utils.ts +102 -0
  1779. package/src/tools/list-limit.ts +40 -0
  1780. package/src/tools/match-line-format.ts +20 -0
  1781. package/src/tools/memory-edit.ts +59 -0
  1782. package/src/tools/memory-recall.ts +104 -0
  1783. package/src/tools/memory-reflect.ts +92 -0
  1784. package/src/tools/memory-render.ts +185 -0
  1785. package/src/tools/memory-retain.ts +91 -0
  1786. package/src/tools/output-meta.ts +754 -0
  1787. package/src/tools/output-schema-validator.ts +132 -0
  1788. package/src/tools/path-utils.ts +1031 -0
  1789. package/src/tools/plan-mode-guard.ts +81 -0
  1790. package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
  1791. package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
  1792. package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
  1793. package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
  1794. package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
  1795. package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
  1796. package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
  1797. package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
  1798. package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
  1799. package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
  1800. package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
  1801. package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
  1802. package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
  1803. package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
  1804. package/src/tools/read.ts +2557 -0
  1805. package/src/tools/render-mermaid.ts +69 -0
  1806. package/src/tools/render-utils.ts +836 -0
  1807. package/src/tools/renderers.ts +75 -0
  1808. package/src/tools/report-tool-issue.ts +528 -0
  1809. package/src/tools/resolve.ts +259 -0
  1810. package/src/tools/review.ts +253 -0
  1811. package/src/tools/search-tool-bm25.ts +338 -0
  1812. package/src/tools/search.ts +1475 -0
  1813. package/src/tools/sqlite-reader.ts +819 -0
  1814. package/src/tools/ssh.ts +347 -0
  1815. package/src/tools/todo.ts +856 -0
  1816. package/src/tools/tool-errors.ts +62 -0
  1817. package/src/tools/tool-result.ts +94 -0
  1818. package/src/tools/tool-timeouts.ts +30 -0
  1819. package/src/tools/tts.ts +133 -0
  1820. package/src/tools/write.ts +1085 -0
  1821. package/src/tools/yield.ts +260 -0
  1822. package/src/tui/code-cell.ts +221 -0
  1823. package/src/tui/file-list.ts +55 -0
  1824. package/src/tui/hyperlink.ts +161 -0
  1825. package/src/tui/index.ts +12 -0
  1826. package/src/tui/output-block.ts +288 -0
  1827. package/src/tui/status-line.ts +50 -0
  1828. package/src/tui/tree-list.ts +84 -0
  1829. package/src/tui/types.ts +15 -0
  1830. package/src/tui/utils.ts +103 -0
  1831. package/src/utils/changelog.ts +106 -0
  1832. package/src/utils/clipboard.ts +193 -0
  1833. package/src/utils/command-args.ts +76 -0
  1834. package/src/utils/commit-message-generator.ts +142 -0
  1835. package/src/utils/edit-mode.ts +41 -0
  1836. package/src/utils/event-bus.ts +33 -0
  1837. package/src/utils/external-editor.ts +65 -0
  1838. package/src/utils/file-display-mode.ts +45 -0
  1839. package/src/utils/file-mentions.ts +280 -0
  1840. package/src/utils/git.ts +1538 -0
  1841. package/src/utils/image-loading.ts +102 -0
  1842. package/src/utils/image-resize.ts +309 -0
  1843. package/src/utils/jj.ts +248 -0
  1844. package/src/utils/lang-from-path.ts +239 -0
  1845. package/src/utils/markit.ts +89 -0
  1846. package/src/utils/open.ts +55 -0
  1847. package/src/utils/session-color.ts +68 -0
  1848. package/src/utils/shell-snapshot.ts +187 -0
  1849. package/src/utils/sixel.ts +69 -0
  1850. package/src/utils/title-generator.ts +353 -0
  1851. package/src/utils/tool-choice.ts +33 -0
  1852. package/src/utils/tools-manager.ts +363 -0
  1853. package/src/web/kagi.ts +302 -0
  1854. package/src/web/parallel.ts +349 -0
  1855. package/src/web/scrapers/artifacthub.ts +207 -0
  1856. package/src/web/scrapers/arxiv.ts +83 -0
  1857. package/src/web/scrapers/aur.ts +162 -0
  1858. package/src/web/scrapers/biorxiv.ts +133 -0
  1859. package/src/web/scrapers/bluesky.ts +262 -0
  1860. package/src/web/scrapers/brew.ts +172 -0
  1861. package/src/web/scrapers/cheatsh.ts +68 -0
  1862. package/src/web/scrapers/chocolatey.ts +196 -0
  1863. package/src/web/scrapers/choosealicense.ts +95 -0
  1864. package/src/web/scrapers/cisa-kev.ts +87 -0
  1865. package/src/web/scrapers/clojars.ts +154 -0
  1866. package/src/web/scrapers/coingecko.ts +177 -0
  1867. package/src/web/scrapers/crates-io.ts +97 -0
  1868. package/src/web/scrapers/crossref.ts +136 -0
  1869. package/src/web/scrapers/devto.ts +147 -0
  1870. package/src/web/scrapers/discogs.ts +306 -0
  1871. package/src/web/scrapers/discourse.ts +197 -0
  1872. package/src/web/scrapers/dockerhub.ts +138 -0
  1873. package/src/web/scrapers/docs-rs.ts +653 -0
  1874. package/src/web/scrapers/fdroid.ts +134 -0
  1875. package/src/web/scrapers/firefox-addons.ts +191 -0
  1876. package/src/web/scrapers/flathub.ts +223 -0
  1877. package/src/web/scrapers/github-gist.ts +58 -0
  1878. package/src/web/scrapers/github.ts +452 -0
  1879. package/src/web/scrapers/gitlab.ts +401 -0
  1880. package/src/web/scrapers/go-pkg.ts +266 -0
  1881. package/src/web/scrapers/hackage.ts +140 -0
  1882. package/src/web/scrapers/hackernews.ts +189 -0
  1883. package/src/web/scrapers/hex.ts +105 -0
  1884. package/src/web/scrapers/huggingface.ts +321 -0
  1885. package/src/web/scrapers/iacr.ts +89 -0
  1886. package/src/web/scrapers/index.ts +252 -0
  1887. package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
  1888. package/src/web/scrapers/lemmy.ts +203 -0
  1889. package/src/web/scrapers/lobsters.ts +175 -0
  1890. package/src/web/scrapers/mastodon.ts +292 -0
  1891. package/src/web/scrapers/maven.ts +138 -0
  1892. package/src/web/scrapers/mdn.ts +173 -0
  1893. package/src/web/scrapers/metacpan.ts +222 -0
  1894. package/src/web/scrapers/musicbrainz.ts +250 -0
  1895. package/src/web/scrapers/npm.ts +98 -0
  1896. package/src/web/scrapers/nuget.ts +183 -0
  1897. package/src/web/scrapers/nvd.ts +222 -0
  1898. package/src/web/scrapers/ollama.ts +239 -0
  1899. package/src/web/scrapers/open-vsx.ts +106 -0
  1900. package/src/web/scrapers/opencorporates.ts +292 -0
  1901. package/src/web/scrapers/openlibrary.ts +336 -0
  1902. package/src/web/scrapers/orcid.ts +286 -0
  1903. package/src/web/scrapers/osv.ts +176 -0
  1904. package/src/web/scrapers/packagist.ts +160 -0
  1905. package/src/web/scrapers/pub-dev.ts +143 -0
  1906. package/src/web/scrapers/pubmed.ts +211 -0
  1907. package/src/web/scrapers/pypi.ts +112 -0
  1908. package/src/web/scrapers/rawg.ts +110 -0
  1909. package/src/web/scrapers/readthedocs.ts +120 -0
  1910. package/src/web/scrapers/reddit.ts +95 -0
  1911. package/src/web/scrapers/repology.ts +251 -0
  1912. package/src/web/scrapers/rfc.ts +201 -0
  1913. package/src/web/scrapers/rubygems.ts +103 -0
  1914. package/src/web/scrapers/searchcode.ts +189 -0
  1915. package/src/web/scrapers/sec-edgar.ts +261 -0
  1916. package/src/web/scrapers/semantic-scholar.ts +171 -0
  1917. package/src/web/scrapers/snapcraft.ts +187 -0
  1918. package/src/web/scrapers/sourcegraph.ts +336 -0
  1919. package/src/web/scrapers/spdx.ts +108 -0
  1920. package/src/web/scrapers/spotify.ts +198 -0
  1921. package/src/web/scrapers/stackoverflow.ts +120 -0
  1922. package/src/web/scrapers/terraform.ts +277 -0
  1923. package/src/web/scrapers/tldr.ts +47 -0
  1924. package/src/web/scrapers/twitter.ts +93 -0
  1925. package/src/web/scrapers/types.ts +318 -0
  1926. package/src/web/scrapers/utils.ts +109 -0
  1927. package/src/web/scrapers/vimeo.ts +133 -0
  1928. package/src/web/scrapers/vscode-marketplace.ts +187 -0
  1929. package/src/web/scrapers/w3c.ts +156 -0
  1930. package/src/web/scrapers/wikidata.ts +344 -0
  1931. package/src/web/scrapers/wikipedia.ts +84 -0
  1932. package/src/web/scrapers/youtube.ts +319 -0
  1933. package/src/web/search/index.ts +292 -0
  1934. package/src/web/search/provider.ts +157 -0
  1935. package/src/web/search/providers/anthropic.ts +302 -0
  1936. package/src/web/search/providers/base.ts +88 -0
  1937. package/src/web/search/providers/brave.ts +149 -0
  1938. package/src/web/search/providers/codex.ts +557 -0
  1939. package/src/web/search/providers/exa.ts +309 -0
  1940. package/src/web/search/providers/gemini.ts +455 -0
  1941. package/src/web/search/providers/jina.ts +101 -0
  1942. package/src/web/search/providers/kagi.ts +79 -0
  1943. package/src/web/search/providers/kimi.ts +171 -0
  1944. package/src/web/search/providers/parallel.ts +210 -0
  1945. package/src/web/search/providers/perplexity.ts +579 -0
  1946. package/src/web/search/providers/searxng.ts +309 -0
  1947. package/src/web/search/providers/synthetic.ts +110 -0
  1948. package/src/web/search/providers/tavily.ts +173 -0
  1949. package/src/web/search/providers/utils.ts +128 -0
  1950. package/src/web/search/providers/zai.ts +320 -0
  1951. package/src/web/search/render.ts +267 -0
  1952. package/src/web/search/types.ts +478 -0
  1953. package/src/web/search/utils.ts +17 -0
  1954. package/src/workspace-tree.ts +286 -0
@@ -0,0 +1,2650 @@
1
+ import * as path from "node:path";
2
+ import {
3
+ type Api,
4
+ type AssistantMessageEventStream,
5
+ type Context,
6
+ createModelManager,
7
+ enrichModelThinking,
8
+ getBundledModels,
9
+ getBundledProviders,
10
+ googleAntigravityModelManagerOptions,
11
+ googleGeminiCliModelManagerOptions,
12
+ type Model,
13
+ type ModelManagerOptions,
14
+ type ModelRefreshStrategy,
15
+ openaiCodexModelManagerOptions,
16
+ PROVIDER_DESCRIPTORS,
17
+ readModelCache,
18
+ registerCustomApi,
19
+ type SimpleStreamOptions,
20
+ type ThinkingConfig,
21
+ UNK_CONTEXT_WINDOW,
22
+ UNK_MAX_TOKENS,
23
+ unregisterCustomApis,
24
+ } from "@prometheus-ai/ai";
25
+
26
+ // Sentinel for local-only OAuth token (LM Studio, vLLM) — declared inline to avoid loading
27
+ // any provider module at startup. Must match `DEFAULT_LOCAL_TOKEN` in oauth/lm-studio.ts.
28
+ const DEFAULT_LOCAL_TOKEN = "lm-studio-local";
29
+
30
+ // Default cap on `max_tokens` for auto-discovered models that do not advertise
31
+ // their own output limit (OpenAI-models-list, Ollama, llama.cpp, new-api/
32
+ // one-api proxies). 32K matches the upper end of what mainstream
33
+ // OpenAI-compatible providers (DeepSeek, MiMo, OpenRouter, etc.) actually
34
+ // accept and keeps `min(contextWindow, …)` honoring smaller local windows.
35
+ // Conservative caps below this caused providers to drop the connection
36
+ // mid-stream when models hit the cap on legitimate large tool calls (see
37
+ // issue #1528: `write` payloads >~5KB on deepseek-v4-pro surfaced as
38
+ // "socket connection was closed unexpectedly").
39
+ const DISCOVERY_DEFAULT_MAX_TOKENS = 32_768;
40
+
41
+ const DEFAULT_OLLAMA_BASE_URL = "http://127.0.0.1:11434";
42
+ const OLLAMA_HOST_DEFAULT_PORT = "11434";
43
+
44
+ function normalizeOllamaHostEnv(value: string | undefined): string | undefined {
45
+ const trimmed = value?.trim();
46
+ if (!trimmed) return undefined;
47
+ const candidate = trimmed.includes("://")
48
+ ? trimmed
49
+ : trimmed.startsWith("//")
50
+ ? `http:${trimmed}`
51
+ : trimmed.startsWith(":")
52
+ ? `http://127.0.0.1${trimmed}`
53
+ : `http://${trimmed}`;
54
+ try {
55
+ const parsed = new URL(candidate);
56
+ if (!parsed.hostname || (parsed.protocol !== "http:" && parsed.protocol !== "https:")) {
57
+ return undefined;
58
+ }
59
+ if (!parsed.port && parsed.protocol === "http:") {
60
+ parsed.port = OLLAMA_HOST_DEFAULT_PORT;
61
+ }
62
+ return `${parsed.protocol}//${parsed.host}`;
63
+ } catch {
64
+ return undefined;
65
+ }
66
+ }
67
+
68
+ function getImplicitOllamaBaseUrl(): string {
69
+ const baseUrl = Bun.env.OLLAMA_BASE_URL?.trim();
70
+ return baseUrl || normalizeOllamaHostEnv(Bun.env.OLLAMA_HOST) || DEFAULT_OLLAMA_BASE_URL;
71
+ }
72
+
73
+ function getOllamaContextLengthOverride(): number | undefined {
74
+ const value = Bun.env.OLLAMA_CONTEXT_LENGTH?.trim();
75
+ if (!value) return undefined;
76
+ const parsed = Number(value);
77
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
78
+ }
79
+
80
+ // Anthropic-safe variant of the discovery cap. The Anthropic stream converter
81
+ // in `packages/ai/src/providers/anthropic.ts` derives the request limit as
82
+ // `(model.maxTokens / 3) | 0`, so the 32K default would surface as 10,922
83
+ // requested output tokens — above the 8,192 hard cap on classic Claude 3.x
84
+ // Sonnet/Haiku/Opus endpoints. Discovered models routed through
85
+ // `anthropic-messages` (proxy `supported_endpoint_types: ["anthropic"]` or a
86
+ // custom provider with `api: anthropic-messages` + openai-models-list
87
+ // discovery) fall back to this conservative value.
88
+ const DISCOVERY_DEFAULT_MAX_TOKENS_ANTHROPIC = 8_192;
89
+
90
+ /** Routes discovered-model `maxTokens` defaults around Anthropic's 3× output divisor. */
91
+ function discoveryDefaultMaxTokens(api: Api | undefined): number {
92
+ return api === "anthropic-messages" ? DISCOVERY_DEFAULT_MAX_TOKENS_ANTHROPIC : DISCOVERY_DEFAULT_MAX_TOKENS;
93
+ }
94
+
95
+ const SPECIAL_MODEL_MANAGER_PROVIDER_IDS: readonly string[] = [
96
+ "google-antigravity",
97
+ "google-gemini-cli",
98
+ "openai-codex",
99
+ ];
100
+
101
+ const STARTUP_MODEL_CACHE_PROVIDER_IDS: readonly string[] = [
102
+ ...PROVIDER_DESCRIPTORS.map(descriptor => descriptor.providerId),
103
+ ...SPECIAL_MODEL_MANAGER_PROVIDER_IDS,
104
+ ];
105
+
106
+ import { registerOAuthProvider, unregisterOAuthProviders } from "@prometheus-ai/ai/utils/oauth";
107
+ import type { OAuthCredentials, OAuthLoginCallbacks } from "@prometheus-ai/ai/utils/oauth/types";
108
+ import { isRecord, logger } from "@prometheus-ai/utils";
109
+ import { parseModelString, resolveProviderModelReference } from "../config/model-resolver";
110
+ import { isValidThemeColor, type ThemeColor } from "../modes/theme/theme";
111
+ import type { AuthStorage, OAuthCredential } from "../session/auth-storage";
112
+ import { type ConfigError, ConfigFile } from "./config-file";
113
+ import {
114
+ buildCanonicalModelIndex,
115
+ type CanonicalModelIndex,
116
+ type CanonicalModelRecord,
117
+ type CanonicalModelVariant,
118
+ formatCanonicalVariantSelector,
119
+ type ModelEquivalenceConfig,
120
+ } from "./model-equivalence";
121
+ import {
122
+ getBracketStrippedModelIdCandidates,
123
+ getLongestModelLikeIdSegment,
124
+ getModelLikeIdSegments,
125
+ stripBracketedModelIdAffixes,
126
+ } from "./model-id-affixes";
127
+ import {
128
+ type ModelOverride,
129
+ type ModelsConfig,
130
+ ModelsConfigSchema,
131
+ type ProviderAuthMode,
132
+ type ProviderDiscovery,
133
+ } from "./models-config-schema";
134
+ import { type Settings, settings } from "./settings";
135
+
136
+ export type { CanonicalModelIndex, CanonicalModelRecord, CanonicalModelVariant, ModelEquivalenceConfig };
137
+
138
+ export const kNoAuth = "N/A";
139
+
140
+ export function isAuthenticated(apiKey: string | undefined | null): apiKey is string {
141
+ return Boolean(apiKey) && apiKey !== kNoAuth;
142
+ }
143
+
144
+ export type ModelRole = "default" | "smol" | "slow" | "vision" | "plan" | "designer" | "commit" | "task";
145
+
146
+ export interface ModelRoleInfo {
147
+ tag?: string;
148
+ name: string;
149
+ color?: ThemeColor;
150
+ }
151
+
152
+ export const MODEL_ROLES: Record<ModelRole, ModelRoleInfo> = {
153
+ default: { tag: "DEFAULT", name: "Default", color: "success" },
154
+ smol: { tag: "SMOL", name: "Fast", color: "warning" },
155
+ slow: { tag: "SLOW", name: "Thinking", color: "accent" },
156
+ vision: { tag: "VISION", name: "Vision", color: "error" },
157
+ plan: { tag: "PLAN", name: "Architect", color: "muted" },
158
+ designer: { tag: "DESIGNER", name: "Designer", color: "muted" },
159
+ commit: { tag: "COMMIT", name: "Commit", color: "dim" },
160
+ task: { tag: "TASK", name: "Subtask", color: "muted" },
161
+ };
162
+
163
+ export const MODEL_ROLE_IDS: ModelRole[] = ["default", "smol", "slow", "vision", "plan", "designer", "commit", "task"];
164
+
165
+ /** Alias for ModelRoleInfo - used for both built-in and custom roles */
166
+ export type RoleInfo = ModelRoleInfo;
167
+
168
+ /**
169
+ * Return the canonical set of known roles for selector/carousel UI.
170
+ *
171
+ * Built-ins always come first. Configured cycle order, model assignments, and
172
+ * tag metadata can introduce additional custom roles without requiring duplicate
173
+ * entries across settings.
174
+ */
175
+ export function getKnownRoleIds(settings: Settings): string[] {
176
+ const roles = [...MODEL_ROLE_IDS] as string[];
177
+ const seen = new Set<string>(roles);
178
+ const addRole = (role: string) => {
179
+ if (seen.has(role)) return;
180
+ seen.add(role);
181
+ roles.push(role);
182
+ };
183
+
184
+ for (const role of settings.get("cycleOrder")) addRole(role);
185
+ for (const role of Object.keys(settings.getModelRoles())) addRole(role);
186
+ for (const role of Object.keys(settings.get("modelTags"))) addRole(role);
187
+
188
+ return roles;
189
+ }
190
+
191
+ /**
192
+ * Get role info for a role name (built-in or custom).
193
+ * Configured metadata overrides built-in defaults when present.
194
+ */
195
+ export function getRoleInfo(role: string, settings: Settings): RoleInfo {
196
+ const builtIn = role in MODEL_ROLES ? MODEL_ROLES[role as ModelRole] : undefined;
197
+ const configured = settings.get("modelTags")[role];
198
+
199
+ if (configured) {
200
+ return {
201
+ tag: builtIn?.tag,
202
+ name: configured.name || builtIn?.name || role,
203
+ color: configured.color && isValidThemeColor(configured.color) ? configured.color : builtIn?.color,
204
+ };
205
+ }
206
+
207
+ if (builtIn) return builtIn;
208
+
209
+ return { name: role, color: "muted" };
210
+ }
211
+
212
+ type ProviderValidationMode = "models-config" | "runtime-register";
213
+
214
+ interface ProviderValidationModel {
215
+ id: string;
216
+ api?: Api;
217
+ contextWindow?: number;
218
+ maxTokens?: number;
219
+ }
220
+
221
+ interface ProviderValidationConfig {
222
+ baseUrl?: string;
223
+ headers?: Record<string, string>;
224
+ apiKey?: string;
225
+ api?: Api;
226
+ auth?: ProviderAuthMode;
227
+ oauthConfigured?: boolean;
228
+ discovery?: ProviderDiscovery;
229
+ compat?: Model<Api>["compat"];
230
+ disableStrictTools?: boolean;
231
+ modelOverrides?: Record<string, unknown>;
232
+ models: ProviderValidationModel[];
233
+ }
234
+
235
+ function validateProviderConfiguration(
236
+ providerName: string,
237
+ config: ProviderValidationConfig,
238
+ mode: ProviderValidationMode,
239
+ ): void {
240
+ const hasProviderApi = !!config.api;
241
+ const models = config.models;
242
+
243
+ if (models.length === 0) {
244
+ if (mode === "models-config") {
245
+ const hasModelOverrides = config.modelOverrides && Object.keys(config.modelOverrides).length > 0;
246
+ if (
247
+ !config.baseUrl &&
248
+ !config.headers &&
249
+ !config.compat &&
250
+ !config.apiKey &&
251
+ !config.disableStrictTools &&
252
+ !hasModelOverrides &&
253
+ !config.discovery
254
+ ) {
255
+ throw new Error(
256
+ `Provider ${providerName}: must specify "baseUrl", "headers", "apiKey", "compat", "disableStrictTools", "modelOverrides", "discovery", or "models"`,
257
+ );
258
+ }
259
+ }
260
+ } else {
261
+ if (!config.baseUrl) {
262
+ throw new Error(`Provider ${providerName}: "baseUrl" is required when defining custom models.`);
263
+ }
264
+ const requiresAuth =
265
+ mode === "runtime-register"
266
+ ? !config.apiKey && !config.oauthConfigured
267
+ : !config.apiKey && (config.auth ?? "apiKey") !== "none";
268
+ if (requiresAuth) {
269
+ throw new Error(
270
+ mode === "runtime-register"
271
+ ? `Provider ${providerName}: "apiKey" or "oauth" is required when defining models.`
272
+ : `Provider ${providerName}: "apiKey" is required when defining custom models unless auth is "none".`,
273
+ );
274
+ }
275
+ }
276
+
277
+ if (mode === "models-config" && config.discovery && !config.api && config.discovery.type !== "proxy") {
278
+ throw new Error(`Provider ${providerName}: "api" is required when discovery is enabled at provider level.`);
279
+ }
280
+
281
+ for (const modelDef of models) {
282
+ if (!hasProviderApi && !modelDef.api) {
283
+ throw new Error(
284
+ mode === "runtime-register"
285
+ ? `Provider ${providerName}, model ${modelDef.id}: no "api" specified.`
286
+ : `Provider ${providerName}, model ${modelDef.id}: no "api" specified. Set at provider or model level.`,
287
+ );
288
+ }
289
+ if (!modelDef.id) {
290
+ throw new Error(`Provider ${providerName}: model missing "id"`);
291
+ }
292
+ if (mode === "models-config") {
293
+ if (modelDef.contextWindow !== undefined && modelDef.contextWindow <= 0) {
294
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);
295
+ }
296
+ if (modelDef.maxTokens !== undefined && modelDef.maxTokens <= 0) {
297
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);
298
+ }
299
+ }
300
+ }
301
+ }
302
+
303
+ export const ModelsConfigFile = new ConfigFile<ModelsConfig>("models", ModelsConfigSchema).withValidation(
304
+ "models",
305
+ config => {
306
+ for (const [providerName, providerConfig] of Object.entries(config.providers ?? {})) {
307
+ validateProviderConfiguration(
308
+ providerName,
309
+ {
310
+ baseUrl: providerConfig.baseUrl,
311
+ headers: providerConfig.headers,
312
+ apiKey: providerConfig.apiKey,
313
+ api: providerConfig.api as Api | undefined,
314
+ auth: (providerConfig.auth ?? "apiKey") as ProviderAuthMode,
315
+ discovery: providerConfig.discovery as ProviderDiscovery | undefined,
316
+ compat: providerConfig.compat,
317
+ disableStrictTools: providerConfig.disableStrictTools,
318
+ modelOverrides: providerConfig.modelOverrides,
319
+ models: (providerConfig.models ?? []) as ProviderValidationModel[],
320
+ },
321
+ "models-config",
322
+ );
323
+ }
324
+ },
325
+ );
326
+
327
+ /** Provider override config (baseUrl, headers, apiKey, compat, transport) without custom models */
328
+ interface ProviderOverride {
329
+ baseUrl?: string;
330
+ headers?: Record<string, string>;
331
+ apiKey?: string;
332
+ authHeader?: boolean;
333
+ compat?: Model<Api>["compat"];
334
+ transport?: Model<Api>["transport"];
335
+ }
336
+
337
+ /**
338
+ * Merge a freshly discovered model with the matching bundled/configured entry
339
+ * (or a runtime provider override when no bundled entry exists).
340
+ *
341
+ * `baseUrl` resolution priority:
342
+ * 1. User-set `providerOverride.baseUrl` (explicit override in models.json)
343
+ * 2. Discovered baseUrl (xiaomi `tp-` token-plan keys resolve to
344
+ * `token-plan-sgp.xiaomimimo.com` at discovery time)
345
+ * 3. Existing bundled baseUrl (the host baked into `models.json`)
346
+ *
347
+ * Without (1), the user's override would lose to discovery; without (2)
348
+ * preferred over (3), the bundled `api.xiaomimimo.com` would shadow the
349
+ * tp- token-plan host and produce 401s on the first stream call.
350
+ * See `xiaomi-tp-discovery-merge.test.ts` and the `refresh()` baseUrl-override
351
+ * regression in `model-registry.test.ts`.
352
+ */
353
+ export function mergeDiscoveredModel<TApi extends Api>(
354
+ model: Model<TApi>,
355
+ existing: Model<Api> | undefined,
356
+ providerOverride?: Pick<ProviderOverride, "baseUrl" | "headers" | "transport">,
357
+ ): Model<TApi> {
358
+ if (existing) {
359
+ return {
360
+ ...model,
361
+ baseUrl: providerOverride?.baseUrl ?? model.baseUrl ?? existing.baseUrl,
362
+ headers: existing.headers ? { ...existing.headers, ...model.headers } : model.headers,
363
+ };
364
+ }
365
+ if (providerOverride) {
366
+ return {
367
+ ...model,
368
+ baseUrl: providerOverride.baseUrl ?? model.baseUrl,
369
+ headers: providerOverride.headers ? { ...model.headers, ...providerOverride.headers } : model.headers,
370
+ ...(providerOverride.transport !== undefined ? { transport: providerOverride.transport } : {}),
371
+ };
372
+ }
373
+ return model;
374
+ }
375
+
376
+ const AUTHORITATIVE_RUNTIME_CATALOG_PROVIDERS = new Set<string>(
377
+ PROVIDER_DESCRIPTORS.filter(descriptor => descriptor.dynamicModelsAuthoritative).map(
378
+ descriptor => descriptor.providerId,
379
+ ),
380
+ );
381
+
382
+ function isAuthoritativeProjectCatalogModel(model: Model<Api>): boolean {
383
+ return (
384
+ model.provider === "google-vertex" &&
385
+ model.api === "openai-completions" &&
386
+ model.baseUrl.includes("/endpoints/openapi")
387
+ );
388
+ }
389
+
390
+ function providersWithAuthoritativeProjectCatalog(models: readonly Model<Api>[]): Set<string> {
391
+ const providers = new Set<string>();
392
+ for (const model of models) {
393
+ if (isAuthoritativeProjectCatalogModel(model)) {
394
+ providers.add(model.provider);
395
+ }
396
+ }
397
+ return providers;
398
+ }
399
+
400
+ function dropProviderModels(models: readonly Model<Api>[], providers: ReadonlySet<string>): Model<Api>[] {
401
+ return models.filter(model => !providers.has(model.provider));
402
+ }
403
+
404
+ interface DiscoveryProviderConfig {
405
+ provider: string;
406
+ api: Api;
407
+ baseUrl?: string;
408
+ headers?: Record<string, string>;
409
+ compat?: Model<Api>["compat"];
410
+ discovery: ProviderDiscovery;
411
+ optional?: boolean;
412
+ }
413
+
414
+ interface BuiltInDiscoveryResult {
415
+ models: Model<Api>[];
416
+ authoritativeProviders: Set<string>;
417
+ }
418
+
419
+ export type ProviderDiscoveryStatus = "idle" | "ok" | "empty" | "cached" | "unavailable" | "unauthenticated";
420
+
421
+ export interface ProviderDiscoveryState {
422
+ provider: string;
423
+ status: ProviderDiscoveryStatus;
424
+ optional: boolean;
425
+ stale: boolean;
426
+ fetchedAt?: number;
427
+ models: string[];
428
+ error?: string;
429
+ }
430
+
431
+ export interface CanonicalModelQueryOptions {
432
+ availableOnly?: boolean;
433
+ candidates?: readonly Model<Api>[];
434
+ }
435
+
436
+ /** Result of loading custom models from models.json */
437
+ interface CustomModelsResult {
438
+ models?: CustomModelOverlay[];
439
+ overrides?: Map<string, ProviderOverride>;
440
+ modelOverrides?: Map<string, Map<string, ModelOverride>>;
441
+ keylessProviders?: Set<string>;
442
+ discoverableProviders?: DiscoveryProviderConfig[];
443
+ configuredProviders?: Set<string>;
444
+ equivalence?: ModelEquivalenceConfig;
445
+ error?: ConfigError;
446
+ found: boolean;
447
+ }
448
+
449
+ type OllamaDiscoveredModelMetadata = {
450
+ reasoning: boolean;
451
+ input: ("text" | "image")[];
452
+ contextWindow?: number;
453
+ };
454
+
455
+ type LlamaCppDiscoveredServerMetadata = {
456
+ contextWindow?: number;
457
+ input?: ("text" | "image")[];
458
+ };
459
+
460
+ /**
461
+ * Resolve an API key config value to an actual key.
462
+ * Checks environment variable first, then treats as literal.
463
+ */
464
+ function resolveApiKeyConfig(keyConfig: string): string | undefined {
465
+ const envValue = Bun.env[keyConfig];
466
+ if (envValue) return envValue;
467
+ return keyConfig;
468
+ }
469
+
470
+ function toPositiveNumberOrUndefined(value: unknown): number | undefined {
471
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
472
+ return value;
473
+ }
474
+ if (typeof value === "string" && value.trim()) {
475
+ const parsed = Number(value);
476
+ if (Number.isFinite(parsed) && parsed > 0) {
477
+ return parsed;
478
+ }
479
+ }
480
+ return undefined;
481
+ }
482
+
483
+ function extractOllamaContextWindow(payload: Record<string, unknown>): number | undefined {
484
+ const modelInfo = payload.model_info;
485
+ if (isRecord(modelInfo)) {
486
+ for (const [key, value] of Object.entries(modelInfo)) {
487
+ if (key === "context_length" || key.endsWith(".context_length")) {
488
+ const contextWindow = toPositiveNumberOrUndefined(value);
489
+ if (contextWindow !== undefined) {
490
+ return contextWindow;
491
+ }
492
+ }
493
+ }
494
+ }
495
+
496
+ const parameters = payload.parameters;
497
+ if (typeof parameters !== "string") {
498
+ return undefined;
499
+ }
500
+ const match = parameters.match(/(?:^|\n)\s*num_ctx\s+(\d+)\s*(?:$|\n)/m);
501
+ return match ? toPositiveNumberOrUndefined(match[1]) : undefined;
502
+ }
503
+
504
+ function extractLlamaCppContextWindow(payload: Record<string, unknown>): number | undefined {
505
+ const generationSettings = payload.default_generation_settings;
506
+ if (isRecord(generationSettings)) {
507
+ const contextWindow = toPositiveNumberOrUndefined(generationSettings.n_ctx);
508
+ if (contextWindow !== undefined) {
509
+ return contextWindow;
510
+ }
511
+ }
512
+ return toPositiveNumberOrUndefined(payload.n_ctx);
513
+ }
514
+
515
+ function extractLlamaCppInputCapabilities(payload: Record<string, unknown>): ("text" | "image")[] | undefined {
516
+ const modalities = payload.modalities;
517
+ if (!isRecord(modalities)) {
518
+ return undefined;
519
+ }
520
+ return modalities.vision === true ? ["text", "image"] : ["text"];
521
+ }
522
+
523
+ function extractGoogleOAuthToken(value: string | undefined): string | undefined {
524
+ if (!isAuthenticated(value)) return undefined;
525
+ try {
526
+ const parsed = JSON.parse(value) as { token?: unknown };
527
+ if (Object.hasOwn(parsed, "token")) {
528
+ if (typeof parsed.token !== "string") {
529
+ return undefined;
530
+ }
531
+ const token = parsed.token.trim();
532
+ return token.length > 0 ? token : undefined;
533
+ }
534
+ } catch {
535
+ // OAuth values for Google providers are expected to be JSON, but custom setups may already provide raw token.
536
+ }
537
+ return value;
538
+ }
539
+
540
+ function getOAuthCredentialsForProvider(authStorage: AuthStorage, provider: string): OAuthCredential[] {
541
+ const providerEntry = authStorage.getAll()[provider];
542
+ if (!providerEntry) {
543
+ return [];
544
+ }
545
+ const entries = Array.isArray(providerEntry) ? providerEntry : [providerEntry];
546
+ return entries.filter((entry): entry is OAuthCredential => entry.type === "oauth");
547
+ }
548
+
549
+ function resolveOAuthAccountIdForAccessToken(
550
+ authStorage: AuthStorage,
551
+ provider: string,
552
+ accessToken: string,
553
+ ): string | undefined {
554
+ const oauthCredentials = getOAuthCredentialsForProvider(authStorage, provider);
555
+ const matchingCredential = oauthCredentials.find(credential => credential.access === accessToken);
556
+ if (matchingCredential) {
557
+ return matchingCredential.accountId;
558
+ }
559
+ if (oauthCredentials.length === 1) {
560
+ return oauthCredentials[0].accountId;
561
+ }
562
+ return undefined;
563
+ }
564
+
565
+ function mergeCompat<TBase extends object, TOverride extends object>(
566
+ baseCompat: TBase | null | undefined,
567
+ overrideCompat: TOverride | null | undefined,
568
+ ): (TBase & TOverride) | TBase | TOverride | undefined {
569
+ if (!baseCompat) return overrideCompat ?? undefined;
570
+ if (!overrideCompat) return baseCompat;
571
+
572
+ const merged: Record<string, unknown> = { ...(baseCompat as Record<string, unknown>) };
573
+ for (const [key, overrideValue] of Object.entries(overrideCompat)) {
574
+ const baseValue = (baseCompat as Record<string, unknown>)[key];
575
+ merged[key] =
576
+ isRecord(baseValue) && isRecord(overrideValue) ? mergeCompat(baseValue, overrideValue) : overrideValue;
577
+ }
578
+ return merged as TBase & TOverride;
579
+ }
580
+
581
+ function applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {
582
+ const result = { ...model };
583
+ if (override.name !== undefined) result.name = override.name;
584
+ if (override.reasoning !== undefined) result.reasoning = override.reasoning;
585
+ if (override.thinking !== undefined) result.thinking = override.thinking as ThinkingConfig;
586
+ if (override.input !== undefined) result.input = override.input as ("text" | "image")[];
587
+ if (override.contextWindow !== undefined) result.contextWindow = override.contextWindow;
588
+ if (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;
589
+ if (override.omitMaxOutputTokens !== undefined) result.omitMaxOutputTokens = override.omitMaxOutputTokens;
590
+ if (override.contextPromotionTarget !== undefined) result.contextPromotionTarget = override.contextPromotionTarget;
591
+ if (override.premiumMultiplier !== undefined) result.premiumMultiplier = override.premiumMultiplier;
592
+ if (override.cost) {
593
+ result.cost = {
594
+ input: override.cost.input ?? model.cost.input,
595
+ output: override.cost.output ?? model.cost.output,
596
+ cacheRead: override.cost.cacheRead ?? model.cost.cacheRead,
597
+ cacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,
598
+ };
599
+ }
600
+ if (override.headers) {
601
+ result.headers = { ...model.headers, ...override.headers };
602
+ }
603
+ result.compat = mergeCompat(model.compat, override.compat);
604
+ return enrichModelThinking(result);
605
+ }
606
+
607
+ interface CustomModelDefinitionLike {
608
+ id: string;
609
+ name?: string;
610
+ api?: Api;
611
+ baseUrl?: string;
612
+ reasoning?: boolean;
613
+ thinking?: ThinkingConfig;
614
+ input?: ("text" | "image")[];
615
+ cost?: { input: number; output: number; cacheRead: number; cacheWrite: number };
616
+ contextWindow?: number;
617
+ maxTokens?: number;
618
+ omitMaxOutputTokens?: boolean;
619
+ headers?: Record<string, string>;
620
+ compat?: Model<Api>["compat"];
621
+ contextPromotionTarget?: string;
622
+ premiumMultiplier?: number;
623
+ }
624
+
625
+ interface CustomModelBuildOptions {
626
+ useDefaults: boolean;
627
+ }
628
+
629
+ type CustomModelOverlay = {
630
+ id: string;
631
+ provider: string;
632
+ api: Api;
633
+ baseUrl: string;
634
+ name?: string;
635
+ reasoning?: boolean;
636
+ thinking?: ThinkingConfig;
637
+ input?: ("text" | "image")[];
638
+ cost?: { input: number; output: number; cacheRead: number; cacheWrite: number };
639
+ contextWindow?: number;
640
+ maxTokens?: number;
641
+ omitMaxOutputTokens?: boolean;
642
+ headers?: Record<string, string>;
643
+ compat?: Model<Api>["compat"];
644
+ contextPromotionTarget?: string;
645
+ premiumMultiplier?: number;
646
+ isOAuth?: boolean;
647
+ };
648
+
649
+ function mergeCustomModelHeaders(
650
+ providerHeaders: Record<string, string> | undefined,
651
+ modelHeaders: Record<string, string> | undefined,
652
+ authHeader: boolean | undefined,
653
+ apiKeyConfig: string | undefined,
654
+ ): Record<string, string> | undefined {
655
+ return mergeAuthHeader({ ...providerHeaders, ...modelHeaders }, authHeader, apiKeyConfig);
656
+ }
657
+
658
+ function mergeAuthHeader(
659
+ headers: Record<string, string> | undefined,
660
+ authHeader: boolean | undefined,
661
+ apiKeyConfig: string | undefined,
662
+ ): Record<string, string> | undefined {
663
+ const nextHeaders = headers && Object.keys(headers).length > 0 ? { ...headers } : undefined;
664
+ if (!authHeader || !apiKeyConfig) {
665
+ return nextHeaders;
666
+ }
667
+ const resolvedKey = resolveApiKeyConfig(apiKeyConfig);
668
+ return resolvedKey ? { ...nextHeaders, Authorization: `Bearer ${resolvedKey}` } : nextHeaders;
669
+ }
670
+
671
+ /**
672
+ * Decide whether a custom-yaml model should force OAuth-style request shaping.
673
+ * - Explicit `auth: oauth` → force on.
674
+ * - Explicit `auth: apiKey` / `auth: none` → leave unset (auto-detect by key prefix).
675
+ * - No `auth` specified and `api: anthropic-messages` → default on. Custom Anthropic
676
+ * endpoints are typically Claude-Code-style proxies (e.g. CLIProxyAPI) that expect
677
+ * the cloaked request shape regardless of how the proxy itself is authenticated.
678
+ * - Otherwise → unset.
679
+ */
680
+ function resolveCustomModelIsOAuth(api: Api, providerAuth: ProviderAuthMode | undefined): boolean | undefined {
681
+ if (providerAuth === "oauth") return true;
682
+ if (providerAuth !== undefined) return undefined;
683
+ if (api === "anthropic-messages") return true;
684
+ return undefined;
685
+ }
686
+
687
+ function buildCustomModelOverlay(
688
+ providerName: string,
689
+ providerBaseUrl: string,
690
+ providerApi: Api | undefined,
691
+ providerHeaders: Record<string, string> | undefined,
692
+ providerApiKey: string | undefined,
693
+ authHeader: boolean | undefined,
694
+ providerCompat: Model<Api>["compat"] | undefined,
695
+ providerAuth: ProviderAuthMode | undefined,
696
+ modelDef: CustomModelDefinitionLike,
697
+ ): CustomModelOverlay | undefined {
698
+ const api = modelDef.api ?? providerApi;
699
+ if (!api) return undefined;
700
+ return {
701
+ id: modelDef.id,
702
+ provider: providerName,
703
+ api,
704
+ baseUrl: modelDef.baseUrl ?? providerBaseUrl,
705
+ name: modelDef.name,
706
+ reasoning: modelDef.reasoning,
707
+ thinking: modelDef.thinking as ThinkingConfig | undefined,
708
+ input: modelDef.input as ("text" | "image")[] | undefined,
709
+ cost: modelDef.cost,
710
+ contextWindow: modelDef.contextWindow,
711
+ maxTokens: modelDef.maxTokens,
712
+ omitMaxOutputTokens: modelDef.omitMaxOutputTokens,
713
+ headers: mergeCustomModelHeaders(providerHeaders, modelDef.headers, authHeader, providerApiKey),
714
+ compat: mergeCompat(providerCompat, modelDef.compat),
715
+ contextPromotionTarget: modelDef.contextPromotionTarget,
716
+ premiumMultiplier: modelDef.premiumMultiplier,
717
+ isOAuth: resolveCustomModelIsOAuth(api, providerAuth),
718
+ };
719
+ }
720
+
721
+ // Custom provider entries often front a known upstream model through a local proxy.
722
+ // Use bundled metadata for missing pricing/capability fields, but keep the custom transport.
723
+ function shouldReplaceCustomReference(existing: Model<Api> | undefined, candidate: Model<Api>): boolean {
724
+ if (!existing) return true;
725
+ if (candidate.contextWindow !== existing.contextWindow) {
726
+ return candidate.contextWindow > existing.contextWindow;
727
+ }
728
+ if (candidate.maxTokens !== existing.maxTokens) {
729
+ return candidate.maxTokens > existing.maxTokens;
730
+ }
731
+ const existingHasCachePricing = existing.cost.cacheRead > 0 || existing.cost.cacheWrite > 0;
732
+ const candidateHasCachePricing = candidate.cost.cacheRead > 0 || candidate.cost.cacheWrite > 0;
733
+ if (candidateHasCachePricing !== existingHasCachePricing) {
734
+ return candidateHasCachePricing;
735
+ }
736
+ return existing.provider !== "openai" && candidate.provider === "openai";
737
+ }
738
+
739
+ function normalizeCustomReferenceKey(value: string): string {
740
+ return value.trim().toLowerCase();
741
+ }
742
+
743
+ function buildCustomReferenceMap(): Map<string, Model<Api>> {
744
+ const references = new Map<string, Model<Api>>();
745
+ for (const provider of getBundledProviders()) {
746
+ for (const model of getBundledModels(provider as Parameters<typeof getBundledModels>[0])) {
747
+ const candidate = model as Model<Api>;
748
+ const key = normalizeCustomReferenceKey(candidate.id);
749
+ if (shouldReplaceCustomReference(references.get(key), candidate)) {
750
+ references.set(key, candidate);
751
+ }
752
+ }
753
+ }
754
+ return references;
755
+ }
756
+
757
+ function buildCustomReferenceSuffixAliasMap(exactReferences: ReadonlyMap<string, Model<Api>>): Map<string, Model<Api>> {
758
+ const aliases = new Map<string, Model<Api>>();
759
+ for (const reference of exactReferences.values()) {
760
+ const slashIndex = reference.id.lastIndexOf("/");
761
+ if (slashIndex === -1) {
762
+ continue;
763
+ }
764
+ const suffix = reference.id.slice(slashIndex + 1);
765
+ const alias = getLongestModelLikeIdSegment(suffix);
766
+ if (!alias) {
767
+ continue;
768
+ }
769
+ if (shouldReplaceCustomReference(aliases.get(alias), reference)) {
770
+ aliases.set(alias, reference);
771
+ }
772
+ }
773
+ return aliases;
774
+ }
775
+
776
+ const customReferenceMap = buildCustomReferenceMap();
777
+ const customReferenceSuffixAliasMap = buildCustomReferenceSuffixAliasMap(customReferenceMap);
778
+
779
+ const CUSTOM_REFERENCE_TRAILING_MARKER_PATTERN =
780
+ /[-:](?:thinking|customtools|high|low|medium|minimal|xhigh|free|cloud|exacto|nitro|original|optimized|nvfp4|fp8|fp4|bf16|int8|int4|search)$/i;
781
+
782
+ function stripCustomReferenceTrailingMarker(candidate: string): string | undefined {
783
+ const match = CUSTOM_REFERENCE_TRAILING_MARKER_PATTERN.exec(candidate);
784
+ return match ? candidate.slice(0, match.index) : undefined;
785
+ }
786
+
787
+ function getCustomReferenceCandidateIds(modelId: string): string[] {
788
+ const candidates = new Set<string>();
789
+ const queue = [modelId];
790
+ for (let index = 0; index < queue.length; index += 1) {
791
+ const candidate = queue[index]?.trim();
792
+ if (!candidate || candidates.has(candidate)) continue;
793
+ candidates.add(candidate);
794
+
795
+ for (const stripped of getBracketStrippedModelIdCandidates(candidate)) {
796
+ queue.push(stripped);
797
+ }
798
+ for (const segment of getModelLikeIdSegments(candidate)) {
799
+ queue.push(segment);
800
+ }
801
+
802
+ for (const suffix of [":cloud", "-cloud"] as const) {
803
+ if (candidate.toLowerCase().endsWith(suffix)) {
804
+ queue.push(candidate.slice(0, -suffix.length));
805
+ }
806
+ }
807
+
808
+ const slashIndex = candidate.lastIndexOf("/");
809
+ if (slashIndex !== -1) {
810
+ queue.push(candidate.slice(slashIndex + 1));
811
+ }
812
+
813
+ const colonToDash = candidate.replace(/:/g, "-");
814
+ if (colonToDash !== candidate) {
815
+ queue.push(colonToDash);
816
+ }
817
+
818
+ const lowercased = candidate.toLowerCase();
819
+ if (lowercased !== candidate) {
820
+ queue.push(lowercased);
821
+ }
822
+
823
+ const strippedMarker = stripCustomReferenceTrailingMarker(candidate);
824
+ if (strippedMarker) {
825
+ queue.push(strippedMarker);
826
+ }
827
+ }
828
+ return [...candidates];
829
+ }
830
+
831
+ function resolveCustomModelReference(modelId: string): Model<Api> | undefined {
832
+ for (const candidate of getCustomReferenceCandidateIds(modelId)) {
833
+ const key = normalizeCustomReferenceKey(candidate);
834
+ const reference = customReferenceMap.get(key) ?? customReferenceSuffixAliasMap.get(key);
835
+ if (reference) return reference;
836
+ }
837
+ return undefined;
838
+ }
839
+
840
+ function applyStandaloneCustomModelPolicies(model: CustomModelOverlay): CustomModelOverlay {
841
+ if (model.id !== "gpt-5.4" || model.provider === "github-copilot" || model.contextWindow !== undefined) {
842
+ return model;
843
+ }
844
+ return { ...model, contextWindow: 1_000_000 };
845
+ }
846
+
847
+ function finalizeCustomModel(model: CustomModelOverlay, options: CustomModelBuildOptions): Model<Api> {
848
+ const resolvedModel = options.useDefaults ? applyStandaloneCustomModelPolicies(model) : model;
849
+ const reference = options.useDefaults ? resolveCustomModelReference(resolvedModel.id) : undefined;
850
+ const cost =
851
+ resolvedModel.cost ??
852
+ reference?.cost ??
853
+ (options.useDefaults ? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } : undefined);
854
+ const input = resolvedModel.input ?? reference?.input ?? (options.useDefaults ? ["text"] : undefined);
855
+ return enrichModelThinking({
856
+ id: resolvedModel.id,
857
+ name: resolvedModel.name ?? (options.useDefaults ? resolvedModel.id : undefined),
858
+ api: resolvedModel.api,
859
+ provider: resolvedModel.provider,
860
+ baseUrl: resolvedModel.baseUrl,
861
+ reasoning: resolvedModel.reasoning ?? reference?.reasoning ?? (options.useDefaults ? false : undefined),
862
+ thinking: resolvedModel.thinking ?? reference?.thinking,
863
+ input: input as ("text" | "image")[],
864
+ cost,
865
+ contextWindow:
866
+ resolvedModel.contextWindow ?? reference?.contextWindow ?? (options.useDefaults ? 128000 : undefined),
867
+ maxTokens: resolvedModel.maxTokens ?? reference?.maxTokens ?? (options.useDefaults ? 16384 : undefined),
868
+ headers: resolvedModel.headers,
869
+ omitMaxOutputTokens: resolvedModel.omitMaxOutputTokens ?? reference?.omitMaxOutputTokens,
870
+ compat: mergeCompat(reference?.compat, resolvedModel.compat),
871
+ contextPromotionTarget: resolvedModel.contextPromotionTarget,
872
+ premiumMultiplier: resolvedModel.premiumMultiplier,
873
+ isOAuth: resolvedModel.isOAuth,
874
+ } as Model<Api>);
875
+ }
876
+
877
+ function normalizeSuppressedSelector(selector: string): string {
878
+ const trimmed = selector.trim();
879
+ if (!trimmed) return trimmed;
880
+ const parsed = parseModelString(trimmed);
881
+ if (!parsed) return trimmed;
882
+ return `${parsed.provider}/${parsed.id}`;
883
+ }
884
+
885
+ function getDisabledProviderIdsFromSettings(): Set<string> {
886
+ try {
887
+ return new Set(settings.get("disabledProviders"));
888
+ } catch {
889
+ return new Set();
890
+ }
891
+ }
892
+
893
+ function getConfiguredProviderOrderFromSettings(): string[] {
894
+ try {
895
+ return settings.get("modelProviderOrder");
896
+ } catch {
897
+ return [];
898
+ }
899
+ }
900
+
901
+ /**
902
+ * Model registry - loads and manages models, resolves API keys via AuthStorage.
903
+ */
904
+ export class ModelRegistry {
905
+ #models: Model<Api>[] = [];
906
+ #canonicalIndex: CanonicalModelIndex = { records: [], byId: new Map(), bySelector: new Map() };
907
+ #customProviderApiKeys: Map<string, string> = new Map();
908
+ #keylessProviders: Set<string> = new Set();
909
+ #discoverableProviders: DiscoveryProviderConfig[] = [];
910
+ #customModelOverlays: CustomModelOverlay[] = [];
911
+ #providerOverrides: Map<string, ProviderOverride> = new Map();
912
+ #modelOverrides: Map<string, Map<string, ModelOverride>> = new Map();
913
+ #equivalenceConfig: ModelEquivalenceConfig | undefined;
914
+ #configError: ConfigError | undefined = undefined;
915
+ #modelsConfigFile: ConfigFile<ModelsConfig>;
916
+ #lastStaticLoadMtime: number | null = null;
917
+ #registeredProviderSources: Set<string> = new Set();
918
+ #providerDiscoveryStates: Map<string, ProviderDiscoveryState> = new Map();
919
+ #cacheDbPath?: string;
920
+ #suppressedSelectors: Map<string, number> = new Map();
921
+ #backgroundRefresh?: Promise<void>;
922
+ #lastDiscoveryWarnings: Map<string, string> = new Map();
923
+ // Runtime extension model overlays — persist across refresh() cycles so that
924
+ // models registered by extensions survive the model selector's offline reload.
925
+ #runtimeModelOverlays: CustomModelOverlay[] = [];
926
+ #runtimeProviderApiKeys: Map<string, string> = new Map();
927
+ #runtimeProviderOverrides: Map<string, ProviderOverride> = new Map();
928
+ #runtimeProvidersBySource: Map<string, Set<string>> = new Map();
929
+ #runtimeProviderSourceByName: Map<string, string> = new Map();
930
+ #rebuildPending: boolean = false;
931
+ #rebuildSuspended: number = 0;
932
+
933
+ /**
934
+ * @param authStorage - Auth storage for API key resolution
935
+ *
936
+ * Sync constructor — eagerly loads bundled + cached models so tests and
937
+ * synchronous callers see a fully-populated registry immediately. Production
938
+ * boot paths SHOULD prefer {@link ModelRegistry.create} so the YAML/JSONC
939
+ * migration step lands off the event loop's hot path before the first
940
+ * `tryLoad()` runs.
941
+ */
942
+ constructor(
943
+ readonly authStorage: AuthStorage,
944
+ modelsPath?: string,
945
+ ) {
946
+ this.#modelsConfigFile = ModelsConfigFile.relocate(modelsPath);
947
+ this.#cacheDbPath = modelsPath ? path.join(path.dirname(modelsPath), "models.db") : undefined;
948
+ // Set up fallback resolver for custom provider API keys
949
+ this.authStorage.setFallbackResolver(provider => {
950
+ const keyConfig = this.#customProviderApiKeys.get(provider);
951
+ if (keyConfig) {
952
+ return resolveApiKeyConfig(keyConfig);
953
+ }
954
+ return undefined;
955
+ });
956
+ // Load models synchronously in constructor.
957
+ this.#loadModels();
958
+ }
959
+
960
+ /**
961
+ * Reload models from disk (built-in + custom from models.json).
962
+ */
963
+ async refresh(strategy: ModelRefreshStrategy = "online-if-uncached"): Promise<void> {
964
+ this.#suspendRebuild();
965
+ try {
966
+ this.#reloadStaticModels();
967
+ this.#suppressedSelectors.clear();
968
+ await this.#refreshRuntimeDiscoveries(strategy);
969
+ } finally {
970
+ this.#resumeRebuild();
971
+ }
972
+ }
973
+
974
+ refreshInBackground(strategy: ModelRefreshStrategy = "online-if-uncached"): void {
975
+ if (this.#backgroundRefresh) {
976
+ return;
977
+ }
978
+ const refreshPromise = this.refresh(strategy)
979
+ .catch(error => {
980
+ logger.warn("background model refresh failed", {
981
+ error: error instanceof Error ? error.message : String(error),
982
+ });
983
+ })
984
+ .finally(() => {
985
+ if (this.#backgroundRefresh === refreshPromise) {
986
+ this.#backgroundRefresh = undefined;
987
+ }
988
+ });
989
+ this.#backgroundRefresh = refreshPromise;
990
+ }
991
+
992
+ async refreshProvider(providerId: string, strategy: ModelRefreshStrategy = "online"): Promise<void> {
993
+ this.#suspendRebuild();
994
+ try {
995
+ this.#reloadStaticModels();
996
+ for (const selector of this.#suppressedSelectors.keys()) {
997
+ if (selector.startsWith(`${providerId}/`)) {
998
+ this.#suppressedSelectors.delete(selector);
999
+ }
1000
+ }
1001
+ await this.#refreshRuntimeDiscoveries(strategy, new Set([providerId]));
1002
+ } finally {
1003
+ this.#resumeRebuild();
1004
+ }
1005
+ }
1006
+
1007
+ #reloadStaticModels(): void {
1008
+ const currentMtime = this.#modelsConfigFile.getMtimeMs();
1009
+ if (currentMtime !== null && currentMtime === this.#lastStaticLoadMtime) {
1010
+ // models.json unchanged since last load; reload + canonical rebuild would be redundant.
1011
+ return;
1012
+ }
1013
+ this.#modelsConfigFile.invalidate();
1014
+ this.#customProviderApiKeys.clear();
1015
+ this.#keylessProviders.clear();
1016
+ this.#discoverableProviders = [];
1017
+ // Drop config-sourced apiKeys from AuthStorage before reload; entries
1018
+ // removed from models.yml must actually disappear from the resolver, not
1019
+ // linger from the previous parse. The post-load setters below repopulate.
1020
+ this.authStorage.clearConfigApiKeys();
1021
+ // Restore runtime API keys before #loadModels — survives because
1022
+ // #loadModels only calls .set() on #customProviderApiKeys, never reassigns it.
1023
+ for (const [k, v] of this.#runtimeProviderApiKeys) {
1024
+ this.#customProviderApiKeys.set(k, v);
1025
+ }
1026
+ this.#providerOverrides.clear();
1027
+ this.#modelOverrides.clear();
1028
+ this.#equivalenceConfig = undefined;
1029
+ this.#configError = undefined;
1030
+ this.#providerDiscoveryStates.clear();
1031
+ this.#loadModels();
1032
+ }
1033
+
1034
+ /**
1035
+ * Get any error from loading models.json (undefined if no error).
1036
+ */
1037
+ getError(): ConfigError | undefined {
1038
+ return this.#configError;
1039
+ }
1040
+
1041
+ #loadModels() {
1042
+ // Load custom models from models.json first (to know which providers to override)
1043
+ const {
1044
+ models: customModels = [],
1045
+ overrides = new Map(),
1046
+ modelOverrides = new Map(),
1047
+ keylessProviders = new Set(),
1048
+ discoverableProviders = [],
1049
+ configuredProviders = new Set(),
1050
+ equivalence,
1051
+ error: configError,
1052
+ } = this.#loadCustomModels();
1053
+ this.#configError = configError;
1054
+ this.#keylessProviders = keylessProviders;
1055
+ this.#discoverableProviders = discoverableProviders;
1056
+ this.#customModelOverlays = customModels;
1057
+ this.#providerOverrides = overrides;
1058
+ this.#modelOverrides = modelOverrides;
1059
+ this.#equivalenceConfig = equivalence;
1060
+
1061
+ this.#addImplicitDiscoverableProviders(configuredProviders);
1062
+ let builtInModels = this.#applyHardcodedModelPolicies(this.#loadBuiltInModels(overrides));
1063
+ const cachedStandardResult = this.#loadCachedStandardProviderModels();
1064
+ const cachedStandardModels = this.#applyHardcodedModelPolicies(cachedStandardResult.models);
1065
+ const cachedDiscoveries = this.#applyHardcodedModelPolicies(this.#loadCachedDiscoverableModels());
1066
+ // Only drop bundled fallback models when the cached project-catalog row is
1067
+ // itself fresh AND authoritative. A stale or non-authoritative snapshot
1068
+ // (e.g. after ADC discovery failure rewrote the row with authoritative=0)
1069
+ // must not strip bundled Vertex Gemini entries — that would leave only the
1070
+ // stale project-scoped rows in API-key-only environments.
1071
+ const cachedAuthoritativeProviders = new Set<string>();
1072
+ for (const provider of providersWithAuthoritativeProjectCatalog(cachedStandardModels)) {
1073
+ if (cachedStandardResult.authoritativeFreshProviders.has(provider)) {
1074
+ cachedAuthoritativeProviders.add(provider);
1075
+ }
1076
+ }
1077
+ for (const provider of cachedStandardResult.authoritativeFreshProviders) {
1078
+ if (AUTHORITATIVE_RUNTIME_CATALOG_PROVIDERS.has(provider)) {
1079
+ cachedAuthoritativeProviders.add(provider);
1080
+ }
1081
+ }
1082
+ if (cachedAuthoritativeProviders.size > 0) {
1083
+ builtInModels = dropProviderModels(builtInModels, cachedAuthoritativeProviders);
1084
+ }
1085
+ const resolvedDefaults = this.#mergeResolvedModels(
1086
+ this.#mergeResolvedModels(builtInModels, cachedStandardModels),
1087
+ cachedDiscoveries,
1088
+ );
1089
+ const withConfigModels = this.#mergeCustomModels(resolvedDefaults, this.#customModelOverlays);
1090
+ // Merge runtime extension models so they survive refresh() cycles
1091
+ const combined = this.#mergeCustomModels(withConfigModels, this.#runtimeModelOverlays);
1092
+ const withModelOverrides = this.#applyModelOverrides(combined, this.#modelOverrides);
1093
+ this.#models = this.#applyRuntimeProviderOverrides(withModelOverrides);
1094
+ this.#rebuildCanonicalIndex();
1095
+ this.#lastStaticLoadMtime = this.#modelsConfigFile.getMtimeMs();
1096
+ }
1097
+
1098
+ /** Load built-in models, applying provider-level overrides only.
1099
+ * Per-model overrides are applied later by #applyModelOverrides. */
1100
+ #loadBuiltInModels(overrides: Map<string, ProviderOverride>): Model<Api>[] {
1101
+ return getBundledProviders().flatMap(provider => {
1102
+ const models = getBundledModels(provider as Parameters<typeof getBundledModels>[0]) as Model<Api>[];
1103
+ const providerOverride = overrides.get(provider);
1104
+
1105
+ return models.map(m => {
1106
+ if (!providerOverride) return m;
1107
+ const withTransportOverride = this.#applyProviderTransportOverride(m, providerOverride);
1108
+ return {
1109
+ ...withTransportOverride,
1110
+ compat: mergeCompat(m.compat, providerOverride.compat),
1111
+ };
1112
+ });
1113
+ });
1114
+ }
1115
+
1116
+ #mergeResolvedModels(baseModels: Model<Api>[], replacementModels: Model<Api>[]): Model<Api>[] {
1117
+ const merged = [...baseModels];
1118
+ const indexByKey = new Map<string, number>();
1119
+ for (let i = 0; i < merged.length; i += 1) {
1120
+ const m = merged[i];
1121
+ indexByKey.set(`${m.provider}\u0000${m.id}`, i);
1122
+ }
1123
+ for (const replacementModel of replacementModels) {
1124
+ const key = `${replacementModel.provider}\u0000${replacementModel.id}`;
1125
+ const existingIndex = indexByKey.get(key);
1126
+ if (existingIndex !== undefined) {
1127
+ const existing = merged[existingIndex];
1128
+ merged[existingIndex] = {
1129
+ ...replacementModel,
1130
+ contextWindow:
1131
+ replacementModel.contextWindow === UNK_CONTEXT_WINDOW
1132
+ ? existing.contextWindow
1133
+ : replacementModel.contextWindow,
1134
+ maxTokens:
1135
+ replacementModel.maxTokens === UNK_MAX_TOKENS ? existing.maxTokens : replacementModel.maxTokens,
1136
+ };
1137
+ } else {
1138
+ merged.push(replacementModel);
1139
+ indexByKey.set(key, merged.length - 1);
1140
+ }
1141
+ }
1142
+ return merged;
1143
+ }
1144
+
1145
+ /** Merge custom models with built-in, replacing by provider+id match */
1146
+ #mergeCustomModels(builtInModels: Model<Api>[], customModels: CustomModelOverlay[]): Model<Api>[] {
1147
+ const merged = [...builtInModels];
1148
+ const indexByKey = new Map<string, number>();
1149
+ for (let i = 0; i < merged.length; i += 1) {
1150
+ const m = merged[i];
1151
+ indexByKey.set(`${m.provider}\u0000${m.id}`, i);
1152
+ }
1153
+ for (const customModel of customModels) {
1154
+ const key = `${customModel.provider}\u0000${customModel.id}`;
1155
+ const existingIndex = indexByKey.get(key);
1156
+ if (existingIndex !== undefined) {
1157
+ const existingModel = merged[existingIndex];
1158
+ merged[existingIndex] = enrichModelThinking({
1159
+ ...existingModel,
1160
+ id: customModel.id,
1161
+ provider: customModel.provider,
1162
+ api: customModel.api,
1163
+ baseUrl: customModel.baseUrl,
1164
+ name: customModel.name ?? existingModel.name,
1165
+ reasoning: customModel.reasoning ?? existingModel.reasoning,
1166
+ thinking: customModel.thinking ?? existingModel.thinking,
1167
+ input: customModel.input ?? existingModel.input,
1168
+ cost: customModel.cost ?? existingModel.cost,
1169
+ contextWindow: customModel.contextWindow ?? existingModel.contextWindow,
1170
+ maxTokens: customModel.maxTokens ?? existingModel.maxTokens,
1171
+ omitMaxOutputTokens: customModel.omitMaxOutputTokens ?? existingModel.omitMaxOutputTokens,
1172
+ // Same-id custom definitions replace bundled transport behavior. Provider-level
1173
+ // headers/compat were already folded into customModel during parsing; do not
1174
+ // re-merge bundled transport metadata here.
1175
+ headers: customModel.headers,
1176
+ compat: customModel.compat,
1177
+ contextPromotionTarget: customModel.contextPromotionTarget ?? existingModel.contextPromotionTarget,
1178
+ premiumMultiplier: customModel.premiumMultiplier ?? existingModel.premiumMultiplier,
1179
+ } as Model<Api>);
1180
+ } else {
1181
+ merged.push(finalizeCustomModel(customModel, { useDefaults: true }));
1182
+ indexByKey.set(key, merged.length - 1);
1183
+ }
1184
+ }
1185
+ return merged;
1186
+ }
1187
+
1188
+ #loadCachedStandardProviderModels(): { models: Model<Api>[]; authoritativeFreshProviders: Set<string> } {
1189
+ const configuredDiscoveryProviders = new Set(this.#discoverableProviders.map(provider => provider.provider));
1190
+ const cachedModels: Model<Api>[] = [];
1191
+ const authoritativeFreshProviders = new Set<string>();
1192
+ for (const providerId of STARTUP_MODEL_CACHE_PROVIDER_IDS) {
1193
+ if (configuredDiscoveryProviders.has(providerId)) {
1194
+ continue;
1195
+ }
1196
+ const cache = readModelCache<Api>(providerId, 24 * 60 * 60 * 1000, Date.now, this.#cacheDbPath);
1197
+ if (!cache) {
1198
+ continue;
1199
+ }
1200
+ if (cache.fresh && cache.authoritative) {
1201
+ authoritativeFreshProviders.add(providerId);
1202
+ }
1203
+ const models = cache.models.map(model =>
1204
+ model.provider === providerId ? model : { ...model, provider: providerId },
1205
+ );
1206
+ const providerOverride = this.#providerOverrides.get(providerId);
1207
+ const withTransport = providerOverride
1208
+ ? models.map(model => this.#applyProviderTransportOverride(model, providerOverride))
1209
+ : models;
1210
+ const withCompat = providerOverride?.compat
1211
+ ? withTransport.map(model => ({ ...model, compat: mergeCompat(model.compat, providerOverride.compat) }))
1212
+ : withTransport;
1213
+ cachedModels.push(...this.#applyProviderModelOverrides(providerId, withCompat));
1214
+ }
1215
+ return { models: cachedModels, authoritativeFreshProviders };
1216
+ }
1217
+
1218
+ #loadCachedDiscoverableModels(): Model<Api>[] {
1219
+ const cachedModels: Model<Api>[] = [];
1220
+ for (const providerConfig of this.#discoverableProviders) {
1221
+ const cache = readModelCache<Api>(providerConfig.provider, 24 * 60 * 60 * 1000, Date.now, this.#cacheDbPath);
1222
+ if (!cache) {
1223
+ this.#providerDiscoveryStates.set(providerConfig.provider, {
1224
+ provider: providerConfig.provider,
1225
+ status: "idle",
1226
+ optional: providerConfig.optional ?? false,
1227
+ stale: false,
1228
+ models: [],
1229
+ });
1230
+ continue;
1231
+ }
1232
+ const models = this.#applyProviderModelOverrides(
1233
+ providerConfig.provider,
1234
+ this.#normalizeDiscoverableModels(
1235
+ providerConfig,
1236
+ this.#applyProviderCompat(providerConfig.compat, cache.models),
1237
+ ),
1238
+ );
1239
+ cachedModels.push(...models);
1240
+ this.#providerDiscoveryStates.set(providerConfig.provider, {
1241
+ provider: providerConfig.provider,
1242
+ status: "cached",
1243
+ optional: providerConfig.optional ?? false,
1244
+ stale: !cache.fresh || !cache.authoritative,
1245
+ fetchedAt: cache.updatedAt,
1246
+ models: models.map(model => model.id),
1247
+ });
1248
+ }
1249
+ return cachedModels;
1250
+ }
1251
+
1252
+ #applyProviderCompat(compat: Model<Api>["compat"] | undefined, models: Model<Api>[]): Model<Api>[] {
1253
+ if (!compat) return models;
1254
+ return models.map(model => ({ ...model, compat: mergeCompat(model.compat, compat) }));
1255
+ }
1256
+
1257
+ #normalizeDiscoverableModels(providerConfig: DiscoveryProviderConfig, models: Model<Api>[]): Model<Api>[] {
1258
+ if (providerConfig.provider !== "ollama" || providerConfig.api !== "openai-responses") {
1259
+ return models;
1260
+ }
1261
+
1262
+ const contextLengthOverride = getOllamaContextLengthOverride();
1263
+ return models.map(model => {
1264
+ const normalized = model.api === "openai-completions" ? { ...model, api: "openai-responses" as const } : model;
1265
+ if (contextLengthOverride === undefined) {
1266
+ return normalized;
1267
+ }
1268
+ return {
1269
+ ...normalized,
1270
+ contextWindow: contextLengthOverride,
1271
+ maxTokens: Math.min(contextLengthOverride, DISCOVERY_DEFAULT_MAX_TOKENS),
1272
+ };
1273
+ });
1274
+ }
1275
+
1276
+ #addImplicitDiscoverableProviders(configuredProviders: Set<string>): void {
1277
+ const disabledProviders = getDisabledProviderIdsFromSettings();
1278
+ if (!configuredProviders.has("ollama") && !disabledProviders.has("ollama")) {
1279
+ this.#discoverableProviders.push({
1280
+ provider: "ollama",
1281
+ api: "openai-responses",
1282
+ baseUrl: getImplicitOllamaBaseUrl(),
1283
+ discovery: { type: "ollama" },
1284
+ optional: true,
1285
+ });
1286
+ this.#keylessProviders.add("ollama");
1287
+ }
1288
+ if (!configuredProviders.has("llama.cpp") && !disabledProviders.has("llama.cpp")) {
1289
+ this.#discoverableProviders.push({
1290
+ provider: "llama.cpp",
1291
+ api: "openai-responses",
1292
+ baseUrl: Bun.env.LLAMA_CPP_BASE_URL || "http://127.0.0.1:8080",
1293
+ discovery: { type: "llama.cpp" },
1294
+ optional: true,
1295
+ });
1296
+ // Only mark as keyless if no API key is configured
1297
+ if (!this.authStorage.hasAuth("llama.cpp")) {
1298
+ this.#keylessProviders.add("llama.cpp");
1299
+ }
1300
+ }
1301
+ if (!configuredProviders.has("lm-studio") && !disabledProviders.has("lm-studio")) {
1302
+ this.#discoverableProviders.push({
1303
+ provider: "lm-studio",
1304
+ api: "openai-completions",
1305
+ baseUrl: Bun.env.LM_STUDIO_BASE_URL || "http://127.0.0.1:1234/v1",
1306
+ discovery: { type: "lm-studio" },
1307
+ optional: true,
1308
+ });
1309
+ this.#keylessProviders.add("lm-studio");
1310
+ }
1311
+ }
1312
+
1313
+ #loadCustomModels(): CustomModelsResult {
1314
+ const { value, error, status } = this.#modelsConfigFile.tryLoad();
1315
+
1316
+ if (status === "error") {
1317
+ return {
1318
+ models: [],
1319
+ overrides: new Map(),
1320
+ modelOverrides: new Map(),
1321
+ keylessProviders: new Set(),
1322
+ discoverableProviders: [],
1323
+ configuredProviders: new Set(),
1324
+ error,
1325
+ found: true,
1326
+ };
1327
+ } else if (status === "not-found") {
1328
+ return {
1329
+ models: [],
1330
+ overrides: new Map(),
1331
+ modelOverrides: new Map(),
1332
+ keylessProviders: new Set(),
1333
+ discoverableProviders: [],
1334
+ configuredProviders: new Set(),
1335
+ found: false,
1336
+ };
1337
+ }
1338
+
1339
+ const overrides = new Map<string, ProviderOverride>();
1340
+ const allModelOverrides = new Map<string, Map<string, ModelOverride>>();
1341
+ const keylessProviders = new Set<string>();
1342
+ const discoverableProviders: DiscoveryProviderConfig[] = [];
1343
+ const providerEntries = Object.entries(value.providers ?? {});
1344
+ const configuredProviders = new Set(Object.keys(value.providers ?? {}));
1345
+
1346
+ for (const [providerName, providerConfig] of providerEntries) {
1347
+ // Always set overrides when baseUrl/headers/apiKey/authHeader/compat/disableStrictTools/transport are present
1348
+ if (
1349
+ providerConfig.baseUrl ||
1350
+ providerConfig.headers ||
1351
+ providerConfig.apiKey ||
1352
+ providerConfig.authHeader !== undefined ||
1353
+ providerConfig.compat ||
1354
+ providerConfig.disableStrictTools ||
1355
+ providerConfig.transport
1356
+ ) {
1357
+ const disableStrictCompat = providerConfig.disableStrictTools ? { disableStrictTools: true } : undefined;
1358
+ overrides.set(providerName, {
1359
+ baseUrl: providerConfig.baseUrl,
1360
+ headers: providerConfig.headers,
1361
+ apiKey: providerConfig.apiKey,
1362
+ authHeader: providerConfig.authHeader,
1363
+ compat: mergeCompat(providerConfig.compat, disableStrictCompat),
1364
+ transport: providerConfig.transport,
1365
+ });
1366
+ }
1367
+
1368
+ const authMode = (providerConfig.auth ?? "apiKey") as ProviderAuthMode;
1369
+ if (authMode === "none") {
1370
+ keylessProviders.add(providerName);
1371
+ }
1372
+
1373
+ if (providerConfig.discovery && (providerConfig.api || providerConfig.discovery.type === "proxy")) {
1374
+ const disableStrictCompat = providerConfig.disableStrictTools ? { disableStrictTools: true } : undefined;
1375
+ discoverableProviders.push({
1376
+ provider: providerName,
1377
+ // Proxy discovery derives per-model api from /v1/models's
1378
+ // supported_endpoint_types; the provider-level api is only a
1379
+ // fallback for entries that don't advertise one.
1380
+ api: (providerConfig.api ?? "openai-completions") as Api,
1381
+ baseUrl: providerConfig.baseUrl,
1382
+ headers: providerConfig.headers,
1383
+ compat: mergeCompat(providerConfig.compat, disableStrictCompat),
1384
+ discovery: providerConfig.discovery,
1385
+ optional: false,
1386
+ });
1387
+ }
1388
+
1389
+ // Store API key for fallback resolver AND register as config override
1390
+ // so it wins over OAuth tokens from the broker — when the user pins a
1391
+ // bearer in models.yml (e.g. for an auth-gateway baseUrl), that bearer
1392
+ // must authenticate the outbound request.
1393
+ if (providerConfig.apiKey) {
1394
+ this.#customProviderApiKeys.set(providerName, providerConfig.apiKey);
1395
+ const resolved = resolveApiKeyConfig(providerConfig.apiKey);
1396
+ if (resolved) this.authStorage.setConfigApiKey(providerName, resolved);
1397
+ }
1398
+
1399
+ // Parse per-model overrides
1400
+ if (providerConfig.modelOverrides) {
1401
+ const perModel = new Map<string, ModelOverride>();
1402
+ for (const [modelId, override] of Object.entries(providerConfig.modelOverrides)) {
1403
+ perModel.set(modelId, override);
1404
+ }
1405
+ allModelOverrides.set(providerName, perModel);
1406
+ }
1407
+ }
1408
+
1409
+ return {
1410
+ models: this.#parseModels(value),
1411
+ overrides,
1412
+ modelOverrides: allModelOverrides,
1413
+ keylessProviders,
1414
+ discoverableProviders,
1415
+ configuredProviders,
1416
+ equivalence: value.equivalence,
1417
+ found: true,
1418
+ };
1419
+ }
1420
+
1421
+ async #refreshRuntimeDiscoveries(
1422
+ strategy: ModelRefreshStrategy,
1423
+ providerFilter?: ReadonlySet<string>,
1424
+ ): Promise<void> {
1425
+ const disabledProviders = getDisabledProviderIdsFromSettings();
1426
+ const selectedDiscoverableProviders = (
1427
+ providerFilter
1428
+ ? this.#discoverableProviders.filter(provider => providerFilter.has(provider.provider))
1429
+ : this.#discoverableProviders
1430
+ ).filter(provider => !disabledProviders.has(provider.provider));
1431
+ const configuredDiscoveriesPromise =
1432
+ selectedDiscoverableProviders.length === 0
1433
+ ? Promise.resolve<Model<Api>[]>([])
1434
+ : Promise.all(
1435
+ selectedDiscoverableProviders.map(provider => this.#discoverProviderModels(provider, strategy)),
1436
+ ).then(results => results.flat());
1437
+ const [configuredDiscovered, builtInDiscovery] = await Promise.all([
1438
+ configuredDiscoveriesPromise,
1439
+ this.#discoverBuiltInProviderModels(strategy, providerFilter),
1440
+ ]);
1441
+ const discovered = [...configuredDiscovered, ...builtInDiscovery.models];
1442
+ if (discovered.length === 0 && builtInDiscovery.authoritativeProviders.size === 0) {
1443
+ return;
1444
+ }
1445
+ const discoveredModels = this.#applyHardcodedModelPolicies(
1446
+ discovered.map(model =>
1447
+ mergeDiscoveredModel(
1448
+ model,
1449
+ this.find(model.provider, model.id),
1450
+ this.#providerOverrides.get(model.provider),
1451
+ ),
1452
+ ),
1453
+ );
1454
+ const authoritativeProviders = providersWithAuthoritativeProjectCatalog(discoveredModels);
1455
+ for (const provider of builtInDiscovery.authoritativeProviders) {
1456
+ authoritativeProviders.add(provider);
1457
+ }
1458
+ const baseModels =
1459
+ authoritativeProviders.size > 0 ? dropProviderModels(this.#models, authoritativeProviders) : this.#models;
1460
+ const resolved = this.#mergeResolvedModels(baseModels, discoveredModels);
1461
+ const withConfigModels = this.#mergeCustomModels(resolved, this.#customModelOverlays);
1462
+ // Merge runtime extension models so they survive online discovery completion
1463
+ const combined = this.#mergeCustomModels(withConfigModels, this.#runtimeModelOverlays);
1464
+ const withModelOverrides = this.#applyModelOverrides(combined, this.#modelOverrides);
1465
+ this.#models = this.#applyRuntimeProviderOverrides(withModelOverrides);
1466
+ this.#rebuildCanonicalIndex();
1467
+ }
1468
+
1469
+ async #discoverProviderModels(
1470
+ providerConfig: DiscoveryProviderConfig,
1471
+ strategy: ModelRefreshStrategy,
1472
+ ): Promise<Model<Api>[]> {
1473
+ const cached = readModelCache<Api>(providerConfig.provider, 24 * 60 * 60 * 1000, Date.now, this.#cacheDbPath);
1474
+ const requiresAuth = !this.#keylessProviders.has(providerConfig.provider);
1475
+ if (requiresAuth) {
1476
+ const apiKey = await this.#peekApiKeyForProvider(providerConfig.provider);
1477
+ if (!isAuthenticated(apiKey)) {
1478
+ this.#providerDiscoveryStates.set(providerConfig.provider, {
1479
+ provider: providerConfig.provider,
1480
+ status: "unauthenticated",
1481
+ optional: providerConfig.optional ?? false,
1482
+ stale: cached !== null,
1483
+ fetchedAt: cached?.updatedAt,
1484
+ models: cached?.models.map(model => model.id) ?? [],
1485
+ });
1486
+ this.#lastDiscoveryWarnings.delete(providerConfig.provider);
1487
+ return cached?.models ?? [];
1488
+ }
1489
+ }
1490
+
1491
+ const providerId = providerConfig.provider;
1492
+ let discoveryError: string | undefined;
1493
+ const fetchDynamicModels = async (): Promise<readonly Model<Api>[] | null> => {
1494
+ try {
1495
+ const models = await this.#discoverModelsByProviderType(providerConfig);
1496
+ this.#lastDiscoveryWarnings.delete(providerId);
1497
+ return models;
1498
+ } catch (error) {
1499
+ discoveryError = error instanceof Error ? error.message : String(error);
1500
+ return null;
1501
+ }
1502
+ };
1503
+
1504
+ const manager = createModelManager<Api>({
1505
+ providerId,
1506
+ staticModels: [],
1507
+ cacheDbPath: this.#cacheDbPath,
1508
+ cacheTtlMs: 24 * 60 * 60 * 1000,
1509
+ fetchDynamicModels,
1510
+ });
1511
+ const result = await manager.refresh(strategy);
1512
+ const status = discoveryError
1513
+ ? result.models.length > 0
1514
+ ? "cached"
1515
+ : "unavailable"
1516
+ : strategy === "offline"
1517
+ ? cached
1518
+ ? "cached"
1519
+ : "idle"
1520
+ : result.models.length > 0
1521
+ ? "ok"
1522
+ : "empty";
1523
+ this.#providerDiscoveryStates.set(providerId, {
1524
+ provider: providerId,
1525
+ status,
1526
+ optional: providerConfig.optional ?? false,
1527
+ stale: result.stale || status === "cached",
1528
+ fetchedAt: discoveryError ? cached?.updatedAt : Date.now(),
1529
+ models: result.models.map(model => model.id),
1530
+ error: discoveryError,
1531
+ });
1532
+ if (discoveryError) {
1533
+ this.#warnProviderDiscoveryFailure(providerConfig, discoveryError);
1534
+ }
1535
+ return this.#applyProviderModelOverrides(
1536
+ providerId,
1537
+ this.#normalizeDiscoverableModels(
1538
+ providerConfig,
1539
+ this.#applyProviderCompat(providerConfig.compat, result.models),
1540
+ ),
1541
+ );
1542
+ }
1543
+
1544
+ #discoverModelsByProviderType(providerConfig: DiscoveryProviderConfig): Promise<Model<Api>[]> {
1545
+ switch (providerConfig.discovery.type) {
1546
+ case "ollama":
1547
+ return this.#discoverOllamaModels(providerConfig);
1548
+ case "llama.cpp":
1549
+ return this.#discoverLlamaCppModels(providerConfig);
1550
+ case "lm-studio":
1551
+ case "openai-models-list":
1552
+ return this.#discoverOpenAIModelsList(providerConfig);
1553
+ case "proxy":
1554
+ return this.#discoverProxyModels(providerConfig);
1555
+ }
1556
+ }
1557
+
1558
+ #warnProviderDiscoveryFailure(providerConfig: DiscoveryProviderConfig, error: string): void {
1559
+ const previous = this.#lastDiscoveryWarnings.get(providerConfig.provider);
1560
+ if (previous === error) {
1561
+ return;
1562
+ }
1563
+ this.#lastDiscoveryWarnings.set(providerConfig.provider, error);
1564
+ logger.warn("model discovery failed for provider", {
1565
+ provider: providerConfig.provider,
1566
+ url: providerConfig.baseUrl,
1567
+ error,
1568
+ });
1569
+ }
1570
+
1571
+ async #discoverBuiltInProviderModels(
1572
+ strategy: ModelRefreshStrategy,
1573
+ providerFilter?: ReadonlySet<string>,
1574
+ ): Promise<BuiltInDiscoveryResult> {
1575
+ // Skip providers already handled by configured discovery (e.g. user-configured ollama with discovery.type)
1576
+ const configuredDiscoveryProviders = new Set(this.#discoverableProviders.map(p => p.provider));
1577
+ const managerOptions = (await this.#collectBuiltInModelManagerOptions()).filter(opts => {
1578
+ if (configuredDiscoveryProviders.has(opts.providerId)) {
1579
+ return false;
1580
+ }
1581
+ return providerFilter ? providerFilter.has(opts.providerId) : true;
1582
+ });
1583
+ if (managerOptions.length === 0) {
1584
+ return { models: [], authoritativeProviders: new Set() };
1585
+ }
1586
+ const discoveries = await Promise.all(
1587
+ managerOptions.map(options => this.#discoverWithModelManager(options, strategy)),
1588
+ );
1589
+ const authoritativeProviders = new Set<string>();
1590
+ const models: Model<Api>[] = [];
1591
+ for (const discovery of discoveries) {
1592
+ models.push(...discovery.models);
1593
+ for (const provider of discovery.authoritativeProviders) {
1594
+ authoritativeProviders.add(provider);
1595
+ }
1596
+ }
1597
+ return { models, authoritativeProviders };
1598
+ }
1599
+
1600
+ async #collectBuiltInModelManagerOptions(): Promise<ModelManagerOptions<Api>[]> {
1601
+ const specialProviderDescriptors: Array<{
1602
+ providerId: string;
1603
+ resolveKey: (value: string | undefined) => string | undefined;
1604
+ createOptions: (key: string) => ModelManagerOptions<Api>;
1605
+ }> = [
1606
+ {
1607
+ providerId: "google-antigravity",
1608
+ resolveKey: extractGoogleOAuthToken,
1609
+ createOptions: oauthToken =>
1610
+ googleAntigravityModelManagerOptions({
1611
+ oauthToken,
1612
+ endpoint: this.getProviderBaseUrl("google-antigravity"),
1613
+ }),
1614
+ },
1615
+ {
1616
+ providerId: "google-gemini-cli",
1617
+ resolveKey: extractGoogleOAuthToken,
1618
+ createOptions: oauthToken =>
1619
+ googleGeminiCliModelManagerOptions({
1620
+ oauthToken,
1621
+ endpoint: this.getProviderBaseUrl("google-gemini-cli"),
1622
+ }),
1623
+ },
1624
+ {
1625
+ providerId: "openai-codex",
1626
+ resolveKey: value => value,
1627
+ createOptions: accessToken => {
1628
+ const accountId = resolveOAuthAccountIdForAccessToken(this.authStorage, "openai-codex", accessToken);
1629
+ return openaiCodexModelManagerOptions({
1630
+ accessToken,
1631
+ accountId,
1632
+ });
1633
+ },
1634
+ },
1635
+ ];
1636
+ const disabledProviders = getDisabledProviderIdsFromSettings();
1637
+ const standardProviderDescriptors = PROVIDER_DESCRIPTORS.filter(
1638
+ descriptor => !disabledProviders.has(descriptor.providerId),
1639
+ );
1640
+ const enabledSpecialProviderDescriptors = specialProviderDescriptors.filter(
1641
+ descriptor => !disabledProviders.has(descriptor.providerId),
1642
+ );
1643
+ // Use peekApiKey to avoid OAuth token refresh during discovery.
1644
+ // The token is only needed if the dynamic fetch fires (cache miss),
1645
+ // and failures there are handled gracefully.
1646
+ const peekKey = (descriptor: { providerId: string }) => this.#peekApiKeyForProvider(descriptor.providerId);
1647
+ const [standardProviderKeys, specialKeys] = await Promise.all([
1648
+ Promise.all(standardProviderDescriptors.map(peekKey)),
1649
+ Promise.all(enabledSpecialProviderDescriptors.map(peekKey)),
1650
+ ]);
1651
+ const options: ModelManagerOptions<Api>[] = [];
1652
+ for (let i = 0; i < standardProviderDescriptors.length; i++) {
1653
+ const descriptor = standardProviderDescriptors[i];
1654
+ const apiKey = standardProviderKeys[i];
1655
+ if (isAuthenticated(apiKey) || descriptor.allowUnauthenticated) {
1656
+ options.push(
1657
+ descriptor.createModelManagerOptions({
1658
+ apiKey: isAuthenticated(apiKey) ? apiKey : undefined,
1659
+ baseUrl: this.getProviderBaseUrl(descriptor.providerId),
1660
+ }),
1661
+ );
1662
+ }
1663
+ }
1664
+
1665
+ for (let i = 0; i < enabledSpecialProviderDescriptors.length; i++) {
1666
+ const descriptor = enabledSpecialProviderDescriptors[i];
1667
+ const key = descriptor.resolveKey(specialKeys[i]);
1668
+ if (!isAuthenticated(key)) {
1669
+ continue;
1670
+ }
1671
+ options.push(descriptor.createOptions(key));
1672
+ }
1673
+ return options;
1674
+ }
1675
+
1676
+ async #discoverWithModelManager(
1677
+ options: ModelManagerOptions<Api>,
1678
+ strategy: ModelRefreshStrategy,
1679
+ ): Promise<BuiltInDiscoveryResult> {
1680
+ try {
1681
+ const manager = createModelManager({ ...options, cacheDbPath: this.#cacheDbPath });
1682
+ const result = await manager.refresh(strategy);
1683
+ const models = result.models.map(model =>
1684
+ model.provider === options.providerId ? model : { ...model, provider: options.providerId },
1685
+ );
1686
+ const authoritativeProviders = new Set<string>();
1687
+ if (options.dynamicModelsAuthoritative && !result.stale) {
1688
+ authoritativeProviders.add(options.providerId);
1689
+ }
1690
+ return { models, authoritativeProviders };
1691
+ } catch (error) {
1692
+ logger.warn("model discovery failed for provider", {
1693
+ provider: options.providerId,
1694
+ error: error instanceof Error ? error.message : String(error),
1695
+ });
1696
+ return { models: [], authoritativeProviders: new Set() };
1697
+ }
1698
+ }
1699
+
1700
+ async #discoverOllamaModelMetadata(
1701
+ endpoint: string,
1702
+ modelId: string,
1703
+ headers: Record<string, string> | undefined,
1704
+ ): Promise<OllamaDiscoveredModelMetadata | null> {
1705
+ const showUrl = `${endpoint}/api/show`;
1706
+ try {
1707
+ const response = await fetch(showUrl, {
1708
+ method: "POST",
1709
+ headers: { ...(headers ?? {}), "Content-Type": "application/json" },
1710
+ body: JSON.stringify({ model: modelId }),
1711
+ signal: AbortSignal.timeout(150),
1712
+ });
1713
+ if (!response.ok) {
1714
+ return null;
1715
+ }
1716
+ const payload = (await response.json()) as unknown;
1717
+ if (!isRecord(payload)) {
1718
+ return null;
1719
+ }
1720
+ const contextWindow = extractOllamaContextWindow(payload);
1721
+ const capabilities = payload.capabilities;
1722
+ if (Array.isArray(capabilities)) {
1723
+ const normalized = new Set(
1724
+ capabilities.flatMap(capability => (typeof capability === "string" ? [capability.toLowerCase()] : [])),
1725
+ );
1726
+ const supportsVision = normalized.has("vision") || normalized.has("image");
1727
+ return {
1728
+ reasoning: normalized.has("thinking"),
1729
+ input: supportsVision ? ["text", "image"] : ["text"],
1730
+ contextWindow,
1731
+ };
1732
+ }
1733
+ if (!isRecord(capabilities)) {
1734
+ return {
1735
+ reasoning: false,
1736
+ input: ["text"],
1737
+ contextWindow,
1738
+ };
1739
+ }
1740
+ const supportsVision = capabilities.vision === true || capabilities.image === true;
1741
+ return {
1742
+ reasoning: capabilities.thinking === true,
1743
+ input: supportsVision ? ["text", "image"] : ["text"],
1744
+ contextWindow,
1745
+ };
1746
+ } catch {
1747
+ return null;
1748
+ }
1749
+ }
1750
+
1751
+ async #discoverOllamaModels(providerConfig: DiscoveryProviderConfig): Promise<Model<Api>[]> {
1752
+ const endpoint = this.#normalizeOllamaBaseUrl(providerConfig.baseUrl);
1753
+ const tagsUrl = `${endpoint}/api/tags`;
1754
+ const headers = { ...(providerConfig.headers ?? {}) };
1755
+ const response = await fetch(tagsUrl, {
1756
+ headers,
1757
+ signal: AbortSignal.timeout(250),
1758
+ });
1759
+ if (!response.ok) {
1760
+ throw new Error(`HTTP ${response.status} from ${tagsUrl}`);
1761
+ }
1762
+ const payload = (await response.json()) as { models?: Array<{ name?: string; model?: string }> };
1763
+ const entries = (payload.models ?? []).flatMap(item => {
1764
+ const id = item.model || item.name;
1765
+ return id ? [{ id, name: item.name || id }] : [];
1766
+ });
1767
+ const metadataById = new Map(
1768
+ await Promise.all(
1769
+ entries.map(
1770
+ async entry => [entry.id, await this.#discoverOllamaModelMetadata(endpoint, entry.id, headers)] as const,
1771
+ ),
1772
+ ),
1773
+ );
1774
+ const discovered = entries.map(entry => {
1775
+ const metadata = metadataById.get(entry.id);
1776
+ return enrichModelThinking({
1777
+ id: entry.id,
1778
+ name: entry.name,
1779
+ api: providerConfig.api,
1780
+ provider: providerConfig.provider,
1781
+ baseUrl: `${endpoint}/v1`,
1782
+ reasoning: metadata?.reasoning ?? false,
1783
+ input: metadata?.input ?? ["text"],
1784
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1785
+ contextWindow: metadata?.contextWindow ?? 128000,
1786
+ maxTokens: Math.min(metadata?.contextWindow ?? Number.POSITIVE_INFINITY, DISCOVERY_DEFAULT_MAX_TOKENS),
1787
+ headers: providerConfig.headers,
1788
+ });
1789
+ });
1790
+ return this.#applyProviderModelOverrides(providerConfig.provider, discovered);
1791
+ }
1792
+
1793
+ async #discoverLlamaCppServerMetadata(
1794
+ baseUrl: string,
1795
+ headers: Record<string, string> | undefined,
1796
+ ): Promise<LlamaCppDiscoveredServerMetadata | null> {
1797
+ const propsUrl = `${this.#toLlamaCppNativeBaseUrl(baseUrl)}/props`;
1798
+ try {
1799
+ const response = await fetch(propsUrl, {
1800
+ headers,
1801
+ signal: AbortSignal.timeout(150),
1802
+ });
1803
+ if (!response.ok) {
1804
+ return null;
1805
+ }
1806
+ const payload = (await response.json()) as unknown;
1807
+ if (!isRecord(payload)) {
1808
+ return null;
1809
+ }
1810
+ return {
1811
+ contextWindow: extractLlamaCppContextWindow(payload),
1812
+ input: extractLlamaCppInputCapabilities(payload),
1813
+ };
1814
+ } catch {
1815
+ return null;
1816
+ }
1817
+ }
1818
+
1819
+ async #discoverLlamaCppModels(providerConfig: DiscoveryProviderConfig): Promise<Model<Api>[]> {
1820
+ const baseUrl = this.#normalizeLlamaCppBaseUrl(providerConfig.baseUrl);
1821
+ const modelsUrl = `${baseUrl}/models`;
1822
+
1823
+ const headers: Record<string, string> = { ...(providerConfig.headers ?? {}) };
1824
+ const apiKey = await this.authStorage.getApiKey(providerConfig.provider);
1825
+ if (apiKey && apiKey !== DEFAULT_LOCAL_TOKEN && apiKey !== kNoAuth) {
1826
+ headers.Authorization = `Bearer ${apiKey}`;
1827
+ }
1828
+
1829
+ const [response, serverMetadata] = await Promise.all([
1830
+ fetch(modelsUrl, {
1831
+ headers,
1832
+ signal: AbortSignal.timeout(250),
1833
+ }),
1834
+ this.#discoverLlamaCppServerMetadata(baseUrl, headers),
1835
+ ]);
1836
+ if (!response.ok) {
1837
+ throw new Error(`HTTP ${response.status} from ${modelsUrl}`);
1838
+ }
1839
+ const payload = (await response.json()) as { data?: Array<{ id: string }> };
1840
+ const models = payload.data ?? [];
1841
+ const discovered: Model<Api>[] = [];
1842
+ for (const item of models) {
1843
+ const id = item.id;
1844
+ if (!id) continue;
1845
+ discovered.push(
1846
+ enrichModelThinking({
1847
+ id,
1848
+ name: id,
1849
+ api: providerConfig.api,
1850
+ provider: providerConfig.provider,
1851
+ baseUrl,
1852
+ reasoning: false,
1853
+ input: serverMetadata?.input ?? ["text"],
1854
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1855
+ contextWindow: serverMetadata?.contextWindow ?? 128000,
1856
+ maxTokens: Math.min(
1857
+ serverMetadata?.contextWindow ?? Number.POSITIVE_INFINITY,
1858
+ DISCOVERY_DEFAULT_MAX_TOKENS,
1859
+ ),
1860
+ headers,
1861
+ compat: {
1862
+ supportsStore: false,
1863
+ supportsDeveloperRole: false,
1864
+ supportsReasoningEffort: false,
1865
+ },
1866
+ }),
1867
+ );
1868
+ }
1869
+ return this.#applyProviderModelOverrides(providerConfig.provider, discovered);
1870
+ }
1871
+
1872
+ async #discoverOpenAIModelsList(providerConfig: DiscoveryProviderConfig): Promise<Model<Api>[]> {
1873
+ const baseUrl = this.#normalizeOpenAIModelsListBaseUrl(providerConfig.baseUrl);
1874
+ const modelsUrl = `${baseUrl}/models`;
1875
+
1876
+ const headers: Record<string, string> = { ...(providerConfig.headers ?? {}) };
1877
+ const apiKey = await this.authStorage.getApiKey(providerConfig.provider);
1878
+ if (apiKey && apiKey !== DEFAULT_LOCAL_TOKEN && apiKey !== kNoAuth) {
1879
+ headers.Authorization = `Bearer ${apiKey}`;
1880
+ }
1881
+
1882
+ const response = await fetch(modelsUrl, {
1883
+ headers,
1884
+ signal: AbortSignal.timeout(10_000),
1885
+ });
1886
+ if (!response.ok) {
1887
+ throw new Error(`HTTP ${response.status} from ${modelsUrl}`);
1888
+ }
1889
+ const payload = (await response.json()) as { data?: Array<{ id: string }> };
1890
+ const models = payload.data ?? [];
1891
+ const discovered: Model<Api>[] = [];
1892
+ for (const item of models) {
1893
+ const id = item.id;
1894
+ if (!id) continue;
1895
+ discovered.push(
1896
+ enrichModelThinking({
1897
+ id,
1898
+ name: id,
1899
+ api: providerConfig.api,
1900
+ provider: providerConfig.provider,
1901
+ baseUrl,
1902
+ reasoning: false,
1903
+ input: ["text"],
1904
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1905
+ contextWindow: 128000,
1906
+ maxTokens: discoveryDefaultMaxTokens(providerConfig.api),
1907
+ headers,
1908
+ compat: {
1909
+ supportsStore: false,
1910
+ supportsDeveloperRole: false,
1911
+ supportsReasoningEffort: false,
1912
+ },
1913
+ }),
1914
+ );
1915
+ }
1916
+ return this.#applyProviderModelOverrides(providerConfig.provider, discovered);
1917
+ }
1918
+
1919
+ /**
1920
+ * Discover models from an Anthropic+OpenAI-compatible reseller proxy that
1921
+ * exposes both `/v1/messages` and `/v1/chat/completions`, advertising each
1922
+ * model's wire capabilities through `supported_endpoint_types` on
1923
+ * `GET /v1/models` (new-api / one-api-style proxies).
1924
+ *
1925
+ * Routing per model:
1926
+ * supported_endpoint_types: ["anthropic", ...] -> api: "anthropic-messages"
1927
+ * supported_endpoint_types: ["openai"] -> api: "openai-completions"
1928
+ * missing / neither -> provider-level api fallback
1929
+ *
1930
+ * Anthropic models share the same baseUrl; the Anthropic SDK strips a
1931
+ * trailing `/v1` itself before appending `/v1/messages`, so the discovery
1932
+ * URL (which ends in `/v1`) round-trips correctly.
1933
+ */
1934
+ async #discoverProxyModels(providerConfig: DiscoveryProviderConfig): Promise<Model<Api>[]> {
1935
+ const baseUrl = this.#normalizeOpenAIModelsListBaseUrl(providerConfig.baseUrl);
1936
+ const modelsUrl = `${baseUrl}/models`;
1937
+
1938
+ const headers: Record<string, string> = { ...(providerConfig.headers ?? {}) };
1939
+ const apiKey = await this.authStorage.getApiKey(providerConfig.provider);
1940
+ if (apiKey && apiKey !== DEFAULT_LOCAL_TOKEN && apiKey !== kNoAuth) {
1941
+ headers.Authorization = `Bearer ${apiKey}`;
1942
+ }
1943
+
1944
+ const response = await fetch(modelsUrl, {
1945
+ headers,
1946
+ signal: AbortSignal.timeout(10_000),
1947
+ });
1948
+ if (!response.ok) {
1949
+ throw new Error(`HTTP ${response.status} from ${modelsUrl}`);
1950
+ }
1951
+ const payload = (await response.json()) as {
1952
+ data?: Array<{ id?: string; name?: string; supported_endpoint_types?: string[] }>;
1953
+ };
1954
+ const items = payload.data ?? [];
1955
+ const discovered: Model<Api>[] = [];
1956
+ for (const item of items) {
1957
+ const id = item.id;
1958
+ if (!id) continue;
1959
+ const endpoints = item.supported_endpoint_types ?? [];
1960
+ const api: Api | undefined = endpoints.includes("anthropic")
1961
+ ? "anthropic-messages"
1962
+ : endpoints.includes("openai")
1963
+ ? "openai-completions"
1964
+ : providerConfig.api;
1965
+ if (!api) continue;
1966
+ const isAnthropic = api === "anthropic-messages";
1967
+ const reference = resolveCustomModelReference(id);
1968
+ const discoveryName = typeof item.name === "string" ? item.name.trim() : "";
1969
+ const displayName =
1970
+ reference?.name ??
1971
+ (discoveryName && discoveryName !== id ? discoveryName : undefined) ??
1972
+ stripBracketedModelIdAffixes(id) ??
1973
+ id;
1974
+ discovered.push(
1975
+ enrichModelThinking({
1976
+ id,
1977
+ name: displayName,
1978
+ api,
1979
+ provider: providerConfig.provider,
1980
+ baseUrl,
1981
+ reasoning: reference?.reasoning ?? false,
1982
+ thinking: reference?.thinking,
1983
+ input: reference?.input ?? ["text"],
1984
+ // Proxy pricing is provider-specific and usually does not match
1985
+ // upstream bundled catalogs, so keep costs local-unknown even when
1986
+ // we successfully recover the upstream model identity.
1987
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
1988
+ contextWindow: reference?.contextWindow ?? 128000,
1989
+ maxTokens: reference?.maxTokens ?? discoveryDefaultMaxTokens(api),
1990
+ headers,
1991
+ // OpenAI-compat fields are no-ops on anthropic models; the
1992
+ // Anthropic SDK ignores them. Provider-level disableStrictTools
1993
+ // flows in via #applyProviderCompat for the third-party-Anthropic
1994
+ // path. Cross-wire bundled compat is intentionally not copied:
1995
+ // request-shaping fields are provider-wire specific.
1996
+ compat: isAnthropic
1997
+ ? undefined
1998
+ : {
1999
+ supportsStore: false,
2000
+ supportsDeveloperRole: false,
2001
+ supportsReasoningEffort: false,
2002
+ },
2003
+ }),
2004
+ );
2005
+ }
2006
+ return this.#applyProviderModelOverrides(providerConfig.provider, discovered);
2007
+ }
2008
+
2009
+ #normalizeLlamaCppBaseUrl(baseUrl?: string): string {
2010
+ const defaultBaseUrl = "http://127.0.0.1:8080";
2011
+ const raw = baseUrl || defaultBaseUrl;
2012
+ try {
2013
+ const parsed = new URL(raw);
2014
+ const trimmedPath = parsed.pathname.replace(/\/+$/g, "");
2015
+ return `${parsed.protocol}//${parsed.host}${trimmedPath}`;
2016
+ } catch {
2017
+ return raw;
2018
+ }
2019
+ }
2020
+
2021
+ #toLlamaCppNativeBaseUrl(baseUrl: string): string {
2022
+ try {
2023
+ const parsed = new URL(baseUrl);
2024
+ const trimmedPath = parsed.pathname.replace(/\/+$/g, "");
2025
+ parsed.pathname = trimmedPath.endsWith("/v1") ? trimmedPath.slice(0, -3) || "/" : trimmedPath || "/";
2026
+ const normalized = `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
2027
+ return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
2028
+ } catch {
2029
+ return baseUrl.endsWith("/v1") ? baseUrl.slice(0, -3) : baseUrl;
2030
+ }
2031
+ }
2032
+
2033
+ #normalizeOpenAIModelsListBaseUrl(baseUrl?: string): string {
2034
+ const defaultBaseUrl = "http://127.0.0.1:1234/v1";
2035
+ const raw = baseUrl || defaultBaseUrl;
2036
+ try {
2037
+ const parsed = new URL(raw);
2038
+ const trimmedPath = parsed.pathname.replace(/\/+$/g, "");
2039
+ parsed.pathname = trimmedPath.endsWith("/v1") ? trimmedPath || "/v1" : `${trimmedPath}/v1`;
2040
+ return `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
2041
+ } catch {
2042
+ return raw;
2043
+ }
2044
+ }
2045
+ #normalizeOllamaBaseUrl(baseUrl?: string): string {
2046
+ const raw = baseUrl || DEFAULT_OLLAMA_BASE_URL;
2047
+ try {
2048
+ const parsed = new URL(raw);
2049
+ return `${parsed.protocol}//${parsed.host}`;
2050
+ } catch {
2051
+ return DEFAULT_OLLAMA_BASE_URL;
2052
+ }
2053
+ }
2054
+
2055
+ #applyProviderModelOverrides(provider: string, models: Model<Api>[]): Model<Api>[] {
2056
+ const overrides = this.#modelOverrides.get(provider);
2057
+ if (!overrides || overrides.size === 0) return models;
2058
+ return models.map(model => {
2059
+ const override = overrides.get(model.id);
2060
+ if (!override) return model;
2061
+ return applyModelOverride(model, override);
2062
+ });
2063
+ }
2064
+
2065
+ #mergeProviderOverride(baseOverride: ProviderOverride | undefined, override: ProviderOverride): ProviderOverride {
2066
+ return {
2067
+ baseUrl: override.baseUrl ?? baseOverride?.baseUrl,
2068
+ apiKey: override.apiKey ?? baseOverride?.apiKey,
2069
+ authHeader: override.authHeader ?? baseOverride?.authHeader,
2070
+ headers: override.headers ? { ...(baseOverride?.headers ?? {}), ...override.headers } : baseOverride?.headers,
2071
+ compat: override.compat ? mergeCompat(baseOverride?.compat, override.compat) : baseOverride?.compat,
2072
+ transport: override.transport ?? baseOverride?.transport,
2073
+ };
2074
+ }
2075
+ #applyProviderTransportOverride<T extends { baseUrl?: string; headers?: Record<string, string> }>(
2076
+ entry: T,
2077
+ override: Pick<ProviderOverride, "baseUrl" | "headers" | "authHeader" | "apiKey" | "transport">,
2078
+ ): T {
2079
+ const headers = mergeAuthHeader(
2080
+ override.headers ? { ...entry.headers, ...override.headers } : entry.headers,
2081
+ override.authHeader,
2082
+ override.apiKey,
2083
+ );
2084
+ return {
2085
+ ...entry,
2086
+ baseUrl: override.baseUrl ?? entry.baseUrl,
2087
+ headers,
2088
+ // Preserve the model's existing transport when the override omits one;
2089
+ // providers without a `transport` field keep the default per-API dispatch.
2090
+ ...(override.transport !== undefined ? { transport: override.transport } : {}),
2091
+ };
2092
+ }
2093
+ #applyRuntimeProviderOverrides(models: Model<Api>[]): Model<Api>[] {
2094
+ if (this.#runtimeProviderOverrides.size === 0) return models;
2095
+ return models.map(model => {
2096
+ const override = this.#runtimeProviderOverrides.get(model.provider);
2097
+ if (!override) return model;
2098
+ return this.#applyProviderTransportOverride(model, override);
2099
+ });
2100
+ }
2101
+ #applyModelOverrides(models: Model<Api>[], overrides: Map<string, Map<string, ModelOverride>>): Model<Api>[] {
2102
+ if (overrides.size === 0) return models;
2103
+ return models.map(model => {
2104
+ const providerOverrides = overrides.get(model.provider);
2105
+ if (!providerOverrides) return model;
2106
+ const override = providerOverrides.get(model.id);
2107
+ if (!override) return model;
2108
+ return applyModelOverride(model, override);
2109
+ });
2110
+ }
2111
+ #applyHardcodedModelPolicies(models: Model<Api>[]): Model<Api>[] {
2112
+ return models.map(model => {
2113
+ if (model.id !== "gpt-5.4" || model.provider === "github-copilot") {
2114
+ return model;
2115
+ }
2116
+ const overrides = this.#modelOverrides.get(model.provider)?.get(model.id);
2117
+ if (!overrides) {
2118
+ return applyModelOverride(model, { contextWindow: 1_000_000 });
2119
+ }
2120
+ return applyModelOverride(model, {
2121
+ contextWindow: overrides.contextWindow ?? 1_000_000,
2122
+ ...overrides,
2123
+ });
2124
+ });
2125
+ }
2126
+
2127
+ #rebuildCanonicalIndex(): void {
2128
+ if (this.#rebuildSuspended > 0) {
2129
+ this.#rebuildPending = true;
2130
+ return;
2131
+ }
2132
+ this.#canonicalIndex = buildCanonicalModelIndex(this.#models, this.#equivalenceConfig);
2133
+ this.#rebuildPending = false;
2134
+ }
2135
+
2136
+ #suspendRebuild(): void {
2137
+ this.#rebuildSuspended += 1;
2138
+ }
2139
+
2140
+ #resumeRebuild(): void {
2141
+ if (this.#rebuildSuspended > 0) {
2142
+ this.#rebuildSuspended -= 1;
2143
+ }
2144
+ if (this.#rebuildSuspended === 0 && this.#rebuildPending) {
2145
+ this.#rebuildPending = false;
2146
+ this.#canonicalIndex = buildCanonicalModelIndex(this.#models, this.#equivalenceConfig);
2147
+ }
2148
+ }
2149
+
2150
+ #parseModels(config: ModelsConfig): CustomModelOverlay[] {
2151
+ const models: CustomModelOverlay[] = [];
2152
+
2153
+ for (const [providerName, providerConfig] of Object.entries(config.providers ?? {})) {
2154
+ const modelDefs = providerConfig.models ?? [];
2155
+ if (modelDefs.length === 0) continue; // Override-only, no custom models
2156
+ if (providerConfig.apiKey) {
2157
+ this.#customProviderApiKeys.set(providerName, providerConfig.apiKey);
2158
+ const resolved = resolveApiKeyConfig(providerConfig.apiKey);
2159
+ if (resolved) this.authStorage.setConfigApiKey(providerName, resolved);
2160
+ }
2161
+ for (const modelDef of modelDefs) {
2162
+ const providerCompat = providerConfig.disableStrictTools
2163
+ ? mergeCompat(providerConfig.compat, { disableStrictTools: true })
2164
+ : providerConfig.compat;
2165
+ const model = buildCustomModelOverlay(
2166
+ providerName,
2167
+ providerConfig.baseUrl!,
2168
+ providerConfig.api as Api | undefined,
2169
+ providerConfig.headers,
2170
+ providerConfig.apiKey,
2171
+ providerConfig.authHeader,
2172
+ providerCompat,
2173
+ (providerConfig.auth as ProviderAuthMode | undefined) ?? undefined,
2174
+ modelDef as CustomModelDefinitionLike,
2175
+ );
2176
+ if (!model) continue;
2177
+ models.push(model);
2178
+ }
2179
+ }
2180
+ return models;
2181
+ }
2182
+
2183
+ /**
2184
+ * Get all models (built-in + custom).
2185
+ * If models.json had errors, returns only built-in models.
2186
+ */
2187
+ getAll(): Model<Api>[] {
2188
+ return this.#models;
2189
+ }
2190
+
2191
+ #isModelAvailable(model: Model<Api>): boolean {
2192
+ const disabledProviders = getDisabledProviderIdsFromSettings();
2193
+ return (
2194
+ !disabledProviders.has(model.provider) &&
2195
+ (this.#keylessProviders.has(model.provider) || this.authStorage.hasAuth(model.provider))
2196
+ );
2197
+ }
2198
+
2199
+ #filterCanonicalVariants(
2200
+ record: CanonicalModelRecord,
2201
+ options: CanonicalModelQueryOptions | undefined,
2202
+ ): CanonicalModelVariant[] {
2203
+ const candidateKeys = options?.candidates
2204
+ ? new Set(options.candidates.map(candidate => formatCanonicalVariantSelector(candidate)))
2205
+ : undefined;
2206
+ return record.variants.filter(variant => {
2207
+ if (candidateKeys && !candidateKeys.has(variant.selector)) {
2208
+ return false;
2209
+ }
2210
+ if (options?.availableOnly && !this.#isModelAvailable(variant.model)) {
2211
+ return false;
2212
+ }
2213
+ return true;
2214
+ });
2215
+ }
2216
+
2217
+ #providerRank(models: readonly Model<Api>[]): Map<string, number> {
2218
+ const configuredProviders = getConfiguredProviderOrderFromSettings();
2219
+ const result = new Map<string, number>();
2220
+ let nextRank = 0;
2221
+ for (const provider of configuredProviders) {
2222
+ const normalized = provider.trim().toLowerCase();
2223
+ if (!normalized || result.has(normalized)) {
2224
+ continue;
2225
+ }
2226
+ result.set(normalized, nextRank);
2227
+ nextRank += 1;
2228
+ }
2229
+ for (const model of models) {
2230
+ const normalized = model.provider.toLowerCase();
2231
+ if (result.has(normalized)) {
2232
+ continue;
2233
+ }
2234
+ result.set(normalized, nextRank);
2235
+ nextRank += 1;
2236
+ }
2237
+ return result;
2238
+ }
2239
+
2240
+ #resolveCanonicalVariant(
2241
+ variants: readonly CanonicalModelVariant[],
2242
+ allCandidates: readonly Model<Api>[],
2243
+ ): CanonicalModelVariant | undefined {
2244
+ if (variants.length === 0) {
2245
+ return undefined;
2246
+ }
2247
+ const providerRank = this.#providerRank(allCandidates);
2248
+ const modelOrder = new Map<string, number>();
2249
+ for (let index = 0; index < allCandidates.length; index += 1) {
2250
+ modelOrder.set(formatCanonicalVariantSelector(allCandidates[index]!), index);
2251
+ }
2252
+ const sourceRank: Record<CanonicalModelVariant["source"], number> = {
2253
+ override: 1,
2254
+ bundled: 1,
2255
+ heuristic: 2,
2256
+ fallback: 3,
2257
+ };
2258
+ return [...variants].sort((left, right) => {
2259
+ const leftProviderRank = providerRank.get(left.model.provider.toLowerCase()) ?? Number.MAX_SAFE_INTEGER;
2260
+ const rightProviderRank = providerRank.get(right.model.provider.toLowerCase()) ?? Number.MAX_SAFE_INTEGER;
2261
+ if (leftProviderRank !== rightProviderRank) {
2262
+ return leftProviderRank - rightProviderRank;
2263
+ }
2264
+ const leftExact = left.model.id === left.canonicalId ? 0 : 1;
2265
+ const rightExact = right.model.id === right.canonicalId ? 0 : 1;
2266
+ if (leftExact !== rightExact) {
2267
+ return leftExact - rightExact;
2268
+ }
2269
+ if (sourceRank[left.source] !== sourceRank[right.source]) {
2270
+ return sourceRank[left.source] - sourceRank[right.source];
2271
+ }
2272
+ if (left.model.id.length !== right.model.id.length) {
2273
+ return left.model.id.length - right.model.id.length;
2274
+ }
2275
+ const leftOrder = modelOrder.get(left.selector) ?? Number.MAX_SAFE_INTEGER;
2276
+ const rightOrder = modelOrder.get(right.selector) ?? Number.MAX_SAFE_INTEGER;
2277
+ return leftOrder - rightOrder;
2278
+ })[0];
2279
+ }
2280
+
2281
+ getCanonicalModels(options?: CanonicalModelQueryOptions): CanonicalModelRecord[] {
2282
+ const records: CanonicalModelRecord[] = [];
2283
+ for (const record of this.#canonicalIndex.records) {
2284
+ const variants = this.#filterCanonicalVariants(record, options);
2285
+ if (variants.length === 0) {
2286
+ continue;
2287
+ }
2288
+ records.push({
2289
+ id: record.id,
2290
+ name: record.name,
2291
+ variants,
2292
+ });
2293
+ }
2294
+ return records;
2295
+ }
2296
+
2297
+ getCanonicalVariants(canonicalId: string, options?: CanonicalModelQueryOptions): CanonicalModelVariant[] {
2298
+ const record = this.#canonicalIndex.byId.get(canonicalId.trim().toLowerCase());
2299
+ if (!record) {
2300
+ return [];
2301
+ }
2302
+ return this.#filterCanonicalVariants(record, options);
2303
+ }
2304
+
2305
+ resolveCanonicalModel(canonicalId: string, options?: CanonicalModelQueryOptions): Model<Api> | undefined {
2306
+ const variants = this.getCanonicalVariants(canonicalId, options);
2307
+ if (variants.length === 0) {
2308
+ return undefined;
2309
+ }
2310
+ const candidates = options?.candidates ?? (options?.availableOnly ? this.getAvailable() : this.getAll());
2311
+ return this.#resolveCanonicalVariant(variants, candidates)?.model;
2312
+ }
2313
+
2314
+ getCanonicalId(model: Model<Api>): string | undefined {
2315
+ return this.#canonicalIndex.bySelector.get(formatCanonicalVariantSelector(model).toLowerCase());
2316
+ }
2317
+
2318
+ /**
2319
+ * Get only models that have auth configured.
2320
+ * This is a fast check that doesn't refresh OAuth tokens.
2321
+ */
2322
+ getAvailable(): Model<Api>[] {
2323
+ return this.#models.filter(model => this.#isModelAvailable(model));
2324
+ }
2325
+
2326
+ /**
2327
+ * Check whether auth is configured for a model's provider.
2328
+ *
2329
+ * Mirrors the upstream `@mariozechner/pi-coding-agent` API surface so that
2330
+ * external plugins/extensions and downstream wrappers (e.g. subagent launch
2331
+ * paths that pre-flight auth before model resolution) can probe a model
2332
+ * without resolving an API key. Returns true for keyless providers as well
2333
+ * as providers with stored credentials. See issue #993.
2334
+ */
2335
+ hasConfiguredAuth(model: Model<Api>): boolean {
2336
+ return this.#keylessProviders.has(model.provider) || this.authStorage.hasAuth(model.provider);
2337
+ }
2338
+
2339
+ getDiscoverableProviders(): string[] {
2340
+ const disabledProviders = getDisabledProviderIdsFromSettings();
2341
+ return this.#discoverableProviders
2342
+ .filter(provider => !disabledProviders.has(provider.provider))
2343
+ .map(provider => provider.provider);
2344
+ }
2345
+
2346
+ getProviderDiscoveryState(provider: string): ProviderDiscoveryState | undefined {
2347
+ return this.#providerDiscoveryStates.get(provider);
2348
+ }
2349
+
2350
+ /**
2351
+ * Find a model by provider and ID.
2352
+ */
2353
+ find(provider: string, modelId: string): Model<Api> | undefined {
2354
+ return resolveProviderModelReference(provider, modelId, this.#models);
2355
+ }
2356
+
2357
+ /**
2358
+ * Get the base URL associated with a provider, if any model defines one.
2359
+ */
2360
+ getProviderBaseUrl(provider: string): string | undefined {
2361
+ return this.#models.find(m => m.provider === provider && m.baseUrl)?.baseUrl;
2362
+ }
2363
+
2364
+ /**
2365
+ * Get API key for a model.
2366
+ */
2367
+ async getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined> {
2368
+ if (this.#keylessProviders.has(model.provider) && !this.authStorage.hasAuth(model.provider)) {
2369
+ return kNoAuth;
2370
+ }
2371
+ return this.authStorage.getApiKey(model.provider, sessionId, { baseUrl: model.baseUrl, modelId: model.id });
2372
+ }
2373
+
2374
+ /**
2375
+ * Get API key for a provider (e.g., "openai").
2376
+ */
2377
+ async getApiKeyForProvider(provider: string, sessionId?: string, baseUrl?: string): Promise<string | undefined> {
2378
+ if (this.#keylessProviders.has(provider) && !this.authStorage.hasAuth(provider)) {
2379
+ return kNoAuth;
2380
+ }
2381
+ return this.authStorage.getApiKey(provider, sessionId, { baseUrl });
2382
+ }
2383
+
2384
+ async #peekApiKeyForProvider(provider: string): Promise<string | undefined> {
2385
+ if (this.#keylessProviders.has(provider) && !this.authStorage.hasAuth(provider)) {
2386
+ return kNoAuth;
2387
+ }
2388
+ return this.authStorage.peekApiKey(provider);
2389
+ }
2390
+
2391
+ /**
2392
+ * Check if a model is using OAuth credentials (subscription).
2393
+ */
2394
+ isUsingOAuth(model: Model<Api>): boolean {
2395
+ return this.authStorage.hasOAuth(model.provider);
2396
+ }
2397
+
2398
+ #clearRuntimeProviderState(providerName: string): void {
2399
+ this.#runtimeProviderApiKeys.delete(providerName);
2400
+ this.#runtimeProviderOverrides.delete(providerName);
2401
+ this.#runtimeModelOverlays = this.#runtimeModelOverlays.filter(overlay => overlay.provider !== providerName);
2402
+ this.authStorage.removeConfigApiKey(providerName);
2403
+ }
2404
+
2405
+ /**
2406
+ * Remove custom API/OAuth registrations for a specific extension source.
2407
+ */
2408
+ clearSourceRegistrations(sourceId: string): void {
2409
+ unregisterCustomApis(sourceId);
2410
+ unregisterOAuthProviders(sourceId);
2411
+ const sourceProviders = this.#runtimeProvidersBySource.get(sourceId);
2412
+ if (!sourceProviders || sourceProviders.size === 0) {
2413
+ return;
2414
+ }
2415
+ this.#runtimeProvidersBySource.delete(sourceId);
2416
+ for (const providerName of sourceProviders) {
2417
+ if (this.#runtimeProviderSourceByName.get(providerName) !== sourceId) {
2418
+ continue;
2419
+ }
2420
+ this.#runtimeProviderSourceByName.delete(providerName);
2421
+ this.#clearRuntimeProviderState(providerName);
2422
+ }
2423
+ this.#lastStaticLoadMtime = null;
2424
+ this.#reloadStaticModels();
2425
+ this.#rebuildCanonicalIndex();
2426
+ }
2427
+
2428
+ /**
2429
+ * Remove registrations for extension sources that are no longer active.
2430
+ */
2431
+ syncExtensionSources(activeSourceIds: string[]): void {
2432
+ const activeSources = new Set(activeSourceIds);
2433
+ for (const sourceId of this.#registeredProviderSources) {
2434
+ if (activeSources.has(sourceId)) {
2435
+ continue;
2436
+ }
2437
+ this.clearSourceRegistrations(sourceId);
2438
+ this.#registeredProviderSources.delete(sourceId);
2439
+ }
2440
+ }
2441
+
2442
+ /**
2443
+ * Register a provider dynamically (from extensions).
2444
+ *
2445
+ * If provider has models: replaces all existing models for this provider.
2446
+ * If provider has only baseUrl/headers: overrides existing models' URLs.
2447
+ * If provider has streamSimple: registers a custom API streaming function.
2448
+ * If provider has oauth: registers OAuth provider for /login support.
2449
+ */
2450
+ registerProvider(providerName: string, config: ProviderConfigInput, sourceId?: string): void {
2451
+ if (config.streamSimple && !config.api) {
2452
+ throw new Error(`Provider ${providerName}: "api" is required when registering streamSimple.`);
2453
+ }
2454
+
2455
+ validateProviderConfiguration(
2456
+ providerName,
2457
+ {
2458
+ baseUrl: config.baseUrl,
2459
+ headers: config.headers,
2460
+ apiKey: config.apiKey,
2461
+ api: config.api,
2462
+ oauthConfigured: Boolean(config.oauth),
2463
+ models: (config.models ?? []) as ProviderValidationModel[],
2464
+ },
2465
+ "runtime-register",
2466
+ );
2467
+
2468
+ if (config.streamSimple && config.api) {
2469
+ const streamSimple = config.streamSimple;
2470
+ registerCustomApi(config.api, streamSimple, sourceId, (model, context, options) =>
2471
+ streamSimple(model, context, options as SimpleStreamOptions),
2472
+ );
2473
+ }
2474
+
2475
+ if (config.oauth) {
2476
+ registerOAuthProvider({
2477
+ ...config.oauth,
2478
+ id: providerName,
2479
+ sourceId,
2480
+ });
2481
+ }
2482
+
2483
+ let sourceHandoff = false;
2484
+ if (sourceId) {
2485
+ this.#registeredProviderSources.add(sourceId);
2486
+ const previousSourceId = this.#runtimeProviderSourceByName.get(providerName);
2487
+ if (previousSourceId && previousSourceId !== sourceId) {
2488
+ const previousProviders = this.#runtimeProvidersBySource.get(previousSourceId);
2489
+ previousProviders?.delete(providerName);
2490
+ if (previousProviders && previousProviders.size === 0) {
2491
+ this.#runtimeProvidersBySource.delete(previousSourceId);
2492
+ }
2493
+ this.#clearRuntimeProviderState(providerName);
2494
+ sourceHandoff = true;
2495
+ }
2496
+ const sourceProviders = this.#runtimeProvidersBySource.get(sourceId) ?? new Set<string>();
2497
+ sourceProviders.add(providerName);
2498
+ this.#runtimeProvidersBySource.set(sourceId, sourceProviders);
2499
+ this.#runtimeProviderSourceByName.set(providerName, sourceId);
2500
+ }
2501
+ if (sourceHandoff) {
2502
+ this.#lastStaticLoadMtime = null;
2503
+ this.#reloadStaticModels();
2504
+ }
2505
+
2506
+ if (config.apiKey) {
2507
+ this.#customProviderApiKeys.set(providerName, config.apiKey);
2508
+ // Persist runtime API keys so they survive #reloadStaticModels() cycles
2509
+ this.#runtimeProviderApiKeys.set(providerName, config.apiKey);
2510
+ const resolved = resolveApiKeyConfig(config.apiKey);
2511
+ if (resolved) this.authStorage.setConfigApiKey(providerName, resolved);
2512
+ }
2513
+
2514
+ if (config.models && config.models.length > 0) {
2515
+ // Build model overlays that persist across refresh() cycles
2516
+ const newOverlays: CustomModelOverlay[] = [];
2517
+ for (const modelDef of config.models) {
2518
+ const overlay = buildCustomModelOverlay(
2519
+ providerName,
2520
+ config.baseUrl!,
2521
+ config.api,
2522
+ config.headers,
2523
+ config.apiKey,
2524
+ config.authHeader,
2525
+ config.compat,
2526
+ undefined,
2527
+ modelDef as CustomModelDefinitionLike,
2528
+ );
2529
+ if (!overlay) {
2530
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: no "api" specified.`);
2531
+ }
2532
+ newOverlays.push(overlay);
2533
+ }
2534
+ // Store as runtime overlays so they survive #reloadStaticModels()
2535
+ this.#runtimeModelOverlays = this.#runtimeModelOverlays.filter(m => m.provider !== providerName);
2536
+ this.#runtimeModelOverlays.push(...newOverlays);
2537
+
2538
+ // Also update #models immediately for the current cycle
2539
+ const nextModels = this.#models.filter(m => m.provider !== providerName);
2540
+ for (const overlay of newOverlays) {
2541
+ nextModels.push(finalizeCustomModel(overlay, { useDefaults: true }));
2542
+ }
2543
+ const runtimeTransportOverride = this.#runtimeProviderOverrides.get(providerName);
2544
+ const withRuntimeTransportOverride = runtimeTransportOverride
2545
+ ? nextModels.map(model => {
2546
+ if (model.provider !== providerName) return model;
2547
+ return this.#applyProviderTransportOverride(model, runtimeTransportOverride);
2548
+ })
2549
+ : nextModels;
2550
+
2551
+ if (config.oauth?.modifyModels) {
2552
+ const credential = this.authStorage.getOAuthCredential(providerName);
2553
+ if (credential) {
2554
+ this.#models = config.oauth.modifyModels(withRuntimeTransportOverride, credential);
2555
+ this.#rebuildCanonicalIndex();
2556
+ return;
2557
+ }
2558
+ }
2559
+
2560
+ this.#models = withRuntimeTransportOverride;
2561
+ this.#rebuildCanonicalIndex();
2562
+ return;
2563
+ }
2564
+
2565
+ if (
2566
+ config.baseUrl ||
2567
+ config.headers ||
2568
+ config.apiKey ||
2569
+ config.authHeader !== undefined ||
2570
+ config.transport !== undefined
2571
+ ) {
2572
+ const transportOverride = {
2573
+ baseUrl: config.baseUrl,
2574
+ headers: config.headers,
2575
+ apiKey: config.apiKey,
2576
+ authHeader: config.authHeader,
2577
+ transport: config.transport,
2578
+ };
2579
+ const nextRuntimeOverride = this.#mergeProviderOverride(
2580
+ this.#runtimeProviderOverrides.get(providerName),
2581
+ transportOverride,
2582
+ );
2583
+ this.#runtimeProviderOverrides.set(providerName, nextRuntimeOverride);
2584
+ this.#models = this.#models.map(m => {
2585
+ if (m.provider !== providerName) return m;
2586
+ return this.#applyProviderTransportOverride(m, transportOverride);
2587
+ });
2588
+ this.#rebuildCanonicalIndex();
2589
+ }
2590
+ }
2591
+
2592
+ /**
2593
+ * Suppress a specific model selector (e.g., "provider/id") until a specific timestamp.
2594
+ */
2595
+ suppressSelector(selector: string, untilMs: number): void {
2596
+ this.#suppressedSelectors.set(normalizeSuppressedSelector(selector), untilMs);
2597
+ }
2598
+
2599
+ /**
2600
+ * Check if a model selector is currently suppressed due to rate limits.
2601
+ */
2602
+ isSelectorSuppressed(selector: string): boolean {
2603
+ const normalizedSelector = normalizeSuppressedSelector(selector);
2604
+ const suppressedUntil = this.#suppressedSelectors.get(normalizedSelector);
2605
+ if (!suppressedUntil) return false;
2606
+ if (suppressedUntil <= Date.now()) {
2607
+ this.#suppressedSelectors.delete(normalizedSelector);
2608
+ return false;
2609
+ }
2610
+ return true;
2611
+ }
2612
+ }
2613
+
2614
+ /**
2615
+ * Input type for registerProvider API (from extensions).
2616
+ */
2617
+ export interface ProviderConfigInput {
2618
+ baseUrl?: string;
2619
+ apiKey?: string;
2620
+ api?: Api;
2621
+ streamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;
2622
+ headers?: Record<string, string>;
2623
+ compat?: Model<Api>["compat"];
2624
+ authHeader?: boolean;
2625
+ /** Streaming transport override — see {@link Model.transport}. */
2626
+ transport?: Model<Api>["transport"];
2627
+ oauth?: {
2628
+ name: string;
2629
+ login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials | string>;
2630
+ refreshToken?(credentials: OAuthCredentials): Promise<OAuthCredentials>;
2631
+ getApiKey?(credentials: OAuthCredentials): string;
2632
+ modifyModels?(models: Model<Api>[], credentials: OAuthCredentials): Model<Api>[];
2633
+ };
2634
+ models?: Array<{
2635
+ id: string;
2636
+ name: string;
2637
+ api?: Api;
2638
+ baseUrl?: string;
2639
+ reasoning: boolean;
2640
+ thinking?: ThinkingConfig;
2641
+ input: ("text" | "image")[];
2642
+ cost: { input: number; output: number; cacheRead: number; cacheWrite: number };
2643
+ contextWindow: number;
2644
+ maxTokens: number;
2645
+ headers?: Record<string, string>;
2646
+ compat?: Model<Api>["compat"];
2647
+ contextPromotionTarget?: string;
2648
+ premiumMultiplier?: number;
2649
+ }>;
2650
+ }