indusagi-coding-agent 0.1.37 → 0.1.39

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 (489) hide show
  1. package/CHANGELOG.md +23 -7
  2. package/README.md +2 -4
  3. package/dist/cli/args.d.ts +6 -128
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +277 -472
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/config-selector.d.ts +9 -62
  8. package/dist/cli/config-selector.d.ts.map +1 -1
  9. package/dist/cli/config-selector.js +31 -146
  10. package/dist/cli/config-selector.js.map +1 -1
  11. package/dist/cli/file-processor.d.ts +1 -69
  12. package/dist/cli/file-processor.d.ts.map +1 -1
  13. package/dist/cli/file-processor.js +36 -267
  14. package/dist/cli/file-processor.js.map +1 -1
  15. package/dist/cli/list-models.d.ts +0 -60
  16. package/dist/cli/list-models.d.ts.map +1 -1
  17. package/dist/cli/list-models.js +53 -246
  18. package/dist/cli/list-models.js.map +1 -1
  19. package/dist/cli/session-picker.d.ts +1 -72
  20. package/dist/cli/session-picker.d.ts.map +1 -1
  21. package/dist/cli/session-picker.js +57 -231
  22. package/dist/cli/session-picker.js.map +1 -1
  23. package/dist/cli.js +25 -31
  24. package/dist/cli.js.map +1 -1
  25. package/dist/config.d.ts +0 -42
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +62 -97
  28. package/dist/config.js.map +1 -1
  29. package/dist/core/agent-session.d.ts +23 -0
  30. package/dist/core/agent-session.d.ts.map +1 -1
  31. package/dist/core/agent-session.js +78 -66
  32. package/dist/core/agent-session.js.map +1 -1
  33. package/dist/core/auth-storage.d.ts +4 -95
  34. package/dist/core/auth-storage.d.ts.map +1 -1
  35. package/dist/core/auth-storage.js +233 -288
  36. package/dist/core/auth-storage.js.map +1 -1
  37. package/dist/core/bash-executor.d.ts +0 -323
  38. package/dist/core/bash-executor.d.ts.map +1 -1
  39. package/dist/core/bash-executor.js +126 -359
  40. package/dist/core/bash-executor.js.map +1 -1
  41. package/dist/core/compaction/branch-summarization.d.ts +3 -3
  42. package/dist/core/compaction/branch-summarization.js +16 -16
  43. package/dist/core/compaction/branch-summarization.js.map +1 -1
  44. package/dist/core/compaction/compaction.d.ts +3 -3
  45. package/dist/core/compaction/compaction.js +40 -40
  46. package/dist/core/compaction/compaction.js.map +1 -1
  47. package/dist/core/compaction/index.d.ts +32 -4
  48. package/dist/core/compaction/index.d.ts.map +1 -1
  49. package/dist/core/compaction/index.js +30 -4
  50. package/dist/core/compaction/index.js.map +1 -1
  51. package/dist/core/compaction/utils.d.ts +1 -19
  52. package/dist/core/compaction/utils.d.ts.map +1 -1
  53. package/dist/core/compaction/utils.js +92 -113
  54. package/dist/core/compaction/utils.js.map +1 -1
  55. package/dist/core/discover-packages.d.ts +0 -4
  56. package/dist/core/discover-packages.d.ts.map +1 -1
  57. package/dist/core/discover-packages.js +41 -44
  58. package/dist/core/discover-packages.js.map +1 -1
  59. package/dist/core/event-bus.d.ts +1 -147
  60. package/dist/core/event-bus.d.ts.map +1 -1
  61. package/dist/core/event-bus.js +17 -106
  62. package/dist/core/event-bus.js.map +1 -1
  63. package/dist/core/exec.d.ts +0 -16
  64. package/dist/core/exec.d.ts.map +1 -1
  65. package/dist/core/exec.js +18 -27
  66. package/dist/core/exec.js.map +1 -1
  67. package/dist/core/export-html/ansi-to-html.ts +262 -0
  68. package/dist/core/export-html/index.ts +433 -0
  69. package/dist/core/export-html/template.html +48 -26
  70. package/dist/core/export-html/tool-renderer.d.ts +0 -21
  71. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  72. package/dist/core/export-html/tool-renderer.js +35 -51
  73. package/dist/core/export-html/tool-renderer.js.map +1 -1
  74. package/dist/core/export-html/tool-renderer.ts +80 -0
  75. package/dist/core/export-html/vendor/highlight.min.js +401 -370
  76. package/dist/core/export-html/vendor/marked.min.js +71 -3
  77. package/dist/core/extensions/index.d.ts +7 -4
  78. package/dist/core/extensions/index.d.ts.map +1 -1
  79. package/dist/core/extensions/index.js +17 -3
  80. package/dist/core/extensions/index.js.map +1 -1
  81. package/dist/core/extensions/loader.d.ts +0 -6
  82. package/dist/core/extensions/loader.d.ts.map +1 -1
  83. package/dist/core/extensions/loader.js +60 -56
  84. package/dist/core/extensions/loader.js.map +1 -1
  85. package/dist/core/extensions/runner.d.ts +3 -0
  86. package/dist/core/extensions/runner.d.ts.map +1 -1
  87. package/dist/core/extensions/runner.js +48 -80
  88. package/dist/core/extensions/runner.js.map +1 -1
  89. package/dist/core/extensions/types.d.ts +50 -23
  90. package/dist/core/extensions/types.d.ts.map +1 -1
  91. package/dist/core/footer-data-provider.d.ts +2 -15
  92. package/dist/core/footer-data-provider.d.ts.map +1 -1
  93. package/dist/core/footer-data-provider.js +21 -33
  94. package/dist/core/footer-data-provider.js.map +1 -1
  95. package/dist/core/hooks/loader.js +2 -2
  96. package/dist/core/hooks/loader.js.map +1 -1
  97. package/dist/core/index.d.ts +29 -10
  98. package/dist/core/index.d.ts.map +1 -1
  99. package/dist/core/index.js +29 -10
  100. package/dist/core/index.js.map +1 -1
  101. package/dist/core/keybindings.d.ts +2 -179
  102. package/dist/core/keybindings.d.ts.map +1 -1
  103. package/dist/core/keybindings.js +64 -238
  104. package/dist/core/keybindings.js.map +1 -1
  105. package/dist/core/model-registry.d.ts +26 -181
  106. package/dist/core/model-registry.d.ts.map +1 -1
  107. package/dist/core/model-registry.js +228 -407
  108. package/dist/core/model-registry.js.map +1 -1
  109. package/dist/core/model-resolver.d.ts +0 -139
  110. package/dist/core/model-resolver.d.ts.map +1 -1
  111. package/dist/core/model-resolver.js +36 -217
  112. package/dist/core/model-resolver.js.map +1 -1
  113. package/dist/core/package-manager.d.ts +25 -57
  114. package/dist/core/package-manager.d.ts.map +1 -1
  115. package/dist/core/package-manager.js +326 -964
  116. package/dist/core/package-manager.js.map +1 -1
  117. package/dist/core/prompt-templates.d.ts +2 -34
  118. package/dist/core/prompt-templates.d.ts.map +1 -1
  119. package/dist/core/prompt-templates.js +122 -170
  120. package/dist/core/prompt-templates.js.map +1 -1
  121. package/dist/core/resource-loader.d.ts +19 -12
  122. package/dist/core/resource-loader.d.ts.map +1 -1
  123. package/dist/core/resource-loader.js +353 -467
  124. package/dist/core/resource-loader.js.map +1 -1
  125. package/dist/core/sdk.d.ts +2 -61
  126. package/dist/core/sdk.d.ts.map +1 -1
  127. package/dist/core/sdk.js +184 -252
  128. package/dist/core/sdk.js.map +1 -1
  129. package/dist/core/session-manager.d.ts +447 -1
  130. package/dist/core/session-manager.d.ts.map +1 -1
  131. package/dist/core/session-manager.js +1176 -1
  132. package/dist/core/session-manager.js.map +1 -1
  133. package/dist/core/settings-manager.d.ts +9 -12
  134. package/dist/core/settings-manager.d.ts.map +1 -1
  135. package/dist/core/settings-manager.js +170 -398
  136. package/dist/core/settings-manager.js.map +1 -1
  137. package/dist/core/skills.d.ts +2 -27
  138. package/dist/core/skills.d.ts.map +1 -1
  139. package/dist/core/skills.js +149 -212
  140. package/dist/core/skills.js.map +1 -1
  141. package/dist/core/subagents.d.ts +2 -2
  142. package/dist/core/subagents.d.ts.map +1 -1
  143. package/dist/core/subagents.js +21 -14
  144. package/dist/core/subagents.js.map +1 -1
  145. package/dist/core/system-prompt.d.ts +0 -11
  146. package/dist/core/system-prompt.d.ts.map +1 -1
  147. package/dist/core/system-prompt.js +168 -139
  148. package/dist/core/system-prompt.js.map +1 -1
  149. package/dist/core/timings.d.ts +1 -4
  150. package/dist/core/timings.d.ts.map +1 -1
  151. package/dist/core/timings.js +34 -18
  152. package/dist/core/timings.js.map +1 -1
  153. package/dist/core/todo-store.d.ts +20 -0
  154. package/dist/core/todo-store.d.ts.map +1 -0
  155. package/dist/core/todo-store.js +60 -0
  156. package/dist/core/todo-store.js.map +1 -0
  157. package/dist/core/tools/bash.d.ts +2 -0
  158. package/dist/core/tools/bash.d.ts.map +1 -0
  159. package/dist/core/tools/bash.js +2 -0
  160. package/dist/core/tools/bash.js.map +1 -0
  161. package/dist/core/tools/bg-process.d.ts +1 -6
  162. package/dist/core/tools/bg-process.d.ts.map +1 -1
  163. package/dist/core/tools/bg-process.js +4 -18
  164. package/dist/core/tools/bg-process.js.map +1 -1
  165. package/dist/core/tools/edit-diff.d.ts +9 -0
  166. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  167. package/dist/core/tools/edit-diff.js +2 -0
  168. package/dist/core/tools/edit-diff.js.map +1 -0
  169. package/dist/core/tools/edit.d.ts +2 -0
  170. package/dist/core/tools/edit.d.ts.map +1 -0
  171. package/dist/core/tools/edit.js +2 -0
  172. package/dist/core/tools/edit.js.map +1 -0
  173. package/dist/core/tools/find.d.ts +2 -0
  174. package/dist/core/tools/find.d.ts.map +1 -0
  175. package/dist/core/tools/find.js +2 -0
  176. package/dist/core/tools/find.js.map +1 -0
  177. package/dist/core/tools/grep.d.ts +2 -0
  178. package/dist/core/tools/grep.d.ts.map +1 -0
  179. package/dist/core/tools/grep.js +2 -0
  180. package/dist/core/tools/grep.js.map +1 -0
  181. package/dist/core/tools/index.d.ts +7 -1
  182. package/dist/core/tools/index.d.ts.map +1 -1
  183. package/dist/core/tools/ls.d.ts +2 -0
  184. package/dist/core/tools/ls.d.ts.map +1 -0
  185. package/dist/core/tools/ls.js +2 -0
  186. package/dist/core/tools/ls.js.map +1 -0
  187. package/dist/core/tools/path-utils.d.ts +2 -0
  188. package/dist/core/tools/path-utils.d.ts.map +1 -0
  189. package/dist/core/tools/path-utils.js +2 -0
  190. package/dist/core/tools/path-utils.js.map +1 -0
  191. package/dist/core/tools/read.d.ts +2 -0
  192. package/dist/core/tools/read.d.ts.map +1 -0
  193. package/dist/core/tools/read.js +2 -0
  194. package/dist/core/tools/read.js.map +1 -0
  195. package/dist/core/tools/registry.d.ts +0 -15
  196. package/dist/core/tools/registry.d.ts.map +1 -1
  197. package/dist/core/tools/registry.js +13 -37
  198. package/dist/core/tools/registry.js.map +1 -1
  199. package/dist/core/tools/task.d.ts +17 -23
  200. package/dist/core/tools/task.d.ts.map +1 -1
  201. package/dist/core/tools/task.js +43 -82
  202. package/dist/core/tools/task.js.map +1 -1
  203. package/dist/core/tools/todo.d.ts +17 -20
  204. package/dist/core/tools/todo.d.ts.map +1 -1
  205. package/dist/core/tools/todo.js +79 -58
  206. package/dist/core/tools/todo.js.map +1 -1
  207. package/dist/core/tools/truncate.d.ts +2 -0
  208. package/dist/core/tools/truncate.d.ts.map +1 -0
  209. package/dist/core/tools/truncate.js +2 -0
  210. package/dist/core/tools/truncate.js.map +1 -0
  211. package/dist/core/tools/webfetch.d.ts +2 -0
  212. package/dist/core/tools/webfetch.d.ts.map +1 -0
  213. package/dist/core/tools/webfetch.js +2 -0
  214. package/dist/core/tools/webfetch.js.map +1 -0
  215. package/dist/core/tools/websearch.d.ts +2 -0
  216. package/dist/core/tools/websearch.d.ts.map +1 -0
  217. package/dist/core/tools/websearch.js +2 -0
  218. package/dist/core/tools/websearch.js.map +1 -0
  219. package/dist/core/tools/write.d.ts +2 -0
  220. package/dist/core/tools/write.d.ts.map +1 -0
  221. package/dist/core/tools/write.js +2 -0
  222. package/dist/core/tools/write.js.map +1 -0
  223. package/dist/index.d.ts +35 -29
  224. package/dist/index.d.ts.map +1 -1
  225. package/dist/index.js +33 -41
  226. package/dist/index.js.map +1 -1
  227. package/dist/main.d.ts.map +1 -1
  228. package/dist/main.js +237 -225
  229. package/dist/main.js.map +1 -1
  230. package/dist/migrations.d.ts +0 -25
  231. package/dist/migrations.d.ts.map +1 -1
  232. package/dist/migrations.js +129 -180
  233. package/dist/migrations.js.map +1 -1
  234. package/dist/modes/index.d.ts +13 -6
  235. package/dist/modes/index.d.ts.map +1 -1
  236. package/dist/modes/index.js +11 -5
  237. package/dist/modes/index.js.map +1 -1
  238. package/dist/modes/interactive/components/armin.d.ts +8 -23
  239. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  240. package/dist/modes/interactive/components/armin.js +217 -266
  241. package/dist/modes/interactive/components/armin.js.map +1 -1
  242. package/dist/modes/interactive/components/assistant-message.d.ts +2 -168
  243. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  244. package/dist/modes/interactive/components/assistant-message.js +61 -216
  245. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  246. package/dist/modes/interactive/components/bash-execution.d.ts +6 -313
  247. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  248. package/dist/modes/interactive/components/bash-execution.js +86 -403
  249. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  250. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -3
  251. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  252. package/dist/modes/interactive/components/bordered-loader.js +59 -29
  253. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  254. package/dist/modes/interactive/components/branch-summary-message.d.ts +3 -3
  255. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  256. package/dist/modes/interactive/components/branch-summary-message.js +30 -17
  257. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  258. package/dist/modes/interactive/components/compaction-summary-message.d.ts +3 -3
  259. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  260. package/dist/modes/interactive/components/compaction-summary-message.js +35 -18
  261. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  262. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  263. package/dist/modes/interactive/components/config-selector.js +60 -68
  264. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  265. package/dist/modes/interactive/components/countdown-timer.d.ts +2 -6
  266. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  267. package/dist/modes/interactive/components/countdown-timer.js +32 -18
  268. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  269. package/dist/modes/interactive/components/custom-editor.d.ts +1 -5
  270. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  271. package/dist/modes/interactive/components/custom-editor.js +45 -37
  272. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  273. package/dist/modes/interactive/components/custom-message.d.ts +5 -6
  274. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  275. package/dist/modes/interactive/components/custom-message.js +43 -53
  276. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  277. package/dist/modes/interactive/components/diff.d.ts +0 -3
  278. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  279. package/dist/modes/interactive/components/diff.js +101 -108
  280. package/dist/modes/interactive/components/diff.js.map +1 -1
  281. package/dist/modes/interactive/components/dynamic-border.d.ts +7 -2
  282. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/dynamic-border.js +24 -4
  284. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  285. package/dist/modes/interactive/components/extension-editor.d.ts +5 -9
  286. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  287. package/dist/modes/interactive/components/extension-editor.js +43 -46
  288. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  289. package/dist/modes/interactive/components/extension-input.d.ts +4 -9
  290. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  291. package/dist/modes/interactive/components/extension-input.js +45 -28
  292. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  293. package/dist/modes/interactive/components/extension-selector.d.ts +7 -12
  294. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  295. package/dist/modes/interactive/components/extension-selector.js +54 -32
  296. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  297. package/dist/modes/interactive/components/footer.d.ts +2 -11
  298. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  299. package/dist/modes/interactive/components/footer.js +135 -183
  300. package/dist/modes/interactive/components/footer.js.map +1 -1
  301. package/dist/modes/interactive/components/index.d.ts +79 -30
  302. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  303. package/dist/modes/interactive/components/index.js +73 -31
  304. package/dist/modes/interactive/components/index.js.map +1 -1
  305. package/dist/modes/interactive/components/keybinding-hints.d.ts +0 -18
  306. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  307. package/dist/modes/interactive/components/keybinding-hints.js +24 -31
  308. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  309. package/dist/modes/interactive/components/login-dialog.d.ts +11 -24
  310. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  311. package/dist/modes/interactive/components/login-dialog.js +89 -86
  312. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  313. package/dist/modes/interactive/components/model-selector.d.ts +15 -19
  314. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  315. package/dist/modes/interactive/components/model-selector.js +104 -157
  316. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  317. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  318. package/dist/modes/interactive/components/oauth-selector.js +5 -5
  319. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  320. package/dist/modes/interactive/components/scoped-models-selector.d.ts +12 -22
  321. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  322. package/dist/modes/interactive/components/scoped-models-selector.js +111 -132
  323. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  324. package/dist/modes/interactive/components/session-selector-search.d.ts +3 -3
  325. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/session-selector-search.js +92 -103
  327. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  328. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  329. package/dist/modes/interactive/components/session-selector.js +28 -39
  330. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  331. package/dist/modes/interactive/components/settings-selector.d.ts +1 -1
  332. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  333. package/dist/modes/interactive/components/settings-selector.js +111 -203
  334. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  335. package/dist/modes/interactive/components/show-images-selector.d.ts +1 -1
  336. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  337. package/dist/modes/interactive/components/show-images-selector.js +17 -19
  338. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  339. package/dist/modes/interactive/components/skill-invocation-message.d.ts +3 -3
  340. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  341. package/dist/modes/interactive/components/skill-invocation-message.js +29 -19
  342. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  343. package/dist/modes/interactive/components/theme-selector.d.ts +2 -2
  344. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  345. package/dist/modes/interactive/components/theme-selector.js +20 -25
  346. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  347. package/dist/modes/interactive/components/thinking-selector.d.ts +1 -1
  348. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  349. package/dist/modes/interactive/components/thinking-selector.js +19 -20
  350. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  351. package/dist/modes/interactive/components/tool-execution.d.ts +12 -10
  352. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/tool-execution.js +14 -8
  354. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  355. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  356. package/dist/modes/interactive/components/tree-selector.js +53 -60
  357. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  358. package/dist/modes/interactive/components/user-message-selector.d.ts +3 -9
  359. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  360. package/dist/modes/interactive/components/user-message-selector.js +57 -68
  361. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  362. package/dist/modes/interactive/components/visual-truncate.d.ts +0 -12
  363. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/visual-truncate.js +14 -22
  365. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  366. package/dist/modes/interactive/interactive-mode.d.ts +6 -0
  367. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  368. package/dist/modes/interactive/interactive-mode.js +118 -113
  369. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  370. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  371. package/dist/modes/interactive/theme/theme.js +189 -39
  372. package/dist/modes/interactive/theme/theme.js.map +1 -1
  373. package/dist/modes/rpc/rpc-client.d.ts +8 -1
  374. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  375. package/dist/modes/rpc/rpc-client.js +88 -59
  376. package/dist/modes/rpc/rpc-client.js.map +1 -1
  377. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  378. package/dist/modes/rpc/rpc-mode.js +24 -46
  379. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  380. package/dist/modes/rpc/rpc-types.d.ts +75 -409
  381. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  382. package/dist/modes/rpc/rpc-types.js +21 -360
  383. package/dist/modes/rpc/rpc-types.js.map +1 -1
  384. package/dist/observability/core/config.d.ts +28 -0
  385. package/dist/observability/core/config.d.ts.map +1 -0
  386. package/dist/observability/core/config.js +150 -0
  387. package/dist/observability/core/config.js.map +1 -0
  388. package/dist/observability/core/event-bus.d.ts +15 -0
  389. package/dist/observability/core/event-bus.d.ts.map +1 -0
  390. package/dist/observability/core/event-bus.js +37 -0
  391. package/dist/observability/core/event-bus.js.map +1 -0
  392. package/dist/observability/core/index.d.ts +12 -0
  393. package/dist/observability/core/index.d.ts.map +1 -0
  394. package/dist/observability/core/index.js +14 -0
  395. package/dist/observability/core/index.js.map +1 -0
  396. package/dist/observability/core/observability.d.ts +63 -0
  397. package/dist/observability/core/observability.d.ts.map +1 -0
  398. package/dist/observability/core/observability.js +127 -0
  399. package/dist/observability/core/observability.js.map +1 -0
  400. package/dist/observability/core/span.d.ts +37 -0
  401. package/dist/observability/core/span.d.ts.map +1 -0
  402. package/dist/observability/core/span.js +90 -0
  403. package/dist/observability/core/span.js.map +1 -0
  404. package/dist/observability/core/tracer.d.ts +22 -0
  405. package/dist/observability/core/tracer.d.ts.map +1 -0
  406. package/dist/observability/core/tracer.js +79 -0
  407. package/dist/observability/core/tracer.js.map +1 -0
  408. package/dist/observability/core/types.d.ts +155 -0
  409. package/dist/observability/core/types.d.ts.map +1 -0
  410. package/dist/observability/core/types.js +38 -0
  411. package/dist/observability/core/types.js.map +1 -0
  412. package/dist/observability/exporters/base-exporter.d.ts +16 -0
  413. package/dist/observability/exporters/base-exporter.d.ts.map +1 -0
  414. package/dist/observability/exporters/base-exporter.js +26 -0
  415. package/dist/observability/exporters/base-exporter.js.map +1 -0
  416. package/dist/observability/exporters/console-exporter.d.ts +22 -0
  417. package/dist/observability/exporters/console-exporter.d.ts.map +1 -0
  418. package/dist/observability/exporters/console-exporter.js +80 -0
  419. package/dist/observability/exporters/console-exporter.js.map +1 -0
  420. package/dist/observability/exporters/file-exporter.d.ts +31 -0
  421. package/dist/observability/exporters/file-exporter.d.ts.map +1 -0
  422. package/dist/observability/exporters/file-exporter.js +120 -0
  423. package/dist/observability/exporters/file-exporter.js.map +1 -0
  424. package/dist/observability/exporters/index.d.ts +12 -0
  425. package/dist/observability/exporters/index.d.ts.map +1 -0
  426. package/dist/observability/exporters/index.js +11 -0
  427. package/dist/observability/exporters/index.js.map +1 -0
  428. package/dist/observability/exporters/langfuse-exporter.d.ts +27 -0
  429. package/dist/observability/exporters/langfuse-exporter.d.ts.map +1 -0
  430. package/dist/observability/exporters/langfuse-exporter.js +146 -0
  431. package/dist/observability/exporters/langfuse-exporter.js.map +1 -0
  432. package/dist/observability/exporters/sentry-exporter.d.ts +22 -0
  433. package/dist/observability/exporters/sentry-exporter.d.ts.map +1 -0
  434. package/dist/observability/exporters/sentry-exporter.js +121 -0
  435. package/dist/observability/exporters/sentry-exporter.js.map +1 -0
  436. package/dist/observability/index.d.ts +3 -0
  437. package/dist/observability/index.d.ts.map +1 -0
  438. package/dist/observability/index.js +3 -0
  439. package/dist/observability/index.js.map +1 -0
  440. package/dist/utils/changelog.d.ts +1 -2
  441. package/dist/utils/changelog.d.ts.map +1 -1
  442. package/dist/utils/changelog.js +53 -61
  443. package/dist/utils/changelog.js.map +1 -1
  444. package/dist/utils/clipboard-image.d.ts.map +1 -1
  445. package/dist/utils/clipboard-image.js +77 -83
  446. package/dist/utils/clipboard-image.js.map +1 -1
  447. package/dist/utils/clipboard.d.ts.map +1 -1
  448. package/dist/utils/clipboard.js +62 -49
  449. package/dist/utils/clipboard.js.map +1 -1
  450. package/dist/utils/image-convert.d.ts +6 -6
  451. package/dist/utils/image-convert.d.ts.map +1 -1
  452. package/dist/utils/image-convert.js +29 -23
  453. package/dist/utils/image-convert.js.map +1 -1
  454. package/dist/utils/image-resize.d.ts +0 -17
  455. package/dist/utils/image-resize.d.ts.map +1 -1
  456. package/dist/utils/image-resize.js +100 -138
  457. package/dist/utils/image-resize.js.map +1 -1
  458. package/dist/utils/mime.d.ts +1 -0
  459. package/dist/utils/mime.d.ts.map +1 -1
  460. package/dist/utils/mime.js +35 -15
  461. package/dist/utils/mime.js.map +1 -1
  462. package/dist/utils/photon.d.ts +4 -15
  463. package/dist/utils/photon.d.ts.map +1 -1
  464. package/dist/utils/photon.js +71 -60
  465. package/dist/utils/photon.js.map +1 -1
  466. package/dist/utils/shell.d.ts +4 -21
  467. package/dist/utils/shell.d.ts.map +1 -1
  468. package/dist/utils/shell.js +101 -124
  469. package/dist/utils/shell.js.map +1 -1
  470. package/dist/utils/sleep.d.ts +1 -1
  471. package/dist/utils/sleep.d.ts.map +1 -1
  472. package/dist/utils/sleep.js +32 -8
  473. package/dist/utils/sleep.js.map +1 -1
  474. package/dist/utils/tools-manager.d.ts +4 -2
  475. package/dist/utils/tools-manager.d.ts.map +1 -1
  476. package/dist/utils/tools-manager.js +96 -122
  477. package/dist/utils/tools-manager.js.map +1 -1
  478. package/docs/PI_MONO_MIT_REMOVAL_GUIDE.md +2132 -0
  479. package/docs/SAME_TO_SAME_PARITY_REPORT.md +312 -0
  480. package/examples/README.md +12 -0
  481. package/package.json +60 -88
  482. package/LICENSE.md +0 -22
  483. package/dist/modes/interactive/theme/dark.json +0 -85
  484. package/dist/modes/interactive/theme/light.json +0 -84
  485. package/dist/modes/interactive/theme/theme-schema.json +0 -335
  486. package/docs/FEATURES.md +0 -306
  487. package/docs/MCP.md +0 -341
  488. package/docs/MEMORY.md +0 -443
  489. package/examples/mcp-servers.example.json +0 -50
@@ -1,103 +1,3 @@
1
- /**
2
- * Model Registry - Central management of AI models and provider configuration
3
- *
4
- * Purpose:
5
- * Manages all available AI models (built-in + custom), handles provider configuration,
6
- * and resolves API keys through multiple sources (env vars, commands, OAuth, auth storage).
7
- *
8
- * Architecture:
9
- * - Loads built-in models from indusagi/ai package
10
- * - Optionally loads custom models from models.json config file
11
- * - Supports provider overrides (baseUrl, headers, apiKey)
12
- * - Integrates with AuthStorage for credential management
13
- * - Supports dynamic provider registration from extensions
14
- *
15
- * Key Features:
16
- * - API key resolution from environment variables or shell commands
17
- * - Custom model definitions via models.json with full schema validation
18
- * - Provider override support (baseUrl, headers without replacing models)
19
- * - OAuth provider integration for subscription-based services
20
- * - Error handling with detailed validation messages
21
- * - Command result caching for performance
22
- *
23
- * Configuration Sources (in order of priority):
24
- * 1. models.json in agent directory (custom models + provider overrides)
25
- * 2. Built-in models from indusagi/ai
26
- * 3. OAuth providers via AuthStorage
27
- * 4. Environment variables for API keys
28
- *
29
- * API Key Resolution:
30
- * - Values starting with "!" are treated as shell commands
31
- * - Other values checked against environment variables first
32
- * - Falls back to literal value if env var not found
33
- * - Commands cached for process lifetime to avoid re-execution
34
- *
35
- * Built-in Providers Supported:
36
- * - OpenAI (gpt-4, gpt-4-turbo, gpt-3.5-turbo, etc.)
37
- * - Anthropic (claude-3-opus, claude-3-sonnet, claude-3-haiku, etc.)
38
- * - Google (gemini-pro, gemini-1.5, etc.)
39
- * - Mistral (mistral-large, mistral-medium, etc.)
40
- * - OpenRouter (routing to 200+ models)
41
- * - Custom providers via models.json
42
- *
43
- * Example models.json:
44
- * ```json
45
- * {
46
- * "providers": {
47
- * "custom-local": {
48
- * "baseUrl": "http://localhost:8000/v1",
49
- * "apiKey": "CUSTOM_API_KEY",
50
- * "models": [{
51
- * "id": "local-model",
52
- * "name": "Local Model",
53
- * "api": "openai",
54
- * "reasoning": false,
55
- * "input": ["text"],
56
- * "cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0},
57
- * "contextWindow": 8192,
58
- * "maxTokens": 4096
59
- * }]
60
- * }
61
- * }
62
- * }
63
- * ```
64
- *
65
- * Usage:
66
- * ```typescript
67
- * const registry = new ModelRegistry(authStorage);
68
- *
69
- * // Get all available models
70
- * const allModels = registry.getAll();
71
- *
72
- * // Get only models with configured auth
73
- * const available = registry.getAvailable();
74
- *
75
- * // Find specific model
76
- * const model = registry.find("openai", "gpt-4");
77
- *
78
- * // Get API key for model
79
- * const apiKey = await registry.getApiKey(model);
80
- *
81
- * // Register custom provider from extension
82
- * registry.registerProvider("my-provider", {
83
- * baseUrl: "https://api.example.com",
84
- * apiKey: "EXAMPLE_API_KEY",
85
- * models: [...]
86
- * });
87
- *
88
- * // Reload models from disk
89
- * registry.refresh();
90
- * ```
91
- *
92
- * Error Handling:
93
- * - Invalid models.json schema returns detailed error messages
94
- * - Validation failures include field name and error description
95
- * - Built-in models loaded even if custom models fail
96
- * - Use getError() to check for loading issues
97
- *
98
- * Based on model registry from indusagi-agent
99
- * Original: https://github.com/varunisrani/indusagi-ts/vendor/indusagi-agent/src/model-registry.ts
100
- */
101
1
  import { getModels, getProviders, registerApiProvider, registerOAuthProvider, } from "indusagi/ai";
102
2
  import { Type } from "@sinclair/typebox";
103
3
  import AjvModule from "ajv";
@@ -106,12 +6,10 @@ import { existsSync, readFileSync } from "fs";
106
6
  import { join } from "path";
107
7
  import { getAgentDir } from "../config.js";
108
8
  const Ajv = AjvModule.default || AjvModule;
109
- // Schema for OpenRouter routing preferences
110
9
  const OpenRouterRoutingSchema = Type.Object({
111
10
  only: Type.Optional(Type.Array(Type.String())),
112
11
  order: Type.Optional(Type.Array(Type.String())),
113
12
  });
114
- // Schema for OpenAI compatibility settings
115
13
  const OpenAICompletionsCompatSchema = Type.Object({
116
14
  supportsStore: Type.Optional(Type.Boolean()),
117
15
  supportsDeveloperRole: Type.Optional(Type.Boolean()),
@@ -125,11 +23,8 @@ const OpenAICompletionsCompatSchema = Type.Object({
125
23
  thinkingFormat: Type.Optional(Type.Union([Type.Literal("openai"), Type.Literal("zai")])),
126
24
  openRouterRouting: Type.Optional(OpenRouterRoutingSchema),
127
25
  });
128
- const OpenAIResponsesCompatSchema = Type.Object({
129
- // Reserved for future use
130
- });
26
+ const OpenAIResponsesCompatSchema = Type.Object({});
131
27
  const OpenAICompatSchema = Type.Union([OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema]);
132
- // Schema for custom model definition
133
28
  const ModelDefinitionSchema = Type.Object({
134
29
  id: Type.String({ minLength: 1 }),
135
30
  name: Type.String({ minLength: 1 }),
@@ -158,49 +53,39 @@ const ProviderConfigSchema = Type.Object({
158
53
  const ModelsConfigSchema = Type.Object({
159
54
  providers: Type.Record(Type.String(), ProviderConfigSchema),
160
55
  });
56
+ const commandResultCache = new Map();
161
57
  function emptyCustomModelsResult(error) {
162
58
  return { models: [], replacedProviders: new Set(), overrides: new Map(), error };
163
59
  }
164
- // Cache for shell command results (persists for process lifetime)
165
- const commandResultCache = new Map();
166
- /**
167
- * Resolve a config value (API key, header value, etc.) to an actual value.
168
- * - If starts with "!", executes the rest as a shell command and uses stdout (cached)
169
- * - Otherwise checks environment variable first, then treats as literal (not cached)
170
- */
171
- function resolveConfigValue(config) {
172
- if (config.startsWith("!")) {
173
- return executeCommand(config);
174
- }
175
- const envValue = process.env[config];
176
- return envValue || config;
177
- }
178
60
  function executeCommand(commandConfig) {
179
61
  if (commandResultCache.has(commandConfig)) {
180
62
  return commandResultCache.get(commandConfig);
181
63
  }
182
64
  const command = commandConfig.slice(1);
183
- let result;
65
+ let output;
184
66
  try {
185
- const output = execSync(command, {
67
+ output = execSync(command, {
186
68
  encoding: "utf-8",
187
69
  timeout: 10000,
188
70
  stdio: ["ignore", "pipe", "ignore"],
189
- });
190
- result = output.trim() || undefined;
71
+ }).trim() || undefined;
191
72
  }
192
73
  catch {
193
- result = undefined;
74
+ output = undefined;
194
75
  }
195
- commandResultCache.set(commandConfig, result);
196
- return result;
76
+ commandResultCache.set(commandConfig, output);
77
+ return output;
78
+ }
79
+ function resolveConfigValue(config) {
80
+ if (config.startsWith("!")) {
81
+ return executeCommand(config);
82
+ }
83
+ return process.env[config] || config;
197
84
  }
198
- /**
199
- * Resolve all header values using the same resolution logic as API keys.
200
- */
201
85
  function resolveHeaders(headers) {
202
- if (!headers)
86
+ if (!headers) {
203
87
  return undefined;
88
+ }
204
89
  const resolved = {};
205
90
  for (const [key, value] of Object.entries(headers)) {
206
91
  const resolvedValue = resolveConfigValue(value);
@@ -210,13 +95,165 @@ function resolveHeaders(headers) {
210
95
  }
211
96
  return Object.keys(resolved).length > 0 ? resolved : undefined;
212
97
  }
213
- /** Clear the config value command cache. Exported for testing. */
98
+ function validateSchema(config, filePath) {
99
+ const ajv = new Ajv();
100
+ const validate = ajv.compile(ModelsConfigSchema);
101
+ if (validate(config)) {
102
+ return undefined;
103
+ }
104
+ const errors = validate.errors?.map((error) => ` - ${error.instancePath || "root"}: ${error.message}`).join("\n") ||
105
+ "Unknown schema error";
106
+ return `Invalid models.json schema:\n${errors}\n\nFile: ${filePath}`;
107
+ }
108
+ function validateModelsConfig(config) {
109
+ for (const [providerName, providerConfig] of Object.entries(config.providers)) {
110
+ const models = providerConfig.models ?? [];
111
+ if (models.length === 0) {
112
+ if (!providerConfig.baseUrl) {
113
+ throw new Error(`Provider ${providerName}: must specify either "baseUrl" (for override) or "models" (for replacement).`);
114
+ }
115
+ continue;
116
+ }
117
+ if (!providerConfig.baseUrl) {
118
+ throw new Error(`Provider ${providerName}: "baseUrl" is required when defining custom models.`);
119
+ }
120
+ if (!providerConfig.apiKey) {
121
+ throw new Error(`Provider ${providerName}: "apiKey" is required when defining custom models.`);
122
+ }
123
+ for (const modelDef of models) {
124
+ if (!providerConfig.api && !modelDef.api) {
125
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: no "api" specified. Set at provider or model level.`);
126
+ }
127
+ if (modelDef.contextWindow <= 0) {
128
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);
129
+ }
130
+ if (modelDef.maxTokens <= 0) {
131
+ throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);
132
+ }
133
+ }
134
+ }
135
+ }
136
+ function loadCustomModelsConfig(filePath) {
137
+ if (!existsSync(filePath)) {
138
+ return {};
139
+ }
140
+ try {
141
+ const config = JSON.parse(readFileSync(filePath, "utf-8"));
142
+ const schemaError = validateSchema(config, filePath);
143
+ if (schemaError) {
144
+ return { error: schemaError };
145
+ }
146
+ validateModelsConfig(config);
147
+ return { config };
148
+ }
149
+ catch (error) {
150
+ if (error instanceof SyntaxError) {
151
+ return { error: `Failed to parse models.json: ${error.message}\n\nFile: ${filePath}` };
152
+ }
153
+ return { error: `Failed to load models.json: ${error instanceof Error ? error.message : error}\n\nFile: ${filePath}` };
154
+ }
155
+ }
156
+ function resolveProviderHeaders(providerHeaders, modelHeaders, providerApiKey, authHeader) {
157
+ const resolvedProviderHeaders = resolveHeaders(providerHeaders);
158
+ const resolvedModelHeaders = resolveHeaders(modelHeaders);
159
+ let headers = resolvedProviderHeaders || resolvedModelHeaders
160
+ ? { ...resolvedProviderHeaders, ...resolvedModelHeaders }
161
+ : undefined;
162
+ if (authHeader && providerApiKey) {
163
+ const resolvedKey = resolveConfigValue(providerApiKey);
164
+ if (resolvedKey) {
165
+ headers = { ...headers, Authorization: `Bearer ${resolvedKey}` };
166
+ }
167
+ }
168
+ return headers;
169
+ }
170
+ function buildCustomModels(config, apiKeyRegistry) {
171
+ const models = [];
172
+ for (const [providerName, providerConfig] of Object.entries(config.providers)) {
173
+ const providerModels = providerConfig.models ?? [];
174
+ if (providerModels.length === 0) {
175
+ continue;
176
+ }
177
+ if (providerConfig.apiKey) {
178
+ apiKeyRegistry.set(providerName, providerConfig.apiKey);
179
+ }
180
+ for (const modelDef of providerModels) {
181
+ const api = modelDef.api || providerConfig.api;
182
+ if (!api) {
183
+ continue;
184
+ }
185
+ models.push({
186
+ id: modelDef.id,
187
+ name: modelDef.name,
188
+ api: api,
189
+ provider: providerName,
190
+ baseUrl: providerConfig.baseUrl,
191
+ reasoning: modelDef.reasoning,
192
+ input: modelDef.input,
193
+ cost: modelDef.cost,
194
+ contextWindow: modelDef.contextWindow,
195
+ maxTokens: modelDef.maxTokens,
196
+ headers: resolveProviderHeaders(providerConfig.headers, modelDef.headers, providerConfig.apiKey, providerConfig.authHeader),
197
+ compat: modelDef.compat,
198
+ });
199
+ }
200
+ }
201
+ return models;
202
+ }
203
+ function collectProviderOverrides(config, apiKeyRegistry) {
204
+ const replacedProviders = new Set();
205
+ const overrides = new Map();
206
+ for (const [providerName, providerConfig] of Object.entries(config.providers)) {
207
+ if (providerConfig.models && providerConfig.models.length > 0) {
208
+ replacedProviders.add(providerName);
209
+ continue;
210
+ }
211
+ overrides.set(providerName, {
212
+ baseUrl: providerConfig.baseUrl,
213
+ headers: providerConfig.headers,
214
+ apiKey: providerConfig.apiKey,
215
+ });
216
+ if (providerConfig.apiKey) {
217
+ apiKeyRegistry.set(providerName, providerConfig.apiKey);
218
+ }
219
+ }
220
+ return { replacedProviders, overrides };
221
+ }
222
+ function applyProviderOverrides(models, overrides) {
223
+ return models.map((model) => {
224
+ const override = overrides.get(model.provider);
225
+ if (!override) {
226
+ return model;
227
+ }
228
+ const resolvedHeaders = resolveHeaders(override.headers);
229
+ return {
230
+ ...model,
231
+ baseUrl: override.baseUrl ?? model.baseUrl,
232
+ headers: resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers,
233
+ };
234
+ });
235
+ }
236
+ function loadBuiltInModels(replacedProviders, overrides) {
237
+ const builtIns = getProviders()
238
+ .filter((provider) => !replacedProviders.has(provider))
239
+ .flatMap((provider) => getModels(provider));
240
+ return applyProviderOverrides(builtIns, overrides);
241
+ }
242
+ function loadCustomModels(filePath, apiKeyRegistry) {
243
+ const loaded = loadCustomModelsConfig(filePath);
244
+ if (!loaded.config) {
245
+ return emptyCustomModelsResult(loaded.error);
246
+ }
247
+ const { replacedProviders, overrides } = collectProviderOverrides(loaded.config, apiKeyRegistry);
248
+ return {
249
+ models: buildCustomModels(loaded.config, apiKeyRegistry),
250
+ replacedProviders,
251
+ overrides,
252
+ };
253
+ }
214
254
  export function clearApiKeyCache() {
215
255
  commandResultCache.clear();
216
256
  }
217
- /**
218
- * Model registry - loads and manages models, resolves API keys via AuthStorage.
219
- */
220
257
  export class ModelRegistry {
221
258
  constructor(authStorage, modelsJsonPath = join(getAgentDir(), "models.json")) {
222
259
  this.authStorage = authStorage;
@@ -224,21 +261,12 @@ export class ModelRegistry {
224
261
  this.models = [];
225
262
  this.customProviderApiKeys = new Map();
226
263
  this.registeredProviders = new Map();
227
- this.loadError = undefined;
228
- // Set up fallback resolver for custom provider API keys
229
264
  this.authStorage.setFallbackResolver((provider) => {
230
- const keyConfig = this.customProviderApiKeys.get(provider);
231
- if (keyConfig) {
232
- return resolveConfigValue(keyConfig);
233
- }
234
- return undefined;
265
+ const configured = this.customProviderApiKeys.get(provider);
266
+ return configured ? resolveConfigValue(configured) : undefined;
235
267
  });
236
- // Load models
237
268
  this.loadModels();
238
269
  }
239
- /**
240
- * Reload models from disk (built-in + custom from models.json).
241
- */
242
270
  refresh() {
243
271
  this.customProviderApiKeys.clear();
244
272
  this.loadError = undefined;
@@ -247,294 +275,58 @@ export class ModelRegistry {
247
275
  this.applyProviderConfig(providerName, config);
248
276
  }
249
277
  }
250
- /**
251
- * Get any error from loading models.json (undefined if no error).
252
- */
253
278
  getError() {
254
279
  return this.loadError;
255
280
  }
256
281
  loadModels() {
257
- // Load custom models from models.json first (to know which providers to skip/override)
258
- const { models: customModels, replacedProviders, overrides, error, } = this.modelsJsonPath ? this.loadCustomModels(this.modelsJsonPath) : emptyCustomModelsResult();
259
- if (error) {
260
- this.loadError = error;
261
- // Keep built-in models even if custom models failed to load
282
+ const custom = this.modelsJsonPath ? loadCustomModels(this.modelsJsonPath, this.customProviderApiKeys) : emptyCustomModelsResult();
283
+ if (custom.error) {
284
+ this.loadError = custom.error;
262
285
  }
263
- const builtInModels = this.loadBuiltInModels(replacedProviders, overrides);
264
- let combined = [...builtInModels, ...customModels];
265
- // Let OAuth providers modify their models (e.g., update baseUrl)
286
+ let combined = [...loadBuiltInModels(custom.replacedProviders, custom.overrides), ...custom.models];
266
287
  for (const oauthProvider of this.authStorage.getOAuthProviders()) {
267
- const cred = this.authStorage.get(oauthProvider.id);
268
- if (cred?.type === "oauth" && oauthProvider.modifyModels) {
269
- combined = oauthProvider.modifyModels(combined, cred);
288
+ const credential = this.authStorage.get(oauthProvider.id);
289
+ if (credential?.type === "oauth" && oauthProvider.modifyModels) {
290
+ combined = oauthProvider.modifyModels(combined, credential);
270
291
  }
271
292
  }
272
293
  this.models = combined;
273
294
  }
274
- /** Load built-in models, skipping replaced providers and applying overrides */
275
- loadBuiltInModels(replacedProviders, overrides) {
276
- return getProviders()
277
- .filter((provider) => !replacedProviders.has(provider))
278
- .flatMap((provider) => {
279
- const models = getModels(provider);
280
- const override = overrides.get(provider);
281
- if (!override)
282
- return models;
283
- // Apply baseUrl/headers override to all models of this provider
284
- const resolvedHeaders = resolveHeaders(override.headers);
285
- return models.map((m) => ({
286
- ...m,
287
- baseUrl: override.baseUrl ?? m.baseUrl,
288
- headers: resolvedHeaders ? { ...m.headers, ...resolvedHeaders } : m.headers,
289
- }));
290
- });
291
- }
292
- loadCustomModels(modelsJsonPath) {
293
- if (!existsSync(modelsJsonPath)) {
294
- return emptyCustomModelsResult();
295
- }
296
- try {
297
- const content = readFileSync(modelsJsonPath, "utf-8");
298
- const config = JSON.parse(content);
299
- // Validate schema
300
- const ajv = new Ajv();
301
- const validate = ajv.compile(ModelsConfigSchema);
302
- if (!validate(config)) {
303
- const errors = validate.errors?.map((e) => ` - ${e.instancePath || "root"}: ${e.message}`).join("\n") ||
304
- "Unknown schema error";
305
- return emptyCustomModelsResult(`Invalid models.json schema:\n${errors}\n\nFile: ${modelsJsonPath}`);
306
- }
307
- // Additional validation
308
- this.validateConfig(config);
309
- // Separate providers into "full replacement" (has models) vs "override-only" (no models)
310
- const replacedProviders = new Set();
311
- const overrides = new Map();
312
- for (const [providerName, providerConfig] of Object.entries(config.providers)) {
313
- if (providerConfig.models && providerConfig.models.length > 0) {
314
- // Has custom models -> full replacement
315
- replacedProviders.add(providerName);
316
- }
317
- else {
318
- // No models -> just override baseUrl/headers on built-in
319
- overrides.set(providerName, {
320
- baseUrl: providerConfig.baseUrl,
321
- headers: providerConfig.headers,
322
- apiKey: providerConfig.apiKey,
323
- });
324
- // Store API key for fallback resolver
325
- if (providerConfig.apiKey) {
326
- this.customProviderApiKeys.set(providerName, providerConfig.apiKey);
327
- }
328
- }
329
- }
330
- return { models: this.parseModels(config), replacedProviders, overrides, error: undefined };
331
- }
332
- catch (error) {
333
- if (error instanceof SyntaxError) {
334
- return emptyCustomModelsResult(`Failed to parse models.json: ${error.message}\n\nFile: ${modelsJsonPath}`);
335
- }
336
- return emptyCustomModelsResult(`Failed to load models.json: ${error instanceof Error ? error.message : error}\n\nFile: ${modelsJsonPath}`);
337
- }
338
- }
339
- validateConfig(config) {
340
- for (const [providerName, providerConfig] of Object.entries(config.providers)) {
341
- const hasProviderApi = !!providerConfig.api;
342
- const models = providerConfig.models ?? [];
343
- if (models.length === 0) {
344
- // Override-only config: just needs baseUrl (to override built-in)
345
- if (!providerConfig.baseUrl) {
346
- throw new Error(`Provider ${providerName}: must specify either "baseUrl" (for override) or "models" (for replacement).`);
347
- }
348
- }
349
- else {
350
- // Full replacement: needs baseUrl and apiKey
351
- if (!providerConfig.baseUrl) {
352
- throw new Error(`Provider ${providerName}: "baseUrl" is required when defining custom models.`);
353
- }
354
- if (!providerConfig.apiKey) {
355
- throw new Error(`Provider ${providerName}: "apiKey" is required when defining custom models.`);
356
- }
357
- }
358
- for (const modelDef of models) {
359
- const hasModelApi = !!modelDef.api;
360
- if (!hasProviderApi && !hasModelApi) {
361
- throw new Error(`Provider ${providerName}, model ${modelDef.id}: no "api" specified. Set at provider or model level.`);
362
- }
363
- if (!modelDef.id)
364
- throw new Error(`Provider ${providerName}: model missing "id"`);
365
- if (!modelDef.name)
366
- throw new Error(`Provider ${providerName}: model missing "name"`);
367
- if (modelDef.contextWindow <= 0)
368
- throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);
369
- if (modelDef.maxTokens <= 0)
370
- throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);
371
- }
372
- }
373
- }
374
- parseModels(config) {
375
- const models = [];
376
- for (const [providerName, providerConfig] of Object.entries(config.providers)) {
377
- const modelDefs = providerConfig.models ?? [];
378
- if (modelDefs.length === 0)
379
- continue; // Override-only, no custom models
380
- // Store API key config for fallback resolver
381
- if (providerConfig.apiKey) {
382
- this.customProviderApiKeys.set(providerName, providerConfig.apiKey);
383
- }
384
- for (const modelDef of modelDefs) {
385
- const api = modelDef.api || providerConfig.api;
386
- if (!api)
387
- continue;
388
- // Merge headers: provider headers are base, model headers override
389
- // Resolve env vars and shell commands in header values
390
- const providerHeaders = resolveHeaders(providerConfig.headers);
391
- const modelHeaders = resolveHeaders(modelDef.headers);
392
- let headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;
393
- // If authHeader is true, add Authorization header with resolved API key
394
- if (providerConfig.authHeader && providerConfig.apiKey) {
395
- const resolvedKey = resolveConfigValue(providerConfig.apiKey);
396
- if (resolvedKey) {
397
- headers = { ...headers, Authorization: `Bearer ${resolvedKey}` };
398
- }
399
- }
400
- // baseUrl is validated to exist for providers with models
401
- models.push({
402
- id: modelDef.id,
403
- name: modelDef.name,
404
- api: api,
405
- provider: providerName,
406
- baseUrl: providerConfig.baseUrl,
407
- reasoning: modelDef.reasoning,
408
- input: modelDef.input,
409
- cost: modelDef.cost,
410
- contextWindow: modelDef.contextWindow,
411
- maxTokens: modelDef.maxTokens,
412
- headers,
413
- compat: modelDef.compat,
414
- });
415
- }
416
- }
417
- return models;
418
- }
419
- /**
420
- * Get all models (built-in + custom).
421
- * If models.json had errors, returns only built-in models.
422
- */
423
- getAll() {
424
- return this.models;
425
- }
426
- /**
427
- * Get only models that have auth configured.
428
- * This is a fast check that doesn't refresh OAuth tokens.
429
- */
430
- getAvailable() {
431
- return this.models.filter((m) => this.authStorage.hasAuth(m.provider));
432
- }
433
- /**
434
- * Find a model by provider and ID.
435
- */
436
- find(provider, modelId) {
437
- return this.models.find((m) => m.provider === provider && m.id === modelId);
438
- }
439
- /**
440
- * Get API key for a model.
441
- * @param model - The model to get API key for
442
- * @param accountId - Optional account ID for multi-account providers
443
- */
444
- async getApiKey(model, accountId) {
445
- return this.authStorage.getApiKey(model.provider, accountId);
446
- }
447
- /**
448
- * Get API key for a provider.
449
- * @param provider - The provider ID
450
- * @param accountId - Optional account ID for multi-account providers
451
- */
452
- async getApiKeyForProvider(provider, accountId) {
453
- return this.authStorage.getApiKey(provider, accountId);
454
- }
455
- /**
456
- * Get all accounts for a provider.
457
- */
458
- getAccounts(provider) {
459
- return this.authStorage.getAccounts(provider);
460
- }
461
- /**
462
- * Get default account for a provider.
463
- */
464
- getDefaultAccount(provider) {
465
- return this.authStorage.getDefaultAccount(provider);
466
- }
467
- /**
468
- * Check if a model is using OAuth credentials (subscription).
469
- */
470
- isUsingOAuth(model) {
471
- const cred = this.authStorage.get(model.provider);
472
- return cred?.type === "oauth";
473
- }
474
- /**
475
- * Register a provider dynamically (from extensions).
476
- *
477
- * If provider has models: replaces all existing models for this provider.
478
- * If provider has only baseUrl/headers: overrides existing models' URLs.
479
- * If provider has oauth: registers OAuth provider for /login support.
480
- */
481
- registerProvider(providerName, config) {
295
+ registerExtensionProvider(providerName, config) {
482
296
  this.registeredProviders.set(providerName, config);
483
297
  this.applyProviderConfig(providerName, config);
484
298
  }
485
299
  applyProviderConfig(providerName, config) {
486
- // Register OAuth provider if provided
487
300
  if (config.oauth) {
488
- // Ensure the OAuth provider ID matches the provider name
489
- const oauthProvider = {
490
- ...config.oauth,
491
- id: providerName,
492
- };
493
- registerOAuthProvider(oauthProvider);
301
+ registerOAuthProvider({ ...config.oauth, id: providerName });
494
302
  }
495
303
  if (config.streamSimple) {
496
304
  if (!config.api) {
497
305
  throw new Error(`Provider ${providerName}: "api" is required when registering streamSimple.`);
498
306
  }
499
- const streamSimple = config.streamSimple;
500
307
  registerApiProvider({
501
308
  api: config.api,
502
- stream: (model, context, options) => streamSimple(model, context, options),
503
- streamSimple,
309
+ stream: (model, context, options) => config.streamSimple(model, context, options),
310
+ streamSimple: config.streamSimple,
504
311
  });
505
312
  }
506
- // Store API key for auth resolution
507
313
  if (config.apiKey) {
508
314
  this.customProviderApiKeys.set(providerName, config.apiKey);
509
315
  }
510
316
  if (config.models && config.models.length > 0) {
511
- // Full replacement: remove existing models for this provider
512
- this.models = this.models.filter((m) => m.provider !== providerName);
513
- // Validate required fields
514
317
  if (!config.baseUrl) {
515
318
  throw new Error(`Provider ${providerName}: "baseUrl" is required when defining models.`);
516
319
  }
517
320
  if (!config.apiKey && !config.oauth) {
518
321
  throw new Error(`Provider ${providerName}: "apiKey" or "oauth" is required when defining models.`);
519
322
  }
520
- // Parse and add new models
521
- for (const modelDef of config.models) {
323
+ this.models = this.models.filter((model) => model.provider !== providerName);
324
+ const replacementModels = config.models.map((modelDef) => {
522
325
  const api = modelDef.api || config.api;
523
326
  if (!api) {
524
327
  throw new Error(`Provider ${providerName}, model ${modelDef.id}: no "api" specified.`);
525
328
  }
526
- // Merge headers
527
- const providerHeaders = resolveHeaders(config.headers);
528
- const modelHeaders = resolveHeaders(modelDef.headers);
529
- let headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;
530
- // If authHeader is true, add Authorization header
531
- if (config.authHeader && config.apiKey) {
532
- const resolvedKey = resolveConfigValue(config.apiKey);
533
- if (resolvedKey) {
534
- headers = { ...headers, Authorization: `Bearer ${resolvedKey}` };
535
- }
536
- }
537
- this.models.push({
329
+ return {
538
330
  id: modelDef.id,
539
331
  name: modelDef.name,
540
332
  api: api,
@@ -545,24 +337,53 @@ export class ModelRegistry {
545
337
  cost: modelDef.cost,
546
338
  contextWindow: modelDef.contextWindow,
547
339
  maxTokens: modelDef.maxTokens,
548
- headers,
340
+ headers: resolveProviderHeaders(config.headers, modelDef.headers, config.apiKey, config.authHeader),
549
341
  compat: modelDef.compat,
550
- });
551
- }
342
+ };
343
+ });
344
+ this.models.push(...replacementModels);
345
+ return;
552
346
  }
553
- else if (config.baseUrl) {
554
- // Override-only: update baseUrl/headers for existing models
347
+ if (config.baseUrl) {
555
348
  const resolvedHeaders = resolveHeaders(config.headers);
556
- this.models = this.models.map((m) => {
557
- if (m.provider !== providerName)
558
- return m;
349
+ this.models = this.models.map((model) => {
350
+ if (model.provider !== providerName) {
351
+ return model;
352
+ }
559
353
  return {
560
- ...m,
561
- baseUrl: config.baseUrl ?? m.baseUrl,
562
- headers: resolvedHeaders ? { ...m.headers, ...resolvedHeaders } : m.headers,
354
+ ...model,
355
+ baseUrl: config.baseUrl ?? model.baseUrl,
356
+ headers: resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers,
563
357
  };
564
358
  });
565
359
  }
566
360
  }
361
+ getAll() {
362
+ return this.models;
363
+ }
364
+ getAvailable() {
365
+ return this.models.filter((model) => this.authStorage.hasAuth(model.provider));
366
+ }
367
+ find(provider, modelId) {
368
+ return this.models.find((model) => model.provider === provider && model.id === modelId);
369
+ }
370
+ async getApiKey(model, accountId) {
371
+ return this.authStorage.getApiKey(model.provider, accountId);
372
+ }
373
+ async getApiKeyForProvider(provider, accountId) {
374
+ return this.authStorage.getApiKey(provider, accountId);
375
+ }
376
+ getAccounts(provider) {
377
+ return this.authStorage.getAccounts(provider);
378
+ }
379
+ getDefaultAccount(provider) {
380
+ return this.authStorage.getDefaultAccount(provider);
381
+ }
382
+ isUsingOAuth(model) {
383
+ return this.authStorage.get(model.provider)?.type === "oauth";
384
+ }
385
+ registerProvider(providerName, config) {
386
+ this.registerExtensionProvider(providerName, config);
387
+ }
567
388
  }
568
389
  //# sourceMappingURL=model-registry.js.map