titan-agent 7.0.0 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/README.md +54 -2
  2. package/dist/agent/agent.js +55 -10
  3. package/dist/agent/agent.js.map +1 -1
  4. package/dist/agent/contextManager.js +1 -1
  5. package/dist/agent/contextManager.js.map +1 -1
  6. package/dist/agent/honestyGuard.js +66 -0
  7. package/dist/agent/honestyGuard.js.map +1 -0
  8. package/dist/agent/selfCritique.js +101 -0
  9. package/dist/agent/selfCritique.js.map +1 -0
  10. package/dist/agent/toolSearch.js +9 -2
  11. package/dist/agent/toolSearch.js.map +1 -1
  12. package/dist/agent/trajectoryLogger.js +19 -2
  13. package/dist/agent/trajectoryLogger.js.map +1 -1
  14. package/dist/analytics/collector.js +1 -1
  15. package/dist/analytics/collector.js.map +1 -1
  16. package/dist/config/schema.js +32 -0
  17. package/dist/config/schema.js.map +1 -1
  18. package/dist/eval/harness.js +4 -1
  19. package/dist/eval/harness.js.map +1 -1
  20. package/dist/gateway/server.js +24 -8
  21. package/dist/gateway/server.js.map +1 -1
  22. package/dist/gateway/slashCommands.js +31 -0
  23. package/dist/gateway/slashCommands.js.map +1 -1
  24. package/dist/mcp/agentTools.js +135 -0
  25. package/dist/mcp/agentTools.js.map +1 -0
  26. package/dist/mcp/server.js +19 -2
  27. package/dist/mcp/server.js.map +1 -1
  28. package/dist/memory/graph.js +2 -0
  29. package/dist/memory/graph.js.map +1 -1
  30. package/dist/providers/errorTaxonomy.js +4 -0
  31. package/dist/providers/errorTaxonomy.js.map +1 -1
  32. package/dist/providers/moa.js +151 -0
  33. package/dist/providers/moa.js.map +1 -0
  34. package/dist/providers/modelCapabilities.js +65 -2
  35. package/dist/providers/modelCapabilities.js.map +1 -1
  36. package/dist/providers/ollama.js +1 -0
  37. package/dist/providers/ollama.js.map +1 -1
  38. package/dist/providers/openai_compat.js +14 -2
  39. package/dist/providers/openai_compat.js.map +1 -1
  40. package/dist/providers/router.js +3 -1
  41. package/dist/providers/router.js.map +1 -1
  42. package/dist/utils/benchMode.js +8 -0
  43. package/dist/utils/benchMode.js.map +1 -0
  44. package/dist/utils/constants.js +1 -1
  45. package/dist/utils/constants.js.map +1 -1
  46. package/package.json +26 -26
  47. package/ui/dist/assets/AboutYouMemory-57X5SqHQ.js +1 -0
  48. package/ui/dist/assets/AuditPanel-AyB8ciLZ.js +1 -0
  49. package/ui/dist/assets/AutonomyPanel-wmVPr-n3.js +1 -0
  50. package/ui/dist/assets/AutopilotPanel-CbLy4lJP.js +1 -0
  51. package/ui/dist/assets/AutoresearchPanel-DxRO1rBF.js +1 -0
  52. package/ui/dist/assets/BackupPanel-BUh9rQ-3.js +1 -0
  53. package/ui/dist/assets/BrowserPanel-OqKwGrIL.js +1 -0
  54. package/ui/dist/assets/CPActivity-DGfS7EY3.js +1 -0
  55. package/ui/dist/assets/CPAgentDetail-p0Kvzhhb.js +1 -0
  56. package/ui/dist/assets/CPAgents-B6wSSQZM.js +1 -0
  57. package/ui/dist/assets/CPApprovals-CYv9Do0i.js +1 -0
  58. package/ui/dist/assets/CPCosts-Dx6Q71rN.js +1 -0
  59. package/ui/dist/assets/CPDashboard-DA8-tE-l.js +1 -0
  60. package/ui/dist/assets/CPFiles-BJ49tzai.js +1 -0
  61. package/ui/dist/assets/CPGoals-h0dKL5V_.js +1 -0
  62. package/ui/dist/assets/CPInbox-CDvefgNH.js +1 -0
  63. package/ui/dist/assets/CPIssueDetail-CnmLzzDD.js +1 -0
  64. package/ui/dist/assets/CPIssues-DknAIMyl.js +1 -0
  65. package/ui/dist/assets/CPLayout-C2nqgkmY.js +2 -0
  66. package/ui/dist/assets/CPOrg-tDbHFphX.js +1 -0
  67. package/ui/dist/assets/CPRuns-UlrIURqG.js +1 -0
  68. package/ui/dist/assets/CPSocial-B-gHgvEw.js +1 -0
  69. package/ui/dist/assets/CPVoice-CJy938ZF.js +1 -0
  70. package/ui/dist/assets/ChannelsPanel-DLbxg1zO.js +1 -0
  71. package/ui/dist/assets/CheckpointsPanel-BB6TT0aE.js +1 -0
  72. package/ui/dist/assets/CommandPostHub-fIslwU_t.js +2 -0
  73. package/ui/dist/assets/ConfirmDialog-6hcNjmAh.js +9 -0
  74. package/ui/dist/assets/CronPanel-DLpw3Y25.js +1 -0
  75. package/ui/dist/assets/DataTable-KVqtDzvP.js +1 -0
  76. package/ui/dist/assets/DreamPanel-lcMXpbEb.js +5 -0
  77. package/ui/dist/assets/EmptyState-D-Dg8B8r.js +1 -0
  78. package/ui/dist/assets/EvalHarnessPanel-BKzRiiQw.js +2 -0
  79. package/ui/dist/assets/EvalPanel-Dtodacmj.js +1 -0
  80. package/ui/dist/assets/FileViewer-DjcVKkO2.js +60 -0
  81. package/ui/dist/assets/FilesPanel-BI90Pplh.js +1 -0
  82. package/ui/dist/assets/FleetPanel-tr0wjAwr.js +1 -0
  83. package/ui/dist/assets/HomelabPanel-m8vMm5rE.js +1 -0
  84. package/ui/dist/assets/InfraView-3WriJnyE.js +2 -0
  85. package/ui/dist/assets/IntegrationsPanel-BmL70fOw.js +1 -0
  86. package/ui/dist/assets/IntelligenceView-BGVxCKD3.js +2 -0
  87. package/ui/dist/assets/LearningPanel-CrYLQ6eV.js +1 -0
  88. package/ui/dist/assets/LiveStudio-CnW3eZYF.js +2 -0
  89. package/ui/dist/assets/LogsPanel-DbShr4Ic.js +1 -0
  90. package/ui/dist/assets/McpPanel-uMYEsPI4.js +1 -0
  91. package/ui/dist/assets/MemoryGraphPanel-C7-Z8f0v.js +1 -0
  92. package/ui/dist/assets/MemoryTaxonomyPanel-KrxN8U1G.js +1 -0
  93. package/ui/dist/assets/MemoryWikiPanel-DI3q6IHC.js +1 -0
  94. package/ui/dist/assets/MeshPanel-D4-g2tlu.js +1 -0
  95. package/ui/dist/assets/MissionCanvas-D8cjakJe.js +61 -0
  96. package/ui/dist/assets/MissionChat-BvqCUf1E.js +3 -0
  97. package/ui/dist/assets/MissionLibrary-CZoJQ9WD.js +1 -0
  98. package/ui/dist/assets/MissionStart-CXCq-_AD.js +1 -0
  99. package/ui/dist/assets/NvidiaPanel-BfI1K5Pg.js +1 -0
  100. package/ui/dist/assets/OrganismPanel-B7Gm9pP-.js +1 -0
  101. package/ui/dist/assets/OverviewPanel-B9tKWRK2.js +1 -0
  102. package/ui/dist/assets/PageHeader-CH85uoZG.js +1 -0
  103. package/ui/dist/assets/PersonaProfilesPanel-BPi8fl-U.js +3 -0
  104. package/ui/dist/assets/PersonasPanel-Dwr7sycT.js +1 -0
  105. package/ui/dist/assets/PhoneDeskPanel-D7qc6wUI.js +1 -0
  106. package/ui/dist/assets/RecipesPanel-DcqPWRSU.js +1 -0
  107. package/ui/dist/assets/SecurityPanel-Bv_B9Ahf.js +1 -0
  108. package/ui/dist/assets/SelfImprovePanel-Ca4rGwEG.js +1 -0
  109. package/ui/dist/assets/SelfProposalsPanel-DteMSASq.js +1 -0
  110. package/ui/dist/assets/SessionsPanel-BdbbKTbL.js +1 -0
  111. package/ui/dist/assets/SessionsTab-BJipiVJs.js +1 -0
  112. package/ui/dist/assets/SettingsPanel-mV7ykOCc.js +1 -0
  113. package/ui/dist/assets/SettingsView-Bu_wYTT5.js +2 -0
  114. package/ui/dist/assets/SkeletonLoader-9H7QWa9E.js +1 -0
  115. package/ui/dist/assets/SkillsPanel-CHwX2kDR.js +1 -0
  116. package/ui/dist/assets/SomaView-Bpsm4ZW7.js +5 -0
  117. package/ui/dist/assets/SomaView-Dghh9om4.css +1 -0
  118. package/ui/dist/assets/StatCard-wmSgMAM3.js +1 -0
  119. package/ui/dist/assets/TeamsPanel-XJiHxdDX.js +1 -0
  120. package/ui/dist/assets/TelemetryPanel-_pmGVxpO.js +1 -0
  121. package/ui/dist/assets/TitanCanvas-Cb7KG80W.css +1 -0
  122. package/ui/dist/assets/TitanCanvas-CmLy7p2N.js +883 -0
  123. package/ui/dist/assets/ToolsView-PHizHZBx.js +2 -0
  124. package/ui/dist/assets/TraceViewer-CYAzIcfB.js +1 -0
  125. package/ui/dist/assets/TracesPanel-CRSN_dzK.js +1 -0
  126. package/ui/dist/assets/TrainingPanel-B9rcuMsV.js +1 -0
  127. package/ui/dist/assets/VoiceOverlay-BL_ns1ZA.js +7 -0
  128. package/ui/dist/assets/VramPanel-BNPQ06_9.js +1 -0
  129. package/ui/dist/assets/WatchView-BgAkNnur.js +13 -0
  130. package/ui/dist/assets/WorkTab-RRpPpEOg.js +1 -0
  131. package/ui/dist/assets/WorkflowBuilderPanel-BPHIH8pf.js +1 -0
  132. package/ui/dist/assets/WorkflowsPanel-DqtmT0NB.js +1 -0
  133. package/ui/dist/assets/approvalHeadline-BRg3ReTi.js +1 -0
  134. package/ui/dist/assets/archive-DcK9HrbE.js +1 -0
  135. package/ui/dist/assets/arrow-left-4c2FnES1.js +1 -0
  136. package/ui/dist/assets/book-open-Ds_yciQm.js +1 -0
  137. package/ui/dist/assets/bot-CWDCc265.js +1 -0
  138. package/ui/dist/assets/chart-column-hhZMdCgB.js +1 -0
  139. package/ui/dist/assets/chevron-right-A_pvnRh_.js +1 -0
  140. package/ui/dist/assets/circle-check-big-C-JUM7wb.js +1 -0
  141. package/ui/dist/assets/circle-stop-yZuG9ZAE.js +1 -0
  142. package/ui/dist/assets/clipboard-list-C2HUEjZc.js +1 -0
  143. package/ui/dist/assets/clock-DSPgndSD.js +1 -0
  144. package/ui/dist/assets/clsx-CjueKrWZ.js +1 -0
  145. package/ui/dist/assets/createLucideIcon-qnlrxww7.js +1 -0
  146. package/ui/dist/assets/database-C1SgHa8T.js +1 -0
  147. package/ui/dist/assets/dollar-sign-D9siqK91.js +1 -0
  148. package/ui/dist/assets/download-CJZWQNfV.js +1 -0
  149. package/ui/dist/assets/external-link-CpQLWKKE.js +1 -0
  150. package/ui/dist/assets/file-text-BbGTi-Po.js +1 -0
  151. package/ui/dist/assets/flask-conical-B1YVft4E.js +1 -0
  152. package/ui/dist/assets/folder-EbR-w2Mq.js +1 -0
  153. package/ui/dist/assets/funnel-D2Dkn8Pf.js +1 -0
  154. package/ui/dist/assets/git-branch-CQ2yNSzU.js +1 -0
  155. package/ui/dist/assets/git-pull-request-BxL5wlGX.js +1 -0
  156. package/ui/dist/assets/index-Cz8190xO.css +2 -0
  157. package/ui/dist/assets/index-WI-E4I3h.js +243 -0
  158. package/ui/dist/assets/jsx-runtime-B15e6lOy.js +1 -0
  159. package/ui/dist/assets/layers-BPu5SRjI.js +1 -0
  160. package/ui/dist/assets/legacy-BIzifT-t.js +3 -0
  161. package/ui/dist/assets/lightbulb-BY7CpMte.js +1 -0
  162. package/ui/dist/assets/link-VDQkrGJw.js +1 -0
  163. package/ui/dist/assets/list-todo-DfnNUV_T.js +1 -0
  164. package/ui/dist/assets/message-square-BpzrINHz.js +1 -0
  165. package/ui/dist/assets/mic-De6oZFaV.js +1 -0
  166. package/ui/dist/assets/missions-y-qg_f9b.js +1 -0
  167. package/ui/dist/assets/network-CM7y1ats.js +1 -0
  168. package/ui/dist/assets/pause-C4TDJSfA.js +1 -0
  169. package/ui/dist/assets/pencil-Dd_vzHE-.js +1 -0
  170. package/ui/dist/assets/play-9WxZWVHA.js +1 -0
  171. package/ui/dist/assets/plug-Dm25Wbrc.js +1 -0
  172. package/ui/dist/assets/plus-CHryCIkk.js +1 -0
  173. package/ui/dist/assets/radio-D-XnoAVu.js +1 -0
  174. package/ui/dist/assets/refresh-cw-Disd5wRB.js +1 -0
  175. package/ui/dist/assets/rotate-ccw-Cw1T2W1T.js +1 -0
  176. package/ui/dist/assets/save-DP7oNar2.js +1 -0
  177. package/ui/dist/assets/search-aNVcX-nv.js +1 -0
  178. package/ui/dist/assets/send-D7iQD57b.js +1 -0
  179. package/ui/dist/assets/server-DFfeYjoM.js +1 -0
  180. package/ui/dist/assets/settings-5NWXzgyY.js +1 -0
  181. package/ui/dist/assets/shared-DLz_Jtg3.js +1 -0
  182. package/ui/dist/assets/shield-check-Cd50jCAn.js +1 -0
  183. package/ui/dist/assets/square-DlcoJ1ZM.js +1 -0
  184. package/ui/dist/assets/terminal-DgFz2Vsf.js +1 -0
  185. package/ui/dist/assets/test-tube-BimtS92_.js +1 -0
  186. package/ui/dist/assets/toggle-right-BMaR-sfT.js +1 -0
  187. package/ui/dist/assets/trash-2-CwUv7ww1.js +1 -0
  188. package/ui/dist/assets/trending-up-Ba9TwEow.js +1 -0
  189. package/ui/dist/assets/trophy-Gfv1QC45.js +1 -0
  190. package/ui/dist/assets/volume-2-BVlfVl2U.js +1 -0
  191. package/ui/dist/assets/wifi-off-CWLeusSV.js +1 -0
  192. package/ui/dist/assets/zoom-out-DeggJ7RM.js +1 -0
  193. package/ui/dist/index.html +4 -2
  194. package/ui/dist/sw.js +1 -1
  195. package/ui/dist/assets/AboutYouMemory-CZKEOd_O.js +0 -11
  196. package/ui/dist/assets/AuditPanel-Bu71N5Er.js +0 -1
  197. package/ui/dist/assets/AutonomyPanel-DB-39dX4.js +0 -11
  198. package/ui/dist/assets/AutopilotPanel-Cj8oKxWv.js +0 -1
  199. package/ui/dist/assets/AutoresearchPanel-3s8pjm6Z.js +0 -6
  200. package/ui/dist/assets/BackupPanel-EUQJMJE7.js +0 -1
  201. package/ui/dist/assets/BrowserPanel-Beo4F5Ar.js +0 -6
  202. package/ui/dist/assets/Button-MdXmb4_n.js +0 -1
  203. package/ui/dist/assets/CPActivity-B1Se9VVc.js +0 -1
  204. package/ui/dist/assets/CPAgentDetail-BYji6tT8.js +0 -1
  205. package/ui/dist/assets/CPAgents-BSUKucTe.js +0 -1
  206. package/ui/dist/assets/CPApprovals-B4v0em6e.js +0 -1
  207. package/ui/dist/assets/CPCosts-9ikh61Kv.js +0 -1
  208. package/ui/dist/assets/CPDashboard-sOok2T5v.js +0 -1
  209. package/ui/dist/assets/CPFiles-DB2nY5JE.js +0 -1
  210. package/ui/dist/assets/CPGoals-8Z1yOY8e.js +0 -1
  211. package/ui/dist/assets/CPInbox-Cq6-UY8F.js +0 -11
  212. package/ui/dist/assets/CPIssueDetail-NAGfmJg8.js +0 -1
  213. package/ui/dist/assets/CPIssues-BzX6Rckx.js +0 -1
  214. package/ui/dist/assets/CPLayout-BcRM6QSg.js +0 -2
  215. package/ui/dist/assets/CPOrg-B7DQ4UQP.js +0 -1
  216. package/ui/dist/assets/CPRuns-D-cpPw_M.js +0 -1
  217. package/ui/dist/assets/CPSocial-DshtmcK0.js +0 -11
  218. package/ui/dist/assets/CPVoice-DfXRnQVU.js +0 -1
  219. package/ui/dist/assets/ChannelsPanel-BnaTOeyf.js +0 -1
  220. package/ui/dist/assets/CheckpointsPanel-C62naE4U.js +0 -1
  221. package/ui/dist/assets/CommandPostHub-B_L1CAss.js +0 -24
  222. package/ui/dist/assets/ConfirmDialog-VErHWAbo.js +0 -1
  223. package/ui/dist/assets/CronPanel-BwMrrZ5d.js +0 -1
  224. package/ui/dist/assets/DataTable-BCqSUuN7.js +0 -1
  225. package/ui/dist/assets/DreamPanel-BNAcCLBB.js +0 -15
  226. package/ui/dist/assets/EmptyState-D9kQf1PX.js +0 -1
  227. package/ui/dist/assets/EvalHarnessPanel-BaMLdBNm.js +0 -2
  228. package/ui/dist/assets/EvalPanel-CW-SSjtg.js +0 -1
  229. package/ui/dist/assets/FileViewer-BL00nsd7.js +0 -61
  230. package/ui/dist/assets/FilesPanel-CeC6YUSd.js +0 -16
  231. package/ui/dist/assets/FleetPanel-EyWF7l3W.js +0 -1
  232. package/ui/dist/assets/HomelabPanel-BRfKRYe7.js +0 -6
  233. package/ui/dist/assets/InfraView-Jmqhg_Yc.js +0 -2
  234. package/ui/dist/assets/InlineEditableField-DgMrLDj1.js +0 -1
  235. package/ui/dist/assets/Input-CBTwa_Iw.js +0 -1
  236. package/ui/dist/assets/IntegrationsPanel-DQL-7Ec6.js +0 -1
  237. package/ui/dist/assets/IntelligenceView-DxD78qfP.js +0 -2
  238. package/ui/dist/assets/LearningPanel-C_JzSbJU.js +0 -1
  239. package/ui/dist/assets/LiveStudio-Db5yeaWo.js +0 -7
  240. package/ui/dist/assets/LogsPanel-CpinKwaZ.js +0 -1
  241. package/ui/dist/assets/McpPanel-D-MqN_f-.js +0 -1
  242. package/ui/dist/assets/MemoryGraphPanel-BnD5jRqf.js +0 -1
  243. package/ui/dist/assets/MemoryTaxonomyPanel-BBI202dd.js +0 -6
  244. package/ui/dist/assets/MemoryWikiPanel-Dn3XZHL0.js +0 -6
  245. package/ui/dist/assets/MeshPanel-C-mRJpr0.js +0 -11
  246. package/ui/dist/assets/MissionCanvas-CbZW83Ch.js +0 -72
  247. package/ui/dist/assets/MissionChat-Bs75jPAD.js +0 -7
  248. package/ui/dist/assets/MissionLibrary-BxQ6SxPe.js +0 -5
  249. package/ui/dist/assets/MissionStart-CBuBPasl.js +0 -1
  250. package/ui/dist/assets/Modal-ybPGvlQs.js +0 -9
  251. package/ui/dist/assets/NvidiaPanel-DdG13OX4.js +0 -1
  252. package/ui/dist/assets/OrganismPanel-xZWUJKyr.js +0 -1
  253. package/ui/dist/assets/OverviewPanel-B45ZYhJV.js +0 -1
  254. package/ui/dist/assets/PageHeader-DdrbS1aq.js +0 -1
  255. package/ui/dist/assets/PersonaProfilesPanel-CKER-EU5.js +0 -8
  256. package/ui/dist/assets/PersonasPanel-CMMQ3nh3.js +0 -1
  257. package/ui/dist/assets/PhoneDeskPanel-Bw_Y-cVE.js +0 -11
  258. package/ui/dist/assets/RecipesPanel-DzMcxpJJ.js +0 -1
  259. package/ui/dist/assets/SecurityPanel-BCq3Fzbr.js +0 -1
  260. package/ui/dist/assets/SelfImprovePanel-YE3hT8jK.js +0 -1
  261. package/ui/dist/assets/SelfProposalsPanel-DXuqBM6p.js +0 -1
  262. package/ui/dist/assets/SessionsPanel-DORz5goR.js +0 -1
  263. package/ui/dist/assets/SessionsTab-qYHDOuC8.js +0 -1
  264. package/ui/dist/assets/SettingsPanel-BbwPu1i7.js +0 -1
  265. package/ui/dist/assets/SettingsView-zgqkDDBJ.js +0 -2
  266. package/ui/dist/assets/SkeletonLoader-r6OGXaU9.js +0 -1
  267. package/ui/dist/assets/SkillsPanel-BjEOBMRo.js +0 -11
  268. package/ui/dist/assets/SomaView-BtCkeWfZ.css +0 -1
  269. package/ui/dist/assets/SomaView-DLzApZVW.js +0 -5
  270. package/ui/dist/assets/StatCard-DLq8aBps.js +0 -1
  271. package/ui/dist/assets/StatusBadge-BqlvIbdj.js +0 -1
  272. package/ui/dist/assets/Tabs-DdUThlp1.js +0 -1
  273. package/ui/dist/assets/TeamsPanel-uIIKoU7I.js +0 -1
  274. package/ui/dist/assets/TelemetryPanel-dVr3yQQr.js +0 -1
  275. package/ui/dist/assets/TitanCanvas-BfitWg9R.css +0 -1
  276. package/ui/dist/assets/TitanCanvas-xHAJqwG2.js +0 -945
  277. package/ui/dist/assets/ToolsView-CG1mZdiy.js +0 -2
  278. package/ui/dist/assets/Tooltip-C2tXJcrN.js +0 -6
  279. package/ui/dist/assets/TraceViewer-BIMD_Osr.js +0 -1
  280. package/ui/dist/assets/TracesPanel-nMUiyMj5.js +0 -1
  281. package/ui/dist/assets/TrainingPanel-CT5R4HWm.js +0 -1
  282. package/ui/dist/assets/VoiceOverlay-Br4QnCtw.js +0 -17
  283. package/ui/dist/assets/VramPanel-CdnJYytg.js +0 -1
  284. package/ui/dist/assets/WatchView-TNU6Ns1Q.js +0 -13
  285. package/ui/dist/assets/WorkTab-wTlX_UKP.js +0 -1
  286. package/ui/dist/assets/WorkflowBuilderPanel-CDpVt5ux.js +0 -6
  287. package/ui/dist/assets/WorkflowsPanel-zsFqsLdn.js +0 -11
  288. package/ui/dist/assets/approvalHeadline-DB9SgR-9.js +0 -1
  289. package/ui/dist/assets/archive-Bh689DNg.js +0 -6
  290. package/ui/dist/assets/arrow-left-WkVYLm80.js +0 -6
  291. package/ui/dist/assets/book-open-ohEXgUsS.js +0 -6
  292. package/ui/dist/assets/bot-DvEcyQcD.js +0 -6
  293. package/ui/dist/assets/chart-column-w3goFd5f.js +0 -6
  294. package/ui/dist/assets/check-CuRYh4Zh.js +0 -6
  295. package/ui/dist/assets/chevron-right-DbLSHmff.js +0 -6
  296. package/ui/dist/assets/circle-check-big-Bkba568b.js +0 -6
  297. package/ui/dist/assets/circle-stop-Bx2ohEg8.js +0 -6
  298. package/ui/dist/assets/clipboard-list-Dj9tORnu.js +0 -6
  299. package/ui/dist/assets/clock-JyQAYy6X.js +0 -6
  300. package/ui/dist/assets/clsx-B-dksMZM.js +0 -1
  301. package/ui/dist/assets/dollar-sign-XxwPAA2a.js +0 -6
  302. package/ui/dist/assets/download-D1izVEOL.js +0 -6
  303. package/ui/dist/assets/external-link-DZ_rZsIt.js +0 -6
  304. package/ui/dist/assets/file-text-Cfawu8Bs.js +0 -6
  305. package/ui/dist/assets/flask-conical-Ql8QxhgY.js +0 -6
  306. package/ui/dist/assets/folder-DAdIw-Pb.js +0 -6
  307. package/ui/dist/assets/funnel-FycfZcXo.js +0 -6
  308. package/ui/dist/assets/git-branch-C2qrhGGu.js +0 -6
  309. package/ui/dist/assets/index-Cml2x9pA.js +0 -507
  310. package/ui/dist/assets/index-yWybhcfI.css +0 -1
  311. package/ui/dist/assets/layers-yzjtGlHB.js +0 -6
  312. package/ui/dist/assets/legacy-D21WSMF1.js +0 -3
  313. package/ui/dist/assets/lightbulb-BZJNK69S.js +0 -6
  314. package/ui/dist/assets/link-CnFkBkaY.js +0 -6
  315. package/ui/dist/assets/list-todo-BlgfQHup.js +0 -6
  316. package/ui/dist/assets/message-square-CRsG9u6_.js +0 -6
  317. package/ui/dist/assets/mic-B32RHc7Y.js +0 -6
  318. package/ui/dist/assets/missions-1iw8Z2_0.js +0 -1
  319. package/ui/dist/assets/network-C9RXQGrV.js +0 -6
  320. package/ui/dist/assets/pause-BT1Bc2q3.js +0 -6
  321. package/ui/dist/assets/pencil-BK5IU6o0.js +0 -6
  322. package/ui/dist/assets/play-Cl1nC_gc.js +0 -6
  323. package/ui/dist/assets/plug-DvcpOalj.js +0 -6
  324. package/ui/dist/assets/plus-Dpo1qfrl.js +0 -6
  325. package/ui/dist/assets/radio-C5c9IyqX.js +0 -6
  326. package/ui/dist/assets/refresh-cw-C-iZkzuS.js +0 -6
  327. package/ui/dist/assets/rotate-ccw-qzrB3SNw.js +0 -6
  328. package/ui/dist/assets/save-DwR9wQVu.js +0 -6
  329. package/ui/dist/assets/search-D10l0m3-.js +0 -6
  330. package/ui/dist/assets/send-DtXGsaFW.js +0 -6
  331. package/ui/dist/assets/server-BzisF3LL.js +0 -6
  332. package/ui/dist/assets/settings-Dbwd1_-c.js +0 -6
  333. package/ui/dist/assets/shield-check-CXlDJyAW.js +0 -6
  334. package/ui/dist/assets/square-BBC-JKzY.js +0 -11
  335. package/ui/dist/assets/terminal-DaBIlWEM.js +0 -6
  336. package/ui/dist/assets/test-tube-CDATRD5t.js +0 -11
  337. package/ui/dist/assets/toggle-right-DTmrC5RD.js +0 -11
  338. package/ui/dist/assets/trash-2-CTeyjxD_.js +0 -6
  339. package/ui/dist/assets/trending-up-CXPRjRV4.js +0 -6
  340. package/ui/dist/assets/trophy-DbVdXRtU.js +0 -6
  341. package/ui/dist/assets/volume-2-DYDBmm3M.js +0 -6
  342. package/ui/dist/assets/wifi-off-BBuIGbiP.js +0 -6
  343. package/ui/dist/assets/zoom-out-D47_pRAO.js +0 -16
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/openai_compat.ts"],"sourcesContent":["/**\n * TITAN — Generic OpenAI-Compatible Provider\n * A single provider class that works with any OpenAI-compatible API endpoint.\n * Used by: Groq, Mistral, OpenRouter, Fireworks, xAI, Together, DeepSeek,\n * Cerebras, Cohere, Perplexity, and any custom provider.\n */\nimport {\n LLMProvider,\n withTimeoutSignal,\n STREAM_FETCH_TIMEOUT_MS,\n type ChatOptions,\n type ChatResponse,\n type ChatStreamChunk,\n type ToolCall,\n} from './base.js';\nimport { loadConfig } from '../config/config.js';\nimport type { ProviderConfig } from '../config/schema.js';\nimport logger from '../utils/logger.js';\nimport { fetchWithRetry } from '../utils/helpers.js';\nimport { resolveApiKey } from './authResolver.js';\nimport { v4 as uuid } from 'uuid';\nimport { clampMaxTokens } from './modelCapabilities.js';\n// Reuse the Ollama provider's battle-tested per-model tool-behavior registry\n// (selfSelectsTools/etc.) so cloud models routed through this GENERIC provider\n// get the same model-agnostic treatment instead of a blind passthrough.\nimport { getModelCapabilities as getToolCapabilities } from './ollama.js';\n\n/**\n * Apply model-agnostic tool / structured-output controls to an OpenAI-compatible\n * request body. Without this, this provider (which fronts ~24 backends incl.\n * DeepSeek/Qwen/GLM/Kimi/MiniMax/xAI) silently ignores forceToolUse and format —\n * so weak-self-selecting models answer in prose instead of calling the tool.\n */\nfunction applyCompatToolControls(body: Record<string, unknown>, model: string, options: ChatOptions): void {\n // forceToolUse → tool_choice:'required', but ONLY for models that don't\n // self-select tools well (forcing a self-selecting model wastes a turn), and\n // NEVER for a DeepSeek reasoner with thinking on — that combo is rejected\n // with HTTP 400 by the reasoner endpoint (vllm #41132 / pydantic-ai #5193).\n const tools = body.tools as unknown[] | undefined;\n if (options.forceToolUse && Array.isArray(tools) && tools.length > 0) {\n const isDeepseekReasoner = /deepseek/i.test(model) && options.thinking === true;\n if (!isDeepseekReasoner && !getToolCapabilities(model).selfSelectsTools) {\n body.tool_choice = 'required';\n }\n }\n // format → native JSON mode + an anti-truncation floor (truncated/empty JSON\n // is a common failure mode; json_object is the universally-supported shape).\n if (options.format === 'json' || (options.format && typeof options.format === 'object')) {\n body.response_format = { type: 'json_object' };\n if (typeof body.max_tokens === 'number' && body.max_tokens < 2048) body.max_tokens = 2048;\n }\n}\n\n/**\n * Parse the model's REAL token ceiling out of a \"max_tokens too large\" 400.\n * Deployments cap a model below our static table (e.g. a vLLM behind LiteLLM with\n * max_total_tokens=12288), so a static maxOutput can't be trusted — we adapt to\n * what the deployment actually allows. Returns null if it's not that error.\n * Examples handled:\n * vLLM: \"max_tokens=32768 cannot be greater than max_model_len=max_total_tokens=12288\"\n * OpenAI:\"maximum context length is 8192 tokens\"\n */\nexport function parseMaxTokenLimit(errText: string): number | null {\n const m = errText.match(/max_model_len=(?:max_total_tokens=)?(\\d+)|max_total_tokens=(\\d+)|maximum context length is (\\d+)/i);\n if (!m) return null;\n const n = Number(m[1] || m[2] || m[3]);\n return Number.isFinite(n) && n > 0 ? n : null;\n}\n\n/** Configuration for an OpenAI-compatible provider */\nexport interface OpenAICompatConfig {\n /** Internal provider name (e.g. 'groq') */\n name: string;\n /** Display name shown to users (e.g. 'Groq (Fast Inference)') */\n displayName: string;\n /** Default API base URL */\n defaultBaseUrl: string;\n /** Environment variable name for the API key */\n envKey: string;\n /** Config key name in titan.json providers section */\n configKey: string;\n /** Default model ID */\n defaultModel: string;\n /** Static model list (returned when health check fails) */\n knownModels: string[];\n /** Extra headers to send with every request */\n extraHeaders?: Record<string, string>;\n /** Whether to fetch models from /v1/models endpoint */\n supportsModelList?: boolean;\n /**\n * The /models catalogue is publicly accessible (no API key required).\n * When true, listModels() will fetch the catalogue even when the user\n * has not configured an API key — useful for picker UIs that want to\n * show the full catalogue before the user has chosen / paid for a key.\n * OpenRouter is the canonical example.\n */\n publicModelList?: boolean;\n /** Keep org/ prefix in model name (e.g. NIM API expects 'nvidia/model-name') */\n keepModelPrefix?: boolean;\n}\n\nexport class OpenAICompatProvider extends LLMProvider {\n readonly name: string;\n readonly displayName: string;\n private readonly config: OpenAICompatConfig;\n\n constructor(config: OpenAICompatConfig) {\n super();\n this.name = config.name;\n this.displayName = config.displayName;\n this.config = config;\n }\n\n private get apiKey(): string {\n const cfg = loadConfig();\n const providerCfg = (cfg.providers as Record<string, unknown>)[this.config.configKey] as ProviderConfig | undefined;\n return resolveApiKey(this.config.name, providerCfg?.authProfiles || [], providerCfg?.apiKey || '', this.config.envKey, providerCfg?.rotationStrategy, providerCfg?.credentialCooldownMs);\n }\n\n private get baseUrl(): string {\n const cfg = loadConfig();\n const providerCfg = (cfg.providers as Record<string, unknown>)[this.config.configKey] as ProviderConfig | undefined;\n return providerCfg?.baseUrl || this.config.defaultBaseUrl;\n }\n\n /** Sanitize messages for strict APIs (e.g., NIM) that reject empty content strings */\n private sanitizeMessages(messages: ChatOptions['messages']): ChatOptions['messages'] {\n return messages.map(m => ({\n ...m,\n content: m.content || (m.role === 'assistant' && m.toolCalls ? '' : ' '),\n }));\n }\n\n async chat(options: ChatOptions): Promise<ChatResponse> {\n const rawModel = options.model || this.config.defaultModel;\n // NIM API requires org/model format — keep prefix as-is or add it\n const model = this.config.keepModelPrefix\n ? (rawModel.includes('/') ? rawModel : `${this.name}/${rawModel}`)\n : rawModel.replace(`${this.name}/`, '');\n\n // Kimi API uses dash model IDs (kimi-k2-6) but TITAN uses dots (kimi-k2.6)\n const apiModel = this.config.configKey === 'kimi'\n ? model.replace(/kimi-k2\\.6/g, 'kimi-k2-6').replace(/kimi-k2\\.5/g, 'kimi-k2-5')\n : model;\n const apiKey = this.apiKey;\n if (!apiKey) throw new Error(`${this.displayName} API key not configured (set ${this.config.envKey} or providers.${this.config.configKey}.apiKey)`);\n\n logger.debug(this.name, `Chat request: model=${model}, messages=${options.messages.length}`);\n\n const sanitized = this.sanitizeMessages(options.messages);\n const body: Record<string, unknown> = {\n model: apiModel,\n messages: sanitized.map((m) => {\n if (m.role === 'tool') {\n return { role: 'tool', content: m.content || ' ', tool_call_id: m.toolCallId };\n }\n if (m.role === 'assistant' && m.toolCalls) {\n return {\n role: 'assistant',\n content: m.content || null,\n tool_calls: m.toolCalls.map((tc) => ({\n id: tc.id,\n type: 'function',\n function: { name: tc.function.name, arguments: tc.function.arguments },\n })),\n };\n }\n return { role: m.role, content: m.content || ' ' };\n }),\n max_tokens: clampMaxTokens(model, options.maxTokens),\n };\n\n if (options.tools && options.tools.length > 0) {\n body.tools = options.tools;\n }\n applyCompatToolControls(body, model, options);\n\n if (options.temperature !== undefined) {\n body.temperature = options.temperature;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n ...(this.config.extraHeaders || {}),\n };\n\n const doFetch = () => fetchWithRetry(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n let response = await doFetch();\n\n // Adaptive max_tokens (model-agnostic): if the deployment caps this model\n // below the max_tokens we requested, it 400s with the real limit. Reduce\n // and retry ONCE so a too-high static ceiling never hard-fails a model.\n if (!response.ok && response.status === 400 && typeof body.max_tokens === 'number') {\n const errText = await response.text();\n const limit = parseMaxTokenLimit(errText);\n if (limit && (body.max_tokens as number) > limit) {\n body.max_tokens = Math.max(512, Math.min(Math.floor(limit / 3), 4096)); // leave room for input\n logger.warn(this.name, `[AdaptiveMaxTokens] ${model} deployment caps total tokens at ${limit}; retrying with max_tokens=${body.max_tokens}`);\n response = await doFetch();\n } else {\n const { createProviderError } = await import('./errorTaxonomy.js');\n throw createProviderError(`${this.displayName} API`, response, errText, { provider: this.name, model });\n }\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n // Hunt Finding #37: attach status + Retry-After so the router can respect backoff\n const { createProviderError } = await import('./errorTaxonomy.js');\n throw createProviderError(`${this.displayName} API`, response, errorText, { provider: this.name, model });\n }\n\n const data = await response.json() as Record<string, unknown>;\n const choices = data.choices as Array<Record<string, unknown>> | undefined;\n\n if (!choices || choices.length === 0) {\n return {\n id: (data.id as string) || uuid(),\n content: '',\n usage: undefined,\n finishReason: 'stop',\n model: model.includes('/') ? model : `${this.name}/${model}`,\n };\n }\n\n const choice = choices[0];\n const message = choice.message as Record<string, unknown>;\n\n const toolCalls: ToolCall[] = [];\n if (message.tool_calls) {\n for (const tc of message.tool_calls as Array<Record<string, unknown>>) {\n const fn = tc.function as Record<string, string>;\n toolCalls.push({\n id: (tc.id as string) || uuid(),\n type: 'function',\n function: { name: fn.name, arguments: fn.arguments },\n });\n }\n }\n\n const usage = data.usage as { prompt_tokens: number; completion_tokens: number; total_tokens: number } | undefined;\n\n return {\n id: (data.id as string) || uuid(),\n content: (message.content as string) || '',\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage: usage\n ? {\n promptTokens: usage.prompt_tokens,\n completionTokens: usage.completion_tokens,\n totalTokens: usage.total_tokens,\n }\n : undefined,\n finishReason: toolCalls.length > 0 ? 'tool_calls' : (choice.finish_reason as 'stop' | 'length') || 'stop',\n model: model.includes('/') ? model : `${this.name}/${model}`,\n };\n }\n\n async *chatStream(options: ChatOptions): AsyncGenerator<ChatStreamChunk> {\n const rawModel = options.model || this.config.defaultModel;\n const model = this.config.keepModelPrefix\n ? (rawModel.includes('/') ? rawModel : `${this.name}/${rawModel}`)\n : rawModel.replace(`${this.name}/`, '');\n const apiKey = this.apiKey;\n if (!apiKey) { yield { type: 'error', error: `${this.displayName} API key not configured` }; return; }\n\n const sanitized = this.sanitizeMessages(options.messages);\n const body: Record<string, unknown> = {\n model,\n stream: true,\n messages: sanitized.map((m) => {\n if (m.role === 'tool') return { role: 'tool', content: m.content || ' ', tool_call_id: m.toolCallId };\n if (m.role === 'assistant' && m.toolCalls) {\n return {\n role: 'assistant', content: m.content || null,\n tool_calls: m.toolCalls.map((tc) => ({ id: tc.id, type: 'function', function: { name: tc.function.name, arguments: tc.function.arguments } })),\n };\n }\n return { role: m.role, content: m.content || ' ' };\n }),\n max_tokens: clampMaxTokens(model, options.maxTokens),\n };\n if (options.tools && options.tools.length > 0) body.tools = options.tools;\n applyCompatToolControls(body, model, options);\n if (options.temperature !== undefined) body.temperature = options.temperature;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n ...(this.config.extraHeaders || {}),\n };\n\n try {\n const response = await fetch(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: withTimeoutSignal(options.signal, STREAM_FETCH_TIMEOUT_MS),\n });\n\n if (!response.ok || !response.body) {\n const errorText = await response.text();\n // v6.5 — THROW (not yield) so the router routes HTTP errors through\n // retry / fallback chain / circuit breaker, like non-streaming chat().\n const { createProviderError } = await import('./errorTaxonomy.js');\n throw createProviderError(this.displayName, response, errorText, { provider: this.name, model });\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n const toolCalls = new Map<number, { id: string; name: string; args: string }>();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue;\n const json = line.slice(6).trim();\n if (json === '[DONE]' || !json) continue;\n try {\n const chunk = JSON.parse(json);\n const delta = chunk.choices?.[0]?.delta;\n if (!delta) continue;\n if (delta.content) yield { type: 'text', content: delta.content };\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index ?? 0;\n if (!toolCalls.has(idx)) toolCalls.set(idx, { id: tc.id || '', name: '', args: '' });\n const entry = toolCalls.get(idx)!;\n if (tc.id) entry.id = tc.id;\n if (tc.function?.name) entry.name = tc.function.name;\n if (tc.function?.arguments) entry.args += tc.function.arguments;\n }\n }\n } catch { /* skip malformed SSE lines */ }\n }\n }\n\n for (const [, tc] of toolCalls) {\n if (tc.id && tc.name) {\n yield { type: 'tool_call', toolCall: { id: tc.id, type: 'function', function: { name: tc.name, arguments: tc.args || '{}' } } };\n }\n }\n yield { type: 'done' };\n } catch (error) {\n yield { type: 'error', error: (error as Error).message };\n }\n }\n\n async listModels(): Promise<string[]> {\n if (!this.config.supportsModelList) {\n return this.config.knownModels;\n }\n\n // Some upstream catalogues are public (no auth needed) — those\n // providers set `publicModelList: true` so the picker can show\n // the full catalogue even before the user configures a key.\n // OpenRouter is the canonical example (~365 models, no key).\n const isPublic = this.config.publicModelList === true;\n if (!isPublic && !this.apiKey) {\n return this.config.knownModels;\n }\n\n try {\n const headers: Record<string, string> = {\n ...(this.config.extraHeaders || {}),\n };\n if (this.apiKey) headers['Authorization'] = `Bearer ${this.apiKey}`;\n const response = await fetch(`${this.baseUrl}/models`, {\n headers,\n signal: AbortSignal.timeout(8000),\n });\n if (!response.ok) return this.config.knownModels;\n const data = await response.json() as { data?: Array<{ id: string }> };\n const ids = (data.data || []).map((m) => m.id).filter(Boolean);\n // Sort alphabetically for stable UX (the catalogue is\n // already typically grouped by family).\n ids.sort();\n return ids.length > 0 ? ids : this.config.knownModels;\n } catch {\n return this.config.knownModels;\n }\n }\n\n isConfigured(): boolean {\n return !!this.apiKey;\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n if (!this.apiKey) return false;\n const response = await fetch(`${this.baseUrl}/models`, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n ...(this.config.extraHeaders || {}),\n },\n signal: AbortSignal.timeout(5000),\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n\n// ── Provider Presets ──────────────────────────────────────────────\n\nexport const PROVIDER_PRESETS: OpenAICompatConfig[] = [\n {\n name: 'groq',\n displayName: 'Groq (Fast Inference)',\n defaultBaseUrl: 'https://api.groq.com/openai/v1',\n envKey: 'GROQ_API_KEY',\n configKey: 'groq',\n defaultModel: 'llama-3.3-70b-versatile',\n knownModels: ['llama-3.3-70b-versatile', 'llama-3.1-8b-instant', 'mixtral-8x7b-32768', 'gemma2-9b-it', 'deepseek-r1-distill-llama-70b'],\n supportsModelList: true,\n },\n {\n name: 'mistral',\n displayName: 'Mistral AI',\n defaultBaseUrl: 'https://api.mistral.ai/v1',\n envKey: 'MISTRAL_API_KEY',\n configKey: 'mistral',\n defaultModel: 'mistral-small-latest',\n knownModels: ['mistral-large-latest', 'mistral-medium-latest', 'mistral-small-latest', 'codestral-latest', 'mistral-nemo'],\n supportsModelList: true,\n },\n {\n name: 'fireworks',\n displayName: 'Fireworks AI',\n defaultBaseUrl: 'https://api.fireworks.ai/inference/v1',\n envKey: 'FIREWORKS_API_KEY',\n configKey: 'fireworks',\n defaultModel: 'accounts/fireworks/models/llama-v3p3-70b-instruct',\n knownModels: ['accounts/fireworks/models/llama-v3p3-70b-instruct', 'accounts/fireworks/models/mixtral-8x7b-instruct', 'accounts/fireworks/models/qwen3-8b'],\n supportsModelList: true,\n },\n {\n name: 'xai',\n displayName: 'xAI (Grok)',\n defaultBaseUrl: 'https://api.x.ai/v1',\n envKey: 'XAI_API_KEY',\n configKey: 'xai',\n defaultModel: 'grok-3-fast',\n knownModels: ['grok-3', 'grok-3-fast', 'grok-3-mini', 'grok-3-mini-fast'],\n supportsModelList: true,\n },\n {\n name: 'together',\n displayName: 'Together AI',\n defaultBaseUrl: 'https://api.together.xyz/v1',\n envKey: 'TOGETHER_API_KEY',\n configKey: 'together',\n defaultModel: 'meta-llama/Llama-3.3-70B-Instruct-Turbo',\n knownModels: ['meta-llama/Llama-3.3-70B-Instruct-Turbo', 'deepseek-ai/DeepSeek-R1', 'Qwen/Qwen2.5-72B-Instruct-Turbo', 'mistralai/Mixtral-8x7B-Instruct-v0.1'],\n supportsModelList: true,\n },\n {\n name: 'deepseek',\n displayName: 'DeepSeek',\n defaultBaseUrl: 'https://api.deepseek.com/v1',\n envKey: 'DEEPSEEK_API_KEY',\n configKey: 'deepseek',\n defaultModel: 'deepseek-chat',\n knownModels: ['deepseek-chat', 'deepseek-reasoner'],\n supportsModelList: false,\n },\n {\n name: 'cerebras',\n displayName: 'Cerebras (Ultra-Fast)',\n defaultBaseUrl: 'https://api.cerebras.ai/v1',\n envKey: 'CEREBRAS_API_KEY',\n configKey: 'cerebras',\n defaultModel: 'llama-3.3-70b',\n knownModels: ['llama-3.3-70b', 'llama-3.1-8b', 'qwen-3-32b'],\n supportsModelList: true,\n },\n {\n name: 'cohere',\n displayName: 'Cohere',\n defaultBaseUrl: 'https://api.cohere.com/compatibility/v1',\n envKey: 'COHERE_API_KEY',\n configKey: 'cohere',\n defaultModel: 'command-r-plus',\n knownModels: ['command-r-plus', 'command-r', 'command-r7b'],\n supportsModelList: false,\n },\n {\n name: 'perplexity',\n displayName: 'Perplexity (Search-Augmented)',\n defaultBaseUrl: 'https://api.perplexity.ai',\n envKey: 'PERPLEXITY_API_KEY',\n configKey: 'perplexity',\n defaultModel: 'sonar',\n knownModels: ['sonar', 'sonar-pro', 'sonar-reasoning'],\n supportsModelList: false,\n },\n {\n name: 'venice',\n displayName: 'Venice AI (Privacy-First)',\n defaultBaseUrl: 'https://api.venice.ai/api/v1',\n envKey: 'VENICE_API_KEY',\n configKey: 'venice',\n defaultModel: 'llama-3.3-70b',\n knownModels: ['llama-3.3-70b', 'deepseek-r1-671b', 'qwen-2.5-vl-72b'],\n supportsModelList: true,\n },\n {\n name: 'bedrock',\n displayName: 'AWS Bedrock (via Proxy)',\n defaultBaseUrl: 'http://localhost:4000/v1',\n envKey: 'AWS_BEDROCK_API_KEY',\n configKey: 'bedrock',\n defaultModel: 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n knownModels: ['anthropic.claude-3-5-sonnet-20241022-v2:0', 'amazon.titan-text-premier-v1:0', 'meta.llama3-70b-instruct-v1:0'],\n supportsModelList: false,\n },\n {\n name: 'litellm',\n displayName: 'LiteLLM (Universal Proxy)',\n defaultBaseUrl: 'http://localhost:4000/v1',\n envKey: 'LITELLM_API_KEY',\n configKey: 'litellm',\n defaultModel: 'gpt-4o',\n knownModels: ['gpt-4o', 'claude-sonnet-4-20250514', 'gemini-2.5-flash'],\n supportsModelList: true,\n },\n // NOTE: Azure OpenAI uses custom endpoints (https://{resource}.openai.azure.com/openai/deployments/{model})\n // and requires api-version query param + api-key header instead of Bearer token.\n // Users must configure baseUrl to their Azure deployment endpoint.\n {\n name: 'azure',\n displayName: 'Azure OpenAI (Enterprise)',\n defaultBaseUrl: '',\n envKey: 'AZURE_OPENAI_API_KEY',\n configKey: 'azure',\n defaultModel: 'gpt-4o',\n knownModels: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'o1-preview'],\n supportsModelList: false,\n },\n {\n name: 'deepinfra',\n displayName: 'DeepInfra (Fast Inference)',\n defaultBaseUrl: 'https://api.deepinfra.com/v1/openai',\n envKey: 'DEEPINFRA_API_KEY',\n configKey: 'deepinfra',\n defaultModel: 'meta-llama/Llama-3.3-70B-Instruct',\n knownModels: ['meta-llama/Llama-3.3-70B-Instruct', 'mistralai/Mixtral-8x22B-Instruct-v0.1', 'Qwen/Qwen2.5-72B-Instruct', 'deepseek-ai/DeepSeek-R1'],\n supportsModelList: true,\n },\n {\n name: 'sambanova',\n displayName: 'SambaNova (Fast Inference)',\n defaultBaseUrl: 'https://api.sambanova.ai/v1',\n envKey: 'SAMBANOVA_API_KEY',\n configKey: 'sambanova',\n defaultModel: 'Meta-Llama-3.3-70B-Instruct',\n knownModels: ['Meta-Llama-3.3-70B-Instruct', 'DeepSeek-R1-Distill-Llama-70B', 'Qwen2.5-72B-Instruct'],\n supportsModelList: true,\n },\n {\n name: 'kimi',\n displayName: 'Kimi (Moonshot)',\n defaultBaseUrl: 'https://api.moonshot.ai/v1',\n envKey: 'MOONSHOT_API_KEY',\n configKey: 'kimi',\n defaultModel: 'kimi-k2.5',\n knownModels: ['kimi-k2.6', 'kimi-k2.5', 'kimi-k2', 'moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],\n supportsModelList: true,\n },\n {\n name: 'huggingface',\n displayName: 'Hugging Face Inference',\n defaultBaseUrl: 'https://api-inference.huggingface.co/v1',\n envKey: 'HF_API_KEY',\n configKey: 'huggingface',\n defaultModel: 'meta-llama/Llama-3.3-70B-Instruct',\n knownModels: ['meta-llama/Llama-3.3-70B-Instruct', 'mistralai/Mixtral-8x7B-Instruct-v0.1', 'Qwen/Qwen2.5-72B-Instruct', 'microsoft/Phi-3-medium-4k-instruct'],\n supportsModelList: true,\n },\n {\n name: 'ai21',\n displayName: 'AI21 Labs (Jamba)',\n defaultBaseUrl: 'https://api.ai21.com/studio/v1',\n envKey: 'AI21_API_KEY',\n configKey: 'ai21',\n defaultModel: 'jamba-1.5-large',\n knownModels: ['jamba-1.5-large', 'jamba-1.5-mini', 'jamba-instruct'],\n supportsModelList: false,\n },\n {\n name: 'cohere-v2',\n displayName: 'Cohere v2 (OpenAI-compat)',\n defaultBaseUrl: 'https://api.cohere.com/v2',\n envKey: 'COHERE_API_KEY',\n configKey: 'cohere-v2',\n defaultModel: 'command-a-03-2025',\n knownModels: ['command-a-03-2025', 'command-r-plus-08-2024', 'command-r-08-2024', 'command-r7b-12-2024'],\n supportsModelList: false,\n },\n {\n name: 'reka',\n displayName: 'Reka AI',\n defaultBaseUrl: 'https://api.reka.ai/v1',\n envKey: 'REKA_API_KEY',\n configKey: 'reka',\n defaultModel: 'reka-core',\n knownModels: ['reka-core', 'reka-flash', 'reka-edge'],\n supportsModelList: false,\n },\n {\n name: 'zhipu',\n displayName: 'Zhipu GLM',\n defaultBaseUrl: 'https://open.bigmodel.cn/api/paas/v4',\n envKey: 'ZHIPU_API_KEY',\n configKey: 'zhipu',\n defaultModel: 'glm-4-plus',\n knownModels: ['glm-4-plus', 'glm-4', 'glm-4-flash', 'glm-4-long'],\n supportsModelList: false,\n },\n {\n name: 'yi',\n displayName: '01.AI (Yi)',\n defaultBaseUrl: 'https://api.01.ai/v1',\n envKey: 'YI_API_KEY',\n configKey: 'yi',\n defaultModel: 'yi-large',\n knownModels: ['yi-large', 'yi-medium', 'yi-spark', 'yi-large-turbo'],\n supportsModelList: true,\n },\n {\n name: 'inflection',\n displayName: 'Inflection (Pi)',\n defaultBaseUrl: 'https://api.inflection.ai/v1',\n envKey: 'INFLECTION_API_KEY',\n configKey: 'inflection',\n defaultModel: 'inflection-3-pi',\n knownModels: ['inflection-3-pi', 'inflection-3-productivity'],\n supportsModelList: false,\n },\n {\n name: 'novita',\n displayName: 'Novita AI',\n defaultBaseUrl: 'https://api.novita.ai/v3/openai',\n envKey: 'NOVITA_API_KEY',\n configKey: 'novita',\n defaultModel: 'meta-llama/llama-3.3-70b-instruct',\n knownModels: ['meta-llama/llama-3.3-70b-instruct', 'deepseek/deepseek-r1', 'qwen/qwen-2.5-72b-instruct', 'mistralai/mistral-large-2411'],\n supportsModelList: true,\n },\n {\n name: 'replicate',\n displayName: 'Replicate',\n defaultBaseUrl: 'https://api.replicate.com/v1',\n envKey: 'REPLICATE_API_KEY',\n configKey: 'replicate',\n defaultModel: 'meta/meta-llama-3-70b-instruct',\n knownModels: ['meta/meta-llama-3-70b-instruct', 'mistralai/mixtral-8x7b-instruct-v0.1', 'meta/meta-llama-3.1-405b-instruct'],\n supportsModelList: false,\n },\n {\n name: 'lepton',\n displayName: 'Lepton AI',\n defaultBaseUrl: 'https://llama3-3-70b.lepton.run/api/v1',\n envKey: 'LEPTON_API_KEY',\n configKey: 'lepton',\n defaultModel: 'llama-3.3-70b',\n knownModels: ['llama-3.3-70b', 'mixtral-8x7b', 'qwen2.5-72b'],\n supportsModelList: false,\n },\n {\n name: 'anyscale',\n displayName: 'Anyscale Endpoints',\n defaultBaseUrl: 'https://api.endpoints.anyscale.com/v1',\n envKey: 'ANYSCALE_API_KEY',\n configKey: 'anyscale',\n defaultModel: 'meta-llama/Meta-Llama-3-70B-Instruct',\n knownModels: ['meta-llama/Meta-Llama-3-70B-Instruct', 'mistralai/Mixtral-8x7B-Instruct-v0.1', 'codellama/CodeLlama-70b-Instruct-hf'],\n supportsModelList: true,\n },\n {\n name: 'octo',\n displayName: 'OctoAI',\n defaultBaseUrl: 'https://text.octoai.run/v1',\n envKey: 'OCTOAI_API_KEY',\n configKey: 'octo',\n defaultModel: 'meta-llama-3.1-70b-instruct',\n knownModels: ['meta-llama-3.1-70b-instruct', 'mixtral-8x7b-instruct', 'qwen2.5-72b-instruct'],\n supportsModelList: true,\n },\n {\n name: 'nous',\n displayName: 'Nous Research (Hermes)',\n defaultBaseUrl: 'https://inference-api.nousresearch.com/v1',\n envKey: 'NOUS_API_KEY',\n configKey: 'nous',\n defaultModel: 'hermes-3-llama-3.1-70b',\n knownModels: ['hermes-3-llama-3.1-70b', 'hermes-3-llama-3.1-8b', 'hermes-2-pro-mistral-7b'],\n supportsModelList: false,\n },\n {\n name: 'openrouter',\n displayName: 'OpenRouter (Universal Gateway)',\n defaultBaseUrl: 'https://openrouter.ai/api/v1',\n envKey: 'OPENROUTER_API_KEY',\n configKey: 'openrouter',\n defaultModel: 'anthropic/claude-3.5-sonnet',\n knownModels: [\n 'anthropic/claude-3.5-sonnet',\n 'anthropic/claude-3.5-haiku',\n 'anthropic/claude-3-opus',\n 'openai/gpt-4o',\n 'openai/gpt-4o-mini',\n 'meta-llama/llama-3.3-70b-instruct',\n 'google/gemini-2.5-flash-preview',\n 'deepseek/deepseek-chat',\n 'deepseek/deepseek-r1',\n 'x-ai/grok-3-beta',\n 'nvidia/llama-3.1-nemotron-70b-instruct',\n ],\n supportsModelList: true,\n // OpenRouter's /api/v1/models is publicly accessible — TITAN can\n // pull the full ~365-model catalogue even before the user has\n // configured an OPENROUTER_API_KEY. Lets the picker show every\n // available model so the user can choose first, then add the key.\n publicModelList: true,\n extraHeaders: {\n 'HTTP-Referer': 'https://titan.local',\n 'X-Title': 'TITAN',\n },\n },\n {\n name: 'nvidia',\n displayName: 'NVIDIA NIM',\n defaultBaseUrl: 'https://integrate.api.nvidia.com/v1',\n envKey: 'NVIDIA_API_KEY',\n configKey: 'nvidia',\n defaultModel: 'nvidia/llama-3.3-nemotron-super-49b-v1',\n knownModels: [\n 'nvidia/llama-3.3-nemotron-super-49b-v1',\n 'nvidia/llama-3.3-nemotron-super-49b-v1.5',\n 'nvidia/llama-3.1-nemotron-ultra-253b-v1',\n 'nvidia/llama-3.1-nemotron-70b-instruct',\n 'nvidia/nemotron-3-nano-30b-a3b',\n 'nvidia/nemotron-3-super-120b-a12b',\n ],\n supportsModelList: true,\n keepModelPrefix: true,\n },\n {\n name: 'minimax',\n displayName: 'MiniMax',\n defaultBaseUrl: 'https://api.minimax.chat/v1',\n envKey: 'MINIMAX_API_KEY',\n configKey: 'minimax',\n defaultModel: 'minimax-m2.7',\n knownModels: [\n 'minimax-m2.7',\n 'minimax-m2.7-highspeed',\n 'minimax-m2.5',\n 'minimax-01',\n 'minimax-text-01',\n ],\n supportsModelList: false,\n },\n];\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/providers/openai_compat.ts"],"sourcesContent":["/**\n * TITAN — Generic OpenAI-Compatible Provider\n * A single provider class that works with any OpenAI-compatible API endpoint.\n * Used by: Groq, Mistral, OpenRouter, Fireworks, xAI, Together, DeepSeek,\n * Cerebras, Cohere, Perplexity, and any custom provider.\n */\nimport {\n LLMProvider,\n withTimeoutSignal,\n STREAM_FETCH_TIMEOUT_MS,\n type ChatOptions,\n type ChatResponse,\n type ChatStreamChunk,\n type ToolCall,\n} from './base.js';\nimport { loadConfig } from '../config/config.js';\nimport type { ProviderConfig } from '../config/schema.js';\nimport logger from '../utils/logger.js';\nimport { fetchWithRetry } from '../utils/helpers.js';\nimport { resolveApiKey } from './authResolver.js';\nimport { v4 as uuid } from 'uuid';\nimport { clampMaxTokens } from './modelCapabilities.js';\n// Reuse the Ollama provider's battle-tested per-model tool-behavior registry\n// (selfSelectsTools/etc.) so cloud models routed through this GENERIC provider\n// get the same model-agnostic treatment instead of a blind passthrough.\nimport { getModelCapabilities as getToolCapabilities } from './ollama.js';\n\n/**\n * Apply model-agnostic tool / structured-output controls to an OpenAI-compatible\n * request body. Without this, this provider (which fronts ~24 backends incl.\n * DeepSeek/Qwen/GLM/Kimi/MiniMax/xAI) silently ignores forceToolUse and format —\n * so weak-self-selecting models answer in prose instead of calling the tool.\n */\nfunction applyCompatToolControls(body: Record<string, unknown>, model: string, options: ChatOptions): void {\n // forceToolUse → tool_choice:'required', but ONLY for models that don't\n // self-select tools well (forcing a self-selecting model wastes a turn), and\n // NEVER for a DeepSeek reasoner with thinking on — that combo is rejected\n // with HTTP 400 by the reasoner endpoint (vllm #41132 / pydantic-ai #5193).\n const tools = body.tools as unknown[] | undefined;\n if (options.forceToolUse && Array.isArray(tools) && tools.length > 0) {\n const isDeepseekReasoner = /deepseek/i.test(model) && options.thinking === true;\n if (!isDeepseekReasoner && !getToolCapabilities(model).selfSelectsTools) {\n body.tool_choice = 'required';\n }\n }\n // format → native JSON mode + an anti-truncation floor (truncated/empty JSON\n // is a common failure mode; json_object is the universally-supported shape).\n if (options.format === 'json' || (options.format && typeof options.format === 'object')) {\n body.response_format = { type: 'json_object' };\n if (typeof body.max_tokens === 'number' && body.max_tokens < 2048) body.max_tokens = 2048;\n }\n}\n\n/**\n * Parse the model's REAL token ceiling out of a \"max_tokens too large\" 400.\n * Deployments cap a model below our static table (e.g. a vLLM behind LiteLLM with\n * max_total_tokens=12288), so a static maxOutput can't be trusted — we adapt to\n * what the deployment actually allows. Returns null if it's not that error.\n * Examples handled:\n * vLLM: \"max_tokens=32768 cannot be greater than max_model_len=max_total_tokens=12288\"\n * OpenAI:\"maximum context length is 8192 tokens\"\n */\nexport function parseMaxTokenLimit(errText: string): number | null {\n const m = errText.match(/max_model_len=(?:max_total_tokens=)?(\\d+)|max_total_tokens=(\\d+)|maximum context length is (\\d+)/i);\n if (!m) return null;\n const n = Number(m[1] || m[2] || m[3]);\n return Number.isFinite(n) && n > 0 ? n : null;\n}\n\n/**\n * Strict backends (vLLM/llama-swap with some chat templates) reject any\n * system message that isn't the first message (\"System message must be at\n * the beginning\"). TITAN legitimately injects mid-conversation system notes\n * (task continuation, approvals) — convert those to user-role context notes\n * so the timeline is preserved and every OpenAI-compatible backend accepts\n * the conversation. The leading system message is untouched.\n */\nexport function normalizeSystemPlacement<T extends { role: string; content: string }>(messages: T[]): T[] {\n return messages.map((m, i) => {\n if (m.role === 'system' && i > 0) {\n return { ...m, role: 'user', content: `[System note]\\n${m.content}` };\n }\n return m;\n });\n}\n\n/** Configuration for an OpenAI-compatible provider */\nexport interface OpenAICompatConfig {\n /** Internal provider name (e.g. 'groq') */\n name: string;\n /** Display name shown to users (e.g. 'Groq (Fast Inference)') */\n displayName: string;\n /** Default API base URL */\n defaultBaseUrl: string;\n /** Environment variable name for the API key */\n envKey: string;\n /** Config key name in titan.json providers section */\n configKey: string;\n /** Default model ID */\n defaultModel: string;\n /** Static model list (returned when health check fails) */\n knownModels: string[];\n /** Extra headers to send with every request */\n extraHeaders?: Record<string, string>;\n /** Whether to fetch models from /v1/models endpoint */\n supportsModelList?: boolean;\n /**\n * The /models catalogue is publicly accessible (no API key required).\n * When true, listModels() will fetch the catalogue even when the user\n * has not configured an API key — useful for picker UIs that want to\n * show the full catalogue before the user has chosen / paid for a key.\n * OpenRouter is the canonical example.\n */\n publicModelList?: boolean;\n /** Keep org/ prefix in model name (e.g. NIM API expects 'nvidia/model-name') */\n keepModelPrefix?: boolean;\n}\n\nexport class OpenAICompatProvider extends LLMProvider {\n readonly name: string;\n readonly displayName: string;\n private readonly config: OpenAICompatConfig;\n\n constructor(config: OpenAICompatConfig) {\n super();\n this.name = config.name;\n this.displayName = config.displayName;\n this.config = config;\n }\n\n private get apiKey(): string {\n const cfg = loadConfig();\n const providerCfg = (cfg.providers as Record<string, unknown>)[this.config.configKey] as ProviderConfig | undefined;\n return resolveApiKey(this.config.name, providerCfg?.authProfiles || [], providerCfg?.apiKey || '', this.config.envKey, providerCfg?.rotationStrategy, providerCfg?.credentialCooldownMs);\n }\n\n private get baseUrl(): string {\n const cfg = loadConfig();\n const providerCfg = (cfg.providers as Record<string, unknown>)[this.config.configKey] as ProviderConfig | undefined;\n return providerCfg?.baseUrl || this.config.defaultBaseUrl;\n }\n\n /** Sanitize messages for strict APIs (e.g., NIM) that reject empty content strings */\n private sanitizeMessages(messages: ChatOptions['messages']): ChatOptions['messages'] {\n return messages.map(m => ({\n ...m,\n content: m.content || (m.role === 'assistant' && m.toolCalls ? '' : ' '),\n }));\n }\n\n async chat(options: ChatOptions): Promise<ChatResponse> {\n const rawModel = options.model || this.config.defaultModel;\n // NIM API requires org/model format — keep prefix as-is or add it\n const model = this.config.keepModelPrefix\n ? (rawModel.includes('/') ? rawModel : `${this.name}/${rawModel}`)\n : rawModel.replace(`${this.name}/`, '');\n\n // Kimi API uses dash model IDs (kimi-k2-6) but TITAN uses dots (kimi-k2.6)\n const apiModel = this.config.configKey === 'kimi'\n ? model.replace(/kimi-k2\\.6/g, 'kimi-k2-6').replace(/kimi-k2\\.5/g, 'kimi-k2-5')\n : model;\n const apiKey = this.apiKey;\n if (!apiKey) throw new Error(`${this.displayName} API key not configured (set ${this.config.envKey} or providers.${this.config.configKey}.apiKey)`);\n\n logger.debug(this.name, `Chat request: model=${model}, messages=${options.messages.length}`);\n\n const sanitized = normalizeSystemPlacement(this.sanitizeMessages(options.messages));\n const body: Record<string, unknown> = {\n model: apiModel,\n messages: sanitized.map((m) => {\n if (m.role === 'tool') {\n return { role: 'tool', content: m.content || ' ', tool_call_id: m.toolCallId };\n }\n if (m.role === 'assistant' && m.toolCalls) {\n return {\n role: 'assistant',\n content: m.content || null,\n tool_calls: m.toolCalls.map((tc) => ({\n id: tc.id,\n type: 'function',\n function: { name: tc.function.name, arguments: tc.function.arguments },\n })),\n };\n }\n return { role: m.role, content: m.content || ' ' };\n }),\n max_tokens: clampMaxTokens(model, options.maxTokens),\n };\n\n if (options.tools && options.tools.length > 0) {\n body.tools = options.tools;\n }\n applyCompatToolControls(body, model, options);\n\n if (options.temperature !== undefined) {\n body.temperature = options.temperature;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n ...(this.config.extraHeaders || {}),\n };\n\n const doFetch = () => fetchWithRetry(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n let response = await doFetch();\n\n // Adaptive max_tokens (model-agnostic): if the deployment caps this model\n // below the max_tokens we requested, it 400s with the real limit. Reduce\n // and retry ONCE so a too-high static ceiling never hard-fails a model.\n if (!response.ok && response.status === 400 && typeof body.max_tokens === 'number') {\n const errText = await response.text();\n const limit = parseMaxTokenLimit(errText);\n if (limit && (body.max_tokens as number) > limit) {\n // v7.1: remember this deployment's real ceiling so tool-tier\n // selection and future requests fit it without a 400 first.\n const { recordLearnedContextWindow } = await import('./modelCapabilities.js');\n recordLearnedContextWindow(model, limit);\n body.max_tokens = Math.max(512, Math.min(Math.floor(limit / 3), 4096)); // leave room for input\n logger.warn(this.name, `[AdaptiveMaxTokens] ${model} deployment caps total tokens at ${limit}; retrying with max_tokens=${body.max_tokens}`);\n response = await doFetch();\n } else {\n const { createProviderError } = await import('./errorTaxonomy.js');\n throw createProviderError(`${this.displayName} API`, response, errText, { provider: this.name, model });\n }\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n // Hunt Finding #37: attach status + Retry-After so the router can respect backoff\n const { createProviderError } = await import('./errorTaxonomy.js');\n throw createProviderError(`${this.displayName} API`, response, errorText, { provider: this.name, model });\n }\n\n const data = await response.json() as Record<string, unknown>;\n const choices = data.choices as Array<Record<string, unknown>> | undefined;\n\n if (!choices || choices.length === 0) {\n return {\n id: (data.id as string) || uuid(),\n content: '',\n usage: undefined,\n finishReason: 'stop',\n model: model.includes('/') ? model : `${this.name}/${model}`,\n };\n }\n\n const choice = choices[0];\n const message = choice.message as Record<string, unknown>;\n\n const toolCalls: ToolCall[] = [];\n if (message.tool_calls) {\n for (const tc of message.tool_calls as Array<Record<string, unknown>>) {\n const fn = tc.function as Record<string, string>;\n toolCalls.push({\n id: (tc.id as string) || uuid(),\n type: 'function',\n function: { name: fn.name, arguments: fn.arguments },\n });\n }\n }\n\n const usage = data.usage as { prompt_tokens: number; completion_tokens: number; total_tokens: number } | undefined;\n\n return {\n id: (data.id as string) || uuid(),\n content: (message.content as string) || '',\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage: usage\n ? {\n promptTokens: usage.prompt_tokens,\n completionTokens: usage.completion_tokens,\n totalTokens: usage.total_tokens,\n }\n : undefined,\n finishReason: toolCalls.length > 0 ? 'tool_calls' : (choice.finish_reason as 'stop' | 'length') || 'stop',\n model: model.includes('/') ? model : `${this.name}/${model}`,\n };\n }\n\n async *chatStream(options: ChatOptions): AsyncGenerator<ChatStreamChunk> {\n const rawModel = options.model || this.config.defaultModel;\n const model = this.config.keepModelPrefix\n ? (rawModel.includes('/') ? rawModel : `${this.name}/${rawModel}`)\n : rawModel.replace(`${this.name}/`, '');\n const apiKey = this.apiKey;\n if (!apiKey) { yield { type: 'error', error: `${this.displayName} API key not configured` }; return; }\n\n const sanitized = normalizeSystemPlacement(this.sanitizeMessages(options.messages));\n const body: Record<string, unknown> = {\n model,\n stream: true,\n messages: sanitized.map((m) => {\n if (m.role === 'tool') return { role: 'tool', content: m.content || ' ', tool_call_id: m.toolCallId };\n if (m.role === 'assistant' && m.toolCalls) {\n return {\n role: 'assistant', content: m.content || null,\n tool_calls: m.toolCalls.map((tc) => ({ id: tc.id, type: 'function', function: { name: tc.function.name, arguments: tc.function.arguments } })),\n };\n }\n return { role: m.role, content: m.content || ' ' };\n }),\n max_tokens: clampMaxTokens(model, options.maxTokens),\n };\n if (options.tools && options.tools.length > 0) body.tools = options.tools;\n applyCompatToolControls(body, model, options);\n if (options.temperature !== undefined) body.temperature = options.temperature;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n ...(this.config.extraHeaders || {}),\n };\n\n try {\n const response = await fetch(`${this.baseUrl}/chat/completions`, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: withTimeoutSignal(options.signal, STREAM_FETCH_TIMEOUT_MS),\n });\n\n if (!response.ok || !response.body) {\n const errorText = await response.text();\n // v6.5 — THROW (not yield) so the router routes HTTP errors through\n // retry / fallback chain / circuit breaker, like non-streaming chat().\n const { createProviderError } = await import('./errorTaxonomy.js');\n throw createProviderError(this.displayName, response, errorText, { provider: this.name, model });\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n const toolCalls = new Map<number, { id: string; name: string; args: string }>();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue;\n const json = line.slice(6).trim();\n if (json === '[DONE]' || !json) continue;\n try {\n const chunk = JSON.parse(json);\n const delta = chunk.choices?.[0]?.delta;\n if (!delta) continue;\n if (delta.content) yield { type: 'text', content: delta.content };\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index ?? 0;\n if (!toolCalls.has(idx)) toolCalls.set(idx, { id: tc.id || '', name: '', args: '' });\n const entry = toolCalls.get(idx)!;\n if (tc.id) entry.id = tc.id;\n if (tc.function?.name) entry.name = tc.function.name;\n if (tc.function?.arguments) entry.args += tc.function.arguments;\n }\n }\n } catch { /* skip malformed SSE lines */ }\n }\n }\n\n for (const [, tc] of toolCalls) {\n if (tc.id && tc.name) {\n yield { type: 'tool_call', toolCall: { id: tc.id, type: 'function', function: { name: tc.name, arguments: tc.args || '{}' } } };\n }\n }\n yield { type: 'done' };\n } catch (error) {\n yield { type: 'error', error: (error as Error).message };\n }\n }\n\n async listModels(): Promise<string[]> {\n if (!this.config.supportsModelList) {\n return this.config.knownModels;\n }\n\n // Some upstream catalogues are public (no auth needed) — those\n // providers set `publicModelList: true` so the picker can show\n // the full catalogue even before the user configures a key.\n // OpenRouter is the canonical example (~365 models, no key).\n const isPublic = this.config.publicModelList === true;\n if (!isPublic && !this.apiKey) {\n return this.config.knownModels;\n }\n\n try {\n const headers: Record<string, string> = {\n ...(this.config.extraHeaders || {}),\n };\n if (this.apiKey) headers['Authorization'] = `Bearer ${this.apiKey}`;\n const response = await fetch(`${this.baseUrl}/models`, {\n headers,\n signal: AbortSignal.timeout(8000),\n });\n if (!response.ok) return this.config.knownModels;\n const data = await response.json() as { data?: Array<{ id: string }> };\n const ids = (data.data || []).map((m) => m.id).filter(Boolean);\n // Sort alphabetically for stable UX (the catalogue is\n // already typically grouped by family).\n ids.sort();\n return ids.length > 0 ? ids : this.config.knownModels;\n } catch {\n return this.config.knownModels;\n }\n }\n\n isConfigured(): boolean {\n return !!this.apiKey;\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n if (!this.apiKey) return false;\n const response = await fetch(`${this.baseUrl}/models`, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n ...(this.config.extraHeaders || {}),\n },\n signal: AbortSignal.timeout(5000),\n });\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n\n// ── Provider Presets ──────────────────────────────────────────────\n\nexport const PROVIDER_PRESETS: OpenAICompatConfig[] = [\n {\n name: 'groq',\n displayName: 'Groq (Fast Inference)',\n defaultBaseUrl: 'https://api.groq.com/openai/v1',\n envKey: 'GROQ_API_KEY',\n configKey: 'groq',\n defaultModel: 'llama-3.3-70b-versatile',\n knownModels: ['llama-3.3-70b-versatile', 'llama-3.1-8b-instant', 'mixtral-8x7b-32768', 'gemma2-9b-it', 'deepseek-r1-distill-llama-70b'],\n supportsModelList: true,\n },\n {\n name: 'mistral',\n displayName: 'Mistral AI',\n defaultBaseUrl: 'https://api.mistral.ai/v1',\n envKey: 'MISTRAL_API_KEY',\n configKey: 'mistral',\n defaultModel: 'mistral-small-latest',\n knownModels: ['mistral-large-latest', 'mistral-medium-latest', 'mistral-small-latest', 'codestral-latest', 'mistral-nemo'],\n supportsModelList: true,\n },\n {\n name: 'fireworks',\n displayName: 'Fireworks AI',\n defaultBaseUrl: 'https://api.fireworks.ai/inference/v1',\n envKey: 'FIREWORKS_API_KEY',\n configKey: 'fireworks',\n defaultModel: 'accounts/fireworks/models/llama-v3p3-70b-instruct',\n knownModels: ['accounts/fireworks/models/llama-v3p3-70b-instruct', 'accounts/fireworks/models/mixtral-8x7b-instruct', 'accounts/fireworks/models/qwen3-8b'],\n supportsModelList: true,\n },\n {\n name: 'xai',\n displayName: 'xAI (Grok)',\n defaultBaseUrl: 'https://api.x.ai/v1',\n envKey: 'XAI_API_KEY',\n configKey: 'xai',\n defaultModel: 'grok-3-fast',\n knownModels: ['grok-3', 'grok-3-fast', 'grok-3-mini', 'grok-3-mini-fast'],\n supportsModelList: true,\n },\n {\n name: 'together',\n displayName: 'Together AI',\n defaultBaseUrl: 'https://api.together.xyz/v1',\n envKey: 'TOGETHER_API_KEY',\n configKey: 'together',\n defaultModel: 'meta-llama/Llama-3.3-70B-Instruct-Turbo',\n knownModels: ['meta-llama/Llama-3.3-70B-Instruct-Turbo', 'deepseek-ai/DeepSeek-R1', 'Qwen/Qwen2.5-72B-Instruct-Turbo', 'mistralai/Mixtral-8x7B-Instruct-v0.1'],\n supportsModelList: true,\n },\n {\n name: 'deepseek',\n displayName: 'DeepSeek',\n defaultBaseUrl: 'https://api.deepseek.com/v1',\n envKey: 'DEEPSEEK_API_KEY',\n configKey: 'deepseek',\n defaultModel: 'deepseek-chat',\n knownModels: ['deepseek-chat', 'deepseek-reasoner'],\n supportsModelList: false,\n },\n {\n name: 'cerebras',\n displayName: 'Cerebras (Ultra-Fast)',\n defaultBaseUrl: 'https://api.cerebras.ai/v1',\n envKey: 'CEREBRAS_API_KEY',\n configKey: 'cerebras',\n defaultModel: 'llama-3.3-70b',\n knownModels: ['llama-3.3-70b', 'llama-3.1-8b', 'qwen-3-32b'],\n supportsModelList: true,\n },\n {\n name: 'cohere',\n displayName: 'Cohere',\n defaultBaseUrl: 'https://api.cohere.com/compatibility/v1',\n envKey: 'COHERE_API_KEY',\n configKey: 'cohere',\n defaultModel: 'command-r-plus',\n knownModels: ['command-r-plus', 'command-r', 'command-r7b'],\n supportsModelList: false,\n },\n {\n name: 'perplexity',\n displayName: 'Perplexity (Search-Augmented)',\n defaultBaseUrl: 'https://api.perplexity.ai',\n envKey: 'PERPLEXITY_API_KEY',\n configKey: 'perplexity',\n defaultModel: 'sonar',\n knownModels: ['sonar', 'sonar-pro', 'sonar-reasoning'],\n supportsModelList: false,\n },\n {\n name: 'venice',\n displayName: 'Venice AI (Privacy-First)',\n defaultBaseUrl: 'https://api.venice.ai/api/v1',\n envKey: 'VENICE_API_KEY',\n configKey: 'venice',\n defaultModel: 'llama-3.3-70b',\n knownModels: ['llama-3.3-70b', 'deepseek-r1-671b', 'qwen-2.5-vl-72b'],\n supportsModelList: true,\n },\n {\n name: 'bedrock',\n displayName: 'AWS Bedrock (via Proxy)',\n defaultBaseUrl: 'http://localhost:4000/v1',\n envKey: 'AWS_BEDROCK_API_KEY',\n configKey: 'bedrock',\n defaultModel: 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n knownModels: ['anthropic.claude-3-5-sonnet-20241022-v2:0', 'amazon.titan-text-premier-v1:0', 'meta.llama3-70b-instruct-v1:0'],\n supportsModelList: false,\n },\n {\n name: 'litellm',\n displayName: 'LiteLLM (Universal Proxy)',\n defaultBaseUrl: 'http://localhost:4000/v1',\n envKey: 'LITELLM_API_KEY',\n configKey: 'litellm',\n defaultModel: 'gpt-4o',\n knownModels: ['gpt-4o', 'claude-sonnet-4-20250514', 'gemini-2.5-flash'],\n supportsModelList: true,\n },\n // NOTE: Azure OpenAI uses custom endpoints (https://{resource}.openai.azure.com/openai/deployments/{model})\n // and requires api-version query param + api-key header instead of Bearer token.\n // Users must configure baseUrl to their Azure deployment endpoint.\n {\n name: 'azure',\n displayName: 'Azure OpenAI (Enterprise)',\n defaultBaseUrl: '',\n envKey: 'AZURE_OPENAI_API_KEY',\n configKey: 'azure',\n defaultModel: 'gpt-4o',\n knownModels: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'o1-preview'],\n supportsModelList: false,\n },\n {\n name: 'deepinfra',\n displayName: 'DeepInfra (Fast Inference)',\n defaultBaseUrl: 'https://api.deepinfra.com/v1/openai',\n envKey: 'DEEPINFRA_API_KEY',\n configKey: 'deepinfra',\n defaultModel: 'meta-llama/Llama-3.3-70B-Instruct',\n knownModels: ['meta-llama/Llama-3.3-70B-Instruct', 'mistralai/Mixtral-8x22B-Instruct-v0.1', 'Qwen/Qwen2.5-72B-Instruct', 'deepseek-ai/DeepSeek-R1'],\n supportsModelList: true,\n },\n {\n name: 'sambanova',\n displayName: 'SambaNova (Fast Inference)',\n defaultBaseUrl: 'https://api.sambanova.ai/v1',\n envKey: 'SAMBANOVA_API_KEY',\n configKey: 'sambanova',\n defaultModel: 'Meta-Llama-3.3-70B-Instruct',\n knownModels: ['Meta-Llama-3.3-70B-Instruct', 'DeepSeek-R1-Distill-Llama-70B', 'Qwen2.5-72B-Instruct'],\n supportsModelList: true,\n },\n {\n name: 'kimi',\n displayName: 'Kimi (Moonshot)',\n defaultBaseUrl: 'https://api.moonshot.ai/v1',\n envKey: 'MOONSHOT_API_KEY',\n configKey: 'kimi',\n defaultModel: 'kimi-k2.5',\n knownModels: ['kimi-k2.6', 'kimi-k2.5', 'kimi-k2', 'moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],\n supportsModelList: true,\n },\n {\n name: 'huggingface',\n displayName: 'Hugging Face Inference',\n defaultBaseUrl: 'https://api-inference.huggingface.co/v1',\n envKey: 'HF_API_KEY',\n configKey: 'huggingface',\n defaultModel: 'meta-llama/Llama-3.3-70B-Instruct',\n knownModels: ['meta-llama/Llama-3.3-70B-Instruct', 'mistralai/Mixtral-8x7B-Instruct-v0.1', 'Qwen/Qwen2.5-72B-Instruct', 'microsoft/Phi-3-medium-4k-instruct'],\n supportsModelList: true,\n },\n {\n name: 'ai21',\n displayName: 'AI21 Labs (Jamba)',\n defaultBaseUrl: 'https://api.ai21.com/studio/v1',\n envKey: 'AI21_API_KEY',\n configKey: 'ai21',\n defaultModel: 'jamba-1.5-large',\n knownModels: ['jamba-1.5-large', 'jamba-1.5-mini', 'jamba-instruct'],\n supportsModelList: false,\n },\n {\n name: 'cohere-v2',\n displayName: 'Cohere v2 (OpenAI-compat)',\n defaultBaseUrl: 'https://api.cohere.com/v2',\n envKey: 'COHERE_API_KEY',\n configKey: 'cohere-v2',\n defaultModel: 'command-a-03-2025',\n knownModels: ['command-a-03-2025', 'command-r-plus-08-2024', 'command-r-08-2024', 'command-r7b-12-2024'],\n supportsModelList: false,\n },\n {\n name: 'reka',\n displayName: 'Reka AI',\n defaultBaseUrl: 'https://api.reka.ai/v1',\n envKey: 'REKA_API_KEY',\n configKey: 'reka',\n defaultModel: 'reka-core',\n knownModels: ['reka-core', 'reka-flash', 'reka-edge'],\n supportsModelList: false,\n },\n {\n name: 'zhipu',\n displayName: 'Zhipu GLM',\n defaultBaseUrl: 'https://open.bigmodel.cn/api/paas/v4',\n envKey: 'ZHIPU_API_KEY',\n configKey: 'zhipu',\n defaultModel: 'glm-4-plus',\n knownModels: ['glm-4-plus', 'glm-4', 'glm-4-flash', 'glm-4-long'],\n supportsModelList: false,\n },\n {\n name: 'yi',\n displayName: '01.AI (Yi)',\n defaultBaseUrl: 'https://api.01.ai/v1',\n envKey: 'YI_API_KEY',\n configKey: 'yi',\n defaultModel: 'yi-large',\n knownModels: ['yi-large', 'yi-medium', 'yi-spark', 'yi-large-turbo'],\n supportsModelList: true,\n },\n {\n name: 'inflection',\n displayName: 'Inflection (Pi)',\n defaultBaseUrl: 'https://api.inflection.ai/v1',\n envKey: 'INFLECTION_API_KEY',\n configKey: 'inflection',\n defaultModel: 'inflection-3-pi',\n knownModels: ['inflection-3-pi', 'inflection-3-productivity'],\n supportsModelList: false,\n },\n {\n name: 'novita',\n displayName: 'Novita AI',\n defaultBaseUrl: 'https://api.novita.ai/v3/openai',\n envKey: 'NOVITA_API_KEY',\n configKey: 'novita',\n defaultModel: 'meta-llama/llama-3.3-70b-instruct',\n knownModels: ['meta-llama/llama-3.3-70b-instruct', 'deepseek/deepseek-r1', 'qwen/qwen-2.5-72b-instruct', 'mistralai/mistral-large-2411'],\n supportsModelList: true,\n },\n {\n name: 'replicate',\n displayName: 'Replicate',\n defaultBaseUrl: 'https://api.replicate.com/v1',\n envKey: 'REPLICATE_API_KEY',\n configKey: 'replicate',\n defaultModel: 'meta/meta-llama-3-70b-instruct',\n knownModels: ['meta/meta-llama-3-70b-instruct', 'mistralai/mixtral-8x7b-instruct-v0.1', 'meta/meta-llama-3.1-405b-instruct'],\n supportsModelList: false,\n },\n {\n name: 'lepton',\n displayName: 'Lepton AI',\n defaultBaseUrl: 'https://llama3-3-70b.lepton.run/api/v1',\n envKey: 'LEPTON_API_KEY',\n configKey: 'lepton',\n defaultModel: 'llama-3.3-70b',\n knownModels: ['llama-3.3-70b', 'mixtral-8x7b', 'qwen2.5-72b'],\n supportsModelList: false,\n },\n {\n name: 'anyscale',\n displayName: 'Anyscale Endpoints',\n defaultBaseUrl: 'https://api.endpoints.anyscale.com/v1',\n envKey: 'ANYSCALE_API_KEY',\n configKey: 'anyscale',\n defaultModel: 'meta-llama/Meta-Llama-3-70B-Instruct',\n knownModels: ['meta-llama/Meta-Llama-3-70B-Instruct', 'mistralai/Mixtral-8x7B-Instruct-v0.1', 'codellama/CodeLlama-70b-Instruct-hf'],\n supportsModelList: true,\n },\n {\n name: 'octo',\n displayName: 'OctoAI',\n defaultBaseUrl: 'https://text.octoai.run/v1',\n envKey: 'OCTOAI_API_KEY',\n configKey: 'octo',\n defaultModel: 'meta-llama-3.1-70b-instruct',\n knownModels: ['meta-llama-3.1-70b-instruct', 'mixtral-8x7b-instruct', 'qwen2.5-72b-instruct'],\n supportsModelList: true,\n },\n {\n name: 'nous',\n displayName: 'Nous Research (Hermes)',\n defaultBaseUrl: 'https://inference-api.nousresearch.com/v1',\n envKey: 'NOUS_API_KEY',\n configKey: 'nous',\n defaultModel: 'hermes-3-llama-3.1-70b',\n knownModels: ['hermes-3-llama-3.1-70b', 'hermes-3-llama-3.1-8b', 'hermes-2-pro-mistral-7b'],\n supportsModelList: false,\n },\n {\n name: 'openrouter',\n displayName: 'OpenRouter (Universal Gateway)',\n defaultBaseUrl: 'https://openrouter.ai/api/v1',\n envKey: 'OPENROUTER_API_KEY',\n configKey: 'openrouter',\n defaultModel: 'anthropic/claude-3.5-sonnet',\n knownModels: [\n 'anthropic/claude-3.5-sonnet',\n 'anthropic/claude-3.5-haiku',\n 'anthropic/claude-3-opus',\n 'openai/gpt-4o',\n 'openai/gpt-4o-mini',\n 'meta-llama/llama-3.3-70b-instruct',\n 'google/gemini-2.5-flash-preview',\n 'deepseek/deepseek-chat',\n 'deepseek/deepseek-r1',\n 'x-ai/grok-3-beta',\n 'nvidia/llama-3.1-nemotron-70b-instruct',\n ],\n supportsModelList: true,\n // OpenRouter's /api/v1/models is publicly accessible — TITAN can\n // pull the full ~365-model catalogue even before the user has\n // configured an OPENROUTER_API_KEY. Lets the picker show every\n // available model so the user can choose first, then add the key.\n publicModelList: true,\n extraHeaders: {\n 'HTTP-Referer': 'https://titan.local',\n 'X-Title': 'TITAN',\n },\n },\n {\n name: 'nvidia',\n displayName: 'NVIDIA NIM',\n defaultBaseUrl: 'https://integrate.api.nvidia.com/v1',\n envKey: 'NVIDIA_API_KEY',\n configKey: 'nvidia',\n defaultModel: 'nvidia/llama-3.3-nemotron-super-49b-v1',\n knownModels: [\n 'nvidia/llama-3.3-nemotron-super-49b-v1',\n 'nvidia/llama-3.3-nemotron-super-49b-v1.5',\n 'nvidia/llama-3.1-nemotron-ultra-253b-v1',\n 'nvidia/llama-3.1-nemotron-70b-instruct',\n 'nvidia/nemotron-3-nano-30b-a3b',\n 'nvidia/nemotron-3-super-120b-a12b',\n ],\n supportsModelList: true,\n keepModelPrefix: true,\n },\n {\n name: 'minimax',\n displayName: 'MiniMax',\n defaultBaseUrl: 'https://api.minimax.chat/v1',\n envKey: 'MINIMAX_API_KEY',\n configKey: 'minimax',\n defaultModel: 'minimax-m2.7',\n knownModels: [\n 'minimax-m2.7',\n 'minimax-m2.7-highspeed',\n 'minimax-m2.5',\n 'minimax-01',\n 'minimax-text-01',\n ],\n supportsModelList: false,\n },\n];\n"],"mappings":"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","names":[]}
@@ -5,6 +5,7 @@ import { OpenAIProvider } from "./openai.js";
5
5
  import { GoogleProvider } from "./google.js";
6
6
  import { OllamaProvider } from "./ollama.js";
7
7
  import { ClaudeCodeProvider } from "./claudeCode.js";
8
+ import { MoaProvider } from "./moa.js";
8
9
  import { OpenAICompatProvider, PROVIDER_PRESETS } from "./openai_compat.js";
9
10
  import { StubProvider, shouldUseStubProvider } from "./stub.js";
10
11
  import { loadConfig } from "../config/config.js";
@@ -111,6 +112,7 @@ function initProviders() {
111
112
  providers.set("google", new GoogleProvider());
112
113
  providers.set("ollama", new OllamaProvider());
113
114
  providers.set("claude-code", new ClaudeCodeProvider());
115
+ providers.set("moa", new MoaProvider());
114
116
  if (shouldUseStubProvider()) {
115
117
  providers.set("stub", new StubProvider());
116
118
  }
@@ -228,7 +230,7 @@ setInterval(() => {
228
230
  circuitBreakers.delete(name);
229
231
  }
230
232
  }
231
- }, 3e5);
233
+ }, 3e5).unref();
232
234
  const MIN_PROBE_INTERVAL_MS = 3e4;
233
235
  const providerRateLimitCooldowns = /* @__PURE__ */ new Map();
234
236
  const RETRY_AFTER_FALLBACK_THRESHOLD_MS = 15e3;