@imdigitalashish/zpi 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. package/CHANGELOG.md +2801 -0
  2. package/README.md +95 -0
  3. package/dist/cli/args.d.ts +47 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +293 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/config-selector.d.ts +14 -0
  8. package/dist/cli/config-selector.d.ts.map +1 -0
  9. package/dist/cli/config-selector.js +31 -0
  10. package/dist/cli/config-selector.js.map +1 -0
  11. package/dist/cli/file-processor.d.ts +15 -0
  12. package/dist/cli/file-processor.d.ts.map +1 -0
  13. package/dist/cli/file-processor.js +79 -0
  14. package/dist/cli/file-processor.js.map +1 -0
  15. package/dist/cli/list-models.d.ts +9 -0
  16. package/dist/cli/list-models.d.ts.map +1 -0
  17. package/dist/cli/list-models.js +92 -0
  18. package/dist/cli/list-models.js.map +1 -0
  19. package/dist/cli/session-picker.d.ts +9 -0
  20. package/dist/cli/session-picker.d.ts.map +1 -0
  21. package/dist/cli/session-picker.js +34 -0
  22. package/dist/cli/session-picker.js.map +1 -0
  23. package/dist/cli.d.ts +3 -0
  24. package/dist/cli.d.ts.map +1 -0
  25. package/dist/cli.js +11 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/config.d.ts +68 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +203 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/core/agent-session.d.ts +571 -0
  32. package/dist/core/agent-session.d.ts.map +1 -0
  33. package/dist/core/agent-session.js +2353 -0
  34. package/dist/core/agent-session.js.map +1 -0
  35. package/dist/core/auth-storage.d.ts +129 -0
  36. package/dist/core/auth-storage.d.ts.map +1 -0
  37. package/dist/core/auth-storage.js +394 -0
  38. package/dist/core/auth-storage.js.map +1 -0
  39. package/dist/core/bash-executor.d.ts +47 -0
  40. package/dist/core/bash-executor.d.ts.map +1 -0
  41. package/dist/core/bash-executor.js +212 -0
  42. package/dist/core/bash-executor.js.map +1 -0
  43. package/dist/core/compaction/branch-summarization.d.ts +86 -0
  44. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  45. package/dist/core/compaction/branch-summarization.js +242 -0
  46. package/dist/core/compaction/branch-summarization.js.map +1 -0
  47. package/dist/core/compaction/compaction.d.ts +121 -0
  48. package/dist/core/compaction/compaction.d.ts.map +1 -0
  49. package/dist/core/compaction/compaction.js +607 -0
  50. package/dist/core/compaction/compaction.js.map +1 -0
  51. package/dist/core/compaction/index.d.ts +7 -0
  52. package/dist/core/compaction/index.d.ts.map +1 -0
  53. package/dist/core/compaction/index.js +7 -0
  54. package/dist/core/compaction/index.js.map +1 -0
  55. package/dist/core/compaction/utils.d.ts +35 -0
  56. package/dist/core/compaction/utils.d.ts.map +1 -0
  57. package/dist/core/compaction/utils.js +138 -0
  58. package/dist/core/compaction/utils.js.map +1 -0
  59. package/dist/core/defaults.d.ts +3 -0
  60. package/dist/core/defaults.d.ts.map +1 -0
  61. package/dist/core/defaults.js +2 -0
  62. package/dist/core/defaults.js.map +1 -0
  63. package/dist/core/diagnostics.d.ts +15 -0
  64. package/dist/core/diagnostics.d.ts.map +1 -0
  65. package/dist/core/diagnostics.js +2 -0
  66. package/dist/core/diagnostics.js.map +1 -0
  67. package/dist/core/event-bus.d.ts +9 -0
  68. package/dist/core/event-bus.d.ts.map +1 -0
  69. package/dist/core/event-bus.js +25 -0
  70. package/dist/core/event-bus.js.map +1 -0
  71. package/dist/core/exec.d.ts +29 -0
  72. package/dist/core/exec.d.ts.map +1 -0
  73. package/dist/core/exec.js +71 -0
  74. package/dist/core/exec.js.map +1 -0
  75. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  76. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  77. package/dist/core/export-html/ansi-to-html.js +249 -0
  78. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  79. package/dist/core/export-html/index.d.ts +34 -0
  80. package/dist/core/export-html/index.d.ts.map +1 -0
  81. package/dist/core/export-html/index.js +222 -0
  82. package/dist/core/export-html/index.js.map +1 -0
  83. package/dist/core/export-html/template.css +971 -0
  84. package/dist/core/export-html/template.html +54 -0
  85. package/dist/core/export-html/template.js +1586 -0
  86. package/dist/core/export-html/tool-renderer.d.ts +35 -0
  87. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  88. package/dist/core/export-html/tool-renderer.js +57 -0
  89. package/dist/core/export-html/tool-renderer.js.map +1 -0
  90. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  91. package/dist/core/export-html/vendor/marked.min.js +6 -0
  92. package/dist/core/extensions/index.d.ts +11 -0
  93. package/dist/core/extensions/index.d.ts.map +1 -0
  94. package/dist/core/extensions/index.js +9 -0
  95. package/dist/core/extensions/index.js.map +1 -0
  96. package/dist/core/extensions/loader.d.ts +25 -0
  97. package/dist/core/extensions/loader.d.ts.map +1 -0
  98. package/dist/core/extensions/loader.js +402 -0
  99. package/dist/core/extensions/loader.js.map +1 -0
  100. package/dist/core/extensions/runner.d.ts +146 -0
  101. package/dist/core/extensions/runner.d.ts.map +1 -0
  102. package/dist/core/extensions/runner.js +626 -0
  103. package/dist/core/extensions/runner.js.map +1 -0
  104. package/dist/core/extensions/types.d.ts +984 -0
  105. package/dist/core/extensions/types.d.ts.map +1 -0
  106. package/dist/core/extensions/types.js +35 -0
  107. package/dist/core/extensions/types.js.map +1 -0
  108. package/dist/core/extensions/wrapper.d.ts +27 -0
  109. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  110. package/dist/core/extensions/wrapper.js +102 -0
  111. package/dist/core/extensions/wrapper.js.map +1 -0
  112. package/dist/core/footer-data-provider.d.ts +32 -0
  113. package/dist/core/footer-data-provider.d.ts.map +1 -0
  114. package/dist/core/footer-data-provider.js +134 -0
  115. package/dist/core/footer-data-provider.js.map +1 -0
  116. package/dist/core/index.d.ts +9 -0
  117. package/dist/core/index.d.ts.map +1 -0
  118. package/dist/core/index.js +9 -0
  119. package/dist/core/index.js.map +1 -0
  120. package/dist/core/keybindings.d.ts +55 -0
  121. package/dist/core/keybindings.d.ts.map +1 -0
  122. package/dist/core/keybindings.js +153 -0
  123. package/dist/core/keybindings.js.map +1 -0
  124. package/dist/core/memory.d.ts +64 -0
  125. package/dist/core/memory.d.ts.map +1 -0
  126. package/dist/core/memory.js +247 -0
  127. package/dist/core/memory.js.map +1 -0
  128. package/dist/core/messages.d.ts +77 -0
  129. package/dist/core/messages.d.ts.map +1 -0
  130. package/dist/core/messages.js +149 -0
  131. package/dist/core/messages.js.map +1 -0
  132. package/dist/core/model-registry.d.ts +102 -0
  133. package/dist/core/model-registry.d.ts.map +1 -0
  134. package/dist/core/model-registry.js +515 -0
  135. package/dist/core/model-registry.js.map +1 -0
  136. package/dist/core/model-resolver.d.ts +104 -0
  137. package/dist/core/model-resolver.d.ts.map +1 -0
  138. package/dist/core/model-resolver.js +403 -0
  139. package/dist/core/model-resolver.js.map +1 -0
  140. package/dist/core/package-manager.d.ts +151 -0
  141. package/dist/core/package-manager.d.ts.map +1 -0
  142. package/dist/core/package-manager.js +1426 -0
  143. package/dist/core/package-manager.js.map +1 -0
  144. package/dist/core/prompt-templates.d.ts +50 -0
  145. package/dist/core/prompt-templates.d.ts.map +1 -0
  146. package/dist/core/prompt-templates.js +251 -0
  147. package/dist/core/prompt-templates.js.map +1 -0
  148. package/dist/core/resolve-config-value.d.ts +17 -0
  149. package/dist/core/resolve-config-value.d.ts.map +1 -0
  150. package/dist/core/resolve-config-value.js +59 -0
  151. package/dist/core/resolve-config-value.js.map +1 -0
  152. package/dist/core/resource-loader.d.ts +184 -0
  153. package/dist/core/resource-loader.d.ts.map +1 -0
  154. package/dist/core/resource-loader.js +673 -0
  155. package/dist/core/resource-loader.js.map +1 -0
  156. package/dist/core/sdk.d.ts +90 -0
  157. package/dist/core/sdk.d.ts.map +1 -0
  158. package/dist/core/sdk.js +238 -0
  159. package/dist/core/sdk.js.map +1 -0
  160. package/dist/core/session-manager.d.ts +323 -0
  161. package/dist/core/session-manager.d.ts.map +1 -0
  162. package/dist/core/session-manager.js +1091 -0
  163. package/dist/core/session-manager.js.map +1 -0
  164. package/dist/core/settings-manager.d.ts +230 -0
  165. package/dist/core/settings-manager.d.ts.map +1 -0
  166. package/dist/core/settings-manager.js +656 -0
  167. package/dist/core/settings-manager.js.map +1 -0
  168. package/dist/core/skills.d.ts +58 -0
  169. package/dist/core/skills.d.ts.map +1 -0
  170. package/dist/core/skills.js +364 -0
  171. package/dist/core/skills.js.map +1 -0
  172. package/dist/core/slash-commands.d.ts +15 -0
  173. package/dist/core/slash-commands.d.ts.map +1 -0
  174. package/dist/core/slash-commands.js +23 -0
  175. package/dist/core/slash-commands.js.map +1 -0
  176. package/dist/core/system-prompt.d.ts +26 -0
  177. package/dist/core/system-prompt.d.ts.map +1 -0
  178. package/dist/core/system-prompt.js +150 -0
  179. package/dist/core/system-prompt.js.map +1 -0
  180. package/dist/core/timings.d.ts +7 -0
  181. package/dist/core/timings.d.ts.map +1 -0
  182. package/dist/core/timings.js +25 -0
  183. package/dist/core/timings.js.map +1 -0
  184. package/dist/core/tools/bash.d.ts +55 -0
  185. package/dist/core/tools/bash.d.ts.map +1 -0
  186. package/dist/core/tools/bash.js +242 -0
  187. package/dist/core/tools/bash.js.map +1 -0
  188. package/dist/core/tools/edit-diff.d.ts +63 -0
  189. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  190. package/dist/core/tools/edit-diff.js +243 -0
  191. package/dist/core/tools/edit-diff.js.map +1 -0
  192. package/dist/core/tools/edit.d.ts +39 -0
  193. package/dist/core/tools/edit.d.ts.map +1 -0
  194. package/dist/core/tools/edit.js +146 -0
  195. package/dist/core/tools/edit.js.map +1 -0
  196. package/dist/core/tools/find.d.ts +39 -0
  197. package/dist/core/tools/find.d.ts.map +1 -0
  198. package/dist/core/tools/find.js +206 -0
  199. package/dist/core/tools/find.js.map +1 -0
  200. package/dist/core/tools/grep.d.ts +45 -0
  201. package/dist/core/tools/grep.d.ts.map +1 -0
  202. package/dist/core/tools/grep.js +239 -0
  203. package/dist/core/tools/grep.js.map +1 -0
  204. package/dist/core/tools/index.d.ts +102 -0
  205. package/dist/core/tools/index.d.ts.map +1 -0
  206. package/dist/core/tools/index.js +71 -0
  207. package/dist/core/tools/index.js.map +1 -0
  208. package/dist/core/tools/ls.d.ts +40 -0
  209. package/dist/core/tools/ls.d.ts.map +1 -0
  210. package/dist/core/tools/ls.js +118 -0
  211. package/dist/core/tools/ls.js.map +1 -0
  212. package/dist/core/tools/memory.d.ts +45 -0
  213. package/dist/core/tools/memory.d.ts.map +1 -0
  214. package/dist/core/tools/memory.js +346 -0
  215. package/dist/core/tools/memory.js.map +1 -0
  216. package/dist/core/tools/path-utils.d.ts +8 -0
  217. package/dist/core/tools/path-utils.d.ts.map +1 -0
  218. package/dist/core/tools/path-utils.js +81 -0
  219. package/dist/core/tools/path-utils.js.map +1 -0
  220. package/dist/core/tools/read.d.ts +39 -0
  221. package/dist/core/tools/read.d.ts.map +1 -0
  222. package/dist/core/tools/read.js +166 -0
  223. package/dist/core/tools/read.js.map +1 -0
  224. package/dist/core/tools/truncate.d.ts +70 -0
  225. package/dist/core/tools/truncate.d.ts.map +1 -0
  226. package/dist/core/tools/truncate.js +205 -0
  227. package/dist/core/tools/truncate.js.map +1 -0
  228. package/dist/core/tools/write.d.ts +29 -0
  229. package/dist/core/tools/write.d.ts.map +1 -0
  230. package/dist/core/tools/write.js +78 -0
  231. package/dist/core/tools/write.js.map +1 -0
  232. package/dist/index.d.ts +28 -0
  233. package/dist/index.d.ts.map +1 -0
  234. package/dist/index.js +43 -0
  235. package/dist/index.js.map +1 -0
  236. package/dist/main.d.ts +8 -0
  237. package/dist/main.d.ts.map +1 -0
  238. package/dist/main.js +651 -0
  239. package/dist/main.js.map +1 -0
  240. package/dist/migrations.d.ts +33 -0
  241. package/dist/migrations.d.ts.map +1 -0
  242. package/dist/migrations.js +261 -0
  243. package/dist/migrations.js.map +1 -0
  244. package/dist/modes/index.d.ts +9 -0
  245. package/dist/modes/index.d.ts.map +1 -0
  246. package/dist/modes/index.js +8 -0
  247. package/dist/modes/index.js.map +1 -0
  248. package/dist/modes/interactive/components/armin.d.ts +34 -0
  249. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  250. package/dist/modes/interactive/components/armin.js +333 -0
  251. package/dist/modes/interactive/components/armin.js.map +1 -0
  252. package/dist/modes/interactive/components/assistant-message.d.ts +16 -0
  253. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  254. package/dist/modes/interactive/components/assistant-message.js +96 -0
  255. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  256. package/dist/modes/interactive/components/bash-execution.d.ts +35 -0
  257. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  258. package/dist/modes/interactive/components/bash-execution.js +162 -0
  259. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  260. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  261. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  262. package/dist/modes/interactive/components/bordered-loader.js +51 -0
  263. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  264. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  265. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  266. package/dist/modes/interactive/components/branch-summary-message.js +44 -0
  267. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  268. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  269. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  270. package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
  271. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  272. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  273. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  274. package/dist/modes/interactive/components/config-selector.js +479 -0
  275. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  276. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  277. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  278. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  279. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  280. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  281. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  282. package/dist/modes/interactive/components/custom-editor.js +70 -0
  283. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  284. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  285. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  286. package/dist/modes/interactive/components/custom-message.js +79 -0
  287. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  288. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  289. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  290. package/dist/modes/interactive/components/daxnuts.js +140 -0
  291. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  292. package/dist/modes/interactive/components/diff.d.ts +12 -0
  293. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  294. package/dist/modes/interactive/components/diff.js +133 -0
  295. package/dist/modes/interactive/components/diff.js.map +1 -0
  296. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  297. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  298. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  299. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  300. package/dist/modes/interactive/components/extension-editor.d.ts +17 -0
  301. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  302. package/dist/modes/interactive/components/extension-editor.js +102 -0
  303. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  304. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  305. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  306. package/dist/modes/interactive/components/extension-input.js +61 -0
  307. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  308. package/dist/modes/interactive/components/extension-selector.d.ts +24 -0
  309. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  310. package/dist/modes/interactive/components/extension-selector.js +78 -0
  311. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  312. package/dist/modes/interactive/components/footer.d.ts +26 -0
  313. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  314. package/dist/modes/interactive/components/footer.js +213 -0
  315. package/dist/modes/interactive/components/footer.js.map +1 -0
  316. package/dist/modes/interactive/components/index.d.ts +32 -0
  317. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  318. package/dist/modes/interactive/components/index.js +33 -0
  319. package/dist/modes/interactive/components/index.js.map +1 -0
  320. package/dist/modes/interactive/components/keybinding-hints.d.ts +41 -0
  321. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  322. package/dist/modes/interactive/components/keybinding-hints.js +61 -0
  323. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  324. package/dist/modes/interactive/components/login-dialog.d.ts +42 -0
  325. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  326. package/dist/modes/interactive/components/login-dialog.js +145 -0
  327. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  328. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  329. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  330. package/dist/modes/interactive/components/model-selector.js +271 -0
  331. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  332. package/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
  333. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  334. package/dist/modes/interactive/components/oauth-selector.js +97 -0
  335. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  336. package/dist/modes/interactive/components/scoped-models-selector.d.ts +49 -0
  337. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  338. package/dist/modes/interactive/components/scoped-models-selector.js +275 -0
  339. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  340. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  341. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  342. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  343. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  344. package/dist/modes/interactive/components/session-selector.d.ts +95 -0
  345. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  346. package/dist/modes/interactive/components/session-selector.js +851 -0
  347. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  348. package/dist/modes/interactive/components/settings-selector.d.ts +58 -0
  349. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  350. package/dist/modes/interactive/components/settings-selector.js +299 -0
  351. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  352. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  353. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  354. package/dist/modes/interactive/components/show-images-selector.js +35 -0
  355. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  356. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  357. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  358. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  359. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  360. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  361. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  362. package/dist/modes/interactive/components/theme-selector.js +46 -0
  363. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  364. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  365. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  366. package/dist/modes/interactive/components/thinking-selector.js +47 -0
  367. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  368. package/dist/modes/interactive/components/tool-execution.d.ts +70 -0
  369. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  370. package/dist/modes/interactive/components/tool-execution.js +636 -0
  371. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  372. package/dist/modes/interactive/components/tree-selector.d.ts +68 -0
  373. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  374. package/dist/modes/interactive/components/tree-selector.js +934 -0
  375. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  376. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  377. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  378. package/dist/modes/interactive/components/user-message-selector.js +113 -0
  379. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  380. package/dist/modes/interactive/components/user-message.d.ts +8 -0
  381. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  382. package/dist/modes/interactive/components/user-message.js +16 -0
  383. package/dist/modes/interactive/components/user-message.js.map +1 -0
  384. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  385. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  386. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  387. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  388. package/dist/modes/interactive/interactive-mode.d.ts +316 -0
  389. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  390. package/dist/modes/interactive/interactive-mode.js +3848 -0
  391. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  392. package/dist/modes/interactive/theme/dark.json +85 -0
  393. package/dist/modes/interactive/theme/light.json +84 -0
  394. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  395. package/dist/modes/interactive/theme/theme.d.ts +78 -0
  396. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  397. package/dist/modes/interactive/theme/theme.js +944 -0
  398. package/dist/modes/interactive/theme/theme.js.map +1 -0
  399. package/dist/modes/print-mode.d.ts +28 -0
  400. package/dist/modes/print-mode.d.ts.map +1 -0
  401. package/dist/modes/print-mode.js +101 -0
  402. package/dist/modes/print-mode.js.map +1 -0
  403. package/dist/modes/rpc/rpc-client.d.ts +217 -0
  404. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  405. package/dist/modes/rpc/rpc-client.js +405 -0
  406. package/dist/modes/rpc/rpc-client.js.map +1 -0
  407. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  408. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  409. package/dist/modes/rpc/rpc-mode.js +511 -0
  410. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  411. package/dist/modes/rpc/rpc-types.d.ts +409 -0
  412. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  413. package/dist/modes/rpc/rpc-types.js +8 -0
  414. package/dist/modes/rpc/rpc-types.js.map +1 -0
  415. package/dist/utils/changelog.d.ts +21 -0
  416. package/dist/utils/changelog.d.ts.map +1 -0
  417. package/dist/utils/changelog.js +87 -0
  418. package/dist/utils/changelog.js.map +1 -0
  419. package/dist/utils/clipboard-image.d.ts +11 -0
  420. package/dist/utils/clipboard-image.d.ts.map +1 -0
  421. package/dist/utils/clipboard-image.js +162 -0
  422. package/dist/utils/clipboard-image.js.map +1 -0
  423. package/dist/utils/clipboard-native.d.ts +7 -0
  424. package/dist/utils/clipboard-native.d.ts.map +1 -0
  425. package/dist/utils/clipboard-native.js +14 -0
  426. package/dist/utils/clipboard-native.js.map +1 -0
  427. package/dist/utils/clipboard.d.ts +2 -0
  428. package/dist/utils/clipboard.d.ts.map +1 -0
  429. package/dist/utils/clipboard.js +67 -0
  430. package/dist/utils/clipboard.js.map +1 -0
  431. package/dist/utils/frontmatter.d.ts +8 -0
  432. package/dist/utils/frontmatter.d.ts.map +1 -0
  433. package/dist/utils/frontmatter.js +26 -0
  434. package/dist/utils/frontmatter.js.map +1 -0
  435. package/dist/utils/git.d.ts +26 -0
  436. package/dist/utils/git.d.ts.map +1 -0
  437. package/dist/utils/git.js +163 -0
  438. package/dist/utils/git.js.map +1 -0
  439. package/dist/utils/image-convert.d.ts +9 -0
  440. package/dist/utils/image-convert.d.ts.map +1 -0
  441. package/dist/utils/image-convert.js +35 -0
  442. package/dist/utils/image-convert.js.map +1 -0
  443. package/dist/utils/image-resize.d.ts +36 -0
  444. package/dist/utils/image-resize.d.ts.map +1 -0
  445. package/dist/utils/image-resize.js +181 -0
  446. package/dist/utils/image-resize.js.map +1 -0
  447. package/dist/utils/mime.d.ts +2 -0
  448. package/dist/utils/mime.d.ts.map +1 -0
  449. package/dist/utils/mime.js +26 -0
  450. package/dist/utils/mime.js.map +1 -0
  451. package/dist/utils/photon.d.ts +21 -0
  452. package/dist/utils/photon.d.ts.map +1 -0
  453. package/dist/utils/photon.js +121 -0
  454. package/dist/utils/photon.js.map +1 -0
  455. package/dist/utils/shell.d.ts +26 -0
  456. package/dist/utils/shell.d.ts.map +1 -0
  457. package/dist/utils/shell.js +186 -0
  458. package/dist/utils/shell.js.map +1 -0
  459. package/dist/utils/sleep.d.ts +5 -0
  460. package/dist/utils/sleep.d.ts.map +1 -0
  461. package/dist/utils/sleep.js +17 -0
  462. package/dist/utils/sleep.js.map +1 -0
  463. package/dist/utils/tools-manager.d.ts +3 -0
  464. package/dist/utils/tools-manager.d.ts.map +1 -0
  465. package/dist/utils/tools-manager.js +207 -0
  466. package/dist/utils/tools-manager.js.map +1 -0
  467. package/docs/compaction.md +390 -0
  468. package/docs/custom-provider.md +548 -0
  469. package/docs/development.md +69 -0
  470. package/docs/extensions.md +1935 -0
  471. package/docs/images/doom-extension.png +0 -0
  472. package/docs/images/exy.png +0 -0
  473. package/docs/images/interactive-mode.png +0 -0
  474. package/docs/images/tree-view.png +0 -0
  475. package/docs/json.md +79 -0
  476. package/docs/keybindings.md +174 -0
  477. package/docs/models.md +293 -0
  478. package/docs/packages.md +209 -0
  479. package/docs/prompt-templates.md +67 -0
  480. package/docs/providers.md +186 -0
  481. package/docs/rpc.md +1317 -0
  482. package/docs/sdk.md +968 -0
  483. package/docs/session.md +412 -0
  484. package/docs/settings.md +223 -0
  485. package/docs/shell-aliases.md +13 -0
  486. package/docs/skills.md +231 -0
  487. package/docs/terminal-setup.md +70 -0
  488. package/docs/termux.md +127 -0
  489. package/docs/themes.md +295 -0
  490. package/docs/tree.md +219 -0
  491. package/docs/tui.md +887 -0
  492. package/docs/windows.md +17 -0
  493. package/examples/README.md +25 -0
  494. package/examples/extensions/README.md +203 -0
  495. package/examples/extensions/antigravity-image-gen.ts +413 -0
  496. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  497. package/examples/extensions/bash-spawn-hook.ts +30 -0
  498. package/examples/extensions/bookmark.ts +50 -0
  499. package/examples/extensions/claude-rules.ts +86 -0
  500. package/examples/extensions/commands.ts +72 -0
  501. package/examples/extensions/confirm-destructive.ts +59 -0
  502. package/examples/extensions/custom-compaction.ts +114 -0
  503. package/examples/extensions/custom-footer.ts +64 -0
  504. package/examples/extensions/custom-header.ts +73 -0
  505. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  506. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  507. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  508. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  509. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  510. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  511. package/examples/extensions/custom-provider-qwen-cli/index.ts +345 -0
  512. package/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
  513. package/examples/extensions/dirty-repo-guard.ts +56 -0
  514. package/examples/extensions/doom-overlay/README.md +46 -0
  515. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  516. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  517. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  518. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  519. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  520. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  521. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  522. package/examples/extensions/doom-overlay/index.ts +74 -0
  523. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  524. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  525. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  526. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  527. package/examples/extensions/dynamic-resources/index.ts +15 -0
  528. package/examples/extensions/event-bus.ts +43 -0
  529. package/examples/extensions/file-trigger.ts +41 -0
  530. package/examples/extensions/git-checkpoint.ts +53 -0
  531. package/examples/extensions/handoff.ts +150 -0
  532. package/examples/extensions/hello.ts +25 -0
  533. package/examples/extensions/inline-bash.ts +94 -0
  534. package/examples/extensions/input-transform.ts +43 -0
  535. package/examples/extensions/interactive-shell.ts +196 -0
  536. package/examples/extensions/mac-system-theme.ts +47 -0
  537. package/examples/extensions/message-renderer.ts +59 -0
  538. package/examples/extensions/minimal-mode.ts +426 -0
  539. package/examples/extensions/modal-editor.ts +85 -0
  540. package/examples/extensions/model-status.ts +31 -0
  541. package/examples/extensions/notify.ts +55 -0
  542. package/examples/extensions/overlay-qa-tests.ts +881 -0
  543. package/examples/extensions/overlay-test.ts +150 -0
  544. package/examples/extensions/permission-gate.ts +34 -0
  545. package/examples/extensions/pirate.ts +47 -0
  546. package/examples/extensions/plan-mode/README.md +65 -0
  547. package/examples/extensions/plan-mode/index.ts +340 -0
  548. package/examples/extensions/plan-mode/utils.ts +168 -0
  549. package/examples/extensions/preset.ts +398 -0
  550. package/examples/extensions/protected-paths.ts +30 -0
  551. package/examples/extensions/qna.ts +119 -0
  552. package/examples/extensions/question.ts +264 -0
  553. package/examples/extensions/questionnaire.ts +427 -0
  554. package/examples/extensions/rainbow-editor.ts +88 -0
  555. package/examples/extensions/reload-runtime.ts +37 -0
  556. package/examples/extensions/rpc-demo.ts +124 -0
  557. package/examples/extensions/sandbox/index.ts +318 -0
  558. package/examples/extensions/sandbox/package-lock.json +92 -0
  559. package/examples/extensions/sandbox/package.json +19 -0
  560. package/examples/extensions/send-user-message.ts +97 -0
  561. package/examples/extensions/session-name.ts +27 -0
  562. package/examples/extensions/shutdown-command.ts +63 -0
  563. package/examples/extensions/snake.ts +343 -0
  564. package/examples/extensions/space-invaders.ts +560 -0
  565. package/examples/extensions/ssh.ts +220 -0
  566. package/examples/extensions/status-line.ts +40 -0
  567. package/examples/extensions/subagent/README.md +172 -0
  568. package/examples/extensions/subagent/agents/planner.md +37 -0
  569. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  570. package/examples/extensions/subagent/agents/scout.md +50 -0
  571. package/examples/extensions/subagent/agents/worker.md +24 -0
  572. package/examples/extensions/subagent/agents.ts +127 -0
  573. package/examples/extensions/subagent/index.ts +964 -0
  574. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  575. package/examples/extensions/subagent/prompts/implement.md +10 -0
  576. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  577. package/examples/extensions/summarize.ts +195 -0
  578. package/examples/extensions/system-prompt-header.ts +17 -0
  579. package/examples/extensions/timed-confirm.ts +70 -0
  580. package/examples/extensions/titlebar-spinner.ts +58 -0
  581. package/examples/extensions/todo.ts +299 -0
  582. package/examples/extensions/tool-override.ts +143 -0
  583. package/examples/extensions/tools.ts +146 -0
  584. package/examples/extensions/trigger-compact.ts +40 -0
  585. package/examples/extensions/truncated-tool.ts +192 -0
  586. package/examples/extensions/widget-placement.ts +17 -0
  587. package/examples/extensions/with-deps/index.ts +36 -0
  588. package/examples/extensions/with-deps/package-lock.json +31 -0
  589. package/examples/extensions/with-deps/package.json +22 -0
  590. package/examples/rpc-extension-ui.ts +632 -0
  591. package/examples/sdk/01-minimal.ts +22 -0
  592. package/examples/sdk/02-custom-model.ts +49 -0
  593. package/examples/sdk/03-custom-prompt.ts +55 -0
  594. package/examples/sdk/04-skills.ts +46 -0
  595. package/examples/sdk/05-tools.ts +56 -0
  596. package/examples/sdk/06-extensions.ts +88 -0
  597. package/examples/sdk/07-context-files.ts +40 -0
  598. package/examples/sdk/08-prompt-templates.ts +47 -0
  599. package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  600. package/examples/sdk/10-settings.ts +51 -0
  601. package/examples/sdk/11-sessions.ts +48 -0
  602. package/examples/sdk/12-full-control.ts +82 -0
  603. package/examples/sdk/README.md +144 -0
  604. package/package.json +96 -0
@@ -0,0 +1,515 @@
1
+ /**
2
+ * Model registry - manages built-in and custom models, provides API key resolution.
3
+ */
4
+ import { getModels, getProviders, registerApiProvider, registerOAuthProvider, } from "@mariozechner/pi-ai";
5
+ import { Type } from "@sinclair/typebox";
6
+ import AjvModule from "ajv";
7
+ import { existsSync, readFileSync } from "fs";
8
+ import { join } from "path";
9
+ import { getAgentDir } from "../config.js";
10
+ import { clearConfigValueCache, resolveConfigValue, resolveHeaders } from "./resolve-config-value.js";
11
+ const Ajv = AjvModule.default || AjvModule;
12
+ // Schema for OpenRouter routing preferences
13
+ const OpenRouterRoutingSchema = Type.Object({
14
+ only: Type.Optional(Type.Array(Type.String())),
15
+ order: Type.Optional(Type.Array(Type.String())),
16
+ });
17
+ // Schema for Vercel AI Gateway routing preferences
18
+ const VercelGatewayRoutingSchema = Type.Object({
19
+ only: Type.Optional(Type.Array(Type.String())),
20
+ order: Type.Optional(Type.Array(Type.String())),
21
+ });
22
+ // Schema for OpenAI compatibility settings
23
+ const OpenAICompletionsCompatSchema = Type.Object({
24
+ supportsStore: Type.Optional(Type.Boolean()),
25
+ supportsDeveloperRole: Type.Optional(Type.Boolean()),
26
+ supportsReasoningEffort: Type.Optional(Type.Boolean()),
27
+ supportsUsageInStreaming: Type.Optional(Type.Boolean()),
28
+ maxTokensField: Type.Optional(Type.Union([Type.Literal("max_completion_tokens"), Type.Literal("max_tokens")])),
29
+ requiresToolResultName: Type.Optional(Type.Boolean()),
30
+ requiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),
31
+ requiresThinkingAsText: Type.Optional(Type.Boolean()),
32
+ requiresMistralToolIds: Type.Optional(Type.Boolean()),
33
+ thinkingFormat: Type.Optional(Type.Union([Type.Literal("openai"), Type.Literal("zai"), Type.Literal("qwen")])),
34
+ openRouterRouting: Type.Optional(OpenRouterRoutingSchema),
35
+ vercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),
36
+ });
37
+ const OpenAIResponsesCompatSchema = Type.Object({});
38
+ const OpenAICompatSchema = Type.Union([OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema]);
39
+ // Schema for custom model definition
40
+ // Most fields are optional with sensible defaults for local models (Ollama, LM Studio, etc.)
41
+ const ModelDefinitionSchema = Type.Object({
42
+ id: Type.String({ minLength: 1 }),
43
+ name: Type.Optional(Type.String({ minLength: 1 })),
44
+ api: Type.Optional(Type.String({ minLength: 1 })),
45
+ reasoning: Type.Optional(Type.Boolean()),
46
+ input: Type.Optional(Type.Array(Type.Union([Type.Literal("text"), Type.Literal("image")]))),
47
+ cost: Type.Optional(Type.Object({
48
+ input: Type.Number(),
49
+ output: Type.Number(),
50
+ cacheRead: Type.Number(),
51
+ cacheWrite: Type.Number(),
52
+ })),
53
+ contextWindow: Type.Optional(Type.Number()),
54
+ maxTokens: Type.Optional(Type.Number()),
55
+ headers: Type.Optional(Type.Record(Type.String(), Type.String())),
56
+ compat: Type.Optional(OpenAICompatSchema),
57
+ });
58
+ // Schema for per-model overrides (all fields optional, merged with built-in model)
59
+ const ModelOverrideSchema = Type.Object({
60
+ name: Type.Optional(Type.String({ minLength: 1 })),
61
+ reasoning: Type.Optional(Type.Boolean()),
62
+ input: Type.Optional(Type.Array(Type.Union([Type.Literal("text"), Type.Literal("image")]))),
63
+ cost: Type.Optional(Type.Object({
64
+ input: Type.Optional(Type.Number()),
65
+ output: Type.Optional(Type.Number()),
66
+ cacheRead: Type.Optional(Type.Number()),
67
+ cacheWrite: Type.Optional(Type.Number()),
68
+ })),
69
+ contextWindow: Type.Optional(Type.Number()),
70
+ maxTokens: Type.Optional(Type.Number()),
71
+ headers: Type.Optional(Type.Record(Type.String(), Type.String())),
72
+ compat: Type.Optional(OpenAICompatSchema),
73
+ });
74
+ const ProviderConfigSchema = Type.Object({
75
+ baseUrl: Type.Optional(Type.String({ minLength: 1 })),
76
+ apiKey: Type.Optional(Type.String({ minLength: 1 })),
77
+ api: Type.Optional(Type.String({ minLength: 1 })),
78
+ headers: Type.Optional(Type.Record(Type.String(), Type.String())),
79
+ authHeader: Type.Optional(Type.Boolean()),
80
+ models: Type.Optional(Type.Array(ModelDefinitionSchema)),
81
+ modelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),
82
+ });
83
+ const ModelsConfigSchema = Type.Object({
84
+ providers: Type.Record(Type.String(), ProviderConfigSchema),
85
+ });
86
+ function emptyCustomModelsResult(error) {
87
+ return { models: [], overrides: new Map(), modelOverrides: new Map(), error };
88
+ }
89
+ function mergeCompat(baseCompat, overrideCompat) {
90
+ if (!overrideCompat)
91
+ return baseCompat;
92
+ const base = baseCompat;
93
+ const override = overrideCompat;
94
+ const merged = { ...base, ...override };
95
+ const baseCompletions = base;
96
+ const overrideCompletions = override;
97
+ const mergedCompletions = merged;
98
+ if (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {
99
+ mergedCompletions.openRouterRouting = {
100
+ ...baseCompletions?.openRouterRouting,
101
+ ...overrideCompletions.openRouterRouting,
102
+ };
103
+ }
104
+ if (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {
105
+ mergedCompletions.vercelGatewayRouting = {
106
+ ...baseCompletions?.vercelGatewayRouting,
107
+ ...overrideCompletions.vercelGatewayRouting,
108
+ };
109
+ }
110
+ return merged;
111
+ }
112
+ /**
113
+ * Deep merge a model override into a model.
114
+ * Handles nested objects (cost, compat) by merging rather than replacing.
115
+ */
116
+ function applyModelOverride(model, override) {
117
+ const result = { ...model };
118
+ // Simple field overrides
119
+ if (override.name !== undefined)
120
+ result.name = override.name;
121
+ if (override.reasoning !== undefined)
122
+ result.reasoning = override.reasoning;
123
+ if (override.input !== undefined)
124
+ result.input = override.input;
125
+ if (override.contextWindow !== undefined)
126
+ result.contextWindow = override.contextWindow;
127
+ if (override.maxTokens !== undefined)
128
+ result.maxTokens = override.maxTokens;
129
+ // Merge cost (partial override)
130
+ if (override.cost) {
131
+ result.cost = {
132
+ input: override.cost.input ?? model.cost.input,
133
+ output: override.cost.output ?? model.cost.output,
134
+ cacheRead: override.cost.cacheRead ?? model.cost.cacheRead,
135
+ cacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,
136
+ };
137
+ }
138
+ // Merge headers
139
+ if (override.headers) {
140
+ const resolvedHeaders = resolveHeaders(override.headers);
141
+ result.headers = resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers;
142
+ }
143
+ // Deep merge compat
144
+ result.compat = mergeCompat(model.compat, override.compat);
145
+ return result;
146
+ }
147
+ /** Clear the config value command cache. Exported for testing. */
148
+ export const clearApiKeyCache = clearConfigValueCache;
149
+ /**
150
+ * Model registry - loads and manages models, resolves API keys via AuthStorage.
151
+ */
152
+ export class ModelRegistry {
153
+ authStorage;
154
+ modelsJsonPath;
155
+ models = [];
156
+ customProviderApiKeys = new Map();
157
+ registeredProviders = new Map();
158
+ loadError = undefined;
159
+ constructor(authStorage, modelsJsonPath = join(getAgentDir(), "models.json")) {
160
+ this.authStorage = authStorage;
161
+ this.modelsJsonPath = modelsJsonPath;
162
+ // Set up fallback resolver for custom provider API keys
163
+ this.authStorage.setFallbackResolver((provider) => {
164
+ const keyConfig = this.customProviderApiKeys.get(provider);
165
+ if (keyConfig) {
166
+ return resolveConfigValue(keyConfig);
167
+ }
168
+ return undefined;
169
+ });
170
+ // Load models
171
+ this.loadModels();
172
+ }
173
+ /**
174
+ * Reload models from disk (built-in + custom from models.json).
175
+ */
176
+ refresh() {
177
+ this.customProviderApiKeys.clear();
178
+ this.loadError = undefined;
179
+ this.loadModels();
180
+ for (const [providerName, config] of this.registeredProviders.entries()) {
181
+ this.applyProviderConfig(providerName, config);
182
+ }
183
+ }
184
+ /**
185
+ * Get any error from loading models.json (undefined if no error).
186
+ */
187
+ getError() {
188
+ return this.loadError;
189
+ }
190
+ loadModels() {
191
+ // Load custom models and overrides from models.json
192
+ const { models: customModels, overrides, modelOverrides, error, } = this.modelsJsonPath ? this.loadCustomModels(this.modelsJsonPath) : emptyCustomModelsResult();
193
+ if (error) {
194
+ this.loadError = error;
195
+ // Keep built-in models even if custom models failed to load
196
+ }
197
+ const builtInModels = this.loadBuiltInModels(overrides, modelOverrides);
198
+ let combined = this.mergeCustomModels(builtInModels, customModels);
199
+ // Let OAuth providers modify their models (e.g., update baseUrl)
200
+ for (const oauthProvider of this.authStorage.getOAuthProviders()) {
201
+ const cred = this.authStorage.get(oauthProvider.id);
202
+ if (cred?.type === "oauth" && oauthProvider.modifyModels) {
203
+ combined = oauthProvider.modifyModels(combined, cred);
204
+ }
205
+ }
206
+ this.models = combined;
207
+ }
208
+ /** Load built-in models and apply provider/model overrides */
209
+ loadBuiltInModels(overrides, modelOverrides) {
210
+ return getProviders().flatMap((provider) => {
211
+ const models = getModels(provider);
212
+ const providerOverride = overrides.get(provider);
213
+ const perModelOverrides = modelOverrides.get(provider);
214
+ return models.map((m) => {
215
+ let model = m;
216
+ // Apply provider-level baseUrl/headers override
217
+ if (providerOverride) {
218
+ const resolvedHeaders = resolveHeaders(providerOverride.headers);
219
+ model = {
220
+ ...model,
221
+ baseUrl: providerOverride.baseUrl ?? model.baseUrl,
222
+ headers: resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers,
223
+ };
224
+ }
225
+ // Apply per-model override
226
+ const modelOverride = perModelOverrides?.get(m.id);
227
+ if (modelOverride) {
228
+ model = applyModelOverride(model, modelOverride);
229
+ }
230
+ return model;
231
+ });
232
+ });
233
+ }
234
+ /** Merge custom models into built-in list by provider+id (custom wins on conflicts). */
235
+ mergeCustomModels(builtInModels, customModels) {
236
+ const merged = [...builtInModels];
237
+ for (const customModel of customModels) {
238
+ const existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);
239
+ if (existingIndex >= 0) {
240
+ merged[existingIndex] = customModel;
241
+ }
242
+ else {
243
+ merged.push(customModel);
244
+ }
245
+ }
246
+ return merged;
247
+ }
248
+ loadCustomModels(modelsJsonPath) {
249
+ if (!existsSync(modelsJsonPath)) {
250
+ return emptyCustomModelsResult();
251
+ }
252
+ try {
253
+ const content = readFileSync(modelsJsonPath, "utf-8");
254
+ const config = JSON.parse(content);
255
+ // Validate schema
256
+ const ajv = new Ajv();
257
+ const validate = ajv.compile(ModelsConfigSchema);
258
+ if (!validate(config)) {
259
+ const errors = validate.errors?.map((e) => ` - ${e.instancePath || "root"}: ${e.message}`).join("\n") ||
260
+ "Unknown schema error";
261
+ return emptyCustomModelsResult(`Invalid models.json schema:\n${errors}\n\nFile: ${modelsJsonPath}`);
262
+ }
263
+ // Additional validation
264
+ this.validateConfig(config);
265
+ const overrides = new Map();
266
+ const modelOverrides = new Map();
267
+ for (const [providerName, providerConfig] of Object.entries(config.providers)) {
268
+ // Apply provider-level baseUrl/headers/apiKey override to built-in models when configured.
269
+ if (providerConfig.baseUrl || providerConfig.headers || providerConfig.apiKey) {
270
+ overrides.set(providerName, {
271
+ baseUrl: providerConfig.baseUrl,
272
+ headers: providerConfig.headers,
273
+ apiKey: providerConfig.apiKey,
274
+ });
275
+ }
276
+ // Store API key for fallback resolver.
277
+ if (providerConfig.apiKey) {
278
+ this.customProviderApiKeys.set(providerName, providerConfig.apiKey);
279
+ }
280
+ if (providerConfig.modelOverrides) {
281
+ modelOverrides.set(providerName, new Map(Object.entries(providerConfig.modelOverrides)));
282
+ }
283
+ }
284
+ return { models: this.parseModels(config), overrides, modelOverrides, error: undefined };
285
+ }
286
+ catch (error) {
287
+ if (error instanceof SyntaxError) {
288
+ return emptyCustomModelsResult(`Failed to parse models.json: ${error.message}\n\nFile: ${modelsJsonPath}`);
289
+ }
290
+ return emptyCustomModelsResult(`Failed to load models.json: ${error instanceof Error ? error.message : error}\n\nFile: ${modelsJsonPath}`);
291
+ }
292
+ }
293
+ validateConfig(config) {
294
+ for (const [providerName, providerConfig] of Object.entries(config.providers)) {
295
+ const hasProviderApi = !!providerConfig.api;
296
+ const models = providerConfig.models ?? [];
297
+ const hasModelOverrides = providerConfig.modelOverrides && Object.keys(providerConfig.modelOverrides).length > 0;
298
+ if (models.length === 0) {
299
+ // Override-only config: needs baseUrl OR modelOverrides (or both)
300
+ if (!providerConfig.baseUrl && !hasModelOverrides) {
301
+ throw new Error(`Provider ${providerName}: must specify "baseUrl", "modelOverrides", or "models".`);
302
+ }
303
+ }
304
+ else {
305
+ // Custom models are merged into provider models and require endpoint + auth.
306
+ if (!providerConfig.baseUrl) {
307
+ throw new Error(`Provider ${providerName}: "baseUrl" is required when defining custom models.`);
308
+ }
309
+ if (!providerConfig.apiKey) {
310
+ throw new Error(`Provider ${providerName}: "apiKey" is required when defining custom models.`);
311
+ }
312
+ }
313
+ for (const modelDef of models) {
314
+ const hasModelApi = !!modelDef.api;
315
+ if (!hasProviderApi && !hasModelApi) {
316
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: no "api" specified. Set at provider or model level.`);
317
+ }
318
+ if (!modelDef.id)
319
+ throw new Error(`Provider ${providerName}: model missing "id"`);
320
+ // Validate contextWindow/maxTokens only if provided (they have defaults)
321
+ if (modelDef.contextWindow !== undefined && modelDef.contextWindow <= 0)
322
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);
323
+ if (modelDef.maxTokens !== undefined && modelDef.maxTokens <= 0)
324
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);
325
+ }
326
+ }
327
+ }
328
+ parseModels(config) {
329
+ const models = [];
330
+ for (const [providerName, providerConfig] of Object.entries(config.providers)) {
331
+ const modelDefs = providerConfig.models ?? [];
332
+ if (modelDefs.length === 0)
333
+ continue; // Override-only, no custom models
334
+ // Store API key config for fallback resolver
335
+ if (providerConfig.apiKey) {
336
+ this.customProviderApiKeys.set(providerName, providerConfig.apiKey);
337
+ }
338
+ for (const modelDef of modelDefs) {
339
+ const api = modelDef.api || providerConfig.api;
340
+ if (!api)
341
+ continue;
342
+ // Merge headers: provider headers are base, model headers override
343
+ // Resolve env vars and shell commands in header values
344
+ const providerHeaders = resolveHeaders(providerConfig.headers);
345
+ const modelHeaders = resolveHeaders(modelDef.headers);
346
+ let headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;
347
+ // If authHeader is true, add Authorization header with resolved API key
348
+ if (providerConfig.authHeader && providerConfig.apiKey) {
349
+ const resolvedKey = resolveConfigValue(providerConfig.apiKey);
350
+ if (resolvedKey) {
351
+ headers = { ...headers, Authorization: `Bearer ${resolvedKey}` };
352
+ }
353
+ }
354
+ // baseUrl is validated to exist for providers with models
355
+ // Apply defaults for optional fields
356
+ const defaultCost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
357
+ models.push({
358
+ id: modelDef.id,
359
+ name: modelDef.name ?? modelDef.id,
360
+ api: api,
361
+ provider: providerName,
362
+ baseUrl: providerConfig.baseUrl,
363
+ reasoning: modelDef.reasoning ?? false,
364
+ input: (modelDef.input ?? ["text"]),
365
+ cost: modelDef.cost ?? defaultCost,
366
+ contextWindow: modelDef.contextWindow ?? 128000,
367
+ maxTokens: modelDef.maxTokens ?? 16384,
368
+ headers,
369
+ compat: modelDef.compat,
370
+ });
371
+ }
372
+ }
373
+ return models;
374
+ }
375
+ /**
376
+ * Get all models (built-in + custom).
377
+ * If models.json had errors, returns only built-in models.
378
+ */
379
+ getAll() {
380
+ return this.models;
381
+ }
382
+ /**
383
+ * Get only models that have auth configured.
384
+ * This is a fast check that doesn't refresh OAuth tokens.
385
+ */
386
+ getAvailable() {
387
+ return this.models.filter((m) => this.authStorage.hasAuth(m.provider));
388
+ }
389
+ /**
390
+ * Find a model by provider and ID.
391
+ */
392
+ find(provider, modelId) {
393
+ return this.models.find((m) => m.provider === provider && m.id === modelId);
394
+ }
395
+ /**
396
+ * Get API key for a model.
397
+ */
398
+ async getApiKey(model) {
399
+ return this.authStorage.getApiKey(model.provider);
400
+ }
401
+ /**
402
+ * Get API key for a provider.
403
+ */
404
+ async getApiKeyForProvider(provider) {
405
+ return this.authStorage.getApiKey(provider);
406
+ }
407
+ /**
408
+ * Check if a model is using OAuth credentials (subscription).
409
+ */
410
+ isUsingOAuth(model) {
411
+ const cred = this.authStorage.get(model.provider);
412
+ return cred?.type === "oauth";
413
+ }
414
+ /**
415
+ * Register a provider dynamically (from extensions).
416
+ *
417
+ * If provider has models: replaces all existing models for this provider.
418
+ * If provider has only baseUrl/headers: overrides existing models' URLs.
419
+ * If provider has oauth: registers OAuth provider for /login support.
420
+ */
421
+ registerProvider(providerName, config) {
422
+ this.registeredProviders.set(providerName, config);
423
+ this.applyProviderConfig(providerName, config);
424
+ }
425
+ applyProviderConfig(providerName, config) {
426
+ // Register OAuth provider if provided
427
+ if (config.oauth) {
428
+ // Ensure the OAuth provider ID matches the provider name
429
+ const oauthProvider = {
430
+ ...config.oauth,
431
+ id: providerName,
432
+ };
433
+ registerOAuthProvider(oauthProvider);
434
+ }
435
+ if (config.streamSimple) {
436
+ if (!config.api) {
437
+ throw new Error(`Provider ${providerName}: "api" is required when registering streamSimple.`);
438
+ }
439
+ const streamSimple = config.streamSimple;
440
+ registerApiProvider({
441
+ api: config.api,
442
+ stream: (model, context, options) => streamSimple(model, context, options),
443
+ streamSimple,
444
+ });
445
+ }
446
+ // Store API key for auth resolution
447
+ if (config.apiKey) {
448
+ this.customProviderApiKeys.set(providerName, config.apiKey);
449
+ }
450
+ if (config.models && config.models.length > 0) {
451
+ // Full replacement: remove existing models for this provider
452
+ this.models = this.models.filter((m) => m.provider !== providerName);
453
+ // Validate required fields
454
+ if (!config.baseUrl) {
455
+ throw new Error(`Provider ${providerName}: "baseUrl" is required when defining models.`);
456
+ }
457
+ if (!config.apiKey && !config.oauth) {
458
+ throw new Error(`Provider ${providerName}: "apiKey" or "oauth" is required when defining models.`);
459
+ }
460
+ // Parse and add new models
461
+ for (const modelDef of config.models) {
462
+ const api = modelDef.api || config.api;
463
+ if (!api) {
464
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: no "api" specified.`);
465
+ }
466
+ // Merge headers
467
+ const providerHeaders = resolveHeaders(config.headers);
468
+ const modelHeaders = resolveHeaders(modelDef.headers);
469
+ let headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;
470
+ // If authHeader is true, add Authorization header
471
+ if (config.authHeader && config.apiKey) {
472
+ const resolvedKey = resolveConfigValue(config.apiKey);
473
+ if (resolvedKey) {
474
+ headers = { ...headers, Authorization: `Bearer ${resolvedKey}` };
475
+ }
476
+ }
477
+ this.models.push({
478
+ id: modelDef.id,
479
+ name: modelDef.name,
480
+ api: api,
481
+ provider: providerName,
482
+ baseUrl: config.baseUrl,
483
+ reasoning: modelDef.reasoning,
484
+ input: modelDef.input,
485
+ cost: modelDef.cost,
486
+ contextWindow: modelDef.contextWindow,
487
+ maxTokens: modelDef.maxTokens,
488
+ headers,
489
+ compat: modelDef.compat,
490
+ });
491
+ }
492
+ // Apply OAuth modifyModels if credentials exist (e.g., to update baseUrl)
493
+ if (config.oauth?.modifyModels) {
494
+ const cred = this.authStorage.get(providerName);
495
+ if (cred?.type === "oauth") {
496
+ this.models = config.oauth.modifyModels(this.models, cred);
497
+ }
498
+ }
499
+ }
500
+ else if (config.baseUrl) {
501
+ // Override-only: update baseUrl/headers for existing models
502
+ const resolvedHeaders = resolveHeaders(config.headers);
503
+ this.models = this.models.map((m) => {
504
+ if (m.provider !== providerName)
505
+ return m;
506
+ return {
507
+ ...m,
508
+ baseUrl: config.baseUrl ?? m.baseUrl,
509
+ headers: resolvedHeaders ? { ...m.headers, ...resolvedHeaders } : m.headers,
510
+ };
511
+ });
512
+ }
513
+ }
514
+ }
515
+ //# sourceMappingURL=model-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Model registry - manages built-in and custom models, provides API key resolution.\r\n */\r\n\r\nimport {\r\n\ttype Api,\r\n\ttype AssistantMessageEventStream,\r\n\ttype Context,\r\n\tgetModels,\r\n\tgetProviders,\r\n\ttype KnownProvider,\r\n\ttype Model,\r\n\ttype OAuthProviderInterface,\r\n\ttype OpenAICompletionsCompat,\r\n\ttype OpenAIResponsesCompat,\r\n\tregisterApiProvider,\r\n\tregisterOAuthProvider,\r\n\ttype SimpleStreamOptions,\r\n} from \"@mariozechner/pi-ai\";\r\nimport { type Static, Type } from \"@sinclair/typebox\";\r\nimport AjvModule from \"ajv\";\r\nimport { existsSync, readFileSync } from \"fs\";\r\nimport { join } from \"path\";\r\nimport { getAgentDir } from \"../config.js\";\r\nimport type { AuthStorage } from \"./auth-storage.js\";\r\nimport { clearConfigValueCache, resolveConfigValue, resolveHeaders } from \"./resolve-config-value.js\";\r\n\r\nconst Ajv = (AjvModule as any).default || AjvModule;\r\n\r\n// Schema for OpenRouter routing preferences\r\nconst OpenRouterRoutingSchema = Type.Object({\r\n\tonly: Type.Optional(Type.Array(Type.String())),\r\n\torder: Type.Optional(Type.Array(Type.String())),\r\n});\r\n\r\n// Schema for Vercel AI Gateway routing preferences\r\nconst VercelGatewayRoutingSchema = Type.Object({\r\n\tonly: Type.Optional(Type.Array(Type.String())),\r\n\torder: Type.Optional(Type.Array(Type.String())),\r\n});\r\n\r\n// Schema for OpenAI compatibility settings\r\nconst OpenAICompletionsCompatSchema = Type.Object({\r\n\tsupportsStore: Type.Optional(Type.Boolean()),\r\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\r\n\tsupportsReasoningEffort: Type.Optional(Type.Boolean()),\r\n\tsupportsUsageInStreaming: Type.Optional(Type.Boolean()),\r\n\tmaxTokensField: Type.Optional(Type.Union([Type.Literal(\"max_completion_tokens\"), Type.Literal(\"max_tokens\")])),\r\n\trequiresToolResultName: Type.Optional(Type.Boolean()),\r\n\trequiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),\r\n\trequiresThinkingAsText: Type.Optional(Type.Boolean()),\r\n\trequiresMistralToolIds: Type.Optional(Type.Boolean()),\r\n\tthinkingFormat: Type.Optional(Type.Union([Type.Literal(\"openai\"), Type.Literal(\"zai\"), Type.Literal(\"qwen\")])),\r\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\r\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\r\n});\r\n\r\nconst OpenAIResponsesCompatSchema = Type.Object({\r\n\t// Reserved for future use\r\n});\r\n\r\nconst OpenAICompatSchema = Type.Union([OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema]);\r\n\r\n// Schema for custom model definition\r\n// Most fields are optional with sensible defaults for local models (Ollama, LM Studio, etc.)\r\nconst ModelDefinitionSchema = Type.Object({\r\n\tid: Type.String({ minLength: 1 }),\r\n\tname: Type.Optional(Type.String({ minLength: 1 })),\r\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\r\n\treasoning: Type.Optional(Type.Boolean()),\r\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\r\n\tcost: Type.Optional(\r\n\t\tType.Object({\r\n\t\t\tinput: Type.Number(),\r\n\t\t\toutput: Type.Number(),\r\n\t\t\tcacheRead: Type.Number(),\r\n\t\t\tcacheWrite: Type.Number(),\r\n\t\t}),\r\n\t),\r\n\tcontextWindow: Type.Optional(Type.Number()),\r\n\tmaxTokens: Type.Optional(Type.Number()),\r\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\r\n\tcompat: Type.Optional(OpenAICompatSchema),\r\n});\r\n\r\n// Schema for per-model overrides (all fields optional, merged with built-in model)\r\nconst ModelOverrideSchema = Type.Object({\r\n\tname: Type.Optional(Type.String({ minLength: 1 })),\r\n\treasoning: Type.Optional(Type.Boolean()),\r\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\r\n\tcost: Type.Optional(\r\n\t\tType.Object({\r\n\t\t\tinput: Type.Optional(Type.Number()),\r\n\t\t\toutput: Type.Optional(Type.Number()),\r\n\t\t\tcacheRead: Type.Optional(Type.Number()),\r\n\t\t\tcacheWrite: Type.Optional(Type.Number()),\r\n\t\t}),\r\n\t),\r\n\tcontextWindow: Type.Optional(Type.Number()),\r\n\tmaxTokens: Type.Optional(Type.Number()),\r\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\r\n\tcompat: Type.Optional(OpenAICompatSchema),\r\n});\r\n\r\ntype ModelOverride = Static<typeof ModelOverrideSchema>;\r\n\r\nconst ProviderConfigSchema = Type.Object({\r\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\r\n\tapiKey: Type.Optional(Type.String({ minLength: 1 })),\r\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\r\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\r\n\tauthHeader: Type.Optional(Type.Boolean()),\r\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\r\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\r\n});\r\n\r\nconst ModelsConfigSchema = Type.Object({\r\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\r\n});\r\n\r\ntype ModelsConfig = Static<typeof ModelsConfigSchema>;\r\n\r\n/** Provider override config (baseUrl, headers, apiKey) without custom models */\r\ninterface ProviderOverride {\r\n\tbaseUrl?: string;\r\n\theaders?: Record<string, string>;\r\n\tapiKey?: string;\r\n}\r\n\r\n/** Result of loading custom models from models.json */\r\ninterface CustomModelsResult {\r\n\tmodels: Model<Api>[];\r\n\t/** Providers with baseUrl/headers/apiKey overrides for built-in models */\r\n\toverrides: Map<string, ProviderOverride>;\r\n\t/** Per-model overrides: provider -> modelId -> override */\r\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>;\r\n\terror: string | undefined;\r\n}\r\n\r\nfunction emptyCustomModelsResult(error?: string): CustomModelsResult {\r\n\treturn { models: [], overrides: new Map(), modelOverrides: new Map(), error };\r\n}\r\n\r\nfunction mergeCompat(\r\n\tbaseCompat: Model<Api>[\"compat\"],\r\n\toverrideCompat: ModelOverride[\"compat\"],\r\n): Model<Api>[\"compat\"] | undefined {\r\n\tif (!overrideCompat) return baseCompat;\r\n\r\n\tconst base = baseCompat as OpenAICompletionsCompat | OpenAIResponsesCompat | undefined;\r\n\tconst override = overrideCompat as OpenAICompletionsCompat | OpenAIResponsesCompat;\r\n\tconst merged = { ...base, ...override } as OpenAICompletionsCompat | OpenAIResponsesCompat;\r\n\r\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\r\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\r\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\r\n\r\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\r\n\t\tmergedCompletions.openRouterRouting = {\r\n\t\t\t...baseCompletions?.openRouterRouting,\r\n\t\t\t...overrideCompletions.openRouterRouting,\r\n\t\t};\r\n\t}\r\n\r\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\r\n\t\tmergedCompletions.vercelGatewayRouting = {\r\n\t\t\t...baseCompletions?.vercelGatewayRouting,\r\n\t\t\t...overrideCompletions.vercelGatewayRouting,\r\n\t\t};\r\n\t}\r\n\r\n\treturn merged as Model<Api>[\"compat\"];\r\n}\r\n\r\n/**\r\n * Deep merge a model override into a model.\r\n * Handles nested objects (cost, compat) by merging rather than replacing.\r\n */\r\nfunction applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\r\n\tconst result = { ...model };\r\n\r\n\t// Simple field overrides\r\n\tif (override.name !== undefined) result.name = override.name;\r\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\r\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\r\n\tif (override.contextWindow !== undefined) result.contextWindow = override.contextWindow;\r\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\r\n\r\n\t// Merge cost (partial override)\r\n\tif (override.cost) {\r\n\t\tresult.cost = {\r\n\t\t\tinput: override.cost.input ?? model.cost.input,\r\n\t\t\toutput: override.cost.output ?? model.cost.output,\r\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\r\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\r\n\t\t};\r\n\t}\r\n\r\n\t// Merge headers\r\n\tif (override.headers) {\r\n\t\tconst resolvedHeaders = resolveHeaders(override.headers);\r\n\t\tresult.headers = resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers;\r\n\t}\r\n\r\n\t// Deep merge compat\r\n\tresult.compat = mergeCompat(model.compat, override.compat);\r\n\r\n\treturn result;\r\n}\r\n\r\n/** Clear the config value command cache. Exported for testing. */\r\nexport const clearApiKeyCache = clearConfigValueCache;\r\n\r\n/**\r\n * Model registry - loads and manages models, resolves API keys via AuthStorage.\r\n */\r\nexport class ModelRegistry {\r\n\tprivate models: Model<Api>[] = [];\r\n\tprivate customProviderApiKeys: Map<string, string> = new Map();\r\n\tprivate registeredProviders: Map<string, ProviderConfigInput> = new Map();\r\n\tprivate loadError: string | undefined = undefined;\r\n\r\n\tconstructor(\r\n\t\treadonly authStorage: AuthStorage,\r\n\t\tprivate modelsJsonPath: string | undefined = join(getAgentDir(), \"models.json\"),\r\n\t) {\r\n\t\t// Set up fallback resolver for custom provider API keys\r\n\t\tthis.authStorage.setFallbackResolver((provider) => {\r\n\t\t\tconst keyConfig = this.customProviderApiKeys.get(provider);\r\n\t\t\tif (keyConfig) {\r\n\t\t\t\treturn resolveConfigValue(keyConfig);\r\n\t\t\t}\r\n\t\t\treturn undefined;\r\n\t\t});\r\n\r\n\t\t// Load models\r\n\t\tthis.loadModels();\r\n\t}\r\n\r\n\t/**\r\n\t * Reload models from disk (built-in + custom from models.json).\r\n\t */\r\n\trefresh(): void {\r\n\t\tthis.customProviderApiKeys.clear();\r\n\t\tthis.loadError = undefined;\r\n\t\tthis.loadModels();\r\n\r\n\t\tfor (const [providerName, config] of this.registeredProviders.entries()) {\r\n\t\t\tthis.applyProviderConfig(providerName, config);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Get any error from loading models.json (undefined if no error).\r\n\t */\r\n\tgetError(): string | undefined {\r\n\t\treturn this.loadError;\r\n\t}\r\n\r\n\tprivate loadModels(): void {\r\n\t\t// Load custom models and overrides from models.json\r\n\t\tconst {\r\n\t\t\tmodels: customModels,\r\n\t\t\toverrides,\r\n\t\t\tmodelOverrides,\r\n\t\t\terror,\r\n\t\t} = this.modelsJsonPath ? this.loadCustomModels(this.modelsJsonPath) : emptyCustomModelsResult();\r\n\r\n\t\tif (error) {\r\n\t\t\tthis.loadError = error;\r\n\t\t\t// Keep built-in models even if custom models failed to load\r\n\t\t}\r\n\r\n\t\tconst builtInModels = this.loadBuiltInModels(overrides, modelOverrides);\r\n\t\tlet combined = this.mergeCustomModels(builtInModels, customModels);\r\n\r\n\t\t// Let OAuth providers modify their models (e.g., update baseUrl)\r\n\t\tfor (const oauthProvider of this.authStorage.getOAuthProviders()) {\r\n\t\t\tconst cred = this.authStorage.get(oauthProvider.id);\r\n\t\t\tif (cred?.type === \"oauth\" && oauthProvider.modifyModels) {\r\n\t\t\t\tcombined = oauthProvider.modifyModels(combined, cred);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tthis.models = combined;\r\n\t}\r\n\r\n\t/** Load built-in models and apply provider/model overrides */\r\n\tprivate loadBuiltInModels(\r\n\t\toverrides: Map<string, ProviderOverride>,\r\n\t\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\r\n\t): Model<Api>[] {\r\n\t\treturn getProviders().flatMap((provider) => {\r\n\t\t\tconst models = getModels(provider as KnownProvider) as Model<Api>[];\r\n\t\t\tconst providerOverride = overrides.get(provider);\r\n\t\t\tconst perModelOverrides = modelOverrides.get(provider);\r\n\r\n\t\t\treturn models.map((m) => {\r\n\t\t\t\tlet model = m;\r\n\r\n\t\t\t\t// Apply provider-level baseUrl/headers override\r\n\t\t\t\tif (providerOverride) {\r\n\t\t\t\t\tconst resolvedHeaders = resolveHeaders(providerOverride.headers);\r\n\t\t\t\t\tmodel = {\r\n\t\t\t\t\t\t...model,\r\n\t\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\r\n\t\t\t\t\t\theaders: resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Apply per-model override\r\n\t\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\r\n\t\t\t\tif (modelOverride) {\r\n\t\t\t\t\tmodel = applyModelOverride(model, modelOverride);\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn model;\r\n\t\t\t});\r\n\t\t});\r\n\t}\r\n\r\n\t/** Merge custom models into built-in list by provider+id (custom wins on conflicts). */\r\n\tprivate mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\r\n\t\tconst merged = [...builtInModels];\r\n\t\tfor (const customModel of customModels) {\r\n\t\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\r\n\t\t\tif (existingIndex >= 0) {\r\n\t\t\t\tmerged[existingIndex] = customModel;\r\n\t\t\t} else {\r\n\t\t\t\tmerged.push(customModel);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn merged;\r\n\t}\r\n\r\n\tprivate loadCustomModels(modelsJsonPath: string): CustomModelsResult {\r\n\t\tif (!existsSync(modelsJsonPath)) {\r\n\t\t\treturn emptyCustomModelsResult();\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\tconst content = readFileSync(modelsJsonPath, \"utf-8\");\r\n\t\t\tconst config: ModelsConfig = JSON.parse(content);\r\n\r\n\t\t\t// Validate schema\r\n\t\t\tconst ajv = new Ajv();\r\n\t\t\tconst validate = ajv.compile(ModelsConfigSchema);\r\n\t\t\tif (!validate(config)) {\r\n\t\t\t\tconst errors =\r\n\t\t\t\t\tvalidate.errors?.map((e: any) => ` - ${e.instancePath || \"root\"}: ${e.message}`).join(\"\\n\") ||\r\n\t\t\t\t\t\"Unknown schema error\";\r\n\t\t\t\treturn emptyCustomModelsResult(`Invalid models.json schema:\\n${errors}\\n\\nFile: ${modelsJsonPath}`);\r\n\t\t\t}\r\n\r\n\t\t\t// Additional validation\r\n\t\t\tthis.validateConfig(config);\r\n\r\n\t\t\tconst overrides = new Map<string, ProviderOverride>();\r\n\t\t\tconst modelOverrides = new Map<string, Map<string, ModelOverride>>();\r\n\r\n\t\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\r\n\t\t\t\t// Apply provider-level baseUrl/headers/apiKey override to built-in models when configured.\r\n\t\t\t\tif (providerConfig.baseUrl || providerConfig.headers || providerConfig.apiKey) {\r\n\t\t\t\t\toverrides.set(providerName, {\r\n\t\t\t\t\t\tbaseUrl: providerConfig.baseUrl,\r\n\t\t\t\t\t\theaders: providerConfig.headers,\r\n\t\t\t\t\t\tapiKey: providerConfig.apiKey,\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Store API key for fallback resolver.\r\n\t\t\t\tif (providerConfig.apiKey) {\r\n\t\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (providerConfig.modelOverrides) {\r\n\t\t\t\t\tmodelOverrides.set(providerName, new Map(Object.entries(providerConfig.modelOverrides)));\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn { models: this.parseModels(config), overrides, modelOverrides, error: undefined };\r\n\t\t} catch (error) {\r\n\t\t\tif (error instanceof SyntaxError) {\r\n\t\t\t\treturn emptyCustomModelsResult(`Failed to parse models.json: ${error.message}\\n\\nFile: ${modelsJsonPath}`);\r\n\t\t\t}\r\n\t\t\treturn emptyCustomModelsResult(\r\n\t\t\t\t`Failed to load models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${modelsJsonPath}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate validateConfig(config: ModelsConfig): void {\r\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\r\n\t\t\tconst hasProviderApi = !!providerConfig.api;\r\n\t\t\tconst models = providerConfig.models ?? [];\r\n\t\t\tconst hasModelOverrides =\r\n\t\t\t\tproviderConfig.modelOverrides && Object.keys(providerConfig.modelOverrides).length > 0;\r\n\r\n\t\t\tif (models.length === 0) {\r\n\t\t\t\t// Override-only config: needs baseUrl OR modelOverrides (or both)\r\n\t\t\t\tif (!providerConfig.baseUrl && !hasModelOverrides) {\r\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: must specify \"baseUrl\", \"modelOverrides\", or \"models\".`);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// Custom models are merged into provider models and require endpoint + auth.\r\n\t\t\t\tif (!providerConfig.baseUrl) {\r\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining custom models.`);\r\n\t\t\t\t}\r\n\t\t\t\tif (!providerConfig.apiKey) {\r\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" is required when defining custom models.`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tfor (const modelDef of models) {\r\n\t\t\t\tconst hasModelApi = !!modelDef.api;\r\n\r\n\t\t\t\tif (!hasProviderApi && !hasModelApi) {\r\n\t\t\t\t\tthrow new Error(\r\n\t\t\t\t\t\t`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified. Set at provider or model level.`,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!modelDef.id) throw new Error(`Provider ${providerName}: model missing \"id\"`);\r\n\t\t\t\t// Validate contextWindow/maxTokens only if provided (they have defaults)\r\n\t\t\t\tif (modelDef.contextWindow !== undefined && modelDef.contextWindow <= 0)\r\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);\r\n\t\t\t\tif (modelDef.maxTokens !== undefined && modelDef.maxTokens <= 0)\r\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate parseModels(config: ModelsConfig): Model<Api>[] {\r\n\t\tconst models: Model<Api>[] = [];\r\n\r\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\r\n\t\t\tconst modelDefs = providerConfig.models ?? [];\r\n\t\t\tif (modelDefs.length === 0) continue; // Override-only, no custom models\r\n\r\n\t\t\t// Store API key config for fallback resolver\r\n\t\t\tif (providerConfig.apiKey) {\r\n\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\r\n\t\t\t}\r\n\r\n\t\t\tfor (const modelDef of modelDefs) {\r\n\t\t\t\tconst api = modelDef.api || providerConfig.api;\r\n\t\t\t\tif (!api) continue;\r\n\r\n\t\t\t\t// Merge headers: provider headers are base, model headers override\r\n\t\t\t\t// Resolve env vars and shell commands in header values\r\n\t\t\t\tconst providerHeaders = resolveHeaders(providerConfig.headers);\r\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\r\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\r\n\r\n\t\t\t\t// If authHeader is true, add Authorization header with resolved API key\r\n\t\t\t\tif (providerConfig.authHeader && providerConfig.apiKey) {\r\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(providerConfig.apiKey);\r\n\t\t\t\t\tif (resolvedKey) {\r\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// baseUrl is validated to exist for providers with models\r\n\t\t\t\t// Apply defaults for optional fields\r\n\t\t\t\tconst defaultCost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\r\n\t\t\t\tmodels.push({\r\n\t\t\t\t\tid: modelDef.id,\r\n\t\t\t\t\tname: modelDef.name ?? modelDef.id,\r\n\t\t\t\t\tapi: api as Api,\r\n\t\t\t\t\tprovider: providerName,\r\n\t\t\t\t\tbaseUrl: providerConfig.baseUrl!,\r\n\t\t\t\t\treasoning: modelDef.reasoning ?? false,\r\n\t\t\t\t\tinput: (modelDef.input ?? [\"text\"]) as (\"text\" | \"image\")[],\r\n\t\t\t\t\tcost: modelDef.cost ?? defaultCost,\r\n\t\t\t\t\tcontextWindow: modelDef.contextWindow ?? 128000,\r\n\t\t\t\t\tmaxTokens: modelDef.maxTokens ?? 16384,\r\n\t\t\t\t\theaders,\r\n\t\t\t\t\tcompat: modelDef.compat,\r\n\t\t\t\t} as Model<Api>);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn models;\r\n\t}\r\n\r\n\t/**\r\n\t * Get all models (built-in + custom).\r\n\t * If models.json had errors, returns only built-in models.\r\n\t */\r\n\tgetAll(): Model<Api>[] {\r\n\t\treturn this.models;\r\n\t}\r\n\r\n\t/**\r\n\t * Get only models that have auth configured.\r\n\t * This is a fast check that doesn't refresh OAuth tokens.\r\n\t */\r\n\tgetAvailable(): Model<Api>[] {\r\n\t\treturn this.models.filter((m) => this.authStorage.hasAuth(m.provider));\r\n\t}\r\n\r\n\t/**\r\n\t * Find a model by provider and ID.\r\n\t */\r\n\tfind(provider: string, modelId: string): Model<Api> | undefined {\r\n\t\treturn this.models.find((m) => m.provider === provider && m.id === modelId);\r\n\t}\r\n\r\n\t/**\r\n\t * Get API key for a model.\r\n\t */\r\n\tasync getApiKey(model: Model<Api>): Promise<string | undefined> {\r\n\t\treturn this.authStorage.getApiKey(model.provider);\r\n\t}\r\n\r\n\t/**\r\n\t * Get API key for a provider.\r\n\t */\r\n\tasync getApiKeyForProvider(provider: string): Promise<string | undefined> {\r\n\t\treturn this.authStorage.getApiKey(provider);\r\n\t}\r\n\r\n\t/**\r\n\t * Check if a model is using OAuth credentials (subscription).\r\n\t */\r\n\tisUsingOAuth(model: Model<Api>): boolean {\r\n\t\tconst cred = this.authStorage.get(model.provider);\r\n\t\treturn cred?.type === \"oauth\";\r\n\t}\r\n\r\n\t/**\r\n\t * Register a provider dynamically (from extensions).\r\n\t *\r\n\t * If provider has models: replaces all existing models for this provider.\r\n\t * If provider has only baseUrl/headers: overrides existing models' URLs.\r\n\t * If provider has oauth: registers OAuth provider for /login support.\r\n\t */\r\n\tregisterProvider(providerName: string, config: ProviderConfigInput): void {\r\n\t\tthis.registeredProviders.set(providerName, config);\r\n\t\tthis.applyProviderConfig(providerName, config);\r\n\t}\r\n\r\n\tprivate applyProviderConfig(providerName: string, config: ProviderConfigInput): void {\r\n\t\t// Register OAuth provider if provided\r\n\t\tif (config.oauth) {\r\n\t\t\t// Ensure the OAuth provider ID matches the provider name\r\n\t\t\tconst oauthProvider: OAuthProviderInterface = {\r\n\t\t\t\t...config.oauth,\r\n\t\t\t\tid: providerName,\r\n\t\t\t};\r\n\t\t\tregisterOAuthProvider(oauthProvider);\r\n\t\t}\r\n\r\n\t\tif (config.streamSimple) {\r\n\t\t\tif (!config.api) {\r\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"api\" is required when registering streamSimple.`);\r\n\t\t\t}\r\n\t\t\tconst streamSimple = config.streamSimple;\r\n\t\t\tregisterApiProvider({\r\n\t\t\t\tapi: config.api,\r\n\t\t\t\tstream: (model, context, options) => streamSimple(model, context, options as SimpleStreamOptions),\r\n\t\t\t\tstreamSimple,\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// Store API key for auth resolution\r\n\t\tif (config.apiKey) {\r\n\t\t\tthis.customProviderApiKeys.set(providerName, config.apiKey);\r\n\t\t}\r\n\r\n\t\tif (config.models && config.models.length > 0) {\r\n\t\t\t// Full replacement: remove existing models for this provider\r\n\t\t\tthis.models = this.models.filter((m) => m.provider !== providerName);\r\n\r\n\t\t\t// Validate required fields\r\n\t\t\tif (!config.baseUrl) {\r\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining models.`);\r\n\t\t\t}\r\n\t\t\tif (!config.apiKey && !config.oauth) {\r\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" or \"oauth\" is required when defining models.`);\r\n\t\t\t}\r\n\r\n\t\t\t// Parse and add new models\r\n\t\t\tfor (const modelDef of config.models) {\r\n\t\t\t\tconst api = modelDef.api || config.api;\r\n\t\t\t\tif (!api) {\r\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified.`);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Merge headers\r\n\t\t\t\tconst providerHeaders = resolveHeaders(config.headers);\r\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\r\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\r\n\r\n\t\t\t\t// If authHeader is true, add Authorization header\r\n\t\t\t\tif (config.authHeader && config.apiKey) {\r\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(config.apiKey);\r\n\t\t\t\t\tif (resolvedKey) {\r\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis.models.push({\r\n\t\t\t\t\tid: modelDef.id,\r\n\t\t\t\t\tname: modelDef.name,\r\n\t\t\t\t\tapi: api as Api,\r\n\t\t\t\t\tprovider: providerName,\r\n\t\t\t\t\tbaseUrl: config.baseUrl,\r\n\t\t\t\t\treasoning: modelDef.reasoning,\r\n\t\t\t\t\tinput: modelDef.input as (\"text\" | \"image\")[],\r\n\t\t\t\t\tcost: modelDef.cost,\r\n\t\t\t\t\tcontextWindow: modelDef.contextWindow,\r\n\t\t\t\t\tmaxTokens: modelDef.maxTokens,\r\n\t\t\t\t\theaders,\r\n\t\t\t\t\tcompat: modelDef.compat,\r\n\t\t\t\t} as Model<Api>);\r\n\t\t\t}\r\n\r\n\t\t\t// Apply OAuth modifyModels if credentials exist (e.g., to update baseUrl)\r\n\t\t\tif (config.oauth?.modifyModels) {\r\n\t\t\t\tconst cred = this.authStorage.get(providerName);\r\n\t\t\t\tif (cred?.type === \"oauth\") {\r\n\t\t\t\t\tthis.models = config.oauth.modifyModels(this.models, cred);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if (config.baseUrl) {\r\n\t\t\t// Override-only: update baseUrl/headers for existing models\r\n\t\t\tconst resolvedHeaders = resolveHeaders(config.headers);\r\n\t\t\tthis.models = this.models.map((m) => {\r\n\t\t\t\tif (m.provider !== providerName) return m;\r\n\t\t\t\treturn {\r\n\t\t\t\t\t...m,\r\n\t\t\t\t\tbaseUrl: config.baseUrl ?? m.baseUrl,\r\n\t\t\t\t\theaders: resolvedHeaders ? { ...m.headers, ...resolvedHeaders } : m.headers,\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Input type for registerProvider API.\r\n */\r\nexport interface ProviderConfigInput {\r\n\tbaseUrl?: string;\r\n\tapiKey?: string;\r\n\tapi?: Api;\r\n\tstreamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;\r\n\theaders?: Record<string, string>;\r\n\tauthHeader?: boolean;\r\n\t/** OAuth provider for /login support */\r\n\toauth?: Omit<OAuthProviderInterface, \"id\">;\r\n\tmodels?: Array<{\r\n\t\tid: string;\r\n\t\tname: string;\r\n\t\tapi?: Api;\r\n\t\treasoning: boolean;\r\n\t\tinput: (\"text\" | \"image\")[];\r\n\t\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number };\r\n\t\tcontextWindow: number;\r\n\t\tmaxTokens: number;\r\n\t\theaders?: Record<string, string>;\r\n\t\tcompat?: Model<Api>[\"compat\"];\r\n\t}>;\r\n}\r\n"]}