@nexus-cortex/core 4.26.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 (1276) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +2 -0
  3. package/README.md +13 -0
  4. package/dist/adapters/AdapterRegistry.d.ts +118 -0
  5. package/dist/adapters/AdapterRegistry.d.ts.map +1 -0
  6. package/dist/adapters/AdapterRegistry.js +195 -0
  7. package/dist/adapters/AdapterRegistry.js.map +1 -0
  8. package/dist/adapters/ChatCompletionsAPIAdapter.d.ts +254 -0
  9. package/dist/adapters/ChatCompletionsAPIAdapter.d.ts.map +1 -0
  10. package/dist/adapters/ChatCompletionsAPIAdapter.js +531 -0
  11. package/dist/adapters/ChatCompletionsAPIAdapter.js.map +1 -0
  12. package/dist/adapters/FormatAdapter.interface.d.ts +66 -0
  13. package/dist/adapters/FormatAdapter.interface.d.ts.map +1 -0
  14. package/dist/adapters/FormatAdapter.interface.js +89 -0
  15. package/dist/adapters/FormatAdapter.interface.js.map +1 -0
  16. package/dist/adapters/GatewayTranslationLayer.d.ts +222 -0
  17. package/dist/adapters/GatewayTranslationLayer.d.ts.map +1 -0
  18. package/dist/adapters/GatewayTranslationLayer.js +679 -0
  19. package/dist/adapters/GatewayTranslationLayer.js.map +1 -0
  20. package/dist/adapters/GenerateContentAPIAdapter.d.ts +240 -0
  21. package/dist/adapters/GenerateContentAPIAdapter.d.ts.map +1 -0
  22. package/dist/adapters/GenerateContentAPIAdapter.js +489 -0
  23. package/dist/adapters/GenerateContentAPIAdapter.js.map +1 -0
  24. package/dist/adapters/GoogleGenAPIAdapter.d.ts +217 -0
  25. package/dist/adapters/GoogleGenAPIAdapter.d.ts.map +1 -0
  26. package/dist/adapters/GoogleGenAPIAdapter.js +310 -0
  27. package/dist/adapters/GoogleGenAPIAdapter.js.map +1 -0
  28. package/dist/adapters/MessagesAPIAdapter.d.ts +280 -0
  29. package/dist/adapters/MessagesAPIAdapter.d.ts.map +1 -0
  30. package/dist/adapters/MessagesAPIAdapter.js +586 -0
  31. package/dist/adapters/MessagesAPIAdapter.js.map +1 -0
  32. package/dist/adapters/ResponsesAPIAdapter.d.ts +323 -0
  33. package/dist/adapters/ResponsesAPIAdapter.d.ts.map +1 -0
  34. package/dist/adapters/ResponsesAPIAdapter.js +584 -0
  35. package/dist/adapters/ResponsesAPIAdapter.js.map +1 -0
  36. package/dist/adapters/ServerSideToolDetection.d.ts +105 -0
  37. package/dist/adapters/ServerSideToolDetection.d.ts.map +1 -0
  38. package/dist/adapters/ServerSideToolDetection.js +249 -0
  39. package/dist/adapters/ServerSideToolDetection.js.map +1 -0
  40. package/dist/adapters/ToolNamingHandler.d.ts +129 -0
  41. package/dist/adapters/ToolNamingHandler.d.ts.map +1 -0
  42. package/dist/adapters/ToolNamingHandler.js +227 -0
  43. package/dist/adapters/ToolNamingHandler.js.map +1 -0
  44. package/dist/adapters/index.d.ts +19 -0
  45. package/dist/adapters/index.d.ts.map +1 -0
  46. package/dist/adapters/index.js +23 -0
  47. package/dist/adapters/index.js.map +1 -0
  48. package/dist/adapters/node/NodeConfigProvider.d.ts +19 -0
  49. package/dist/adapters/node/NodeConfigProvider.d.ts.map +1 -0
  50. package/dist/adapters/node/NodeConfigProvider.js +37 -0
  51. package/dist/adapters/node/NodeConfigProvider.js.map +1 -0
  52. package/dist/adapters/node/NodeHistoryStoreAdapter.d.ts +26 -0
  53. package/dist/adapters/node/NodeHistoryStoreAdapter.d.ts.map +1 -0
  54. package/dist/adapters/node/NodeHistoryStoreAdapter.js +61 -0
  55. package/dist/adapters/node/NodeHistoryStoreAdapter.js.map +1 -0
  56. package/dist/adapters/node/NodePermissionAdapter.d.ts +21 -0
  57. package/dist/adapters/node/NodePermissionAdapter.d.ts.map +1 -0
  58. package/dist/adapters/node/NodePermissionAdapter.js +39 -0
  59. package/dist/adapters/node/NodePermissionAdapter.js.map +1 -0
  60. package/dist/adapters/node/NodeToolExecutorAdapter.d.ts +22 -0
  61. package/dist/adapters/node/NodeToolExecutorAdapter.d.ts.map +1 -0
  62. package/dist/adapters/node/NodeToolExecutorAdapter.js +33 -0
  63. package/dist/adapters/node/NodeToolExecutorAdapter.js.map +1 -0
  64. package/dist/adapters/node/index.d.ts +18 -0
  65. package/dist/adapters/node/index.d.ts.map +1 -0
  66. package/dist/adapters/node/index.js +18 -0
  67. package/dist/adapters/node/index.js.map +1 -0
  68. package/dist/agents/AgentStore.d.ts +172 -0
  69. package/dist/agents/AgentStore.d.ts.map +1 -0
  70. package/dist/agents/AgentStore.js +649 -0
  71. package/dist/agents/AgentStore.js.map +1 -0
  72. package/dist/agents/index.d.ts +9 -0
  73. package/dist/agents/index.d.ts.map +1 -0
  74. package/dist/agents/index.js +8 -0
  75. package/dist/agents/index.js.map +1 -0
  76. package/dist/agents/projectRoot.d.ts +2 -0
  77. package/dist/agents/projectRoot.d.ts.map +1 -0
  78. package/dist/agents/projectRoot.js +37 -0
  79. package/dist/agents/projectRoot.js.map +1 -0
  80. package/dist/commands/SlashCommandCompleter.d.ts +116 -0
  81. package/dist/commands/SlashCommandCompleter.d.ts.map +1 -0
  82. package/dist/commands/SlashCommandCompleter.js +321 -0
  83. package/dist/commands/SlashCommandCompleter.js.map +1 -0
  84. package/dist/commands/SlashCommandParser.d.ts +139 -0
  85. package/dist/commands/SlashCommandParser.d.ts.map +1 -0
  86. package/dist/commands/SlashCommandParser.js +338 -0
  87. package/dist/commands/SlashCommandParser.js.map +1 -0
  88. package/dist/commands/SlashCommandRegistry.d.ts +92 -0
  89. package/dist/commands/SlashCommandRegistry.d.ts.map +1 -0
  90. package/dist/commands/SlashCommandRegistry.js +983 -0
  91. package/dist/commands/SlashCommandRegistry.js.map +1 -0
  92. package/dist/commands/index.d.ts +13 -0
  93. package/dist/commands/index.d.ts.map +1 -0
  94. package/dist/commands/index.js +15 -0
  95. package/dist/commands/index.js.map +1 -0
  96. package/dist/commands/types.d.ts +154 -0
  97. package/dist/commands/types.d.ts.map +1 -0
  98. package/dist/commands/types.js +10 -0
  99. package/dist/commands/types.js.map +1 -0
  100. package/dist/config/AnthropicCredentialService.d.ts +107 -0
  101. package/dist/config/AnthropicCredentialService.d.ts.map +1 -0
  102. package/dist/config/AnthropicCredentialService.js +209 -0
  103. package/dist/config/AnthropicCredentialService.js.map +1 -0
  104. package/dist/config/InteractiveConfigurator.d.ts +26 -0
  105. package/dist/config/InteractiveConfigurator.d.ts.map +1 -0
  106. package/dist/config/InteractiveConfigurator.js +330 -0
  107. package/dist/config/InteractiveConfigurator.js.map +1 -0
  108. package/dist/config/MentorshipConfigService.d.ts +90 -0
  109. package/dist/config/MentorshipConfigService.d.ts.map +1 -0
  110. package/dist/config/MentorshipConfigService.js +318 -0
  111. package/dist/config/MentorshipConfigService.js.map +1 -0
  112. package/dist/config/RuntimeConfigRegistry.d.ts +20 -0
  113. package/dist/config/RuntimeConfigRegistry.d.ts.map +1 -0
  114. package/dist/config/RuntimeConfigRegistry.js +57 -0
  115. package/dist/config/RuntimeConfigRegistry.js.map +1 -0
  116. package/dist/config/SettingsLoader.d.ts +128 -0
  117. package/dist/config/SettingsLoader.d.ts.map +1 -0
  118. package/dist/config/SettingsLoader.js +487 -0
  119. package/dist/config/SettingsLoader.js.map +1 -0
  120. package/dist/config/SettingsSchema.d.ts +219 -0
  121. package/dist/config/SettingsSchema.d.ts.map +1 -0
  122. package/dist/config/SettingsSchema.js +855 -0
  123. package/dist/config/SettingsSchema.js.map +1 -0
  124. package/dist/config/SettingsWriter.d.ts +83 -0
  125. package/dist/config/SettingsWriter.d.ts.map +1 -0
  126. package/dist/config/SettingsWriter.js +256 -0
  127. package/dist/config/SettingsWriter.js.map +1 -0
  128. package/dist/config/index.d.ts +13 -0
  129. package/dist/config/index.d.ts.map +1 -0
  130. package/dist/config/index.js +13 -0
  131. package/dist/config/index.js.map +1 -0
  132. package/dist/conversation/ContextBudgetManager.d.ts +172 -0
  133. package/dist/conversation/ContextBudgetManager.d.ts.map +1 -0
  134. package/dist/conversation/ContextBudgetManager.js +445 -0
  135. package/dist/conversation/ContextBudgetManager.js.map +1 -0
  136. package/dist/conversation/StoredCompactionManager.d.ts +208 -0
  137. package/dist/conversation/StoredCompactionManager.d.ts.map +1 -0
  138. package/dist/conversation/StoredCompactionManager.js +314 -0
  139. package/dist/conversation/StoredCompactionManager.js.map +1 -0
  140. package/dist/conversation/SummaryTemplates.d.ts +35 -0
  141. package/dist/conversation/SummaryTemplates.d.ts.map +1 -0
  142. package/dist/conversation/SummaryTemplates.js +174 -0
  143. package/dist/conversation/SummaryTemplates.js.map +1 -0
  144. package/dist/conversation/index.d.ts +8 -0
  145. package/dist/conversation/index.d.ts.map +1 -0
  146. package/dist/conversation/index.js +8 -0
  147. package/dist/conversation/index.js.map +1 -0
  148. package/dist/file-tracking/ContentAddressableStore.d.ts +86 -0
  149. package/dist/file-tracking/ContentAddressableStore.d.ts.map +1 -0
  150. package/dist/file-tracking/ContentAddressableStore.js +187 -0
  151. package/dist/file-tracking/ContentAddressableStore.js.map +1 -0
  152. package/dist/file-tracking/FileCheckpointManager.d.ts +103 -0
  153. package/dist/file-tracking/FileCheckpointManager.d.ts.map +1 -0
  154. package/dist/file-tracking/FileCheckpointManager.js +269 -0
  155. package/dist/file-tracking/FileCheckpointManager.js.map +1 -0
  156. package/dist/file-tracking/index.d.ts +7 -0
  157. package/dist/file-tracking/index.d.ts.map +1 -0
  158. package/dist/file-tracking/index.js +7 -0
  159. package/dist/file-tracking/index.js.map +1 -0
  160. package/dist/index.d.ts +54 -0
  161. package/dist/index.d.ts.map +1 -0
  162. package/dist/index.js +73 -0
  163. package/dist/index.js.map +1 -0
  164. package/dist/interfaces/APITransport.d.ts +120 -0
  165. package/dist/interfaces/APITransport.d.ts.map +1 -0
  166. package/dist/interfaces/APITransport.js +14 -0
  167. package/dist/interfaces/APITransport.js.map +1 -0
  168. package/dist/interfaces/ConfigProvider.d.ts +52 -0
  169. package/dist/interfaces/ConfigProvider.d.ts.map +1 -0
  170. package/dist/interfaces/ConfigProvider.js +14 -0
  171. package/dist/interfaces/ConfigProvider.js.map +1 -0
  172. package/dist/interfaces/CredentialResolver.d.ts +57 -0
  173. package/dist/interfaces/CredentialResolver.d.ts.map +1 -0
  174. package/dist/interfaces/CredentialResolver.js +13 -0
  175. package/dist/interfaces/CredentialResolver.js.map +1 -0
  176. package/dist/interfaces/HistoryStore.d.ts +108 -0
  177. package/dist/interfaces/HistoryStore.d.ts.map +1 -0
  178. package/dist/interfaces/HistoryStore.js +14 -0
  179. package/dist/interfaces/HistoryStore.js.map +1 -0
  180. package/dist/interfaces/PermissionHandler.d.ts +74 -0
  181. package/dist/interfaces/PermissionHandler.d.ts.map +1 -0
  182. package/dist/interfaces/PermissionHandler.js +13 -0
  183. package/dist/interfaces/PermissionHandler.js.map +1 -0
  184. package/dist/interfaces/ToolExecutorRegistry.d.ts +126 -0
  185. package/dist/interfaces/ToolExecutorRegistry.d.ts.map +1 -0
  186. package/dist/interfaces/ToolExecutorRegistry.js +14 -0
  187. package/dist/interfaces/ToolExecutorRegistry.js.map +1 -0
  188. package/dist/interfaces/index.d.ts +19 -0
  189. package/dist/interfaces/index.d.ts.map +1 -0
  190. package/dist/interfaces/index.js +14 -0
  191. package/dist/interfaces/index.js.map +1 -0
  192. package/dist/mcp/McpClient.d.ts +142 -0
  193. package/dist/mcp/McpClient.d.ts.map +1 -0
  194. package/dist/mcp/McpClient.js +349 -0
  195. package/dist/mcp/McpClient.js.map +1 -0
  196. package/dist/mcp/McpClientManager.d.ts +148 -0
  197. package/dist/mcp/McpClientManager.d.ts.map +1 -0
  198. package/dist/mcp/McpClientManager.js +366 -0
  199. package/dist/mcp/McpClientManager.js.map +1 -0
  200. package/dist/mcp/McpConfigManager.d.ts +125 -0
  201. package/dist/mcp/McpConfigManager.d.ts.map +1 -0
  202. package/dist/mcp/McpConfigManager.js +448 -0
  203. package/dist/mcp/McpConfigManager.js.map +1 -0
  204. package/dist/mcp/McpServerRegistry.d.ts +102 -0
  205. package/dist/mcp/McpServerRegistry.d.ts.map +1 -0
  206. package/dist/mcp/McpServerRegistry.js +281 -0
  207. package/dist/mcp/McpServerRegistry.js.map +1 -0
  208. package/dist/mcp/index.d.ts +11 -0
  209. package/dist/mcp/index.d.ts.map +1 -0
  210. package/dist/mcp/index.js +9 -0
  211. package/dist/mcp/index.js.map +1 -0
  212. package/dist/mcp/mcpToolNamespacing.d.ts +26 -0
  213. package/dist/mcp/mcpToolNamespacing.d.ts.map +1 -0
  214. package/dist/mcp/mcpToolNamespacing.js +36 -0
  215. package/dist/mcp/mcpToolNamespacing.js.map +1 -0
  216. package/dist/mcp/test-mcp-integration.d.ts +8 -0
  217. package/dist/mcp/test-mcp-integration.d.ts.map +1 -0
  218. package/dist/mcp/test-mcp-integration.js +115 -0
  219. package/dist/mcp/test-mcp-integration.js.map +1 -0
  220. package/dist/middleware/ErrorClassificationMiddleware.d.ts +116 -0
  221. package/dist/middleware/ErrorClassificationMiddleware.d.ts.map +1 -0
  222. package/dist/middleware/ErrorClassificationMiddleware.js +225 -0
  223. package/dist/middleware/ErrorClassificationMiddleware.js.map +1 -0
  224. package/dist/middleware/HelperModelMiddleware.d.ts +337 -0
  225. package/dist/middleware/HelperModelMiddleware.d.ts.map +1 -0
  226. package/dist/middleware/HelperModelMiddleware.js +1376 -0
  227. package/dist/middleware/HelperModelMiddleware.js.map +1 -0
  228. package/dist/middleware/MentorshipMiddleware.d.ts +210 -0
  229. package/dist/middleware/MentorshipMiddleware.d.ts.map +1 -0
  230. package/dist/middleware/MentorshipMiddleware.js +427 -0
  231. package/dist/middleware/MentorshipMiddleware.js.map +1 -0
  232. package/dist/middleware/PermissionsMiddleware.d.ts +193 -0
  233. package/dist/middleware/PermissionsMiddleware.d.ts.map +1 -0
  234. package/dist/middleware/PermissionsMiddleware.js +344 -0
  235. package/dist/middleware/PermissionsMiddleware.js.map +1 -0
  236. package/dist/middleware/RetryMiddleware.d.ts +159 -0
  237. package/dist/middleware/RetryMiddleware.d.ts.map +1 -0
  238. package/dist/middleware/RetryMiddleware.js +268 -0
  239. package/dist/middleware/RetryMiddleware.js.map +1 -0
  240. package/dist/middleware/SystemMessageMiddleware.d.ts +165 -0
  241. package/dist/middleware/SystemMessageMiddleware.d.ts.map +1 -0
  242. package/dist/middleware/SystemMessageMiddleware.js +354 -0
  243. package/dist/middleware/SystemMessageMiddleware.js.map +1 -0
  244. package/dist/middleware/contracts/MiddlewareContracts.d.ts +294 -0
  245. package/dist/middleware/contracts/MiddlewareContracts.d.ts.map +1 -0
  246. package/dist/middleware/contracts/MiddlewareContracts.js +12 -0
  247. package/dist/middleware/contracts/MiddlewareContracts.js.map +1 -0
  248. package/dist/middleware/helpers/HelperMiddlewareAdapter.interface.d.ts +211 -0
  249. package/dist/middleware/helpers/HelperMiddlewareAdapter.interface.d.ts.map +1 -0
  250. package/dist/middleware/helpers/HelperMiddlewareAdapter.interface.js +211 -0
  251. package/dist/middleware/helpers/HelperMiddlewareAdapter.interface.js.map +1 -0
  252. package/dist/middleware/helpers/HelperModelMiddlewareRegistry.d.ts +106 -0
  253. package/dist/middleware/helpers/HelperModelMiddlewareRegistry.d.ts.map +1 -0
  254. package/dist/middleware/helpers/HelperModelMiddlewareRegistry.js +148 -0
  255. package/dist/middleware/helpers/HelperModelMiddlewareRegistry.js.map +1 -0
  256. package/dist/middleware/helpers/adapters/ChatCompletionsAPIHelperAdapter.d.ts +76 -0
  257. package/dist/middleware/helpers/adapters/ChatCompletionsAPIHelperAdapter.d.ts.map +1 -0
  258. package/dist/middleware/helpers/adapters/ChatCompletionsAPIHelperAdapter.js +277 -0
  259. package/dist/middleware/helpers/adapters/ChatCompletionsAPIHelperAdapter.js.map +1 -0
  260. package/dist/middleware/helpers/adapters/GenerateContentAPIHelperAdapter.d.ts +57 -0
  261. package/dist/middleware/helpers/adapters/GenerateContentAPIHelperAdapter.d.ts.map +1 -0
  262. package/dist/middleware/helpers/adapters/GenerateContentAPIHelperAdapter.js +155 -0
  263. package/dist/middleware/helpers/adapters/GenerateContentAPIHelperAdapter.js.map +1 -0
  264. package/dist/middleware/helpers/adapters/GoogleGenAPIHelperAdapter.d.ts +124 -0
  265. package/dist/middleware/helpers/adapters/GoogleGenAPIHelperAdapter.d.ts.map +1 -0
  266. package/dist/middleware/helpers/adapters/GoogleGenAPIHelperAdapter.js +276 -0
  267. package/dist/middleware/helpers/adapters/GoogleGenAPIHelperAdapter.js.map +1 -0
  268. package/dist/middleware/helpers/adapters/MessagesAPIHelperAdapter.d.ts +71 -0
  269. package/dist/middleware/helpers/adapters/MessagesAPIHelperAdapter.d.ts.map +1 -0
  270. package/dist/middleware/helpers/adapters/MessagesAPIHelperAdapter.js +264 -0
  271. package/dist/middleware/helpers/adapters/MessagesAPIHelperAdapter.js.map +1 -0
  272. package/dist/middleware/helpers/adapters/ResponsesAPIHelperAdapter.d.ts +64 -0
  273. package/dist/middleware/helpers/adapters/ResponsesAPIHelperAdapter.d.ts.map +1 -0
  274. package/dist/middleware/helpers/adapters/ResponsesAPIHelperAdapter.js +189 -0
  275. package/dist/middleware/helpers/adapters/ResponsesAPIHelperAdapter.js.map +1 -0
  276. package/dist/middleware/helpers/adapters/index.d.ts +31 -0
  277. package/dist/middleware/helpers/adapters/index.d.ts.map +1 -0
  278. package/dist/middleware/helpers/adapters/index.js +40 -0
  279. package/dist/middleware/helpers/adapters/index.js.map +1 -0
  280. package/dist/middleware/helpers/index.d.ts +10 -0
  281. package/dist/middleware/helpers/index.d.ts.map +1 -0
  282. package/dist/middleware/helpers/index.js +13 -0
  283. package/dist/middleware/helpers/index.js.map +1 -0
  284. package/dist/middleware/index.d.ts +12 -0
  285. package/dist/middleware/index.d.ts.map +1 -0
  286. package/dist/middleware/index.js +13 -0
  287. package/dist/middleware/index.js.map +1 -0
  288. package/dist/middleware/permissions/ApprovalHandler.d.ts +22 -0
  289. package/dist/middleware/permissions/ApprovalHandler.d.ts.map +1 -0
  290. package/dist/middleware/permissions/ApprovalHandler.js +27 -0
  291. package/dist/middleware/permissions/ApprovalHandler.js.map +1 -0
  292. package/dist/middleware/permissions/AutoApproveHandler.d.ts +62 -0
  293. package/dist/middleware/permissions/AutoApproveHandler.d.ts.map +1 -0
  294. package/dist/middleware/permissions/AutoApproveHandler.js +68 -0
  295. package/dist/middleware/permissions/AutoApproveHandler.js.map +1 -0
  296. package/dist/middleware/permissions/BashCommandPolicy.d.ts +134 -0
  297. package/dist/middleware/permissions/BashCommandPolicy.d.ts.map +1 -0
  298. package/dist/middleware/permissions/BashCommandPolicy.js +239 -0
  299. package/dist/middleware/permissions/BashCommandPolicy.js.map +1 -0
  300. package/dist/middleware/permissions/BlacklistPolicy.d.ts +66 -0
  301. package/dist/middleware/permissions/BlacklistPolicy.d.ts.map +1 -0
  302. package/dist/middleware/permissions/BlacklistPolicy.js +82 -0
  303. package/dist/middleware/permissions/BlacklistPolicy.js.map +1 -0
  304. package/dist/middleware/permissions/CLIApprovalHandler.d.ts +124 -0
  305. package/dist/middleware/permissions/CLIApprovalHandler.d.ts.map +1 -0
  306. package/dist/middleware/permissions/CLIApprovalHandler.js +366 -0
  307. package/dist/middleware/permissions/CLIApprovalHandler.js.map +1 -0
  308. package/dist/middleware/permissions/DefaultPolicies.d.ts +53 -0
  309. package/dist/middleware/permissions/DefaultPolicies.d.ts.map +1 -0
  310. package/dist/middleware/permissions/DefaultPolicies.js +307 -0
  311. package/dist/middleware/permissions/DefaultPolicies.js.map +1 -0
  312. package/dist/middleware/permissions/DenyAllHandler.d.ts +58 -0
  313. package/dist/middleware/permissions/DenyAllHandler.d.ts.map +1 -0
  314. package/dist/middleware/permissions/DenyAllHandler.js +59 -0
  315. package/dist/middleware/permissions/DenyAllHandler.js.map +1 -0
  316. package/dist/middleware/permissions/FileOperationPolicy.d.ts +117 -0
  317. package/dist/middleware/permissions/FileOperationPolicy.d.ts.map +1 -0
  318. package/dist/middleware/permissions/FileOperationPolicy.js +222 -0
  319. package/dist/middleware/permissions/FileOperationPolicy.js.map +1 -0
  320. package/dist/middleware/permissions/IPCApprovalHandler.d.ts +94 -0
  321. package/dist/middleware/permissions/IPCApprovalHandler.d.ts.map +1 -0
  322. package/dist/middleware/permissions/IPCApprovalHandler.js +178 -0
  323. package/dist/middleware/permissions/IPCApprovalHandler.js.map +1 -0
  324. package/dist/middleware/permissions/PermissionAuditLogger.d.ts +169 -0
  325. package/dist/middleware/permissions/PermissionAuditLogger.d.ts.map +1 -0
  326. package/dist/middleware/permissions/PermissionAuditLogger.js +267 -0
  327. package/dist/middleware/permissions/PermissionAuditLogger.js.map +1 -0
  328. package/dist/middleware/permissions/PermissionConfig.d.ts +181 -0
  329. package/dist/middleware/permissions/PermissionConfig.d.ts.map +1 -0
  330. package/dist/middleware/permissions/PermissionConfig.js +110 -0
  331. package/dist/middleware/permissions/PermissionConfig.js.map +1 -0
  332. package/dist/middleware/permissions/PermissionConfigLoader.d.ts +89 -0
  333. package/dist/middleware/permissions/PermissionConfigLoader.d.ts.map +1 -0
  334. package/dist/middleware/permissions/PermissionConfigLoader.js +296 -0
  335. package/dist/middleware/permissions/PermissionConfigLoader.js.map +1 -0
  336. package/dist/middleware/permissions/PermissionEvaluator.d.ts +111 -0
  337. package/dist/middleware/permissions/PermissionEvaluator.d.ts.map +1 -0
  338. package/dist/middleware/permissions/PermissionEvaluator.js +196 -0
  339. package/dist/middleware/permissions/PermissionEvaluator.js.map +1 -0
  340. package/dist/middleware/permissions/PermissionPolicy.d.ts +59 -0
  341. package/dist/middleware/permissions/PermissionPolicy.d.ts.map +1 -0
  342. package/dist/middleware/permissions/PermissionPolicy.js +67 -0
  343. package/dist/middleware/permissions/PermissionPolicy.js.map +1 -0
  344. package/dist/middleware/permissions/PermissionProfileStore.d.ts +77 -0
  345. package/dist/middleware/permissions/PermissionProfileStore.d.ts.map +1 -0
  346. package/dist/middleware/permissions/PermissionProfileStore.js +167 -0
  347. package/dist/middleware/permissions/PermissionProfileStore.js.map +1 -0
  348. package/dist/middleware/permissions/WhitelistPolicy.d.ts +66 -0
  349. package/dist/middleware/permissions/WhitelistPolicy.d.ts.map +1 -0
  350. package/dist/middleware/permissions/WhitelistPolicy.js +82 -0
  351. package/dist/middleware/permissions/WhitelistPolicy.js.map +1 -0
  352. package/dist/middleware/permissions/index.d.ts +40 -0
  353. package/dist/middleware/permissions/index.d.ts.map +1 -0
  354. package/dist/middleware/permissions/index.js +30 -0
  355. package/dist/middleware/permissions/index.js.map +1 -0
  356. package/dist/middleware/permissions/profilePath.d.ts +15 -0
  357. package/dist/middleware/permissions/profilePath.d.ts.map +1 -0
  358. package/dist/middleware/permissions/profilePath.js +35 -0
  359. package/dist/middleware/permissions/profilePath.js.map +1 -0
  360. package/dist/models/ModelConfig.interface.d.ts +18 -0
  361. package/dist/models/ModelConfig.interface.d.ts.map +1 -0
  362. package/dist/models/ModelConfig.interface.js +157 -0
  363. package/dist/models/ModelConfig.interface.js.map +1 -0
  364. package/dist/models/cards/anthropic/claude-3-5-haiku.d.ts +11 -0
  365. package/dist/models/cards/anthropic/claude-3-5-haiku.d.ts.map +1 -0
  366. package/dist/models/cards/anthropic/claude-3-5-haiku.js +19 -0
  367. package/dist/models/cards/anthropic/claude-3-5-haiku.js.map +1 -0
  368. package/dist/models/cards/anthropic/claude-3-5-sonnet.d.ts +11 -0
  369. package/dist/models/cards/anthropic/claude-3-5-sonnet.d.ts.map +1 -0
  370. package/dist/models/cards/anthropic/claude-3-5-sonnet.js +19 -0
  371. package/dist/models/cards/anthropic/claude-3-5-sonnet.js.map +1 -0
  372. package/dist/models/cards/anthropic/claude-3-haiku.d.ts +11 -0
  373. package/dist/models/cards/anthropic/claude-3-haiku.d.ts.map +1 -0
  374. package/dist/models/cards/anthropic/claude-3-haiku.js +19 -0
  375. package/dist/models/cards/anthropic/claude-3-haiku.js.map +1 -0
  376. package/dist/models/cards/anthropic/claude-4-5-haiku.d.ts +11 -0
  377. package/dist/models/cards/anthropic/claude-4-5-haiku.d.ts.map +1 -0
  378. package/dist/models/cards/anthropic/claude-4-5-haiku.js +26 -0
  379. package/dist/models/cards/anthropic/claude-4-5-haiku.js.map +1 -0
  380. package/dist/models/cards/anthropic/claude-fable-5.d.ts +14 -0
  381. package/dist/models/cards/anthropic/claude-fable-5.d.ts.map +1 -0
  382. package/dist/models/cards/anthropic/claude-fable-5.js +30 -0
  383. package/dist/models/cards/anthropic/claude-fable-5.js.map +1 -0
  384. package/dist/models/cards/anthropic/claude-opus-4-1.d.ts +11 -0
  385. package/dist/models/cards/anthropic/claude-opus-4-1.d.ts.map +1 -0
  386. package/dist/models/cards/anthropic/claude-opus-4-1.js +19 -0
  387. package/dist/models/cards/anthropic/claude-opus-4-1.js.map +1 -0
  388. package/dist/models/cards/anthropic/claude-opus-4-5.d.ts +11 -0
  389. package/dist/models/cards/anthropic/claude-opus-4-5.d.ts.map +1 -0
  390. package/dist/models/cards/anthropic/claude-opus-4-5.js +27 -0
  391. package/dist/models/cards/anthropic/claude-opus-4-5.js.map +1 -0
  392. package/dist/models/cards/anthropic/claude-opus-4-6.d.ts +10 -0
  393. package/dist/models/cards/anthropic/claude-opus-4-6.d.ts.map +1 -0
  394. package/dist/models/cards/anthropic/claude-opus-4-6.js +26 -0
  395. package/dist/models/cards/anthropic/claude-opus-4-6.js.map +1 -0
  396. package/dist/models/cards/anthropic/claude-opus-4-7.d.ts +10 -0
  397. package/dist/models/cards/anthropic/claude-opus-4-7.d.ts.map +1 -0
  398. package/dist/models/cards/anthropic/claude-opus-4-7.js +26 -0
  399. package/dist/models/cards/anthropic/claude-opus-4-7.js.map +1 -0
  400. package/dist/models/cards/anthropic/claude-opus-4-8.d.ts +12 -0
  401. package/dist/models/cards/anthropic/claude-opus-4-8.d.ts.map +1 -0
  402. package/dist/models/cards/anthropic/claude-opus-4-8.js +28 -0
  403. package/dist/models/cards/anthropic/claude-opus-4-8.js.map +1 -0
  404. package/dist/models/cards/anthropic/claude-sonnet-4-5.d.ts +11 -0
  405. package/dist/models/cards/anthropic/claude-sonnet-4-5.d.ts.map +1 -0
  406. package/dist/models/cards/anthropic/claude-sonnet-4-5.js +27 -0
  407. package/dist/models/cards/anthropic/claude-sonnet-4-5.js.map +1 -0
  408. package/dist/models/cards/anthropic/claude-sonnet-4-6.d.ts +10 -0
  409. package/dist/models/cards/anthropic/claude-sonnet-4-6.d.ts.map +1 -0
  410. package/dist/models/cards/anthropic/claude-sonnet-4-6.js +26 -0
  411. package/dist/models/cards/anthropic/claude-sonnet-4-6.js.map +1 -0
  412. package/dist/models/cards/anthropic/claude-sonnet-4.d.ts +11 -0
  413. package/dist/models/cards/anthropic/claude-sonnet-4.d.ts.map +1 -0
  414. package/dist/models/cards/anthropic/claude-sonnet-4.js +19 -0
  415. package/dist/models/cards/anthropic/claude-sonnet-4.js.map +1 -0
  416. package/dist/models/cards/anthropic/index.d.ts +15 -0
  417. package/dist/models/cards/anthropic/index.d.ts.map +1 -0
  418. package/dist/models/cards/anthropic/index.js +15 -0
  419. package/dist/models/cards/anthropic/index.js.map +1 -0
  420. package/dist/models/cards/cloudflare/gemma-4-26b.d.ts +3 -0
  421. package/dist/models/cards/cloudflare/gemma-4-26b.d.ts.map +1 -0
  422. package/dist/models/cards/cloudflare/gemma-4-26b.js +17 -0
  423. package/dist/models/cards/cloudflare/gemma-4-26b.js.map +1 -0
  424. package/dist/models/cards/cloudflare/glm-4-7-flash.d.ts +3 -0
  425. package/dist/models/cards/cloudflare/glm-4-7-flash.d.ts.map +1 -0
  426. package/dist/models/cards/cloudflare/glm-4-7-flash.js +18 -0
  427. package/dist/models/cards/cloudflare/glm-4-7-flash.js.map +1 -0
  428. package/dist/models/cards/cloudflare/gpt-oss-120b.d.ts +3 -0
  429. package/dist/models/cards/cloudflare/gpt-oss-120b.d.ts.map +1 -0
  430. package/dist/models/cards/cloudflare/gpt-oss-120b.js +18 -0
  431. package/dist/models/cards/cloudflare/gpt-oss-120b.js.map +1 -0
  432. package/dist/models/cards/cloudflare/gpt-oss-20b.d.ts +3 -0
  433. package/dist/models/cards/cloudflare/gpt-oss-20b.d.ts.map +1 -0
  434. package/dist/models/cards/cloudflare/gpt-oss-20b.js +18 -0
  435. package/dist/models/cards/cloudflare/gpt-oss-20b.js.map +1 -0
  436. package/dist/models/cards/cloudflare/granite-4.d.ts +3 -0
  437. package/dist/models/cards/cloudflare/granite-4.d.ts.map +1 -0
  438. package/dist/models/cards/cloudflare/granite-4.js +17 -0
  439. package/dist/models/cards/cloudflare/granite-4.js.map +1 -0
  440. package/dist/models/cards/cloudflare/index.d.ts +24 -0
  441. package/dist/models/cards/cloudflare/index.d.ts.map +1 -0
  442. package/dist/models/cards/cloudflare/index.js +24 -0
  443. package/dist/models/cards/cloudflare/index.js.map +1 -0
  444. package/dist/models/cards/cloudflare/kimi-k2-5.d.ts +3 -0
  445. package/dist/models/cards/cloudflare/kimi-k2-5.d.ts.map +1 -0
  446. package/dist/models/cards/cloudflare/kimi-k2-5.js +17 -0
  447. package/dist/models/cards/cloudflare/kimi-k2-5.js.map +1 -0
  448. package/dist/models/cards/cloudflare/kimi-k2-6.d.ts +3 -0
  449. package/dist/models/cards/cloudflare/kimi-k2-6.d.ts.map +1 -0
  450. package/dist/models/cards/cloudflare/kimi-k2-6.js +20 -0
  451. package/dist/models/cards/cloudflare/kimi-k2-6.js.map +1 -0
  452. package/dist/models/cards/cloudflare/llama-3-3-70b.d.ts +3 -0
  453. package/dist/models/cards/cloudflare/llama-3-3-70b.d.ts.map +1 -0
  454. package/dist/models/cards/cloudflare/llama-3-3-70b.js +17 -0
  455. package/dist/models/cards/cloudflare/llama-3-3-70b.js.map +1 -0
  456. package/dist/models/cards/cloudflare/llama-4-scout.d.ts +3 -0
  457. package/dist/models/cards/cloudflare/llama-4-scout.d.ts.map +1 -0
  458. package/dist/models/cards/cloudflare/llama-4-scout.js +18 -0
  459. package/dist/models/cards/cloudflare/llama-4-scout.js.map +1 -0
  460. package/dist/models/cards/cloudflare/mistral-small-3-1.d.ts +3 -0
  461. package/dist/models/cards/cloudflare/mistral-small-3-1.d.ts.map +1 -0
  462. package/dist/models/cards/cloudflare/mistral-small-3-1.js +18 -0
  463. package/dist/models/cards/cloudflare/mistral-small-3-1.js.map +1 -0
  464. package/dist/models/cards/cloudflare/nemotron-3-120b.d.ts +3 -0
  465. package/dist/models/cards/cloudflare/nemotron-3-120b.d.ts.map +1 -0
  466. package/dist/models/cards/cloudflare/nemotron-3-120b.js +16 -0
  467. package/dist/models/cards/cloudflare/nemotron-3-120b.js.map +1 -0
  468. package/dist/models/cards/cloudflare/qwen3-30b.d.ts +3 -0
  469. package/dist/models/cards/cloudflare/qwen3-30b.d.ts.map +1 -0
  470. package/dist/models/cards/cloudflare/qwen3-30b.js +17 -0
  471. package/dist/models/cards/cloudflare/qwen3-30b.js.map +1 -0
  472. package/dist/models/cards/cloudflare/qwq-32b.d.ts +3 -0
  473. package/dist/models/cards/cloudflare/qwq-32b.d.ts.map +1 -0
  474. package/dist/models/cards/cloudflare/qwq-32b.js +18 -0
  475. package/dist/models/cards/cloudflare/qwq-32b.js.map +1 -0
  476. package/dist/models/cards/deepseek/deepseek-v4-flash.d.ts +11 -0
  477. package/dist/models/cards/deepseek/deepseek-v4-flash.d.ts.map +1 -0
  478. package/dist/models/cards/deepseek/deepseek-v4-flash.js +25 -0
  479. package/dist/models/cards/deepseek/deepseek-v4-flash.js.map +1 -0
  480. package/dist/models/cards/deepseek/deepseek-v4-pro.d.ts +11 -0
  481. package/dist/models/cards/deepseek/deepseek-v4-pro.d.ts.map +1 -0
  482. package/dist/models/cards/deepseek/deepseek-v4-pro.js +25 -0
  483. package/dist/models/cards/deepseek/deepseek-v4-pro.js.map +1 -0
  484. package/dist/models/cards/deepseek/index.d.ts +22 -0
  485. package/dist/models/cards/deepseek/index.d.ts.map +1 -0
  486. package/dist/models/cards/deepseek/index.js +22 -0
  487. package/dist/models/cards/deepseek/index.js.map +1 -0
  488. package/dist/models/cards/gemma/gemma-3-12b-it.d.ts +10 -0
  489. package/dist/models/cards/gemma/gemma-3-12b-it.d.ts.map +1 -0
  490. package/dist/models/cards/gemma/gemma-3-12b-it.js +16 -0
  491. package/dist/models/cards/gemma/gemma-3-12b-it.js.map +1 -0
  492. package/dist/models/cards/gemma/gemma-3-1b-it.d.ts +10 -0
  493. package/dist/models/cards/gemma/gemma-3-1b-it.d.ts.map +1 -0
  494. package/dist/models/cards/gemma/gemma-3-1b-it.js +16 -0
  495. package/dist/models/cards/gemma/gemma-3-1b-it.js.map +1 -0
  496. package/dist/models/cards/gemma/gemma-3-27b-it.d.ts +10 -0
  497. package/dist/models/cards/gemma/gemma-3-27b-it.d.ts.map +1 -0
  498. package/dist/models/cards/gemma/gemma-3-27b-it.js +16 -0
  499. package/dist/models/cards/gemma/gemma-3-27b-it.js.map +1 -0
  500. package/dist/models/cards/gemma/gemma-3-4b-it.d.ts +10 -0
  501. package/dist/models/cards/gemma/gemma-3-4b-it.d.ts.map +1 -0
  502. package/dist/models/cards/gemma/gemma-3-4b-it.js +16 -0
  503. package/dist/models/cards/gemma/gemma-3-4b-it.js.map +1 -0
  504. package/dist/models/cards/gemma/index.d.ts +9 -0
  505. package/dist/models/cards/gemma/index.d.ts.map +1 -0
  506. package/dist/models/cards/gemma/index.js +9 -0
  507. package/dist/models/cards/gemma/index.js.map +1 -0
  508. package/dist/models/cards/glm/glm-4-5-air.d.ts +17 -0
  509. package/dist/models/cards/glm/glm-4-5-air.d.ts.map +1 -0
  510. package/dist/models/cards/glm/glm-4-5-air.js +27 -0
  511. package/dist/models/cards/glm/glm-4-5-air.js.map +1 -0
  512. package/dist/models/cards/glm/glm-4-5.d.ts +16 -0
  513. package/dist/models/cards/glm/glm-4-5.d.ts.map +1 -0
  514. package/dist/models/cards/glm/glm-4-5.js +26 -0
  515. package/dist/models/cards/glm/glm-4-5.js.map +1 -0
  516. package/dist/models/cards/glm/glm-4-6.d.ts +17 -0
  517. package/dist/models/cards/glm/glm-4-6.d.ts.map +1 -0
  518. package/dist/models/cards/glm/glm-4-6.js +27 -0
  519. package/dist/models/cards/glm/glm-4-6.js.map +1 -0
  520. package/dist/models/cards/glm/glm-4-flash.d.ts +12 -0
  521. package/dist/models/cards/glm/glm-4-flash.d.ts.map +1 -0
  522. package/dist/models/cards/glm/glm-4-flash.js +20 -0
  523. package/dist/models/cards/glm/glm-4-flash.js.map +1 -0
  524. package/dist/models/cards/glm/glm-4.d.ts +12 -0
  525. package/dist/models/cards/glm/glm-4.d.ts.map +1 -0
  526. package/dist/models/cards/glm/glm-4.js +21 -0
  527. package/dist/models/cards/glm/glm-4.js.map +1 -0
  528. package/dist/models/cards/glm/index.d.ts +13 -0
  529. package/dist/models/cards/glm/index.d.ts.map +1 -0
  530. package/dist/models/cards/glm/index.js +13 -0
  531. package/dist/models/cards/glm/index.js.map +1 -0
  532. package/dist/models/cards/google/gemini-1-5-flash.d.ts +10 -0
  533. package/dist/models/cards/google/gemini-1-5-flash.d.ts.map +1 -0
  534. package/dist/models/cards/google/gemini-1-5-flash.js +18 -0
  535. package/dist/models/cards/google/gemini-1-5-flash.js.map +1 -0
  536. package/dist/models/cards/google/gemini-1-5-pro.d.ts +10 -0
  537. package/dist/models/cards/google/gemini-1-5-pro.d.ts.map +1 -0
  538. package/dist/models/cards/google/gemini-1-5-pro.js +18 -0
  539. package/dist/models/cards/google/gemini-1-5-pro.js.map +1 -0
  540. package/dist/models/cards/google/gemini-2-0-flash-lite.d.ts +10 -0
  541. package/dist/models/cards/google/gemini-2-0-flash-lite.d.ts.map +1 -0
  542. package/dist/models/cards/google/gemini-2-0-flash-lite.js +18 -0
  543. package/dist/models/cards/google/gemini-2-0-flash-lite.js.map +1 -0
  544. package/dist/models/cards/google/gemini-2-0-flash.d.ts +10 -0
  545. package/dist/models/cards/google/gemini-2-0-flash.d.ts.map +1 -0
  546. package/dist/models/cards/google/gemini-2-0-flash.js +24 -0
  547. package/dist/models/cards/google/gemini-2-0-flash.js.map +1 -0
  548. package/dist/models/cards/google/gemini-2-5-computer-use-preview.d.ts +18 -0
  549. package/dist/models/cards/google/gemini-2-5-computer-use-preview.d.ts.map +1 -0
  550. package/dist/models/cards/google/gemini-2-5-computer-use-preview.js +26 -0
  551. package/dist/models/cards/google/gemini-2-5-computer-use-preview.js.map +1 -0
  552. package/dist/models/cards/google/gemini-2-5-flash-lite.d.ts +10 -0
  553. package/dist/models/cards/google/gemini-2-5-flash-lite.d.ts.map +1 -0
  554. package/dist/models/cards/google/gemini-2-5-flash-lite.js +18 -0
  555. package/dist/models/cards/google/gemini-2-5-flash-lite.js.map +1 -0
  556. package/dist/models/cards/google/gemini-2-5-flash-sdk.d.ts +11 -0
  557. package/dist/models/cards/google/gemini-2-5-flash-sdk.d.ts.map +1 -0
  558. package/dist/models/cards/google/gemini-2-5-flash-sdk.js +25 -0
  559. package/dist/models/cards/google/gemini-2-5-flash-sdk.js.map +1 -0
  560. package/dist/models/cards/google/gemini-2-5-flash.d.ts +10 -0
  561. package/dist/models/cards/google/gemini-2-5-flash.d.ts.map +1 -0
  562. package/dist/models/cards/google/gemini-2-5-flash.js +24 -0
  563. package/dist/models/cards/google/gemini-2-5-flash.js.map +1 -0
  564. package/dist/models/cards/google/gemini-2-5-pro.d.ts +10 -0
  565. package/dist/models/cards/google/gemini-2-5-pro.d.ts.map +1 -0
  566. package/dist/models/cards/google/gemini-2-5-pro.js +24 -0
  567. package/dist/models/cards/google/gemini-2-5-pro.js.map +1 -0
  568. package/dist/models/cards/google/gemini-3-1-flash-lite-preview.d.ts +11 -0
  569. package/dist/models/cards/google/gemini-3-1-flash-lite-preview.d.ts.map +1 -0
  570. package/dist/models/cards/google/gemini-3-1-flash-lite-preview.js +20 -0
  571. package/dist/models/cards/google/gemini-3-1-flash-lite-preview.js.map +1 -0
  572. package/dist/models/cards/google/gemini-3-1-pro-preview.d.ts +10 -0
  573. package/dist/models/cards/google/gemini-3-1-pro-preview.d.ts.map +1 -0
  574. package/dist/models/cards/google/gemini-3-1-pro-preview.js +19 -0
  575. package/dist/models/cards/google/gemini-3-1-pro-preview.js.map +1 -0
  576. package/dist/models/cards/google/gemini-3-5-flash.d.ts +10 -0
  577. package/dist/models/cards/google/gemini-3-5-flash.d.ts.map +1 -0
  578. package/dist/models/cards/google/gemini-3-5-flash.js +19 -0
  579. package/dist/models/cards/google/gemini-3-5-flash.js.map +1 -0
  580. package/dist/models/cards/google/gemini-3-flash-preview.d.ts +11 -0
  581. package/dist/models/cards/google/gemini-3-flash-preview.d.ts.map +1 -0
  582. package/dist/models/cards/google/gemini-3-flash-preview.js +20 -0
  583. package/dist/models/cards/google/gemini-3-flash-preview.js.map +1 -0
  584. package/dist/models/cards/google/gemini-3.d.ts +11 -0
  585. package/dist/models/cards/google/gemini-3.d.ts.map +1 -0
  586. package/dist/models/cards/google/gemini-3.js +20 -0
  587. package/dist/models/cards/google/gemini-3.js.map +1 -0
  588. package/dist/models/cards/google/index.d.ts +17 -0
  589. package/dist/models/cards/google/index.d.ts.map +1 -0
  590. package/dist/models/cards/google/index.js +17 -0
  591. package/dist/models/cards/google/index.js.map +1 -0
  592. package/dist/models/cards/huggingface/index.d.ts +10 -0
  593. package/dist/models/cards/huggingface/index.d.ts.map +1 -0
  594. package/dist/models/cards/huggingface/index.js +10 -0
  595. package/dist/models/cards/huggingface/index.js.map +1 -0
  596. package/dist/models/cards/huggingface/llama-3-8b-instruct.d.ts +17 -0
  597. package/dist/models/cards/huggingface/llama-3-8b-instruct.d.ts.map +1 -0
  598. package/dist/models/cards/huggingface/llama-3-8b-instruct.js +25 -0
  599. package/dist/models/cards/huggingface/llama-3-8b-instruct.js.map +1 -0
  600. package/dist/models/cards/huggingface/mistral-7b-instruct.d.ts +10 -0
  601. package/dist/models/cards/huggingface/mistral-7b-instruct.d.ts.map +1 -0
  602. package/dist/models/cards/huggingface/mistral-7b-instruct.js +18 -0
  603. package/dist/models/cards/huggingface/mistral-7b-instruct.js.map +1 -0
  604. package/dist/models/cards/local/codellama-13b-local.d.ts +19 -0
  605. package/dist/models/cards/local/codellama-13b-local.d.ts.map +1 -0
  606. package/dist/models/cards/local/codellama-13b-local.js +28 -0
  607. package/dist/models/cards/local/codellama-13b-local.js.map +1 -0
  608. package/dist/models/cards/local/index.d.ts +17 -0
  609. package/dist/models/cards/local/index.d.ts.map +1 -0
  610. package/dist/models/cards/local/index.js +17 -0
  611. package/dist/models/cards/local/index.js.map +1 -0
  612. package/dist/models/cards/local/llama-3-8b-local.d.ts +25 -0
  613. package/dist/models/cards/local/llama-3-8b-local.d.ts.map +1 -0
  614. package/dist/models/cards/local/llama-3-8b-local.js +34 -0
  615. package/dist/models/cards/local/llama-3-8b-local.js.map +1 -0
  616. package/dist/models/cards/local/mistral-7b-ollama.d.ts +18 -0
  617. package/dist/models/cards/local/mistral-7b-ollama.d.ts.map +1 -0
  618. package/dist/models/cards/local/mistral-7b-ollama.js +27 -0
  619. package/dist/models/cards/local/mistral-7b-ollama.js.map +1 -0
  620. package/dist/models/cards/mercury/index.d.ts +10 -0
  621. package/dist/models/cards/mercury/index.d.ts.map +1 -0
  622. package/dist/models/cards/mercury/index.js +10 -0
  623. package/dist/models/cards/mercury/index.js.map +1 -0
  624. package/dist/models/cards/mercury/mercury-2.d.ts +24 -0
  625. package/dist/models/cards/mercury/mercury-2.d.ts.map +1 -0
  626. package/dist/models/cards/mercury/mercury-2.js +33 -0
  627. package/dist/models/cards/mercury/mercury-2.js.map +1 -0
  628. package/dist/models/cards/minimax/index.d.ts +10 -0
  629. package/dist/models/cards/minimax/index.d.ts.map +1 -0
  630. package/dist/models/cards/minimax/index.js +10 -0
  631. package/dist/models/cards/minimax/index.js.map +1 -0
  632. package/dist/models/cards/minimax/minimax-m2-stable.d.ts +21 -0
  633. package/dist/models/cards/minimax/minimax-m2-stable.d.ts.map +1 -0
  634. package/dist/models/cards/minimax/minimax-m2-stable.js +31 -0
  635. package/dist/models/cards/minimax/minimax-m2-stable.js.map +1 -0
  636. package/dist/models/cards/minimax/minimax-m2.d.ts +20 -0
  637. package/dist/models/cards/minimax/minimax-m2.d.ts.map +1 -0
  638. package/dist/models/cards/minimax/minimax-m2.js +30 -0
  639. package/dist/models/cards/minimax/minimax-m2.js.map +1 -0
  640. package/dist/models/cards/moonshot/index.d.ts +9 -0
  641. package/dist/models/cards/moonshot/index.d.ts.map +1 -0
  642. package/dist/models/cards/moonshot/index.js +9 -0
  643. package/dist/models/cards/moonshot/index.js.map +1 -0
  644. package/dist/models/cards/moonshot/kimi-chat-128k.d.ts +10 -0
  645. package/dist/models/cards/moonshot/kimi-chat-128k.d.ts.map +1 -0
  646. package/dist/models/cards/moonshot/kimi-chat-128k.js +18 -0
  647. package/dist/models/cards/moonshot/kimi-chat-128k.js.map +1 -0
  648. package/dist/models/cards/moonshot/kimi-chat-32k.d.ts +10 -0
  649. package/dist/models/cards/moonshot/kimi-chat-32k.d.ts.map +1 -0
  650. package/dist/models/cards/moonshot/kimi-chat-32k.js +18 -0
  651. package/dist/models/cards/moonshot/kimi-chat-32k.js.map +1 -0
  652. package/dist/models/cards/moonshot/kimi-chat.d.ts +12 -0
  653. package/dist/models/cards/moonshot/kimi-chat.d.ts.map +1 -0
  654. package/dist/models/cards/moonshot/kimi-chat.js +20 -0
  655. package/dist/models/cards/moonshot/kimi-chat.js.map +1 -0
  656. package/dist/models/cards/moonshot/kimi-k2-instruct.d.ts +17 -0
  657. package/dist/models/cards/moonshot/kimi-k2-instruct.d.ts.map +1 -0
  658. package/dist/models/cards/moonshot/kimi-k2-instruct.js +26 -0
  659. package/dist/models/cards/moonshot/kimi-k2-instruct.js.map +1 -0
  660. package/dist/models/cards/moonshot/kimi-k2-thinking.d.ts +18 -0
  661. package/dist/models/cards/moonshot/kimi-k2-thinking.d.ts.map +1 -0
  662. package/dist/models/cards/moonshot/kimi-k2-thinking.js +27 -0
  663. package/dist/models/cards/moonshot/kimi-k2-thinking.js.map +1 -0
  664. package/dist/models/cards/openai/gpt-4-1-mini.d.ts +10 -0
  665. package/dist/models/cards/openai/gpt-4-1-mini.d.ts.map +1 -0
  666. package/dist/models/cards/openai/gpt-4-1-mini.js +18 -0
  667. package/dist/models/cards/openai/gpt-4-1-mini.js.map +1 -0
  668. package/dist/models/cards/openai/gpt-4-1-nano.d.ts +10 -0
  669. package/dist/models/cards/openai/gpt-4-1-nano.d.ts.map +1 -0
  670. package/dist/models/cards/openai/gpt-4-1-nano.js +18 -0
  671. package/dist/models/cards/openai/gpt-4-1-nano.js.map +1 -0
  672. package/dist/models/cards/openai/gpt-4-1.d.ts +10 -0
  673. package/dist/models/cards/openai/gpt-4-1.d.ts.map +1 -0
  674. package/dist/models/cards/openai/gpt-4-1.js +18 -0
  675. package/dist/models/cards/openai/gpt-4-1.js.map +1 -0
  676. package/dist/models/cards/openai/gpt-4o-mini.d.ts +10 -0
  677. package/dist/models/cards/openai/gpt-4o-mini.d.ts.map +1 -0
  678. package/dist/models/cards/openai/gpt-4o-mini.js +19 -0
  679. package/dist/models/cards/openai/gpt-4o-mini.js.map +1 -0
  680. package/dist/models/cards/openai/gpt-4o.d.ts +10 -0
  681. package/dist/models/cards/openai/gpt-4o.d.ts.map +1 -0
  682. package/dist/models/cards/openai/gpt-4o.js +19 -0
  683. package/dist/models/cards/openai/gpt-4o.js.map +1 -0
  684. package/dist/models/cards/openai/gpt-5-1-reasoning.d.ts +14 -0
  685. package/dist/models/cards/openai/gpt-5-1-reasoning.d.ts.map +1 -0
  686. package/dist/models/cards/openai/gpt-5-1-reasoning.js +29 -0
  687. package/dist/models/cards/openai/gpt-5-1-reasoning.js.map +1 -0
  688. package/dist/models/cards/openai/gpt-5-1.d.ts +11 -0
  689. package/dist/models/cards/openai/gpt-5-1.d.ts.map +1 -0
  690. package/dist/models/cards/openai/gpt-5-1.js +27 -0
  691. package/dist/models/cards/openai/gpt-5-1.js.map +1 -0
  692. package/dist/models/cards/openai/gpt-5-2.d.ts +21 -0
  693. package/dist/models/cards/openai/gpt-5-2.d.ts.map +1 -0
  694. package/dist/models/cards/openai/gpt-5-2.js +37 -0
  695. package/dist/models/cards/openai/gpt-5-2.js.map +1 -0
  696. package/dist/models/cards/openai/gpt-5-4-mini.d.ts +11 -0
  697. package/dist/models/cards/openai/gpt-5-4-mini.d.ts.map +1 -0
  698. package/dist/models/cards/openai/gpt-5-4-mini.js +27 -0
  699. package/dist/models/cards/openai/gpt-5-4-mini.js.map +1 -0
  700. package/dist/models/cards/openai/gpt-5-4.d.ts +11 -0
  701. package/dist/models/cards/openai/gpt-5-4.d.ts.map +1 -0
  702. package/dist/models/cards/openai/gpt-5-4.js +27 -0
  703. package/dist/models/cards/openai/gpt-5-4.js.map +1 -0
  704. package/dist/models/cards/openai/gpt-5-5.d.ts +11 -0
  705. package/dist/models/cards/openai/gpt-5-5.d.ts.map +1 -0
  706. package/dist/models/cards/openai/gpt-5-5.js +27 -0
  707. package/dist/models/cards/openai/gpt-5-5.js.map +1 -0
  708. package/dist/models/cards/openai/gpt-5-chat-latest.d.ts +10 -0
  709. package/dist/models/cards/openai/gpt-5-chat-latest.d.ts.map +1 -0
  710. package/dist/models/cards/openai/gpt-5-chat-latest.js +26 -0
  711. package/dist/models/cards/openai/gpt-5-chat-latest.js.map +1 -0
  712. package/dist/models/cards/openai/gpt-5-codex.d.ts +11 -0
  713. package/dist/models/cards/openai/gpt-5-codex.d.ts.map +1 -0
  714. package/dist/models/cards/openai/gpt-5-codex.js +19 -0
  715. package/dist/models/cards/openai/gpt-5-codex.js.map +1 -0
  716. package/dist/models/cards/openai/gpt-5-mini.d.ts +10 -0
  717. package/dist/models/cards/openai/gpt-5-mini.d.ts.map +1 -0
  718. package/dist/models/cards/openai/gpt-5-mini.js +26 -0
  719. package/dist/models/cards/openai/gpt-5-mini.js.map +1 -0
  720. package/dist/models/cards/openai/gpt-5-nano.d.ts +10 -0
  721. package/dist/models/cards/openai/gpt-5-nano.d.ts.map +1 -0
  722. package/dist/models/cards/openai/gpt-5-nano.js +26 -0
  723. package/dist/models/cards/openai/gpt-5-nano.js.map +1 -0
  724. package/dist/models/cards/openai/gpt-5.d.ts +10 -0
  725. package/dist/models/cards/openai/gpt-5.d.ts.map +1 -0
  726. package/dist/models/cards/openai/gpt-5.js +26 -0
  727. package/dist/models/cards/openai/gpt-5.js.map +1 -0
  728. package/dist/models/cards/openai/index.d.ts +32 -0
  729. package/dist/models/cards/openai/index.d.ts.map +1 -0
  730. package/dist/models/cards/openai/index.js +38 -0
  731. package/dist/models/cards/openai/index.js.map +1 -0
  732. package/dist/models/cards/openai/o1-mini.d.ts +11 -0
  733. package/dist/models/cards/openai/o1-mini.d.ts.map +1 -0
  734. package/dist/models/cards/openai/o1-mini.js +28 -0
  735. package/dist/models/cards/openai/o1-mini.js.map +1 -0
  736. package/dist/models/cards/openai/o1-pro.d.ts +11 -0
  737. package/dist/models/cards/openai/o1-pro.d.ts.map +1 -0
  738. package/dist/models/cards/openai/o1-pro.js +28 -0
  739. package/dist/models/cards/openai/o1-pro.js.map +1 -0
  740. package/dist/models/cards/openai/o1.d.ts +11 -0
  741. package/dist/models/cards/openai/o1.d.ts.map +1 -0
  742. package/dist/models/cards/openai/o1.js +28 -0
  743. package/dist/models/cards/openai/o1.js.map +1 -0
  744. package/dist/models/cards/openai/o3-mini.d.ts +11 -0
  745. package/dist/models/cards/openai/o3-mini.d.ts.map +1 -0
  746. package/dist/models/cards/openai/o3-mini.js +30 -0
  747. package/dist/models/cards/openai/o3-mini.js.map +1 -0
  748. package/dist/models/cards/openai/o3-pro.d.ts +11 -0
  749. package/dist/models/cards/openai/o3-pro.d.ts.map +1 -0
  750. package/dist/models/cards/openai/o3-pro.js +28 -0
  751. package/dist/models/cards/openai/o3-pro.js.map +1 -0
  752. package/dist/models/cards/openai/o3.d.ts +11 -0
  753. package/dist/models/cards/openai/o3.d.ts.map +1 -0
  754. package/dist/models/cards/openai/o3.js +28 -0
  755. package/dist/models/cards/openai/o3.js.map +1 -0
  756. package/dist/models/cards/openai/o4-mini.d.ts +11 -0
  757. package/dist/models/cards/openai/o4-mini.d.ts.map +1 -0
  758. package/dist/models/cards/openai/o4-mini.js +27 -0
  759. package/dist/models/cards/openai/o4-mini.js.map +1 -0
  760. package/dist/models/cards/qwen/index.d.ts +13 -0
  761. package/dist/models/cards/qwen/index.d.ts.map +1 -0
  762. package/dist/models/cards/qwen/index.js +13 -0
  763. package/dist/models/cards/qwen/index.js.map +1 -0
  764. package/dist/models/cards/qwen/qwen-3-coder.d.ts +17 -0
  765. package/dist/models/cards/qwen/qwen-3-coder.d.ts.map +1 -0
  766. package/dist/models/cards/qwen/qwen-3-coder.js +27 -0
  767. package/dist/models/cards/qwen/qwen-3-coder.js.map +1 -0
  768. package/dist/models/cards/qwen/qwen-3-max-preview.d.ts +17 -0
  769. package/dist/models/cards/qwen/qwen-3-max-preview.d.ts.map +1 -0
  770. package/dist/models/cards/qwen/qwen-3-max-preview.js +27 -0
  771. package/dist/models/cards/qwen/qwen-3-max-preview.js.map +1 -0
  772. package/dist/models/cards/qwen/qwen-max.d.ts +10 -0
  773. package/dist/models/cards/qwen/qwen-max.d.ts.map +1 -0
  774. package/dist/models/cards/qwen/qwen-max.js +18 -0
  775. package/dist/models/cards/qwen/qwen-max.js.map +1 -0
  776. package/dist/models/cards/qwen/qwen-plus.d.ts +10 -0
  777. package/dist/models/cards/qwen/qwen-plus.d.ts.map +1 -0
  778. package/dist/models/cards/qwen/qwen-plus.js +18 -0
  779. package/dist/models/cards/qwen/qwen-plus.js.map +1 -0
  780. package/dist/models/cards/qwen/qwen-turbo.d.ts +10 -0
  781. package/dist/models/cards/qwen/qwen-turbo.d.ts.map +1 -0
  782. package/dist/models/cards/qwen/qwen-turbo.js +18 -0
  783. package/dist/models/cards/qwen/qwen-turbo.js.map +1 -0
  784. package/dist/models/cards/xai/grok-4-1-fast-non-reasoning.d.ts +15 -0
  785. package/dist/models/cards/xai/grok-4-1-fast-non-reasoning.d.ts.map +1 -0
  786. package/dist/models/cards/xai/grok-4-1-fast-non-reasoning.js +24 -0
  787. package/dist/models/cards/xai/grok-4-1-fast-non-reasoning.js.map +1 -0
  788. package/dist/models/cards/xai/grok-4-1.d.ts +14 -0
  789. package/dist/models/cards/xai/grok-4-1.d.ts.map +1 -0
  790. package/dist/models/cards/xai/grok-4-1.js +24 -0
  791. package/dist/models/cards/xai/grok-4-1.js.map +1 -0
  792. package/dist/models/cards/xai/grok-4-20-multi-agent.d.ts +13 -0
  793. package/dist/models/cards/xai/grok-4-20-multi-agent.d.ts.map +1 -0
  794. package/dist/models/cards/xai/grok-4-20-multi-agent.js +23 -0
  795. package/dist/models/cards/xai/grok-4-20-multi-agent.js.map +1 -0
  796. package/dist/models/cards/xai/grok-4-20-non-reasoning.d.ts +10 -0
  797. package/dist/models/cards/xai/grok-4-20-non-reasoning.d.ts.map +1 -0
  798. package/dist/models/cards/xai/grok-4-20-non-reasoning.js +19 -0
  799. package/dist/models/cards/xai/grok-4-20-non-reasoning.js.map +1 -0
  800. package/dist/models/cards/xai/grok-4-20-reasoning.d.ts +10 -0
  801. package/dist/models/cards/xai/grok-4-20-reasoning.d.ts.map +1 -0
  802. package/dist/models/cards/xai/grok-4-20-reasoning.js +20 -0
  803. package/dist/models/cards/xai/grok-4-20-reasoning.js.map +1 -0
  804. package/dist/models/cards/xai/grok-4-3.d.ts +11 -0
  805. package/dist/models/cards/xai/grok-4-3.d.ts.map +1 -0
  806. package/dist/models/cards/xai/grok-4-3.js +22 -0
  807. package/dist/models/cards/xai/grok-4-3.js.map +1 -0
  808. package/dist/models/cards/xai/grok-4-fast-non-reasoning.d.ts +13 -0
  809. package/dist/models/cards/xai/grok-4-fast-non-reasoning.d.ts.map +1 -0
  810. package/dist/models/cards/xai/grok-4-fast-non-reasoning.js +22 -0
  811. package/dist/models/cards/xai/grok-4-fast-non-reasoning.js.map +1 -0
  812. package/dist/models/cards/xai/grok-4-fast.d.ts +12 -0
  813. package/dist/models/cards/xai/grok-4-fast.d.ts.map +1 -0
  814. package/dist/models/cards/xai/grok-4-fast.js +21 -0
  815. package/dist/models/cards/xai/grok-4-fast.js.map +1 -0
  816. package/dist/models/cards/xai/grok-build-0-1-responses.d.ts +22 -0
  817. package/dist/models/cards/xai/grok-build-0-1-responses.d.ts.map +1 -0
  818. package/dist/models/cards/xai/grok-build-0-1-responses.js +39 -0
  819. package/dist/models/cards/xai/grok-build-0-1-responses.js.map +1 -0
  820. package/dist/models/cards/xai/grok-build-0-1.d.ts +17 -0
  821. package/dist/models/cards/xai/grok-build-0-1.d.ts.map +1 -0
  822. package/dist/models/cards/xai/grok-build-0-1.js +31 -0
  823. package/dist/models/cards/xai/grok-build-0-1.js.map +1 -0
  824. package/dist/models/cards/xai/grok-code-fast-1.d.ts +10 -0
  825. package/dist/models/cards/xai/grok-code-fast-1.d.ts.map +1 -0
  826. package/dist/models/cards/xai/grok-code-fast-1.js +22 -0
  827. package/dist/models/cards/xai/grok-code-fast-1.js.map +1 -0
  828. package/dist/models/cards/xai/index.d.ts +17 -0
  829. package/dist/models/cards/xai/index.d.ts.map +1 -0
  830. package/dist/models/cards/xai/index.js +18 -0
  831. package/dist/models/cards/xai/index.js.map +1 -0
  832. package/dist/models/configurators/AnthropicConfigurator.d.ts +57 -0
  833. package/dist/models/configurators/AnthropicConfigurator.d.ts.map +1 -0
  834. package/dist/models/configurators/AnthropicConfigurator.js +108 -0
  835. package/dist/models/configurators/AnthropicConfigurator.js.map +1 -0
  836. package/dist/models/configurators/CloudflareConfigurator.d.ts +46 -0
  837. package/dist/models/configurators/CloudflareConfigurator.d.ts.map +1 -0
  838. package/dist/models/configurators/CloudflareConfigurator.js +112 -0
  839. package/dist/models/configurators/CloudflareConfigurator.js.map +1 -0
  840. package/dist/models/configurators/DeepSeekConfigurator.d.ts +26 -0
  841. package/dist/models/configurators/DeepSeekConfigurator.d.ts.map +1 -0
  842. package/dist/models/configurators/DeepSeekConfigurator.js +81 -0
  843. package/dist/models/configurators/DeepSeekConfigurator.js.map +1 -0
  844. package/dist/models/configurators/GLMConfigurator.d.ts +22 -0
  845. package/dist/models/configurators/GLMConfigurator.d.ts.map +1 -0
  846. package/dist/models/configurators/GLMConfigurator.js +82 -0
  847. package/dist/models/configurators/GLMConfigurator.js.map +1 -0
  848. package/dist/models/configurators/GemmaConfigurator.d.ts +18 -0
  849. package/dist/models/configurators/GemmaConfigurator.d.ts.map +1 -0
  850. package/dist/models/configurators/GemmaConfigurator.js +89 -0
  851. package/dist/models/configurators/GemmaConfigurator.js.map +1 -0
  852. package/dist/models/configurators/GoogleConfigurator.d.ts +26 -0
  853. package/dist/models/configurators/GoogleConfigurator.d.ts.map +1 -0
  854. package/dist/models/configurators/GoogleConfigurator.js +91 -0
  855. package/dist/models/configurators/GoogleConfigurator.js.map +1 -0
  856. package/dist/models/configurators/GoogleSDKConfigurator.d.ts +29 -0
  857. package/dist/models/configurators/GoogleSDKConfigurator.d.ts.map +1 -0
  858. package/dist/models/configurators/GoogleSDKConfigurator.js +95 -0
  859. package/dist/models/configurators/GoogleSDKConfigurator.js.map +1 -0
  860. package/dist/models/configurators/HuggingFaceConfigurator.d.ts +31 -0
  861. package/dist/models/configurators/HuggingFaceConfigurator.d.ts.map +1 -0
  862. package/dist/models/configurators/HuggingFaceConfigurator.js +85 -0
  863. package/dist/models/configurators/HuggingFaceConfigurator.js.map +1 -0
  864. package/dist/models/configurators/LocalModelConfigurator.d.ts +30 -0
  865. package/dist/models/configurators/LocalModelConfigurator.d.ts.map +1 -0
  866. package/dist/models/configurators/LocalModelConfigurator.js +88 -0
  867. package/dist/models/configurators/LocalModelConfigurator.js.map +1 -0
  868. package/dist/models/configurators/MercuryConfigurator.d.ts +27 -0
  869. package/dist/models/configurators/MercuryConfigurator.d.ts.map +1 -0
  870. package/dist/models/configurators/MercuryConfigurator.js +91 -0
  871. package/dist/models/configurators/MercuryConfigurator.js.map +1 -0
  872. package/dist/models/configurators/MiniMaxConfigurator.d.ts +47 -0
  873. package/dist/models/configurators/MiniMaxConfigurator.d.ts.map +1 -0
  874. package/dist/models/configurators/MiniMaxConfigurator.js +103 -0
  875. package/dist/models/configurators/MiniMaxConfigurator.js.map +1 -0
  876. package/dist/models/configurators/MoonshotConfigurator.d.ts +21 -0
  877. package/dist/models/configurators/MoonshotConfigurator.d.ts.map +1 -0
  878. package/dist/models/configurators/MoonshotConfigurator.js +81 -0
  879. package/dist/models/configurators/MoonshotConfigurator.js.map +1 -0
  880. package/dist/models/configurators/OpenAIConfigurator.d.ts +52 -0
  881. package/dist/models/configurators/OpenAIConfigurator.d.ts.map +1 -0
  882. package/dist/models/configurators/OpenAIConfigurator.js +128 -0
  883. package/dist/models/configurators/OpenAIConfigurator.js.map +1 -0
  884. package/dist/models/configurators/OpenAIResponsesConfigurator.d.ts +23 -0
  885. package/dist/models/configurators/OpenAIResponsesConfigurator.d.ts.map +1 -0
  886. package/dist/models/configurators/OpenAIResponsesConfigurator.js +113 -0
  887. package/dist/models/configurators/OpenAIResponsesConfigurator.js.map +1 -0
  888. package/dist/models/configurators/QwenConfigurator.d.ts +26 -0
  889. package/dist/models/configurators/QwenConfigurator.d.ts.map +1 -0
  890. package/dist/models/configurators/QwenConfigurator.js +87 -0
  891. package/dist/models/configurators/QwenConfigurator.js.map +1 -0
  892. package/dist/models/configurators/XAIConfigurator.d.ts +52 -0
  893. package/dist/models/configurators/XAIConfigurator.d.ts.map +1 -0
  894. package/dist/models/configurators/XAIConfigurator.js +130 -0
  895. package/dist/models/configurators/XAIConfigurator.js.map +1 -0
  896. package/dist/models/configurators/index.d.ts +19 -0
  897. package/dist/models/configurators/index.d.ts.map +1 -0
  898. package/dist/models/configurators/index.js +19 -0
  899. package/dist/models/configurators/index.js.map +1 -0
  900. package/dist/models/index.d.ts +7 -0
  901. package/dist/models/index.d.ts.map +1 -0
  902. package/dist/models/index.js +7 -0
  903. package/dist/models/index.js.map +1 -0
  904. package/dist/models/registry/ModelAliasResolver.d.ts +109 -0
  905. package/dist/models/registry/ModelAliasResolver.d.ts.map +1 -0
  906. package/dist/models/registry/ModelAliasResolver.js +255 -0
  907. package/dist/models/registry/ModelAliasResolver.js.map +1 -0
  908. package/dist/models/registry/ModelCardLoader.d.ts +44 -0
  909. package/dist/models/registry/ModelCardLoader.d.ts.map +1 -0
  910. package/dist/models/registry/ModelCardLoader.js +124 -0
  911. package/dist/models/registry/ModelCardLoader.js.map +1 -0
  912. package/dist/models/registry/ModularModelRegistry.d.ts +86 -0
  913. package/dist/models/registry/ModularModelRegistry.d.ts.map +1 -0
  914. package/dist/models/registry/ModularModelRegistry.js +311 -0
  915. package/dist/models/registry/ModularModelRegistry.js.map +1 -0
  916. package/dist/models/registry/index.d.ts +8 -0
  917. package/dist/models/registry/index.d.ts.map +1 -0
  918. package/dist/models/registry/index.js +9 -0
  919. package/dist/models/registry/index.js.map +1 -0
  920. package/dist/orchestrator/APIClient.d.ts +274 -0
  921. package/dist/orchestrator/APIClient.d.ts.map +1 -0
  922. package/dist/orchestrator/APIClient.js +2770 -0
  923. package/dist/orchestrator/APIClient.js.map +1 -0
  924. package/dist/orchestrator/CortexOrchestrator.d.ts +986 -0
  925. package/dist/orchestrator/CortexOrchestrator.d.ts.map +1 -0
  926. package/dist/orchestrator/CortexOrchestrator.js +6374 -0
  927. package/dist/orchestrator/CortexOrchestrator.js.map +1 -0
  928. package/dist/orchestrator/OrchestratorFactory.d.ts +81 -0
  929. package/dist/orchestrator/OrchestratorFactory.d.ts.map +1 -0
  930. package/dist/orchestrator/OrchestratorFactory.js +433 -0
  931. package/dist/orchestrator/OrchestratorFactory.js.map +1 -0
  932. package/dist/orchestrator/PauseController.d.ts +126 -0
  933. package/dist/orchestrator/PauseController.d.ts.map +1 -0
  934. package/dist/orchestrator/PauseController.js +248 -0
  935. package/dist/orchestrator/PauseController.js.map +1 -0
  936. package/dist/orchestrator/SubAgentEventEmitter.d.ts +152 -0
  937. package/dist/orchestrator/SubAgentEventEmitter.d.ts.map +1 -0
  938. package/dist/orchestrator/SubAgentEventEmitter.js +372 -0
  939. package/dist/orchestrator/SubAgentEventEmitter.js.map +1 -0
  940. package/dist/orchestrator/SubAgentIPC.d.ts +242 -0
  941. package/dist/orchestrator/SubAgentIPC.d.ts.map +1 -0
  942. package/dist/orchestrator/SubAgentIPC.js +85 -0
  943. package/dist/orchestrator/SubAgentIPC.js.map +1 -0
  944. package/dist/orchestrator/SubAgentManager.d.ts +215 -0
  945. package/dist/orchestrator/SubAgentManager.d.ts.map +1 -0
  946. package/dist/orchestrator/SubAgentManager.js +477 -0
  947. package/dist/orchestrator/SubAgentManager.js.map +1 -0
  948. package/dist/orchestrator/SubAgentOrchestrator.d.ts +125 -0
  949. package/dist/orchestrator/SubAgentOrchestrator.d.ts.map +1 -0
  950. package/dist/orchestrator/SubAgentOrchestrator.js +395 -0
  951. package/dist/orchestrator/SubAgentOrchestrator.js.map +1 -0
  952. package/dist/orchestrator/SubAgentPermissionChecker.d.ts +132 -0
  953. package/dist/orchestrator/SubAgentPermissionChecker.d.ts.map +1 -0
  954. package/dist/orchestrator/SubAgentPermissionChecker.js +239 -0
  955. package/dist/orchestrator/SubAgentPermissionChecker.js.map +1 -0
  956. package/dist/orchestrator/SubAgentProcessManager.d.ts +228 -0
  957. package/dist/orchestrator/SubAgentProcessManager.d.ts.map +1 -0
  958. package/dist/orchestrator/SubAgentProcessManager.js +679 -0
  959. package/dist/orchestrator/SubAgentProcessManager.js.map +1 -0
  960. package/dist/orchestrator/SubAgentTypes.d.ts +428 -0
  961. package/dist/orchestrator/SubAgentTypes.d.ts.map +1 -0
  962. package/dist/orchestrator/SubAgentTypes.js +12 -0
  963. package/dist/orchestrator/SubAgentTypes.js.map +1 -0
  964. package/dist/orchestrator/apiErrorClassifier.d.ts +17 -0
  965. package/dist/orchestrator/apiErrorClassifier.d.ts.map +1 -0
  966. package/dist/orchestrator/apiErrorClassifier.js +38 -0
  967. package/dist/orchestrator/apiErrorClassifier.js.map +1 -0
  968. package/dist/orchestrator/assistantTextPresence.d.ts +32 -0
  969. package/dist/orchestrator/assistantTextPresence.d.ts.map +1 -0
  970. package/dist/orchestrator/assistantTextPresence.js +47 -0
  971. package/dist/orchestrator/assistantTextPresence.js.map +1 -0
  972. package/dist/orchestrator/citationVerification.d.ts +32 -0
  973. package/dist/orchestrator/citationVerification.d.ts.map +1 -0
  974. package/dist/orchestrator/citationVerification.js +47 -0
  975. package/dist/orchestrator/citationVerification.js.map +1 -0
  976. package/dist/orchestrator/coordinateVerification.d.ts +50 -0
  977. package/dist/orchestrator/coordinateVerification.d.ts.map +1 -0
  978. package/dist/orchestrator/coordinateVerification.js +114 -0
  979. package/dist/orchestrator/coordinateVerification.js.map +1 -0
  980. package/dist/orchestrator/cortexTrainingRecord.d.ts +88 -0
  981. package/dist/orchestrator/cortexTrainingRecord.d.ts.map +1 -0
  982. package/dist/orchestrator/cortexTrainingRecord.js +102 -0
  983. package/dist/orchestrator/cortexTrainingRecord.js.map +1 -0
  984. package/dist/orchestrator/index.d.ts +20 -0
  985. package/dist/orchestrator/index.d.ts.map +1 -0
  986. package/dist/orchestrator/index.js +18 -0
  987. package/dist/orchestrator/index.js.map +1 -0
  988. package/dist/orchestrator/mcpAutoInjectPolicy.d.ts +18 -0
  989. package/dist/orchestrator/mcpAutoInjectPolicy.d.ts.map +1 -0
  990. package/dist/orchestrator/mcpAutoInjectPolicy.js +24 -0
  991. package/dist/orchestrator/mcpAutoInjectPolicy.js.map +1 -0
  992. package/dist/orchestrator/staticSystemPromptPin.d.ts +20 -0
  993. package/dist/orchestrator/staticSystemPromptPin.d.ts.map +1 -0
  994. package/dist/orchestrator/staticSystemPromptPin.js +33 -0
  995. package/dist/orchestrator/staticSystemPromptPin.js.map +1 -0
  996. package/dist/orchestrator/toolBudgetSignal.d.ts +41 -0
  997. package/dist/orchestrator/toolBudgetSignal.d.ts.map +1 -0
  998. package/dist/orchestrator/toolBudgetSignal.js +77 -0
  999. package/dist/orchestrator/toolBudgetSignal.js.map +1 -0
  1000. package/dist/orchestrator/toolNameMatcher.d.ts +21 -0
  1001. package/dist/orchestrator/toolNameMatcher.d.ts.map +1 -0
  1002. package/dist/orchestrator/toolNameMatcher.js +69 -0
  1003. package/dist/orchestrator/toolNameMatcher.js.map +1 -0
  1004. package/dist/session/CacheMetricsAccumulator.d.ts +72 -0
  1005. package/dist/session/CacheMetricsAccumulator.d.ts.map +1 -0
  1006. package/dist/session/CacheMetricsAccumulator.js +144 -0
  1007. package/dist/session/CacheMetricsAccumulator.js.map +1 -0
  1008. package/dist/session/CheckpointManager.d.ts +106 -0
  1009. package/dist/session/CheckpointManager.d.ts.map +1 -0
  1010. package/dist/session/CheckpointManager.js +223 -0
  1011. package/dist/session/CheckpointManager.js.map +1 -0
  1012. package/dist/session/JSONLHistoryStore.d.ts +154 -0
  1013. package/dist/session/JSONLHistoryStore.d.ts.map +1 -0
  1014. package/dist/session/JSONLHistoryStore.js +393 -0
  1015. package/dist/session/JSONLHistoryStore.js.map +1 -0
  1016. package/dist/session/MessageTypes.d.ts +269 -0
  1017. package/dist/session/MessageTypes.d.ts.map +1 -0
  1018. package/dist/session/MessageTypes.js +38 -0
  1019. package/dist/session/MessageTypes.js.map +1 -0
  1020. package/dist/session/SessionTimeline.d.ts +304 -0
  1021. package/dist/session/SessionTimeline.d.ts.map +1 -0
  1022. package/dist/session/SessionTimeline.js +396 -0
  1023. package/dist/session/SessionTimeline.js.map +1 -0
  1024. package/dist/session/index.d.ts +10 -0
  1025. package/dist/session/index.d.ts.map +1 -0
  1026. package/dist/session/index.js +10 -0
  1027. package/dist/session/index.js.map +1 -0
  1028. package/dist/system-messages/MessageValidator.d.ts +71 -0
  1029. package/dist/system-messages/MessageValidator.d.ts.map +1 -0
  1030. package/dist/system-messages/MessageValidator.js +305 -0
  1031. package/dist/system-messages/MessageValidator.js.map +1 -0
  1032. package/dist/system-messages/SystemMessageLoader.d.ts +154 -0
  1033. package/dist/system-messages/SystemMessageLoader.d.ts.map +1 -0
  1034. package/dist/system-messages/SystemMessageLoader.js +695 -0
  1035. package/dist/system-messages/SystemMessageLoader.js.map +1 -0
  1036. package/dist/system-messages/SystemMessageRegistry.d.ts +67 -0
  1037. package/dist/system-messages/SystemMessageRegistry.d.ts.map +1 -0
  1038. package/dist/system-messages/SystemMessageRegistry.interface.d.ts +166 -0
  1039. package/dist/system-messages/SystemMessageRegistry.interface.d.ts.map +1 -0
  1040. package/dist/system-messages/SystemMessageRegistry.interface.js +6 -0
  1041. package/dist/system-messages/SystemMessageRegistry.interface.js.map +1 -0
  1042. package/dist/system-messages/SystemMessageRegistry.js +164 -0
  1043. package/dist/system-messages/SystemMessageRegistry.js.map +1 -0
  1044. package/dist/system-messages/SystemMessageStore.d.ts +207 -0
  1045. package/dist/system-messages/SystemMessageStore.d.ts.map +1 -0
  1046. package/dist/system-messages/SystemMessageStore.js +748 -0
  1047. package/dist/system-messages/SystemMessageStore.js.map +1 -0
  1048. package/dist/system-messages/SystemReminderInjector.d.ts +148 -0
  1049. package/dist/system-messages/SystemReminderInjector.d.ts.map +1 -0
  1050. package/dist/system-messages/SystemReminderInjector.js +331 -0
  1051. package/dist/system-messages/SystemReminderInjector.js.map +1 -0
  1052. package/dist/system-messages/docTruncation.d.ts +31 -0
  1053. package/dist/system-messages/docTruncation.d.ts.map +1 -0
  1054. package/dist/system-messages/docTruncation.js +26 -0
  1055. package/dist/system-messages/docTruncation.js.map +1 -0
  1056. package/dist/system-messages/index.d.ts +12 -0
  1057. package/dist/system-messages/index.d.ts.map +1 -0
  1058. package/dist/system-messages/index.js +15 -0
  1059. package/dist/system-messages/index.js.map +1 -0
  1060. package/dist/system-messages/messages/ACTIVE_DISCOVERY.md +26 -0
  1061. package/dist/system-messages/messages/EXAMPLES.md +73 -0
  1062. package/dist/system-messages/messages/PERIODIC_REMINDER.md +6 -0
  1063. package/dist/system-messages/messages/REASONING_GUIDE.md +12 -0
  1064. package/dist/system-messages/messages/SYSTEM_PROMPT.md +47 -0
  1065. package/dist/system-messages/messages/TASK_AGENT_GUIDE.md +5 -0
  1066. package/dist/system-messages/messages/TOOL_USAGE_GUIDE.md +131 -0
  1067. package/dist/system-messages/system-message-registry.json +233 -0
  1068. package/dist/system-messages/turnVaryingClassifier.d.ts +20 -0
  1069. package/dist/system-messages/turnVaryingClassifier.d.ts.map +1 -0
  1070. package/dist/system-messages/turnVaryingClassifier.js +27 -0
  1071. package/dist/system-messages/turnVaryingClassifier.js.map +1 -0
  1072. package/dist/system-messages/types.d.ts +184 -0
  1073. package/dist/system-messages/types.d.ts.map +1 -0
  1074. package/dist/system-messages/types.js +7 -0
  1075. package/dist/system-messages/types.js.map +1 -0
  1076. package/dist/tools/ClientSideToolFilter.d.ts +35 -0
  1077. package/dist/tools/ClientSideToolFilter.d.ts.map +1 -0
  1078. package/dist/tools/ClientSideToolFilter.js +74 -0
  1079. package/dist/tools/ClientSideToolFilter.js.map +1 -0
  1080. package/dist/tools/ServerSideTools.d.ts +181 -0
  1081. package/dist/tools/ServerSideTools.d.ts.map +1 -0
  1082. package/dist/tools/ServerSideTools.js +309 -0
  1083. package/dist/tools/ServerSideTools.js.map +1 -0
  1084. package/dist/tools/ToolFactory.d.ts +88 -0
  1085. package/dist/tools/ToolFactory.d.ts.map +1 -0
  1086. package/dist/tools/ToolFactory.js +153 -0
  1087. package/dist/tools/ToolFactory.js.map +1 -0
  1088. package/dist/tools/context-management/InitCortexContext.d.ts +184 -0
  1089. package/dist/tools/context-management/InitCortexContext.d.ts.map +1 -0
  1090. package/dist/tools/context-management/InitCortexContext.js +1063 -0
  1091. package/dist/tools/context-management/InitCortexContext.js.map +1 -0
  1092. package/dist/tools/context-management/index.d.ts +8 -0
  1093. package/dist/tools/context-management/index.d.ts.map +1 -0
  1094. package/dist/tools/context-management/index.js +7 -0
  1095. package/dist/tools/context-management/index.js.map +1 -0
  1096. package/dist/tools/historical/GetConversationSegment.d.ts +131 -0
  1097. package/dist/tools/historical/GetConversationSegment.d.ts.map +1 -0
  1098. package/dist/tools/historical/GetConversationSegment.js +306 -0
  1099. package/dist/tools/historical/GetConversationSegment.js.map +1 -0
  1100. package/dist/tools/historical/HistoricalContextService.d.ts +229 -0
  1101. package/dist/tools/historical/HistoricalContextService.d.ts.map +1 -0
  1102. package/dist/tools/historical/HistoricalContextService.js +206 -0
  1103. package/dist/tools/historical/HistoricalContextService.js.map +1 -0
  1104. package/dist/tools/historical/ListCompactionBoundaries.d.ts +107 -0
  1105. package/dist/tools/historical/ListCompactionBoundaries.d.ts.map +1 -0
  1106. package/dist/tools/historical/ListCompactionBoundaries.js +175 -0
  1107. package/dist/tools/historical/ListCompactionBoundaries.js.map +1 -0
  1108. package/dist/tools/historical/ListSessions.d.ts +50 -0
  1109. package/dist/tools/historical/ListSessions.d.ts.map +1 -0
  1110. package/dist/tools/historical/ListSessions.js +93 -0
  1111. package/dist/tools/historical/ListSessions.js.map +1 -0
  1112. package/dist/tools/historical/LoadSession.d.ts +51 -0
  1113. package/dist/tools/historical/LoadSession.d.ts.map +1 -0
  1114. package/dist/tools/historical/LoadSession.js +89 -0
  1115. package/dist/tools/historical/LoadSession.js.map +1 -0
  1116. package/dist/tools/historical/RequestHistoricalContext.d.ts +122 -0
  1117. package/dist/tools/historical/RequestHistoricalContext.d.ts.map +1 -0
  1118. package/dist/tools/historical/RequestHistoricalContext.js +250 -0
  1119. package/dist/tools/historical/RequestHistoricalContext.js.map +1 -0
  1120. package/dist/tools/historical/SearchConversationHistory.d.ts +117 -0
  1121. package/dist/tools/historical/SearchConversationHistory.d.ts.map +1 -0
  1122. package/dist/tools/historical/SearchConversationHistory.js +239 -0
  1123. package/dist/tools/historical/SearchConversationHistory.js.map +1 -0
  1124. package/dist/tools/historical/index.d.ts +14 -0
  1125. package/dist/tools/historical/index.d.ts.map +1 -0
  1126. package/dist/tools/historical/index.js +14 -0
  1127. package/dist/tools/historical/index.js.map +1 -0
  1128. package/dist/tools/index.d.ts +15 -0
  1129. package/dist/tools/index.d.ts.map +1 -0
  1130. package/dist/tools/index.js +21 -0
  1131. package/dist/tools/index.js.map +1 -0
  1132. package/dist/tools/mcp-management/ConfigureMcpServer.d.ts +41 -0
  1133. package/dist/tools/mcp-management/ConfigureMcpServer.d.ts.map +1 -0
  1134. package/dist/tools/mcp-management/ConfigureMcpServer.js +147 -0
  1135. package/dist/tools/mcp-management/ConfigureMcpServer.js.map +1 -0
  1136. package/dist/tools/mcp-management/DisableMcpServer.d.ts +39 -0
  1137. package/dist/tools/mcp-management/DisableMcpServer.d.ts.map +1 -0
  1138. package/dist/tools/mcp-management/DisableMcpServer.js +108 -0
  1139. package/dist/tools/mcp-management/DisableMcpServer.js.map +1 -0
  1140. package/dist/tools/mcp-management/EnableMcpServer.d.ts +49 -0
  1141. package/dist/tools/mcp-management/EnableMcpServer.d.ts.map +1 -0
  1142. package/dist/tools/mcp-management/EnableMcpServer.js +134 -0
  1143. package/dist/tools/mcp-management/EnableMcpServer.js.map +1 -0
  1144. package/dist/tools/mcp-management/GetMcpConfig.d.ts +52 -0
  1145. package/dist/tools/mcp-management/GetMcpConfig.d.ts.map +1 -0
  1146. package/dist/tools/mcp-management/GetMcpConfig.js +95 -0
  1147. package/dist/tools/mcp-management/GetMcpConfig.js.map +1 -0
  1148. package/dist/tools/mcp-management/InitMcpConfig.d.ts +113 -0
  1149. package/dist/tools/mcp-management/InitMcpConfig.d.ts.map +1 -0
  1150. package/dist/tools/mcp-management/InitMcpConfig.js +421 -0
  1151. package/dist/tools/mcp-management/InitMcpConfig.js.map +1 -0
  1152. package/dist/tools/mcp-management/ListAvailableMcpServers.d.ts +50 -0
  1153. package/dist/tools/mcp-management/ListAvailableMcpServers.d.ts.map +1 -0
  1154. package/dist/tools/mcp-management/ListAvailableMcpServers.js +92 -0
  1155. package/dist/tools/mcp-management/ListAvailableMcpServers.js.map +1 -0
  1156. package/dist/tools/mcp-management/SearchMcpServers.d.ts +44 -0
  1157. package/dist/tools/mcp-management/SearchMcpServers.d.ts.map +1 -0
  1158. package/dist/tools/mcp-management/SearchMcpServers.js +96 -0
  1159. package/dist/tools/mcp-management/SearchMcpServers.js.map +1 -0
  1160. package/dist/tools/mcp-management/index.d.ts +23 -0
  1161. package/dist/tools/mcp-management/index.d.ts.map +1 -0
  1162. package/dist/tools/mcp-management/index.js +16 -0
  1163. package/dist/tools/mcp-management/index.js.map +1 -0
  1164. package/dist/tools/registries/AddonToolRegistry.d.ts +70 -0
  1165. package/dist/tools/registries/AddonToolRegistry.d.ts.map +1 -0
  1166. package/dist/tools/registries/AddonToolRegistry.js +138 -0
  1167. package/dist/tools/registries/AddonToolRegistry.js.map +1 -0
  1168. package/dist/tools/registries/BaseToolRegistry.d.ts +38 -0
  1169. package/dist/tools/registries/BaseToolRegistry.d.ts.map +1 -0
  1170. package/dist/tools/registries/BaseToolRegistry.js +2058 -0
  1171. package/dist/tools/registries/BaseToolRegistry.js.map +1 -0
  1172. package/dist/tools/registries/index.d.ts +8 -0
  1173. package/dist/tools/registries/index.d.ts.map +1 -0
  1174. package/dist/tools/registries/index.js +8 -0
  1175. package/dist/tools/registries/index.js.map +1 -0
  1176. package/dist/tools/types/CanonicalTool.d.ts +130 -0
  1177. package/dist/tools/types/CanonicalTool.d.ts.map +1 -0
  1178. package/dist/tools/types/CanonicalTool.js +10 -0
  1179. package/dist/tools/types/CanonicalTool.js.map +1 -0
  1180. package/dist/tools/types/index.d.ts +7 -0
  1181. package/dist/tools/types/index.d.ts.map +1 -0
  1182. package/dist/tools/types/index.js +7 -0
  1183. package/dist/tools/types/index.js.map +1 -0
  1184. package/dist/training/AutoResearchGate.d.ts +64 -0
  1185. package/dist/training/AutoResearchGate.d.ts.map +1 -0
  1186. package/dist/training/AutoResearchGate.js +94 -0
  1187. package/dist/training/AutoResearchGate.js.map +1 -0
  1188. package/dist/training/AutoResearchStats.d.ts +128 -0
  1189. package/dist/training/AutoResearchStats.d.ts.map +1 -0
  1190. package/dist/training/AutoResearchStats.js +210 -0
  1191. package/dist/training/AutoResearchStats.js.map +1 -0
  1192. package/dist/training/BenchRunner.d.ts +177 -0
  1193. package/dist/training/BenchRunner.d.ts.map +1 -0
  1194. package/dist/training/BenchRunner.js +211 -0
  1195. package/dist/training/BenchRunner.js.map +1 -0
  1196. package/dist/training/DecisionPriorInjector.d.ts +18 -0
  1197. package/dist/training/DecisionPriorInjector.d.ts.map +1 -0
  1198. package/dist/training/DecisionPriorInjector.js +34 -0
  1199. package/dist/training/DecisionPriorInjector.js.map +1 -0
  1200. package/dist/training/DecisionStore.d.ts +78 -0
  1201. package/dist/training/DecisionStore.d.ts.map +1 -0
  1202. package/dist/training/DecisionStore.js +171 -0
  1203. package/dist/training/DecisionStore.js.map +1 -0
  1204. package/dist/training/ExperimentLedger.d.ts +138 -0
  1205. package/dist/training/ExperimentLedger.d.ts.map +1 -0
  1206. package/dist/training/ExperimentLedger.js +160 -0
  1207. package/dist/training/ExperimentLedger.js.map +1 -0
  1208. package/dist/training/ExperimentRunner.d.ts +88 -0
  1209. package/dist/training/ExperimentRunner.d.ts.map +1 -0
  1210. package/dist/training/ExperimentRunner.js +97 -0
  1211. package/dist/training/ExperimentRunner.js.map +1 -0
  1212. package/dist/training/ModelRouterMatrix.d.ts +197 -0
  1213. package/dist/training/ModelRouterMatrix.d.ts.map +1 -0
  1214. package/dist/training/ModelRouterMatrix.js +0 -0
  1215. package/dist/training/ModelRouterMatrix.js.map +1 -0
  1216. package/dist/training/ResearchBacklog.d.ts +102 -0
  1217. package/dist/training/ResearchBacklog.d.ts.map +1 -0
  1218. package/dist/training/ResearchBacklog.js +149 -0
  1219. package/dist/training/ResearchBacklog.js.map +1 -0
  1220. package/dist/training/TaskClassifier.d.ts +16 -0
  1221. package/dist/training/TaskClassifier.d.ts.map +1 -0
  1222. package/dist/training/TaskClassifier.js +70 -0
  1223. package/dist/training/TaskClassifier.js.map +1 -0
  1224. package/dist/training/ThompsonRouter.d.ts +53 -0
  1225. package/dist/training/ThompsonRouter.d.ts.map +1 -0
  1226. package/dist/training/ThompsonRouter.js +73 -0
  1227. package/dist/training/ThompsonRouter.js.map +1 -0
  1228. package/dist/training/VersionComparison.d.ts +90 -0
  1229. package/dist/training/VersionComparison.d.ts.map +1 -0
  1230. package/dist/training/VersionComparison.js +117 -0
  1231. package/dist/training/VersionComparison.js.map +1 -0
  1232. package/dist/ui/index.d.ts +13 -0
  1233. package/dist/ui/index.d.ts.map +1 -0
  1234. package/dist/ui/index.js +15 -0
  1235. package/dist/ui/index.js.map +1 -0
  1236. package/dist/ui/menu-types.d.ts +314 -0
  1237. package/dist/ui/menu-types.d.ts.map +1 -0
  1238. package/dist/ui/menu-types.js +138 -0
  1239. package/dist/ui/menu-types.js.map +1 -0
  1240. package/dist/ui/types.d.ts +86 -0
  1241. package/dist/ui/types.d.ts.map +1 -0
  1242. package/dist/ui/types.js +12 -0
  1243. package/dist/ui/types.js.map +1 -0
  1244. package/dist/utils/ContextResolver.d.ts +132 -0
  1245. package/dist/utils/ContextResolver.d.ts.map +1 -0
  1246. package/dist/utils/ContextResolver.js +269 -0
  1247. package/dist/utils/ContextResolver.js.map +1 -0
  1248. package/dist/utils/DiffParser.d.ts +101 -0
  1249. package/dist/utils/DiffParser.d.ts.map +1 -0
  1250. package/dist/utils/DiffParser.js +193 -0
  1251. package/dist/utils/DiffParser.js.map +1 -0
  1252. package/dist/utils/ErrorDetector.d.ts +99 -0
  1253. package/dist/utils/ErrorDetector.d.ts.map +1 -0
  1254. package/dist/utils/ErrorDetector.js +258 -0
  1255. package/dist/utils/ErrorDetector.js.map +1 -0
  1256. package/dist/utils/TokenCounter.d.ts +97 -0
  1257. package/dist/utils/TokenCounter.d.ts.map +1 -0
  1258. package/dist/utils/TokenCounter.js +193 -0
  1259. package/dist/utils/TokenCounter.js.map +1 -0
  1260. package/dist/utils/agentDiscovery.d.ts +12 -0
  1261. package/dist/utils/agentDiscovery.d.ts.map +1 -0
  1262. package/dist/utils/agentDiscovery.js +72 -0
  1263. package/dist/utils/agentDiscovery.js.map +1 -0
  1264. package/dist/utils/ids.d.ts +5 -0
  1265. package/dist/utils/ids.d.ts.map +1 -0
  1266. package/dist/utils/ids.js +14 -0
  1267. package/dist/utils/ids.js.map +1 -0
  1268. package/dist/utils/index.d.ts +14 -0
  1269. package/dist/utils/index.d.ts.map +1 -0
  1270. package/dist/utils/index.js +14 -0
  1271. package/dist/utils/index.js.map +1 -0
  1272. package/dist/utils/logger.d.ts +22 -0
  1273. package/dist/utils/logger.d.ts.map +1 -0
  1274. package/dist/utils/logger.js +44 -0
  1275. package/dist/utils/logger.js.map +1 -0
  1276. package/package.json +87 -0
@@ -0,0 +1,2770 @@
1
+ /**
2
+ * API Client
3
+ * Handles actual HTTP requests to AI provider APIs
4
+ *
5
+ * Phase 2.1: Real API Integration
6
+ */
7
+ import Anthropic from '@anthropic-ai/sdk';
8
+ import OpenAI from 'openai';
9
+ import { GoogleGenerativeAI } from '@google/generative-ai';
10
+ import { GoogleGenAI } from '@google/genai';
11
+ import { v4 as uuidv4 } from 'uuid';
12
+ import { anthropicCredentialService, CredentialError } from '../config/AnthropicCredentialService.js';
13
+ /**
14
+ * Anthropic families on the adaptive-thinking-only request surface — sending
15
+ * thinking.type 'enabled'/budget_tokens returns a 400 (sampling params are
16
+ * rejected too, but cards opt out by leaving temperature.default unset).
17
+ * Fable 5 is stricter still: an explicit {type:'disabled'} also 400s — both
18
+ * request paths already OMIT thinking instead of disabling it explicitly.
19
+ */
20
+ const ANTHROPIC_ADAPTIVE_THINKING_FAMILIES = new Set([
21
+ 'claude-4.7',
22
+ 'claude-4.8',
23
+ 'claude-fable-5'
24
+ ]);
25
+ /**
26
+ * API Client for making requests to AI providers
27
+ *
28
+ * Supports: Anthropic, OpenAI, Google (Gemini + Gemma)
29
+ */
30
+ export class APIClient {
31
+ anthropicClient;
32
+ openaiClient;
33
+ googleClient;
34
+ googleGenAIClient;
35
+ constructor() {
36
+ // Initialize clients lazily when needed
37
+ }
38
+ /**
39
+ * Decode HTML entities in an object (recursive)
40
+ *
41
+ * WORKAROUND for model bugs (e.g., grok-4-1-fast) that incorrectly
42
+ * encode special characters in tool call arguments.
43
+ *
44
+ * @param obj - Object to decode (may contain nested objects/arrays)
45
+ * @returns Decoded object with HTML entities converted to plain characters
46
+ */
47
+ decodeHtmlEntitiesInObject(obj) {
48
+ if (typeof obj === 'string') {
49
+ // Decode common HTML entities
50
+ return obj
51
+ .replace(/&/g, '&')
52
+ .replace(/&lt;/g, '<')
53
+ .replace(/&gt;/g, '>')
54
+ .replace(/&quot;/g, '"')
55
+ .replace(/&#39;/g, "'")
56
+ .replace(/&apos;/g, "'");
57
+ }
58
+ if (Array.isArray(obj)) {
59
+ return obj.map(item => this.decodeHtmlEntitiesInObject(item));
60
+ }
61
+ if (obj !== null && typeof obj === 'object') {
62
+ const decoded = {};
63
+ for (const key in obj) {
64
+ if (obj.hasOwnProperty(key)) {
65
+ decoded[key] = this.decodeHtmlEntitiesInObject(obj[key]);
66
+ }
67
+ }
68
+ return decoded;
69
+ }
70
+ return obj;
71
+ }
72
+ /**
73
+ * Attempt to repair truncated JSON from streaming tool arguments.
74
+ * When providers truncate output (max_tokens), the accumulated JSON is incomplete.
75
+ * Tries progressively aggressive repairs: closing open strings, objects, arrays.
76
+ */
77
+ repairTruncatedJSON(raw) {
78
+ const trimmed = raw.trim();
79
+ if (!trimmed)
80
+ throw new Error('Empty JSON');
81
+ // Try direct parse first
82
+ try {
83
+ return JSON.parse(trimmed);
84
+ }
85
+ catch { /* continue */ }
86
+ // Try closing open string + object combinations
87
+ const repairs = [
88
+ trimmed + '"}',
89
+ trimmed + '"}}',
90
+ trimmed + '"]',
91
+ trimmed + '"}]',
92
+ trimmed + '}',
93
+ trimmed + '}}',
94
+ ];
95
+ for (const attempt of repairs) {
96
+ try {
97
+ const parsed = JSON.parse(attempt);
98
+ if (typeof parsed === 'object' && parsed !== null) {
99
+ if (process.env.DEBUG === 'true')
100
+ console.log(`[APIClient] Repaired truncated JSON (${raw.length} chars) by appending ${attempt.slice(trimmed.length)}`);
101
+ return parsed;
102
+ }
103
+ }
104
+ catch { /* continue */ }
105
+ }
106
+ throw new Error(`Cannot repair truncated JSON (${raw.length} chars)`);
107
+ }
108
+ /**
109
+ * Send request to provider API
110
+ *
111
+ * Routes by API PATTERN (not provider) to maintain architectural consistency.
112
+ * The pattern is specified in modelConfig.api.pattern and determines which
113
+ * adapter and API endpoint to use.
114
+ *
115
+ * @param request - Prepared request from GatewayTranslationLayer
116
+ * @param modelConfig - Model configuration
117
+ * @returns Provider response
118
+ */
119
+ async sendRequest(request, modelConfig) {
120
+ // Clamp any requested temperature to THIS model's valid range before dispatch — the
121
+ // cross-provider gate (e.g. Anthropic is 0–1, OpenAI/DeepSeek 0–2). Lets a per-subagent
122
+ // temperature (an auto-research diversity lever) vary freely without 400-ing a model whose
123
+ // range is narrower. Applies to every API pattern below.
124
+ const tRange = modelConfig.parameters?.temperature;
125
+ const t = request.parameters?.temperature;
126
+ if (typeof t === 'number' && Number.isFinite(t) && tRange) {
127
+ const clamped = Math.max(tRange.min ?? 0, Math.min(tRange.max ?? 2, t));
128
+ if (clamped !== t)
129
+ request.parameters.temperature = clamped;
130
+ }
131
+ const apiPattern = modelConfig.api.pattern;
132
+ switch (apiPattern) {
133
+ case 'messages':
134
+ // Anthropic Messages API (used by Anthropic, XAI)
135
+ return this.sendMessagesAPI(request, modelConfig);
136
+ case 'chat/completions':
137
+ // OpenAI Chat Completions API (used by OpenAI, XAI, DeepSeek, Groq)
138
+ return this.sendChatCompletionsAPI(request, modelConfig);
139
+ case 'responses':
140
+ // OpenAI Responses API (used by OpenAI gpt-5-codex, XAI stateful)
141
+ return this.sendResponsesAPI(request, modelConfig);
142
+ case 'generateContent':
143
+ // Google Gemini GenerateContent API
144
+ return this.sendGenerateContentAPI(request, modelConfig);
145
+ case 'google-genai':
146
+ // Google GenAI API (FREE Gemma models)
147
+ return this.sendGoogleGenAIRequest(request, modelConfig);
148
+ case 'google-sdk':
149
+ // Google SDK with full tool support
150
+ return this.sendGoogleSDK(request, modelConfig);
151
+ default:
152
+ throw new Error(`Unsupported API pattern: ${apiPattern}`);
153
+ }
154
+ }
155
+ /**
156
+ * Stream request to provider API (with real-time chunks)
157
+ *
158
+ * Routes by API PATTERN (not provider) to maintain architectural consistency
159
+ * with non-streaming sendRequest() method
160
+ *
161
+ * @param request - Prepared request from GatewayTranslationLayer
162
+ * @param modelConfig - Model configuration
163
+ * @returns Streaming response with chunks and final message
164
+ */
165
+ streamRequest(request, modelConfig) {
166
+ const apiPattern = modelConfig.api.pattern;
167
+ switch (apiPattern) {
168
+ case 'messages':
169
+ // Anthropic Messages API (used by Anthropic, XAI)
170
+ return this.streamMessagesAPI(request, modelConfig);
171
+ case 'chat/completions':
172
+ // OpenAI Chat Completions API (used by OpenAI, XAI, DeepSeek, Groq)
173
+ return this.streamChatCompletionsAPI(request, modelConfig);
174
+ case 'responses':
175
+ // OpenAI Responses API (used by OpenAI gpt-5-codex, XAI stateful)
176
+ return this.streamResponsesAPI(request, modelConfig);
177
+ case 'generateContent':
178
+ // Google Gemini GenerateContent API
179
+ return this.streamGenerateContentAPI(request, modelConfig);
180
+ case 'google-genai':
181
+ throw new Error('Streaming not supported for google-genai pattern');
182
+ case 'google-sdk':
183
+ // Google SDK with full tool support (experimental)
184
+ return this.streamGoogleSDK(request, modelConfig);
185
+ default:
186
+ throw new Error(`Unsupported API pattern for streaming: ${apiPattern}`);
187
+ }
188
+ }
189
+ /**
190
+ * Send request using Messages API pattern
191
+ *
192
+ * Used by: Anthropic (native), XAI (Anthropic-compatible)
193
+ * Format: Anthropic Messages API
194
+ */
195
+ async sendMessagesAPI(request, modelConfig) {
196
+ const provider = modelConfig.provider.toLowerCase();
197
+ // Anthropic: Use native SDK
198
+ if (provider === 'anthropic') {
199
+ return this.sendAnthropicMessagesAPI(request, modelConfig);
200
+ }
201
+ // XAI: Use Anthropic-compatible Messages API
202
+ if (provider === 'xai') {
203
+ return this.sendXAIMessagesAPI(request, modelConfig);
204
+ }
205
+ throw new Error(`Messages API not supported for provider: ${provider}`);
206
+ }
207
+ /**
208
+ * Send request to Anthropic Messages API (native)
209
+ *
210
+ * Supports:
211
+ * - OAuth authentication (Claude.ai Max subscriptions)
212
+ * - API key authentication (traditional)
213
+ * - Prompt caching for 90% cost reduction
214
+ */
215
+ async sendAnthropicMessagesAPI(request, modelConfig) {
216
+ // Initialize Anthropic client with OAuth or API key
217
+ if (!this.anthropicClient) {
218
+ this.anthropicClient = this.initializeAnthropicClient();
219
+ }
220
+ // Phase 2.8: Extract internal flags before building request
221
+ // Note: Anthropic requires thinking blocks to precede tool_use in assistant messages
222
+ // when thinking is enabled. Continuations after tool execution must respect this ordering.
223
+ const disableThinking = request.parameters.disableThinking;
224
+ const reasoningEffort = request.parameters.reasoningEffort;
225
+ // Exclude internal flags from API request parameters
226
+ const { disableThinking: _, reasoningEffort: _re, ...apiParameters } = request.parameters;
227
+ // Check if prompt caching is enabled
228
+ const enableCaching = process.env.ANTHROPIC_PROMPT_CACHING !== 'false';
229
+ // Build Anthropic request
230
+ const anthropicRequest = {
231
+ model: request.modelId,
232
+ messages: request.messages,
233
+ max_tokens: request.parameters.max_tokens || request.parameters.maxTokens || 4096,
234
+ ...apiParameters
235
+ };
236
+ // Add system message if present (with cache_control for caching)
237
+ if (request.systemMessage) {
238
+ if (enableCaching) {
239
+ // Use array format with cache_control for prompt caching
240
+ anthropicRequest.system = [{
241
+ type: 'text',
242
+ text: request.systemMessage,
243
+ cache_control: { type: 'ephemeral' }
244
+ }];
245
+ }
246
+ else {
247
+ anthropicRequest.system = request.systemMessage;
248
+ }
249
+ }
250
+ // Add tools if present (with cache_control on last tool for caching)
251
+ if (request.tools && request.tools.length > 0) {
252
+ if (enableCaching) {
253
+ // Clone tools and add cache_control to last tool
254
+ const tools = request.tools.map((tool, index) => {
255
+ if (index === request.tools.length - 1) {
256
+ return { ...tool, cache_control: { type: 'ephemeral' } };
257
+ }
258
+ return tool;
259
+ });
260
+ anthropicRequest.tools = tools;
261
+ }
262
+ else {
263
+ anthropicRequest.tools = request.tools;
264
+ }
265
+ }
266
+ // Phase 2.8: Enable extended thinking for Claude 4+ models with reasoning support
267
+ // Requires beta header: anthropic-beta: interleaved-thinking-2025-05-14
268
+ // Skip if disableThinking option is set (used for continuation requests)
269
+ // reasoningEffort scales budget_tokens: none/undefined=10000 (default), low=5000, medium=10000, high=50000
270
+ // Note: 'none' means "no extra effort" = default budget. Thinking is always on for supported models.
271
+ if (modelConfig.reasoning?.supported && modelConfig.reasoning?.pattern === 'interleaved' && !disableThinking) {
272
+ // Opus 4.7/4.8 and Fable 5 REMOVED thinking.type=enabled / budget_tokens (400).
273
+ // They require thinking.type=adaptive (+ optional output_config.effort). Older
274
+ // Claude families still accept enabled.
275
+ const useAdaptive = ANTHROPIC_ADAPTIVE_THINKING_FAMILIES.has(modelConfig.family);
276
+ if (useAdaptive) {
277
+ // Opus 4.7/4.8 adaptive thinking defaults to display:'omitted' (empty thinking
278
+ // blocks, $0 reasoning tokens). DEBUG_THINKING opts into 'summarized' to surface
279
+ // reasoning in the CLI — costs extra output tokens, so it's off by default.
280
+ anthropicRequest.thinking =
281
+ process.env.DEBUG_THINKING === 'true'
282
+ ? { type: 'adaptive', display: 'summarized' }
283
+ : { type: 'adaptive' };
284
+ }
285
+ else {
286
+ const budgetMap = {
287
+ none: 10000,
288
+ low: 5000,
289
+ medium: 10000,
290
+ high: 50000,
291
+ };
292
+ const budgetTokens = reasoningEffort ? (budgetMap[reasoningEffort] || 10000) : 10000;
293
+ anthropicRequest.thinking = {
294
+ type: 'enabled',
295
+ budget_tokens: budgetTokens
296
+ };
297
+ }
298
+ }
299
+ // Build beta headers
300
+ const betaFeatures = [];
301
+ if (anthropicRequest.thinking) {
302
+ betaFeatures.push('interleaved-thinking-2025-05-14');
303
+ }
304
+ if (enableCaching) {
305
+ betaFeatures.push('prompt-caching-2024-07-31');
306
+ }
307
+ const headers = betaFeatures.length > 0
308
+ ? { 'anthropic-beta': betaFeatures.join(',') }
309
+ : undefined;
310
+ const response = await this.anthropicClient.messages.create(anthropicRequest, { headers });
311
+ return {
312
+ data: response,
313
+ status: 200,
314
+ headers: {}
315
+ };
316
+ }
317
+ /**
318
+ * Initialize Anthropic client with OAuth or API key
319
+ *
320
+ * Priority:
321
+ * 1. ~/.claude/.credentials.json (OAuth from Claude.ai Max)
322
+ * 2. CLAUDE_CODE_OAUTH_TOKEN env var (OAuth override)
323
+ * 3. ANTHROPIC_API_KEY env var (API key fallback)
324
+ */
325
+ initializeAnthropicClient() {
326
+ const authMethod = (process.env.ANTHROPIC_AUTH_METHOD || 'auto');
327
+ try {
328
+ const credential = anthropicCredentialService.loadCredential(authMethod);
329
+ if (process.env.DEBUG === 'true') {
330
+ console.log(`[APIClient] Using Anthropic credential: ${anthropicCredentialService.getCredentialSummary(credential)}`);
331
+ }
332
+ // Check for token expiry warning (7 days)
333
+ const daysUntilExpiry = anthropicCredentialService.getDaysUntilExpiry(credential);
334
+ if (daysUntilExpiry !== null && daysUntilExpiry <= 7) {
335
+ console.warn(`[APIClient] OAuth token expires in ${daysUntilExpiry} days. Run \`claude login\` to refresh.`);
336
+ }
337
+ // For OAuth tokens, use authToken parameter (Bearer auth)
338
+ // For API keys, use apiKey parameter (x-api-key header)
339
+ if (credential.type === 'oauth') {
340
+ return new Anthropic({
341
+ authToken: credential.token, // Uses Authorization: Bearer header
342
+ });
343
+ }
344
+ else {
345
+ return new Anthropic({
346
+ apiKey: credential.token, // Uses x-api-key header
347
+ });
348
+ }
349
+ }
350
+ catch (error) {
351
+ if (error instanceof CredentialError) {
352
+ throw new Error(`Anthropic authentication failed: ${error.message}`);
353
+ }
354
+ throw error;
355
+ }
356
+ }
357
+ /**
358
+ * Send request to XAI Messages API (Anthropic-compatible)
359
+ */
360
+ async sendXAIMessagesAPI(request, modelConfig) {
361
+ const apiKey = process.env[modelConfig.api.apiKeyEnvVar];
362
+ if (!apiKey) {
363
+ throw new Error(`Missing API key: ${modelConfig.api.apiKeyEnvVar}`);
364
+ }
365
+ // Extract internal flags before spreading into API request
366
+ // XAI Messages API does NOT support Anthropic's thinking parameter —
367
+ // XAI models think natively (embedded <thinking> tags or thinking content blocks)
368
+ const { disableThinking, reasoningEffort, ...apiParameters } = request.parameters;
369
+ // Build request (Anthropic Messages API format)
370
+ const messagesRequest = {
371
+ model: request.modelId,
372
+ messages: request.messages,
373
+ max_tokens: apiParameters.max_tokens || apiParameters.maxTokens || 4096,
374
+ ...apiParameters
375
+ };
376
+ if (request.systemMessage) {
377
+ messagesRequest.system = request.systemMessage;
378
+ }
379
+ if (request.tools && request.tools.length > 0) {
380
+ messagesRequest.tools = request.tools;
381
+ }
382
+ const debugPayloadXai = process.env.DEBUG_PAYLOAD;
383
+ if (debugPayloadXai === '1' || debugPayloadXai === '2') {
384
+ try {
385
+ const msgBytes = JSON.stringify(messagesRequest.messages || []).length;
386
+ const toolBytes = JSON.stringify(messagesRequest.tools || []).length;
387
+ const totalBytes = JSON.stringify(messagesRequest).length;
388
+ const sysBytes = messagesRequest.system ? JSON.stringify(messagesRequest.system).length : 0;
389
+ const toolCount = messagesRequest.tools?.length || 0;
390
+ const msgCount = messagesRequest.messages?.length || 0;
391
+ const lastUserMsg = messagesRequest.messages?.filter((m) => m.role === 'user').slice(-1)[0];
392
+ const lastUserBytes = lastUserMsg ? JSON.stringify(lastUserMsg).length : 0;
393
+ console.error(`[DEBUG_PAYLOAD-xai] model=${request.modelId} total=${totalBytes}B msgs=${msgCount}/${msgBytes}B tools=${toolCount}/${toolBytes}B sysMsg=${sysBytes}B lastUserMsg=${lastUserBytes}B`);
394
+ if (debugPayloadXai === '2') {
395
+ const breakdown = (messagesRequest.messages || []).map((m, i) => `${i}:${m.role}=${JSON.stringify(m).length}B`).join(' ');
396
+ console.error(`[DEBUG_PAYLOAD-xai] msg breakdown: ${breakdown}`);
397
+ if (messagesRequest.system) {
398
+ const sysContent = typeof messagesRequest.system === 'string' ? messagesRequest.system : JSON.stringify(messagesRequest.system);
399
+ console.error(`[DEBUG_PAYLOAD-xai] sysMsg first 600c: ${sysContent.slice(0, 600)}`);
400
+ console.error(`[DEBUG_PAYLOAD-xai] sysMsg last 400c: ${sysContent.slice(-400)}`);
401
+ }
402
+ if (lastUserMsg) {
403
+ const lastUserContent = typeof lastUserMsg.content === 'string' ? lastUserMsg.content : JSON.stringify(lastUserMsg.content);
404
+ // Find user prompts vs system-reminder boundaries
405
+ const blocks = [];
406
+ if (Array.isArray(lastUserMsg.content)) {
407
+ for (const block of lastUserMsg.content) {
408
+ const text = block.text || block.content || JSON.stringify(block);
409
+ const trimmed = text.length > 200 ? text.slice(0, 100) + '...[' + (text.length - 200) + 'B truncated]...' + text.slice(-100) : text;
410
+ const cacheMarker = block.cache_control ? ` cache=${JSON.stringify(block.cache_control)}` : '';
411
+ blocks.push(`{type=${block.type}${cacheMarker}, len=${text.length}: ${trimmed}}`);
412
+ }
413
+ console.error(`[DEBUG_PAYLOAD-xai] lastUserMsg blocks (${lastUserMsg.content.length}): ${blocks.join(' | ')}`);
414
+ }
415
+ else {
416
+ console.error(`[DEBUG_PAYLOAD-xai] lastUserMsg first 1500c: ${lastUserContent.slice(0, 1500)}`);
417
+ console.error(`[DEBUG_PAYLOAD-xai] lastUserMsg last 500c: ${lastUserContent.slice(-500)}`);
418
+ }
419
+ }
420
+ // Also dump first user message to see what user originally sent
421
+ const firstUserMsg = messagesRequest.messages?.find((m) => m.role === 'user');
422
+ if (firstUserMsg && firstUserMsg !== lastUserMsg) {
423
+ const firstUserContent = typeof firstUserMsg.content === 'string' ? firstUserMsg.content : JSON.stringify(firstUserMsg.content);
424
+ console.error(`[DEBUG_PAYLOAD-xai] firstUserMsg: ${firstUserContent.slice(0, 400)}`);
425
+ }
426
+ if (messagesRequest.tools && messagesRequest.tools.length > 0) {
427
+ const toolNames = messagesRequest.tools.map((t) => (t.name || t.function?.name) + '=' + JSON.stringify(t).length + 'B').join(', ');
428
+ console.error(`[DEBUG_PAYLOAD-xai] tools: ${toolNames}`);
429
+ }
430
+ }
431
+ }
432
+ catch (e) {
433
+ console.error(`[DEBUG_PAYLOAD-xai] failed to log:`, e);
434
+ }
435
+ }
436
+ // Make raw HTTP request to XAI Messages API.
437
+ // `x-grok-conv-id` routes same-session requests to same server for cache hits —
438
+ // per XAI docs (advanced-api-usage/prompt-caching/maximizing-cache-hits).
439
+ const headers = {
440
+ 'Content-Type': 'application/json',
441
+ [modelConfig.api.authHeader]: apiKey,
442
+ 'anthropic-version': '2023-06-01'
443
+ };
444
+ if (request.conversationId) {
445
+ headers['x-grok-conv-id'] = request.conversationId;
446
+ }
447
+ const httpResponse = await fetch(modelConfig.api.endpoint, {
448
+ method: 'POST',
449
+ headers,
450
+ body: JSON.stringify(messagesRequest)
451
+ });
452
+ if (!httpResponse.ok) {
453
+ const errorText = await httpResponse.text();
454
+ throw new Error(`XAI Messages API error (${httpResponse.status}): ${errorText}`);
455
+ }
456
+ const data = await httpResponse.json();
457
+ // Post-process: extract <thinking> tags from text content into separate thinking blocks
458
+ // grok-4-1-fast-reasoning embeds thinking in text as <thinking>...</thinking> tags
459
+ if (data.content && Array.isArray(data.content)) {
460
+ data.content = this.extractThinkingFromTextBlocks(data.content);
461
+ }
462
+ return {
463
+ data,
464
+ status: httpResponse.status,
465
+ headers: Object.fromEntries(httpResponse.headers.entries())
466
+ };
467
+ }
468
+ /**
469
+ * Extract <thinking> tags from text content blocks into separate thinking content blocks.
470
+ * XAI grok-4-1-fast-reasoning embeds native thinking in text as <thinking>...</thinking> tags.
471
+ * This converts them to proper thinking blocks so the UI can display them correctly.
472
+ */
473
+ extractThinkingFromTextBlocks(content) {
474
+ const result = [];
475
+ for (const block of content) {
476
+ if (block.type !== 'text' || !block.text) {
477
+ result.push(block);
478
+ continue;
479
+ }
480
+ const text = block.text;
481
+ const thinkingRegex = /<thinking>([\s\S]*?)<\/thinking>/g;
482
+ let lastIndex = 0;
483
+ let match;
484
+ let hasThinking = false;
485
+ while ((match = thinkingRegex.exec(text)) !== null) {
486
+ hasThinking = true;
487
+ // Add any text before the thinking tag
488
+ const beforeText = text.slice(lastIndex, match.index).trim();
489
+ if (beforeText) {
490
+ result.push({ type: 'text', text: beforeText });
491
+ }
492
+ // Add thinking block
493
+ result.push({
494
+ type: 'thinking',
495
+ thinking: (match[1] ?? '').trim()
496
+ });
497
+ lastIndex = match.index + match[0].length;
498
+ }
499
+ if (hasThinking) {
500
+ // Add any remaining text after the last thinking tag
501
+ const afterText = text.slice(lastIndex).trim();
502
+ if (afterText) {
503
+ result.push({ type: 'text', text: afterText });
504
+ }
505
+ }
506
+ else {
507
+ // No thinking tags — keep original block
508
+ result.push(block);
509
+ }
510
+ }
511
+ return result;
512
+ }
513
+ /**
514
+ * Round 7 (parallel-bench output): shared request-construction helper.
515
+ *
516
+ * `sendChatCompletionsAPI` and `streamChatCompletionsAPI` previously
517
+ * duplicated ~100 lines each (API key check, baseURL strip, OpenRouter
518
+ * headers, client construction, max_tokens→max_completion_tokens rename,
519
+ * reasoning_effort handling, tool attachment, DEBUG_PAYLOAD logging).
520
+ * This helper builds {client, chatRequest} for both callers; the streaming
521
+ * caller passes `stream: true` and continues into its generator loop.
522
+ *
523
+ * Behavior note (called out in commit): non-streaming previously did NOT
524
+ * reuse `this.openaiClient` for the openai provider — the unified helper
525
+ * does. This reduces socket churn and matches the streaming path; no
526
+ * external semantics change.
527
+ */
528
+ buildChatCompletionsRequest(request, modelConfig, opts) {
529
+ const apiKey = process.env[modelConfig.api.apiKeyEnvVar];
530
+ if (!apiKey) {
531
+ throw new Error(`Missing API key: ${modelConfig.api.apiKeyEnvVar}`);
532
+ }
533
+ // Extract base URL (remove endpoint-specific paths)
534
+ const baseURL = modelConfig.api.endpoint
535
+ .replace('/chat/completions', '')
536
+ .replace('/messages', '')
537
+ .replace('/responses', '');
538
+ const defaultHeaders = {};
539
+ // Reuse cached openai client when possible (matches the streaming path's
540
+ // pre-refactor behavior; now applied uniformly).
541
+ const client = modelConfig.provider.toLowerCase() === 'openai' && this.openaiClient
542
+ ? this.openaiClient
543
+ : new OpenAI({
544
+ apiKey,
545
+ baseURL,
546
+ ...(Object.keys(defaultHeaders).length > 0 && { defaultHeaders })
547
+ });
548
+ // Phase 2.8: Exclude internal flags from API request parameters
549
+ const { disableThinking, ...apiParameters } = request.parameters;
550
+ // Transform max_tokens to max_completion_tokens if model requires it (GPT-5 family)
551
+ const maxTokensParamName = modelConfig.parameters?.maxTokens?.paramName || 'max_tokens';
552
+ let transformedParams = { ...apiParameters };
553
+ if (maxTokensParamName === 'max_completion_tokens') {
554
+ if ('max_tokens' in transformedParams) {
555
+ transformedParams.max_completion_tokens = transformedParams.max_tokens;
556
+ delete transformedParams.max_tokens;
557
+ }
558
+ if ('maxTokens' in transformedParams) {
559
+ transformedParams.max_completion_tokens = transformedParams.maxTokens;
560
+ delete transformedParams.maxTokens;
561
+ }
562
+ }
563
+ // Extract reasoningEffort before spreading (custom param, not OpenAI)
564
+ const reasoningEffort = transformedParams.reasoningEffort || 'medium';
565
+ delete transformedParams.reasoningEffort;
566
+ // Build the request body
567
+ const chatRequest = {
568
+ model: request.modelId,
569
+ messages: request.messages,
570
+ ...transformedParams,
571
+ ...(opts.stream ? { stream: true } : {}),
572
+ };
573
+ // R19b: OpenAI chat/completions REJECTS `reasoning_effort` + tools for
574
+ // some gpt-5 variants (`gpt-5.4`, possibly others) with
575
+ // "400 Function tools with reasoning_effort are not supported for ... in /v1/chat/completions".
576
+ // Drop reasoning_effort silently when both are present on chat/completions;
577
+ // the model still works without explicit reasoning effort (defaults apply).
578
+ const willAttachTools = !!(request.tools && request.tools.length > 0);
579
+ const isChatCompletionsRoute = modelConfig.api.pattern === 'chat/completions';
580
+ const dropReasoningForToolCompat = willAttachTools && isChatCompletionsRoute && modelConfig.provider === 'openai';
581
+ // Enable reasoning for OpenAI models that support it (GPT-5 family, o-series)
582
+ if (modelConfig.reasoning?.supported &&
583
+ !disableThinking &&
584
+ reasoningEffort !== 'none' &&
585
+ !dropReasoningForToolCompat) {
586
+ chatRequest.reasoning_effort = reasoningEffort;
587
+ delete chatRequest.temperature;
588
+ delete chatRequest.top_p;
589
+ delete chatRequest.logprobs;
590
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
591
+ const tag = opts.stream ? 'streaming ' : '';
592
+ console.log(`[DEBUG APIClient] Reasoning ENABLED for ${tag}${modelConfig.id} (effort: ${reasoningEffort}, removed temperature/top_p)`);
593
+ }
594
+ }
595
+ else if (dropReasoningForToolCompat && (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true')) {
596
+ console.log(`[DEBUG APIClient] Reasoning DROPPED for ${modelConfig.id} — chat/completions doesn't support reasoning_effort+tools combo (R19b)`);
597
+ }
598
+ else if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
599
+ const tag = opts.stream ? 'streaming ' : '';
600
+ console.log(`[DEBUG APIClient] Reasoning DISABLED for ${tag}${modelConfig.id} (effort: ${reasoningEffort}, disableThinking: ${disableThinking})`);
601
+ }
602
+ // Attach tools
603
+ if (request.tools && request.tools.length > 0) {
604
+ chatRequest.tools = request.tools;
605
+ }
606
+ this.logChatCompletionsPayload(chatRequest, request.modelId, opts.stream);
607
+ return { client, chatRequest };
608
+ }
609
+ /**
610
+ * DEBUG_PAYLOAD logging extracted from both send/stream methods.
611
+ * Same observable output as before; suffix `-stream` on the log tag
612
+ * distinguishes streaming-side breakdowns.
613
+ */
614
+ logChatCompletionsPayload(chatRequest, modelId, streaming) {
615
+ const debugPayload = process.env.DEBUG_PAYLOAD;
616
+ if (debugPayload !== '1' && debugPayload !== '2')
617
+ return;
618
+ const tag = streaming ? 'DEBUG_PAYLOAD-stream' : 'DEBUG_PAYLOAD';
619
+ try {
620
+ const msgBytes = JSON.stringify(chatRequest.messages || []).length;
621
+ const toolBytes = JSON.stringify(chatRequest.tools || []).length;
622
+ const totalBytes = JSON.stringify(chatRequest).length;
623
+ const sysMsg = chatRequest.messages?.find((m) => m.role === 'system');
624
+ const sysBytes = sysMsg ? JSON.stringify(sysMsg).length : 0;
625
+ const toolCount = chatRequest.tools?.length || 0;
626
+ const msgCount = chatRequest.messages?.length || 0;
627
+ const lastUserMsg = chatRequest.messages?.filter((m) => m.role === 'user').slice(-1)[0];
628
+ const lastUserBytes = lastUserMsg ? JSON.stringify(lastUserMsg).length : 0;
629
+ console.error(`[${tag}] model=${modelId} total=${totalBytes}B msgs=${msgCount}/${msgBytes}B tools=${toolCount}/${toolBytes}B sysMsg=${sysBytes}B lastUserMsg=${lastUserBytes}B`);
630
+ if (debugPayload === '2') {
631
+ const breakdown = (chatRequest.messages || []).map((m, i) => `${i}:${m.role}=${JSON.stringify(m).length}B`).join(' ');
632
+ console.error(`[${tag}] msg breakdown: ${breakdown}`);
633
+ if (sysMsg) {
634
+ const previewLen = streaming ? 800 : 500;
635
+ const sysPreview = (typeof sysMsg.content === 'string' ? sysMsg.content : JSON.stringify(sysMsg.content)).slice(0, previewLen);
636
+ console.error(`[${tag}] sysMsg preview: ${sysPreview}`);
637
+ }
638
+ if (streaming && chatRequest.tools && chatRequest.tools.length > 0) {
639
+ const toolNames = chatRequest.tools.map((t) => (t.function?.name || t.name) + '=' + JSON.stringify(t).length + 'B').join(', ');
640
+ console.error(`[${tag}] tools: ${toolNames}`);
641
+ }
642
+ }
643
+ }
644
+ catch (e) {
645
+ console.error(`[${tag}] failed to log:`, e);
646
+ }
647
+ }
648
+ /**
649
+ * Send request using Chat Completions API pattern
650
+ *
651
+ * Used by: OpenAI, XAI, DeepSeek, Groq
652
+ * Format: OpenAI Chat Completions API
653
+ */
654
+ async sendChatCompletionsAPI(request, modelConfig) {
655
+ const { client, chatRequest } = this.buildChatCompletionsRequest(request, modelConfig, { stream: false });
656
+ // Send request
657
+ const response = await client.chat.completions.create(chatRequest);
658
+ return {
659
+ data: response,
660
+ status: 200,
661
+ headers: {}
662
+ };
663
+ }
664
+ /**
665
+ * Extract <system-reminder> content from Responses API input items.
666
+ *
667
+ * System messages are injected as <system-reminder> tags inside user message
668
+ * content by SystemMessageMiddleware. For the Responses API, we extract these
669
+ * into the dedicated `instructions` parameter so the provider can cache them
670
+ * separately. The tags are stripped from the user message to avoid duplication.
671
+ *
672
+ * Other API methods (Messages, Chat Completions) are unaffected — they continue
673
+ * to receive system context embedded in user content as before.
674
+ */
675
+ extractSystemRemindersForResponsesAPI(inputItems) {
676
+ const systemReminderRegex = /<system-reminder>\n([\s\S]*?)\n<\/system-reminder>/g;
677
+ const extractedParts = [];
678
+ const cleanedItems = [];
679
+ for (const item of inputItems) {
680
+ if (item.type === 'message' && item.role === 'user' && Array.isArray(item.content)) {
681
+ const cleanedContent = [];
682
+ for (const block of item.content) {
683
+ if (block.type === 'input_text' && block.text) {
684
+ // Extract all <system-reminder> blocks from this text
685
+ let text = block.text;
686
+ let match;
687
+ const reminders = [];
688
+ // Reset regex state
689
+ systemReminderRegex.lastIndex = 0;
690
+ while ((match = systemReminderRegex.exec(text)) !== null) {
691
+ reminders.push(match[1] ?? '');
692
+ }
693
+ if (reminders.length > 0) {
694
+ extractedParts.push(...reminders);
695
+ // Strip the tags from the text
696
+ const strippedText = text.replace(systemReminderRegex, '').trim();
697
+ if (strippedText) {
698
+ cleanedContent.push({ ...block, text: strippedText });
699
+ }
700
+ }
701
+ else {
702
+ cleanedContent.push(block);
703
+ }
704
+ }
705
+ else {
706
+ cleanedContent.push(block);
707
+ }
708
+ }
709
+ if (cleanedContent.length > 0) {
710
+ cleanedItems.push({ ...item, content: cleanedContent });
711
+ }
712
+ // If all content was system-reminder, skip the empty message
713
+ }
714
+ else {
715
+ cleanedItems.push(item);
716
+ }
717
+ }
718
+ return {
719
+ instructions: extractedParts.length > 0 ? extractedParts.join('\n\n') : undefined,
720
+ cleanedItems
721
+ };
722
+ }
723
+ /**
724
+ * Send request using Responses API pattern
725
+ *
726
+ * Used by: OpenAI (gpt-5-codex), XAI (stateful)
727
+ * Format: OpenAI Responses API with server-side tools
728
+ */
729
+ async sendResponsesAPI(request, modelConfig) {
730
+ const apiKey = process.env[modelConfig.api.apiKeyEnvVar];
731
+ if (!apiKey) {
732
+ throw new Error(`Missing API key: ${modelConfig.api.apiKeyEnvVar}`);
733
+ }
734
+ // Use provider-formatted input items directly from ResponsesAPIAdapter.toProviderMessages()
735
+ // The adapter already creates correctly typed items (message, function_call_output, etc.)
736
+ // Re-wrapping them would strip tool results and function calls, breaking the tool loop.
737
+ //
738
+ // Extract <system-reminder> content from user messages into `instructions` parameter.
739
+ // This lets the Responses API cache system context separately from conversation content.
740
+ const { instructions, cleanedItems: inputItems } = this.extractSystemRemindersForResponsesAPI(request.messages);
741
+ // Check reasoning support
742
+ const supportsReasoning = modelConfig.reasoning?.supported;
743
+ const { disableThinking, reasoningEffort, ...apiParameters } = request.parameters;
744
+ // Transform parameters: max_tokens / max_completion_tokens / maxTokens →
745
+ // max_output_tokens for Responses API.
746
+ // R20c: GPT-5 cards default to chat/completions and use
747
+ // max_completion_tokens. On a dynamic switch to Responses, that key was
748
+ // forwarded unchanged and OpenAI 400'd ("Unsupported parameter:
749
+ // 'max_completion_tokens'. In the Responses API, this parameter has moved
750
+ // to 'max_output_tokens'"). Normalize all three input forms.
751
+ let transformedParams = { ...apiParameters };
752
+ for (const oldKey of ['max_tokens', 'max_completion_tokens', 'maxTokens']) {
753
+ if (oldKey in transformedParams) {
754
+ transformedParams.max_output_tokens = transformedParams[oldKey];
755
+ delete transformedParams[oldKey];
756
+ }
757
+ }
758
+ // Remove model from params to prevent overwriting
759
+ const { model: _ignoredModel, ...paramsWithoutModel } = transformedParams;
760
+ // Use modelId from config (for alias resolution)
761
+ const actualModelId = modelConfig.modelId || request.modelId;
762
+ const isXAI = modelConfig.provider?.toLowerCase() === 'xai';
763
+ const responsesRequest = {
764
+ model: actualModelId,
765
+ input: inputItems,
766
+ ...paramsWithoutModel
767
+ };
768
+ // Stateful chaining: use previous_response_id when available
769
+ // This lets the server preserve reasoning state across tool loop iterations,
770
+ // dramatically improving coherence for long tool chains (XAI, OpenAI).
771
+ if (request.previousResponseId) {
772
+ responsesRequest.previous_response_id = request.previousResponseId;
773
+ }
774
+ // XAI stores conversations server-side by default (store: true).
775
+ // Being explicit ensures server-side reasoning preservation.
776
+ if (isXAI) {
777
+ responsesRequest.store = true;
778
+ // Cache-routing: `prompt_cache_key` routes requests with same session id to
779
+ // the same server, maximizing cache hits. Per XAI docs
780
+ // (advanced-api-usage/prompt-caching/maximizing-cache-hits).
781
+ if (request.conversationId) {
782
+ responsesRequest.prompt_cache_key = request.conversationId;
783
+ }
784
+ // NOTE: tried adding `include: ["reasoning.encrypted_content"]` to capture
785
+ // encrypted reasoning for JSONL preservation (per XAI docs_guides_responses-api.md
786
+ // lines 93-95), but that triggered a regression where visible output tokens
787
+ // dropped to near-zero (~6 visible vs ~220 reasoning) on a basic 3-turn test.
788
+ // Deferred until we can investigate: possibly needs to be paired with
789
+ // different content-block wiring in ResponsesAPIAdapter, or only applied
790
+ // when we've explicitly asked for reasoning via the `reasoning` param.
791
+ }
792
+ // Set extracted system context as instructions (enables provider-side caching)
793
+ // XAI does NOT support the `instructions` parameter — skip for XAI provider.
794
+ if (instructions && !isXAI) {
795
+ responsesRequest.instructions = instructions;
796
+ }
797
+ // Add reasoning if supported and not disabled.
798
+ // Per-request reasoningEffort takes priority; fall back to card's defaultEffort.
799
+ // Models without defaultEffort (e.g. grok-4) get no reasoning block — grok-4
800
+ // rejects reasoning_effort per XAI docs.
801
+ const effectiveReasoningEffort = reasoningEffort || modelConfig.reasoning?.defaultEffort;
802
+ if (supportsReasoning && !disableThinking && effectiveReasoningEffort && effectiveReasoningEffort !== 'none') {
803
+ // R20: OpenAI Responses API rejects 'xhigh' (XAI-only effort level).
804
+ // Cross-provider sessions where the prior turn was XAI at xhigh would
805
+ // 400 on switch. Clamp at egress — standard cross-provider guard.
806
+ const effort = (!isXAI && effectiveReasoningEffort === 'xhigh') ? 'high' : effectiveReasoningEffort;
807
+ responsesRequest.reasoning = { effort, summary: 'auto' };
808
+ }
809
+ // Add tools if present (already in correct format from ResponsesAPIAdapter)
810
+ if (request.tools && request.tools.length > 0) {
811
+ responsesRequest.tools = request.tools;
812
+ }
813
+ if (process.env.DEBUG === 'true') {
814
+ const { input, tools, instructions: instr, ...requestSummary } = responsesRequest;
815
+ const inputTypes = (input || []).map((i) => i.type);
816
+ console.log(`[DEBUG APIClient] Responses API (non-streaming) request:`, JSON.stringify({
817
+ ...requestSummary,
818
+ input: `[${input?.length || 0} items: ${inputTypes.join(', ')}]`,
819
+ tools: tools ? `[${tools.length} tools]` : undefined,
820
+ max_output_tokens: responsesRequest.max_output_tokens,
821
+ has_instructions: !!responsesRequest.instructions,
822
+ has_previous_response_id: !!responsesRequest.previous_response_id
823
+ }, null, 2));
824
+ }
825
+ // R27: XAI's /v1/responses route rejects the OpenAI SDK's request shape
826
+ // (404 "No handler found on route") and, without server-side tools, returns
827
+ // a body the SDK path surfaces as empty content. Use a raw fetch with
828
+ // Bearer auth — standard Responses API transport auth.
829
+ // OpenAI's own Responses API still uses the SDK (R20-proven, unaffected).
830
+ if (isXAI) {
831
+ const httpResponse = await fetch(modelConfig.api.endpoint, {
832
+ method: 'POST',
833
+ headers: {
834
+ 'Content-Type': 'application/json',
835
+ 'Authorization': `Bearer ${apiKey}`,
836
+ },
837
+ body: JSON.stringify(responsesRequest),
838
+ });
839
+ if (!httpResponse.ok) {
840
+ const errorText = await httpResponse.text().catch(() => 'Unknown error');
841
+ throw new Error(`XAI Responses API error ${httpResponse.status}: ${errorText}`);
842
+ }
843
+ const data = await httpResponse.json();
844
+ return { data, status: 200, headers: {} };
845
+ }
846
+ // OpenAI Responses API — SDK path (R20-proven working)
847
+ const OpenAI = (await import('openai')).default;
848
+ const baseURL = modelConfig.api.endpoint.replace(/\/(messages|responses)$/, '');
849
+ const client = new OpenAI({ apiKey, baseURL });
850
+ const data = await client.responses.create(responsesRequest);
851
+ return {
852
+ data,
853
+ status: 200,
854
+ headers: {}
855
+ };
856
+ }
857
+ /**
858
+ * Send request using GenerateContent API pattern
859
+ *
860
+ * Used by: Google Gemini (Vertex AI, AI Studio)
861
+ * Format: Google GenerativeAI GenerateContent API
862
+ */
863
+ async sendGenerateContentAPI(request, modelConfig) {
864
+ const apiKey = process.env[modelConfig.api.apiKeyEnvVar];
865
+ if (!apiKey) {
866
+ throw new Error(`Missing API key: ${modelConfig.api.apiKeyEnvVar}`);
867
+ }
868
+ // For models with tools, use direct HTTP to ensure v1beta endpoint is used
869
+ // The SDK sometimes uses v1 which doesn't support tools for newer models
870
+ if (request.tools && request.tools.length > 0) {
871
+ return this.sendGenerateContentHTTP(request, modelConfig, apiKey);
872
+ }
873
+ // For non-tool requests, use SDK as before
874
+ if (!this.googleClient) {
875
+ this.googleClient = new GoogleGenerativeAI(apiKey);
876
+ }
877
+ // Get model - models/gemini-1.5-flash format
878
+ const modelName = request.modelId.startsWith('models/') ? request.modelId : `models/${request.modelId}`;
879
+ const model = this.googleClient.getGenerativeModel({ model: modelName });
880
+ // Build generation config (exclude model parameter - disableThinking is NOT an API parameter)
881
+ const { model: _model, ...generationConfig } = request.parameters;
882
+ // Build request
883
+ const geminiRequest = {
884
+ contents: request.messages,
885
+ generationConfig
886
+ };
887
+ // Send request
888
+ const result = await model.generateContent(geminiRequest);
889
+ const response = result.response;
890
+ // Return response with usageMetadata for proper token tracking
891
+ // The usageMetadata is at the response level, not nested
892
+ // Based on gemini-cli implementation (packages/core/src/core/turn.ts:308)
893
+ // and official docs: https://ai.google.dev/api/generate-content
894
+ return {
895
+ data: response, // response already has usageMetadata
896
+ status: 200,
897
+ headers: {}
898
+ };
899
+ }
900
+ /**
901
+ * Send GenerateContent request via direct HTTP
902
+ * Ensures v1beta endpoint is used for tool support
903
+ */
904
+ async sendGenerateContentHTTP(request, modelConfig, apiKey) {
905
+ // Get model ID (no models/ prefix - endpoint already includes it)
906
+ const modelId = request.modelId.startsWith('models/')
907
+ ? request.modelId.replace('models/', '')
908
+ : request.modelId;
909
+ // Build URL using configured endpoint (should be v1beta)
910
+ // Endpoint already ends with /models, so just append modelId
911
+ const url = `${modelConfig.api.endpoint}/${modelId}:generateContent`;
912
+ // Build generation config (exclude model parameter - disableThinking is NOT an API parameter)
913
+ // Extract the nested generationConfig object from request.parameters
914
+ const { generationConfig } = request.parameters;
915
+ // Build request body (REST API uses snake_case)
916
+ const requestBody = {
917
+ contents: request.messages,
918
+ generation_config: generationConfig // Use the nested object directly
919
+ };
920
+ // Add tools if present
921
+ if (request.tools && request.tools.length > 0) {
922
+ // REST API uses snake_case "function_declarations", not camelCase "functionDeclarations"
923
+ requestBody.tools = [{ function_declarations: request.tools }];
924
+ // DEBUG: Log Gemini tool request details
925
+ if (process.env.DEBUG === 'true') {
926
+ console.log(`[DEBUG APIClient] Gemini HTTP request with ${request.tools.length} tools:`);
927
+ console.log(`[DEBUG APIClient] Tool names: ${request.tools.map((t) => t.name).join(', ')}`);
928
+ console.log(`[DEBUG APIClient] First tool structure:`, JSON.stringify(request.tools[0], null, 2));
929
+ console.log(`[DEBUG APIClient] Request body tools wrapper:`, JSON.stringify(requestBody.tools[0], null, 2).substring(0, 500));
930
+ }
931
+ }
932
+ // Make HTTP request
933
+ const httpResponse = await fetch(url, {
934
+ method: 'POST',
935
+ headers: {
936
+ 'Content-Type': 'application/json',
937
+ [modelConfig.api.authHeader]: apiKey
938
+ },
939
+ body: JSON.stringify(requestBody)
940
+ });
941
+ if (!httpResponse.ok) {
942
+ const errorText = await httpResponse.text();
943
+ throw new Error(`Google GenerateContent API error (${httpResponse.status}): ${errorText}`);
944
+ }
945
+ const data = await httpResponse.json();
946
+ // Return full response (same structure as SDK)
947
+ // The response has: candidates, usageMetadata, modelVersion, responseId
948
+ return {
949
+ data: data,
950
+ status: httpResponse.status,
951
+ headers: Object.fromEntries(httpResponse.headers.entries())
952
+ };
953
+ }
954
+ /**
955
+ * Send request using Google GenAI API pattern
956
+ *
957
+ * Used by: Google Gemma (FREE models)
958
+ * Format: @google/genai simplified API
959
+ * Note: This is different from GenerateContent API used by Gemini
960
+ */
961
+ async sendGoogleGenAIRequest(request, modelConfig) {
962
+ if (!this.googleGenAIClient) {
963
+ const apiKey = process.env[modelConfig.api.apiKeyEnvVar];
964
+ if (!apiKey) {
965
+ throw new Error(`Missing API key: ${modelConfig.api.apiKeyEnvVar}`);
966
+ }
967
+ this.googleGenAIClient = new GoogleGenAI({ apiKey });
968
+ }
969
+ // Build request for GoogleGenAI (simpler format)
970
+ // Convert messages array to conversation history
971
+ const messages = request.messages.map((msg) => ({
972
+ role: msg.role === 'model' ? 'model' : 'user',
973
+ content: typeof msg.content === 'string'
974
+ ? msg.content
975
+ : msg.parts?.map((p) => p.text || '').join('') || ''
976
+ }));
977
+ // Use last message as prompt
978
+ const lastMessage = messages[messages.length - 1];
979
+ const prompt = lastMessage?.content || '';
980
+ // Send request using simplified API
981
+ const response = await this.googleGenAIClient.models.generateContent({
982
+ model: request.modelId,
983
+ contents: prompt
984
+ });
985
+ // Return response in standard format
986
+ // Note: GoogleGenAI doesn't provide detailed usage metadata
987
+ return {
988
+ data: {
989
+ text: response.text,
990
+ // Estimate token usage (no actual counts from this API)
991
+ usage: {
992
+ inputTokens: Math.ceil((prompt.length) / 4),
993
+ outputTokens: Math.ceil((response.text?.length || 0) / 4),
994
+ }
995
+ },
996
+ status: 200,
997
+ headers: {}
998
+ };
999
+ }
1000
+ /**
1001
+ * Stream request using Messages API pattern
1002
+ *
1003
+ * Used by: Anthropic (native), XAI (Anthropic-compatible)
1004
+ * Format: Anthropic Messages API with SSE events
1005
+ */
1006
+ streamMessagesAPI(request, modelConfig) {
1007
+ const provider = modelConfig.provider.toLowerCase();
1008
+ // Anthropic: Use native SDK with OAuth or API key + prompt caching
1009
+ if (provider === 'anthropic') {
1010
+ if (!this.anthropicClient) {
1011
+ this.anthropicClient = this.initializeAnthropicClient();
1012
+ }
1013
+ // Phase 2.8: Extract internal flags before building request
1014
+ const disableThinking = request.parameters.disableThinking;
1015
+ const reasoningEffort = request.parameters.reasoningEffort;
1016
+ // Exclude internal flags from API request parameters
1017
+ const { disableThinking: _, reasoningEffort: _re, ...apiParameters } = request.parameters;
1018
+ // Check if prompt caching is enabled
1019
+ const enableCaching = process.env.ANTHROPIC_PROMPT_CACHING !== 'false';
1020
+ // Build request (same as non-streaming)
1021
+ const anthropicRequest = {
1022
+ model: request.modelId,
1023
+ messages: request.messages,
1024
+ max_tokens: request.parameters.max_tokens || request.parameters.maxTokens || 4096,
1025
+ ...apiParameters
1026
+ };
1027
+ // Add system message with cache_control for prompt caching
1028
+ if (request.systemMessage) {
1029
+ if (enableCaching) {
1030
+ anthropicRequest.system = [{
1031
+ type: 'text',
1032
+ text: request.systemMessage,
1033
+ cache_control: { type: 'ephemeral' }
1034
+ }];
1035
+ }
1036
+ else {
1037
+ anthropicRequest.system = request.systemMessage;
1038
+ }
1039
+ }
1040
+ // Add tools with cache_control on last tool for caching
1041
+ if (request.tools && request.tools.length > 0) {
1042
+ if (enableCaching) {
1043
+ const tools = request.tools.map((tool, index) => {
1044
+ if (index === request.tools.length - 1) {
1045
+ return { ...tool, cache_control: { type: 'ephemeral' } };
1046
+ }
1047
+ return tool;
1048
+ });
1049
+ anthropicRequest.tools = tools;
1050
+ }
1051
+ else {
1052
+ anthropicRequest.tools = request.tools;
1053
+ }
1054
+ }
1055
+ // Phase 2.8: Enable extended thinking for Claude 4+ models with reasoning support
1056
+ // Requires beta header: anthropic-beta: interleaved-thinking-2025-05-14
1057
+ // Skip if disableThinking option is set (used for continuation requests)
1058
+ // reasoningEffort scales budget_tokens: none/undefined=10000 (default), low=5000, medium=10000, high=50000
1059
+ // 'none' = default budget (thinking stays on). Anthropic thinking always enabled for supported models.
1060
+ if (modelConfig.reasoning?.supported && modelConfig.reasoning?.pattern === 'interleaved' && !disableThinking) {
1061
+ // Opus 4.7/4.8 and Fable 5 require adaptive thinking — enabled/budget_tokens
1062
+ // 400s (parity with the non-streaming path above).
1063
+ const useAdaptive = ANTHROPIC_ADAPTIVE_THINKING_FAMILIES.has(modelConfig.family);
1064
+ if (useAdaptive) {
1065
+ // display:'summarized' surfaces reasoning in the CLI but costs extra output
1066
+ // tokens; default 'omitted' streams empty thinking blocks for $0. Gated on
1067
+ // DEBUG_THINKING (parity with the non-streaming path above).
1068
+ anthropicRequest.thinking =
1069
+ process.env.DEBUG_THINKING === 'true'
1070
+ ? { type: 'adaptive', display: 'summarized' }
1071
+ : { type: 'adaptive' };
1072
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1073
+ console.log(`[DEBUG APIClient] Adaptive thinking for ${modelConfig.id}${process.env.DEBUG_THINKING === 'true' ? ' (display: summarized)' : ''}`);
1074
+ }
1075
+ }
1076
+ else {
1077
+ const budgetMap = {
1078
+ none: 10000, // default budget — thinking stays on
1079
+ low: 5000,
1080
+ medium: 10000,
1081
+ high: 50000,
1082
+ };
1083
+ const budgetTokens = reasoningEffort ? (budgetMap[reasoningEffort] || 10000) : 10000;
1084
+ anthropicRequest.thinking = {
1085
+ type: 'enabled',
1086
+ budget_tokens: budgetTokens
1087
+ };
1088
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1089
+ console.log(`[DEBUG APIClient] Thinking ENABLED for ${modelConfig.id} (budget: ${budgetTokens}, effort: ${reasoningEffort || 'default'})`);
1090
+ }
1091
+ }
1092
+ }
1093
+ else if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1094
+ console.log(`[DEBUG APIClient] Thinking NOT enabled: supported=${modelConfig.reasoning?.supported}, pattern=${modelConfig.reasoning?.pattern}, disableThinking=${disableThinking}`);
1095
+ }
1096
+ // PTC: Add container for session persistence
1097
+ const enablePTC = request.parameters.enablePTC;
1098
+ const ptcContainerId = request.parameters.containerId;
1099
+ if (enablePTC && modelConfig.supportsPTC) {
1100
+ if (ptcContainerId) {
1101
+ anthropicRequest.container = { id: ptcContainerId };
1102
+ }
1103
+ else {
1104
+ anthropicRequest.container = {};
1105
+ }
1106
+ }
1107
+ // Build beta headers for thinking, tool streaming, and caching
1108
+ const betaFeatures = [];
1109
+ if (anthropicRequest.thinking) {
1110
+ betaFeatures.push('interleaved-thinking-2025-05-14');
1111
+ betaFeatures.push('fine-grained-tool-streaming-2025-05-14');
1112
+ }
1113
+ if (enablePTC && modelConfig.supportsPTC) {
1114
+ betaFeatures.push('code-execution-2026-01-20');
1115
+ }
1116
+ if (enableCaching) {
1117
+ betaFeatures.push('prompt-caching-2024-07-31');
1118
+ }
1119
+ const headers = betaFeatures.length > 0
1120
+ ? { 'anthropic-beta': betaFeatures.join(',') }
1121
+ : undefined;
1122
+ const stream = this.anthropicClient.messages.stream(anthropicRequest, { headers });
1123
+ // Capture 'this' context before entering async generator
1124
+ const self = this;
1125
+ // Track thinking blocks and signatures for proper accumulation
1126
+ // SDK's finalMessage() doesn't include signatures streamed via signature_delta
1127
+ // This map is shared between the generator and finalMessage handler
1128
+ const thinkingSignatures = new Map();
1129
+ // SDK's finalMessage() might not accumulate tool inputs correctly with beta features
1130
+ // Track accumulated inputs by block index for injection into finalMessage
1131
+ const toolInputs = new Map();
1132
+ // Create async generator for chunks
1133
+ const chunks = async function* () {
1134
+ // Phase 2.8: Track tool use accumulation for streaming tool execution
1135
+ let currentToolUse = null;
1136
+ let partialJson = '';
1137
+ let currentToolUseIndex = -1;
1138
+ // Track current thinking block for signature association
1139
+ let currentThinkingIndex = -1;
1140
+ let signatureAccumulator = '';
1141
+ try {
1142
+ // Use SDK's async iteration for events
1143
+ for await (const event of stream) {
1144
+ // DEBUG: Log important event types (skip repetitive text_delta)
1145
+ if (process.env.DEBUG_THINKING === 'true') {
1146
+ const delta = event.delta;
1147
+ if (event.type === 'content_block_delta') {
1148
+ // Only log non-text delta types to reduce noise
1149
+ if (delta?.type && delta.type !== 'text_delta') {
1150
+ console.log(`[DEBUG APIClient] Claude event: ${event.type}, delta.type: ${delta?.type}`);
1151
+ }
1152
+ }
1153
+ else if (event.type === 'content_block_start') {
1154
+ if (process.env.DEBUG === 'true')
1155
+ console.log(`[DEBUG APIClient] Claude event: ${event.type}, content_block.type: ${event.content_block?.type}, index: ${event.index}`);
1156
+ }
1157
+ }
1158
+ if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
1159
+ yield {
1160
+ type: 'text_delta',
1161
+ delta: event.delta.text,
1162
+ data: event
1163
+ };
1164
+ }
1165
+ else if (event.type === 'content_block_delta' && event.delta.type === 'thinking_delta') {
1166
+ // Anthropic Claude extended thinking (interleaved reasoning)
1167
+ yield {
1168
+ type: 'content_block_delta',
1169
+ delta: event.delta.thinking,
1170
+ data: { ...event, reasoning: true }
1171
+ };
1172
+ }
1173
+ else if (event.type === 'content_block_start') {
1174
+ // Track content block index from event
1175
+ const blockIndex = event.index;
1176
+ // Phase 2.8: Check if this is a tool_use block
1177
+ if (event.content_block?.type === 'tool_use') {
1178
+ currentToolUse = {
1179
+ id: event.content_block.id,
1180
+ name: event.content_block.name,
1181
+ input: {}
1182
+ };
1183
+ currentToolUseIndex = blockIndex;
1184
+ partialJson = '';
1185
+ }
1186
+ else if (event.content_block?.type === 'server_tool_use') {
1187
+ // PTC: Server-side tool use — accumulate same as tool_use
1188
+ currentToolUse = {
1189
+ id: event.content_block.id,
1190
+ name: event.content_block.name,
1191
+ input: {}
1192
+ };
1193
+ currentToolUseIndex = blockIndex;
1194
+ partialJson = '';
1195
+ }
1196
+ // Track thinking blocks for signature association
1197
+ if (event.content_block?.type === 'thinking') {
1198
+ currentThinkingIndex = blockIndex;
1199
+ signatureAccumulator = '';
1200
+ }
1201
+ yield {
1202
+ type: 'content_block_start',
1203
+ data: event
1204
+ };
1205
+ }
1206
+ else if (event.type === 'content_block_delta' && event.delta.type === 'signature_delta') {
1207
+ // Accumulate signature for current thinking block
1208
+ signatureAccumulator += event.delta.signature || '';
1209
+ }
1210
+ else if (event.type === 'content_block_delta' && event.delta.type === 'input_json_delta') {
1211
+ // Phase 2.8: Accumulate tool input JSON incrementally
1212
+ partialJson += event.delta.partial_json;
1213
+ // Try parsing accumulated JSON
1214
+ try {
1215
+ currentToolUse.input = JSON.parse(partialJson);
1216
+ }
1217
+ catch {
1218
+ // JSON not complete yet, continue accumulating
1219
+ }
1220
+ yield {
1221
+ type: 'content_block_delta',
1222
+ delta: event.delta.partial_json,
1223
+ data: event
1224
+ };
1225
+ }
1226
+ else if (event.type === 'content_block_stop') {
1227
+ // Phase 2.8: If we have a complete tool use, emit it
1228
+ if (currentToolUse) {
1229
+ // If incremental JSON parsing never succeeded, try repair on the full accumulated string
1230
+ if ((!currentToolUse.input || Object.keys(currentToolUse.input).length === 0) && partialJson.length > 0) {
1231
+ try {
1232
+ currentToolUse.input = self.repairTruncatedJSON(partialJson);
1233
+ }
1234
+ catch {
1235
+ console.error(`[APIClient Anthropic] Failed to repair tool JSON (${partialJson.length} chars): ${partialJson.slice(0, 200)}...`);
1236
+ }
1237
+ }
1238
+ const decodedInput = self.decodeHtmlEntitiesInObject(currentToolUse.input);
1239
+ currentToolUse.input = decodedInput;
1240
+ // Save accumulated input for injection into finalMessage
1241
+ // SDK's finalMessage might not accumulate input_json_delta correctly with beta features
1242
+ if (currentToolUseIndex >= 0 && decodedInput && Object.keys(decodedInput).length > 0) {
1243
+ toolInputs.set(currentToolUseIndex, decodedInput);
1244
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1245
+ console.log(`[DEBUG APIClient] Captured tool input for block ${currentToolUseIndex}, keys: ${Object.keys(decodedInput).join(', ')}`);
1246
+ }
1247
+ }
1248
+ yield {
1249
+ type: 'tool_use_complete',
1250
+ toolUse: currentToolUse,
1251
+ data: event
1252
+ };
1253
+ // Reset for next tool use
1254
+ currentToolUse = null;
1255
+ currentToolUseIndex = -1;
1256
+ partialJson = '';
1257
+ }
1258
+ // Save accumulated signature for thinking block
1259
+ if (currentThinkingIndex >= 0 && signatureAccumulator) {
1260
+ thinkingSignatures.set(currentThinkingIndex, signatureAccumulator);
1261
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1262
+ console.log(`[DEBUG APIClient] Captured signature for thinking block ${currentThinkingIndex}, length: ${signatureAccumulator.length}`);
1263
+ }
1264
+ currentThinkingIndex = -1;
1265
+ signatureAccumulator = '';
1266
+ }
1267
+ yield {
1268
+ type: 'content_block_stop',
1269
+ data: event
1270
+ };
1271
+ }
1272
+ else if (event.type === 'message_start') {
1273
+ yield {
1274
+ type: 'message_start',
1275
+ data: event
1276
+ };
1277
+ }
1278
+ else if (event.type === 'message_delta') {
1279
+ yield {
1280
+ type: 'message_delta',
1281
+ data: event
1282
+ };
1283
+ }
1284
+ else if (event.type === 'message_stop') {
1285
+ yield {
1286
+ type: 'message_stop',
1287
+ data: event
1288
+ };
1289
+ }
1290
+ }
1291
+ }
1292
+ catch (streamError) {
1293
+ // Handle stream errors gracefully (e.g., "request ended without sending any chunks")
1294
+ const errorMessage = streamError?.message || 'Unknown streaming error';
1295
+ console.error(`[APIClient Anthropic] Stream error: ${errorMessage}`);
1296
+ // Yield an error event that the orchestrator can handle
1297
+ yield {
1298
+ type: 'error',
1299
+ error: {
1300
+ type: 'stream_error',
1301
+ message: `API stream failed: ${errorMessage}. This is usually a transient error - please retry.`
1302
+ }
1303
+ };
1304
+ }
1305
+ }();
1306
+ // Get final message promise (SDK accumulates internally)
1307
+ // Inject signatures that were captured from signature_delta events
1308
+ const finalMessage = stream.finalMessage().then(msg => {
1309
+ // Inject captured signatures into thinking blocks
1310
+ // The SDK doesn't accumulate signature_delta into the final message
1311
+ if (msg.content && thinkingSignatures.size > 0) {
1312
+ let thinkingBlockIndex = 0;
1313
+ for (let i = 0; i < msg.content.length; i++) {
1314
+ const block = msg.content[i];
1315
+ if (block.type === 'thinking') {
1316
+ const signature = thinkingSignatures.get(i);
1317
+ if (signature) {
1318
+ block.signature = signature;
1319
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1320
+ console.log(`[DEBUG APIClient] Injected signature into thinking block ${i}`);
1321
+ }
1322
+ }
1323
+ thinkingBlockIndex++;
1324
+ }
1325
+ }
1326
+ }
1327
+ // Inject captured tool inputs into tool_use blocks
1328
+ // SDK's finalMessage might not accumulate input_json_delta correctly with beta features
1329
+ if (msg.content && toolInputs.size > 0) {
1330
+ for (let i = 0; i < msg.content.length; i++) {
1331
+ const block = msg.content[i];
1332
+ if (block.type === 'tool_use') {
1333
+ const accumulatedInput = toolInputs.get(i);
1334
+ // Only inject if SDK's input is empty but we have accumulated input
1335
+ if (accumulatedInput && (!block.input || Object.keys(block.input).length === 0)) {
1336
+ block.input = accumulatedInput;
1337
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1338
+ console.log(`[DEBUG APIClient] Injected accumulated tool input into block ${i}, keys: ${Object.keys(accumulatedInput).join(', ')}`);
1339
+ }
1340
+ }
1341
+ }
1342
+ }
1343
+ }
1344
+ // DEBUG: Log final message content to diagnose thinking block signatures
1345
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1346
+ console.log(`[DEBUG APIClient] Claude finalMessage content types:`, msg.content?.map((b) => `${b.type}${b.type === 'thinking' ? ` (sig: ${b.signature ? 'yes' : 'no'})` : ''}`));
1347
+ // Log tool_use input to debug parameter extraction
1348
+ for (const block of msg.content || []) {
1349
+ if (block.type === 'tool_use') {
1350
+ console.log(`[DEBUG APIClient] Tool use block:`, {
1351
+ id: block.id,
1352
+ name: block.name,
1353
+ input: block.input,
1354
+ inputKeys: Object.keys(block.input || {})
1355
+ });
1356
+ }
1357
+ }
1358
+ }
1359
+ return msg;
1360
+ });
1361
+ return {
1362
+ chunks,
1363
+ finalMessage
1364
+ };
1365
+ }
1366
+ // XAI Messages API: Anthropic-compatible, use Anthropic SDK with custom baseURL
1367
+ if (provider === 'xai') {
1368
+ const apiKey = process.env[modelConfig.api.apiKeyEnvVar];
1369
+ if (!apiKey) {
1370
+ throw new Error(`Missing API key: ${modelConfig.api.apiKeyEnvVar}`);
1371
+ }
1372
+ // Create Anthropic client with XAI base URL.
1373
+ // `x-grok-conv-id` default header routes same-session requests to same server
1374
+ // for cache hits — per XAI docs (advanced-api-usage/prompt-caching/maximizing-cache-hits).
1375
+ const xaiDefaultHeaders = {};
1376
+ if (request.conversationId) {
1377
+ xaiDefaultHeaders['x-grok-conv-id'] = request.conversationId;
1378
+ }
1379
+ const xaiClient = new Anthropic({
1380
+ apiKey,
1381
+ baseURL: modelConfig.api.endpoint.replace('/v1/messages', ''), // Strip path, keep base
1382
+ defaultHeaders: xaiDefaultHeaders
1383
+ });
1384
+ // Extract internal flags before spreading into API request
1385
+ // XAI Messages API does NOT support Anthropic's thinking parameter —
1386
+ // XAI models think natively (embedded <thinking> tags or thinking content blocks)
1387
+ const { disableThinking: _xaiDisableThinking, reasoningEffort: _xaiReasoningEffort, ...xaiApiParameters } = request.parameters;
1388
+ // Build request (same format as Anthropic)
1389
+ const anthropicRequest = {
1390
+ model: request.modelId,
1391
+ messages: request.messages,
1392
+ max_tokens: xaiApiParameters.max_tokens || xaiApiParameters.maxTokens || 4096,
1393
+ ...xaiApiParameters
1394
+ };
1395
+ if (request.systemMessage) {
1396
+ anthropicRequest.system = request.systemMessage;
1397
+ }
1398
+ if (request.tools && request.tools.length > 0) {
1399
+ // XAI requires complete tool schemas with descriptions for ALL tools and parameters
1400
+ anthropicRequest.tools = this.validateXAITools(request.tools);
1401
+ }
1402
+ // Use SDK streaming (same as Anthropic!)
1403
+ const stream = xaiClient.messages.stream(anthropicRequest);
1404
+ // Phase 2.8: XAI Bug Fix - Build our own finalMessage because SDK doesn't accumulate tool inputs
1405
+ const accumulatedContent = [];
1406
+ let textAccumulator = '';
1407
+ let thinkingAccumulator = '';
1408
+ let streamCompleteResolve;
1409
+ const streamCompletePromise = new Promise(resolve => {
1410
+ streamCompleteResolve = resolve;
1411
+ });
1412
+ // Create async generator for chunks (same pattern as Anthropic)
1413
+ const chunks = async function* () {
1414
+ // Phase 2.8: Track tool use accumulation
1415
+ let currentToolUse = null;
1416
+ let partialJson = '';
1417
+ let currentBlockType = null;
1418
+ let redactedThinkingData = '';
1419
+ // R28c (Cache-Hit Contract Rule 2): capture the thinking-block
1420
+ // signature from signature_delta so it round-trips to XAI. Omitting
1421
+ // reasoning signature is xAI's documented #1 cause of cache misses.
1422
+ // The Anthropic path already does this (signatureAccumulator); the
1423
+ // XAI stream previously did not — that broke the XAI prompt cache.
1424
+ let xaiSignatureAccumulator = '';
1425
+ try {
1426
+ // Use SDK's async iteration for events (same as Anthropic)
1427
+ for await (const event of stream) {
1428
+ if (event.type === 'content_block_start') {
1429
+ currentBlockType = event.content_block?.type;
1430
+ // Phase 2.8: Check if this is a tool_use block
1431
+ if (event.content_block?.type === 'tool_use') {
1432
+ currentToolUse = {
1433
+ id: event.content_block.id,
1434
+ name: event.content_block.name,
1435
+ input: {}
1436
+ };
1437
+ partialJson = '';
1438
+ }
1439
+ else if (event.content_block?.type === 'server_tool_use') {
1440
+ // PTC: Server-side tool use — accumulate same as tool_use
1441
+ currentToolUse = {
1442
+ id: event.content_block.id,
1443
+ name: event.content_block.name,
1444
+ input: {}
1445
+ };
1446
+ partialJson = '';
1447
+ }
1448
+ else if (event.content_block?.type === 'text') {
1449
+ textAccumulator = '';
1450
+ }
1451
+ else if (event.content_block?.type === 'thinking') {
1452
+ thinkingAccumulator = '';
1453
+ }
1454
+ else if (event.content_block?.type === 'redacted_thinking') {
1455
+ // XAI grok-4/4.1 encrypted reasoning — accumulate data field
1456
+ redactedThinkingData = event.content_block?.data || '';
1457
+ }
1458
+ else if (event.content_block?.type === 'code_execution_tool_result') {
1459
+ // PTC: Code execution result — accumulate text output
1460
+ textAccumulator = '';
1461
+ }
1462
+ yield {
1463
+ type: 'content_block_start',
1464
+ data: event
1465
+ };
1466
+ }
1467
+ else if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
1468
+ textAccumulator += event.delta.text;
1469
+ yield {
1470
+ type: 'text_delta',
1471
+ delta: event.delta.text,
1472
+ data: event
1473
+ };
1474
+ }
1475
+ else if (event.type === 'content_block_delta' && event.delta.type === 'thinking_delta') {
1476
+ // XAI Grok reasoning traces (grok-code-fast-1 exposes plaintext thinking)
1477
+ thinkingAccumulator += event.delta.thinking;
1478
+ yield {
1479
+ type: 'content_block_delta',
1480
+ delta: event.delta.thinking,
1481
+ data: { ...event, reasoning: true }
1482
+ };
1483
+ }
1484
+ else if (event.type === 'content_block_delta' && event.delta.type === 'redacted_thinking_delta') {
1485
+ // XAI grok-4/4.1 encrypted reasoning delta
1486
+ redactedThinkingData += event.delta.data || '';
1487
+ yield {
1488
+ type: 'content_block_delta',
1489
+ delta: event.delta.data || '',
1490
+ data: { ...event, reasoning: true, redacted: true }
1491
+ };
1492
+ }
1493
+ else if (event.type === 'content_block_delta' && event.delta.type === 'signature_delta') {
1494
+ // R28c: accumulate the thinking-block signature (Cache-Hit Contract Rule 2)
1495
+ xaiSignatureAccumulator += event.delta.signature || '';
1496
+ }
1497
+ else if (event.type === 'content_block_delta' && event.delta.type === 'input_json_delta') {
1498
+ // Phase 2.8: Accumulate tool input JSON incrementally
1499
+ partialJson += event.delta.partial_json;
1500
+ // Try parsing accumulated JSON
1501
+ try {
1502
+ currentToolUse.input = JSON.parse(partialJson);
1503
+ }
1504
+ catch {
1505
+ // JSON not complete yet, continue accumulating
1506
+ }
1507
+ yield {
1508
+ type: 'content_block_delta',
1509
+ delta: event.delta.partial_json,
1510
+ data: event
1511
+ };
1512
+ }
1513
+ else if (event.type === 'content_block_stop') {
1514
+ // Phase 2.8: Save completed content block to our accumulator
1515
+ if (currentBlockType === 'text' && textAccumulator) {
1516
+ accumulatedContent.push({ type: 'text', text: textAccumulator });
1517
+ }
1518
+ else if (currentBlockType === 'thinking' && thinkingAccumulator) {
1519
+ // R28c: attach the captured signature so it round-trips to XAI (Rule 2)
1520
+ accumulatedContent.push({
1521
+ type: 'thinking',
1522
+ thinking: thinkingAccumulator,
1523
+ ...(xaiSignatureAccumulator && { signature: xaiSignatureAccumulator })
1524
+ });
1525
+ xaiSignatureAccumulator = '';
1526
+ }
1527
+ else if (currentBlockType === 'redacted_thinking' && redactedThinkingData) {
1528
+ accumulatedContent.push({ type: 'redacted_thinking', data: redactedThinkingData });
1529
+ redactedThinkingData = '';
1530
+ }
1531
+ else if (currentBlockType === 'tool_use' && currentToolUse) {
1532
+ // Use our accumulated input, not the SDK's empty one!
1533
+ accumulatedContent.push({
1534
+ type: 'tool_use',
1535
+ id: currentToolUse.id,
1536
+ name: currentToolUse.name,
1537
+ input: currentToolUse.input
1538
+ });
1539
+ yield {
1540
+ type: 'tool_use_complete',
1541
+ toolUse: currentToolUse,
1542
+ data: event
1543
+ };
1544
+ // Reset for next tool use
1545
+ currentToolUse = null;
1546
+ partialJson = '';
1547
+ }
1548
+ else if (currentBlockType === 'server_tool_use' && currentToolUse) {
1549
+ // PTC: Server-side tool use — push as server_tool_use
1550
+ accumulatedContent.push({
1551
+ type: 'server_tool_use',
1552
+ id: currentToolUse.id,
1553
+ name: currentToolUse.name,
1554
+ input: currentToolUse.input
1555
+ });
1556
+ yield {
1557
+ type: 'tool_use_complete',
1558
+ toolUse: currentToolUse,
1559
+ data: event
1560
+ };
1561
+ currentToolUse = null;
1562
+ partialJson = '';
1563
+ }
1564
+ else if (currentBlockType === 'code_execution_tool_result' && textAccumulator) {
1565
+ // PTC: Code execution result — push accumulated output
1566
+ accumulatedContent.push({
1567
+ type: 'code_execution_tool_result',
1568
+ tool_use_id: '',
1569
+ content: textAccumulator
1570
+ });
1571
+ }
1572
+ yield {
1573
+ type: 'content_block_stop',
1574
+ data: event
1575
+ };
1576
+ }
1577
+ else if (event.type === 'message_start') {
1578
+ yield {
1579
+ type: 'message_start',
1580
+ data: event
1581
+ };
1582
+ }
1583
+ else if (event.type === 'message_delta') {
1584
+ yield {
1585
+ type: 'message_delta',
1586
+ data: event
1587
+ };
1588
+ }
1589
+ else if (event.type === 'message_stop') {
1590
+ yield {
1591
+ type: 'message_stop',
1592
+ data: event
1593
+ };
1594
+ }
1595
+ }
1596
+ }
1597
+ catch (streamError) {
1598
+ // Handle stream errors gracefully (e.g., "request ended without sending any chunks")
1599
+ const errorMessage = streamError?.message || 'Unknown streaming error';
1600
+ console.error(`[APIClient XAI] Stream error: ${errorMessage}`);
1601
+ // Yield an error event that the orchestrator can handle
1602
+ yield {
1603
+ type: 'error',
1604
+ error: {
1605
+ type: 'stream_error',
1606
+ message: `XAI API stream failed: ${errorMessage}. This is usually a transient error - please retry.`
1607
+ }
1608
+ };
1609
+ }
1610
+ // Stream complete - resolve promise so finalMessage can build
1611
+ streamCompleteResolve();
1612
+ }();
1613
+ // Phase 2.8: Build our own finalMessage with correctly accumulated tool inputs
1614
+ // The SDK's finalMessage() doesn't accumulate tool inputs for XAI, so we build our own
1615
+ const finalMessage = Promise.all([stream.finalMessage(), streamCompletePromise]).then(([sdkMessage]) => {
1616
+ // After stream completes, replace the SDK's broken content with our correctly accumulated content
1617
+ let finalContent = accumulatedContent.length > 0 ? accumulatedContent : sdkMessage.content;
1618
+ // XAI: Check for reasoning_content field in the message
1619
+ // XAI can include reasoning_content or encrypted_content at the message level
1620
+ if (sdkMessage.reasoning_content) {
1621
+ // Insert reasoning content as first block (upfront thinking)
1622
+ finalContent = [
1623
+ { type: 'thinking', thinking: sdkMessage.reasoning_content },
1624
+ ...finalContent
1625
+ ];
1626
+ }
1627
+ // Extract <thinking> tags from text blocks (grok-4-1 embeds thinking in text)
1628
+ finalContent = this.extractThinkingFromTextBlocks(finalContent);
1629
+ return {
1630
+ ...sdkMessage,
1631
+ content: finalContent
1632
+ };
1633
+ });
1634
+ return {
1635
+ chunks,
1636
+ finalMessage
1637
+ };
1638
+ }
1639
+ throw new Error(`Streaming not yet implemented for ${provider} with Messages API pattern`);
1640
+ }
1641
+ /**
1642
+ * Stream request using Chat Completions API pattern
1643
+ *
1644
+ * Used by: OpenAI, XAI, DeepSeek, Groq, Anthropic (OpenAI-compatible)
1645
+ * Format: OpenAI Chat Completions with SSE chunks
1646
+ * SDK: Uses OpenAI SDK's ChatCompletionStream with .finalMessage() accumulation
1647
+ */
1648
+ streamChatCompletionsAPI(request, modelConfig) {
1649
+ // Round 7: shared request construction (env check, baseURL strip,
1650
+ // OpenRouter headers, client cache, param rename, reasoning_effort,
1651
+ // tool attachment, DEBUG_PAYLOAD logging).
1652
+ const { client, chatRequest: openaiRequest } = this.buildChatCompletionsRequest(request, modelConfig, { stream: true });
1653
+ // Import ChatCompletionStream dynamically (avoid top-level import issues)
1654
+ // Note: We'll use the client's .create() with stream: true which returns Stream<ChatCompletionChunk>
1655
+ // However, we want the ChatCompletionStream helper for .finalMessage()
1656
+ // For now, use manual iteration and accumulation (SDK's Stream doesn't have finalMessage)
1657
+ // TODO: Investigate if there's a better way to use ChatCompletionStream.createChatCompletion
1658
+ let fullContent = '';
1659
+ let fullReasoningContent = '';
1660
+ let firstChunk = null;
1661
+ let finalMessageResolve;
1662
+ const finalMessagePromise = new Promise((resolve) => {
1663
+ finalMessageResolve = resolve;
1664
+ });
1665
+ // Phase 2.8: Track tool calls for streaming tool execution
1666
+ const accumulatedToolCalls = new Map();
1667
+ // Capture this context before entering generator
1668
+ const self = this;
1669
+ // Create async generator that both yields chunks AND accumulates final message
1670
+ const chunks = async function* () {
1671
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1672
+ console.log(`[DEBUG APIClient] OpenAI request:`, JSON.stringify(openaiRequest, null, 2));
1673
+ }
1674
+ const stream = await client.chat.completions.create(openaiRequest);
1675
+ let chunkCount = 0;
1676
+ for await (const chunk of stream) {
1677
+ if (!firstChunk)
1678
+ firstChunk = chunk;
1679
+ chunkCount++;
1680
+ const delta = chunk.choices[0]?.delta;
1681
+ // Debug: Log first few chunks to see what fields are present
1682
+ if ((process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') && chunkCount <= 3) {
1683
+ console.log(`[DEBUG APIClient] Chunk ${chunkCount} delta keys:`, delta ? Object.keys(delta) : 'null');
1684
+ if (delta?.reasoning_content) {
1685
+ console.log(`[DEBUG APIClient] Found reasoning_content in chunk ${chunkCount}`);
1686
+ }
1687
+ }
1688
+ // Extract reasoning content (for models with native interleaved thinking)
1689
+ // XAI: chunk.choices[0].delta.reasoning_content
1690
+ // DeepSeek: chunk.choices[0].delta.reasoning_content
1691
+ // GPT-5: chunk.choices[0].delta.reasoning_content (when reasoning_effort != 'none')
1692
+ if (delta?.reasoning_content) {
1693
+ fullReasoningContent += delta.reasoning_content;
1694
+ yield {
1695
+ type: 'content_block_delta',
1696
+ delta: delta.reasoning_content,
1697
+ data: { ...chunk, reasoning: true }
1698
+ };
1699
+ }
1700
+ // Extract regular text content
1701
+ if (delta?.content) {
1702
+ fullContent += delta.content;
1703
+ yield {
1704
+ type: 'text_delta',
1705
+ delta: delta.content,
1706
+ data: chunk
1707
+ };
1708
+ }
1709
+ // Phase 2.8: Handle streaming tool_calls
1710
+ if (delta?.tool_calls && Array.isArray(delta.tool_calls)) {
1711
+ for (const toolCallDelta of delta.tool_calls) {
1712
+ const index = toolCallDelta.index;
1713
+ // Initialize tool call accumulator if needed
1714
+ if (!accumulatedToolCalls.has(index)) {
1715
+ accumulatedToolCalls.set(index, { arguments: '' });
1716
+ }
1717
+ const accumulated = accumulatedToolCalls.get(index);
1718
+ // Accumulate tool call properties
1719
+ if (toolCallDelta.id) {
1720
+ accumulated.id = toolCallDelta.id;
1721
+ }
1722
+ if (toolCallDelta.function?.name) {
1723
+ accumulated.name = toolCallDelta.function.name;
1724
+ }
1725
+ if (toolCallDelta.function?.arguments) {
1726
+ accumulated.arguments += toolCallDelta.function.arguments;
1727
+ }
1728
+ }
1729
+ }
1730
+ // Check if finish_reason indicates tool_calls completion (or length-truncated tool call)
1731
+ const finishReason = chunk.choices[0]?.finish_reason;
1732
+ if ((finishReason === 'tool_calls' || finishReason === 'length') && accumulatedToolCalls.size > 0) {
1733
+ // Emit tool_use_complete events for each accumulated tool call
1734
+ for (const [_, toolCall] of accumulatedToolCalls) {
1735
+ if (toolCall.id && toolCall.name) {
1736
+ try {
1737
+ let input;
1738
+ try {
1739
+ input = JSON.parse(toolCall.arguments);
1740
+ }
1741
+ catch {
1742
+ input = self.repairTruncatedJSON(toolCall.arguments);
1743
+ }
1744
+ const decodedInput = self.decodeHtmlEntitiesInObject(input);
1745
+ yield {
1746
+ type: 'tool_use_complete',
1747
+ toolUse: {
1748
+ id: toolCall.id,
1749
+ name: toolCall.name,
1750
+ input: decodedInput
1751
+ },
1752
+ data: chunk
1753
+ };
1754
+ }
1755
+ catch (error) {
1756
+ console.error(`[APIClient] Failed to parse tool arguments (${toolCall.arguments.length} chars): ${toolCall.arguments.slice(0, 200)}...`);
1757
+ }
1758
+ }
1759
+ }
1760
+ }
1761
+ }
1762
+ // Stream complete - log summary
1763
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1764
+ console.log(`[DEBUG APIClient] Stream complete - total chunks: ${chunkCount}, reasoning content length: ${fullReasoningContent.length}, content length: ${fullContent.length}`);
1765
+ }
1766
+ // Stream complete - resolve final message in OpenAI Chat Completions format
1767
+ // Include accumulated tool_calls in the final message
1768
+ const finalToolCalls = Array.from(accumulatedToolCalls.values())
1769
+ .filter(tc => tc.id && tc.name)
1770
+ .map(tc => ({
1771
+ id: tc.id,
1772
+ type: 'function',
1773
+ function: {
1774
+ name: tc.name,
1775
+ arguments: tc.arguments
1776
+ }
1777
+ }));
1778
+ finalMessageResolve({
1779
+ id: firstChunk?.id || 'chatcmpl-' + Date.now(),
1780
+ object: 'chat.completion',
1781
+ created: firstChunk?.created || Math.floor(Date.now() / 1000),
1782
+ model: firstChunk?.model || request.modelId,
1783
+ choices: [{
1784
+ index: 0,
1785
+ message: {
1786
+ role: 'assistant',
1787
+ content: fullContent || null,
1788
+ ...(fullReasoningContent && { reasoning_content: fullReasoningContent }),
1789
+ ...(finalToolCalls.length > 0 && { tool_calls: finalToolCalls })
1790
+ },
1791
+ finish_reason: finalToolCalls.length > 0 ? 'tool_calls' : 'stop'
1792
+ }],
1793
+ usage: {
1794
+ prompt_tokens: 0,
1795
+ completion_tokens: 0,
1796
+ total_tokens: 0
1797
+ }
1798
+ });
1799
+ }();
1800
+ return {
1801
+ chunks,
1802
+ finalMessage: finalMessagePromise
1803
+ };
1804
+ }
1805
+ /**
1806
+ * Stream request using Responses API pattern
1807
+ *
1808
+ * Used by: OpenAI (gpt-5-codex)
1809
+ * Format: OpenAI Responses API with structured streaming events
1810
+ * SDK: Uses OpenAI SDK's client.responses.create() with stream: true
1811
+ */
1812
+ streamResponsesAPI(request, modelConfig) {
1813
+ const apiKey = process.env[modelConfig.api.apiKeyEnvVar];
1814
+ if (!apiKey) {
1815
+ throw new Error(`Missing API key: ${modelConfig.api.apiKeyEnvVar}`);
1816
+ }
1817
+ // Use provider-formatted input items directly from ResponsesAPIAdapter.toProviderMessages()
1818
+ // The adapter already creates correctly typed items (message, function_call_output, etc.)
1819
+ // Re-wrapping them would strip tool results and function calls, breaking the tool loop.
1820
+ //
1821
+ // Extract <system-reminder> content from user messages into `instructions` parameter.
1822
+ const { instructions, cleanedItems: inputItems } = this.extractSystemRemindersForResponsesAPI(request.messages);
1823
+ // Accumulate content from stream
1824
+ let fullContent = '';
1825
+ let fullReasoningContent = '';
1826
+ let responseId = null;
1827
+ let finalResponse = null;
1828
+ const accumulatedToolCalls = [];
1829
+ let finalMessageResolve;
1830
+ const finalMessagePromise = new Promise((resolve) => {
1831
+ finalMessageResolve = resolve;
1832
+ });
1833
+ // Check if reasoning is supported and enabled
1834
+ const supportsReasoning = modelConfig.reasoning?.supported;
1835
+ const { disableThinking, reasoningEffort, ...apiParameters } = request.parameters;
1836
+ // Transform parameters for Responses API.
1837
+ // Responses API uses max_output_tokens instead of max_tokens.
1838
+ // R20c: also accept max_completion_tokens (GPT-5 chat/completions default key)
1839
+ // — needed on dynamic switch where the card never re-resolved the param name.
1840
+ let transformedParams = { ...apiParameters };
1841
+ for (const oldKey of ['max_tokens', 'max_completion_tokens', 'maxTokens']) {
1842
+ if (oldKey in transformedParams) {
1843
+ transformedParams.max_output_tokens = transformedParams[oldKey];
1844
+ delete transformedParams[oldKey];
1845
+ }
1846
+ }
1847
+ const isXAI = modelConfig.provider?.toLowerCase() === 'xai';
1848
+ const chunks = async function* () {
1849
+ // Import OpenAI SDK dynamically — set baseURL from model config endpoint
1850
+ const OpenAI = (await import('openai')).default;
1851
+ const streamBaseURL = modelConfig.api.endpoint.replace(/\/(messages|responses)$/, '');
1852
+ const client = new OpenAI({ apiKey, baseURL: streamBaseURL });
1853
+ // Create streaming request
1854
+ // Use modelConfig.modelId if available (for alias models like gpt-5.1-reasoning -> gpt-5.1)
1855
+ const actualModelId = modelConfig.modelId || request.modelId;
1856
+ // Remove model from transformedParams to prevent overwriting
1857
+ const { model: _ignoredModel, ...paramsWithoutModel } = transformedParams;
1858
+ const responsesRequest = {
1859
+ model: actualModelId,
1860
+ input: inputItems,
1861
+ stream: true,
1862
+ ...paramsWithoutModel
1863
+ };
1864
+ // Stateful chaining: use previous_response_id when available
1865
+ if (request.previousResponseId) {
1866
+ responsesRequest.previous_response_id = request.previousResponseId;
1867
+ }
1868
+ // XAI stores conversations server-side by default. Being explicit ensures preservation.
1869
+ // `prompt_cache_key` routes same-session requests to same server for cache hits.
1870
+ // NOTE: `include: ["reasoning.encrypted_content"]` triggered empty-output regression —
1871
+ // see sendResponsesAPI comment for details. Not sending it for now.
1872
+ if (isXAI) {
1873
+ responsesRequest.store = true;
1874
+ if (request.conversationId) {
1875
+ responsesRequest.prompt_cache_key = request.conversationId;
1876
+ }
1877
+ }
1878
+ // Set extracted system context as instructions (enables provider-side caching)
1879
+ // XAI does NOT support the `instructions` parameter — skip for XAI provider.
1880
+ if (instructions && !isXAI) {
1881
+ responsesRequest.instructions = instructions;
1882
+ }
1883
+ // Add reasoning if supported and not disabled
1884
+ // Responses API uses 'reasoning' object with 'effort' parameter
1885
+ // summary: 'auto' requests visible reasoning summaries for interleaved thinking
1886
+ if (supportsReasoning && !disableThinking && reasoningEffort && reasoningEffort !== 'none') {
1887
+ // R20: OpenAI Responses API rejects 'xhigh' (XAI-only effort level). Clamp at egress.
1888
+ const effectiveEffort = (!isXAI && reasoningEffort === 'xhigh') ? 'high' : reasoningEffort;
1889
+ responsesRequest.reasoning = { effort: effectiveEffort, summary: 'auto' };
1890
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1891
+ console.log(`[DEBUG APIClient] Responses API reasoning ENABLED (effort: ${effectiveEffort}, summary: auto)`);
1892
+ }
1893
+ }
1894
+ if (request.tools && request.tools.length > 0) {
1895
+ responsesRequest.tools = request.tools;
1896
+ }
1897
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1898
+ // Log summary without full tools/messages to avoid excessive output
1899
+ const { input, tools, ...requestSummary } = responsesRequest;
1900
+ console.log(`[DEBUG APIClient] Responses API request:`, JSON.stringify({
1901
+ ...requestSummary,
1902
+ input: `[${input?.length || 0} items]`,
1903
+ tools: tools ? `[${tools.length} tools]` : undefined
1904
+ }, null, 2));
1905
+ }
1906
+ // Stream using OpenAI SDK
1907
+ // client.responses.create() with stream:true returns a Promise<Stream>
1908
+ // We await it to get the Stream object which is async iterable
1909
+ const stream = await client.responses.create(responsesRequest);
1910
+ let chunkCount = 0;
1911
+ try {
1912
+ for await (const chunk of stream) {
1913
+ chunkCount++;
1914
+ // Store response ID and full response
1915
+ if (chunk.response?.id && !responseId) {
1916
+ responseId = chunk.response.id;
1917
+ }
1918
+ if (chunk.response) {
1919
+ finalResponse = chunk.response;
1920
+ }
1921
+ // Debug: Log chunks to see event types (only with DEBUG=true)
1922
+ if (process.env.DEBUG === 'true' && chunkCount <= 10) {
1923
+ console.log(`[APIClient] Responses chunk ${chunkCount}:`, chunk.type, chunk.item?.type || '');
1924
+ }
1925
+ // Handle reasoning items (when modalities includes 'reasoning')
1926
+ // Responses API returns reasoning as output items with type: 'reasoning'
1927
+ if (chunk.type === 'response.output_item.added' && chunk.item?.type === 'reasoning') {
1928
+ // Reasoning item started
1929
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
1930
+ console.log(`[DEBUG APIClient] Reasoning item started`);
1931
+ }
1932
+ }
1933
+ else if (chunk.type === 'response.output_item.done' && chunk.item?.type === 'reasoning') {
1934
+ // Reasoning item completed - extract summary
1935
+ const reasoningSummary = chunk.item.summary || '';
1936
+ if (reasoningSummary) {
1937
+ fullReasoningContent += reasoningSummary;
1938
+ yield {
1939
+ type: 'content_block_delta',
1940
+ delta: reasoningSummary,
1941
+ data: { ...chunk, reasoning: true }
1942
+ };
1943
+ }
1944
+ }
1945
+ // Handle reasoning content deltas (streamed reasoning text)
1946
+ if (chunk.type === 'response.reasoning_summary_text.delta' && chunk.delta) {
1947
+ fullReasoningContent += chunk.delta;
1948
+ yield {
1949
+ type: 'content_block_delta',
1950
+ delta: chunk.delta,
1951
+ data: { ...chunk, reasoning: true }
1952
+ };
1953
+ }
1954
+ // Handle text content deltas
1955
+ if (chunk.type === 'response.output_text.delta' && chunk.delta) {
1956
+ fullContent += chunk.delta;
1957
+ yield {
1958
+ type: 'text_delta',
1959
+ delta: chunk.delta,
1960
+ data: chunk
1961
+ };
1962
+ }
1963
+ // Handle function calls (tool use)
1964
+ // Responses API sends function_call items with name and arguments
1965
+ if (chunk.type === 'response.output_item.done' && chunk.item?.type === 'function_call') {
1966
+ const item = chunk.item;
1967
+ if (item.name && item.call_id) {
1968
+ // Round 18a: dedupe by call_id. Without this guard, the
1969
+ // OpenAI Responses streaming protocol can re-emit the same
1970
+ // `response.output_item.done` event multiple times (observed
1971
+ // in gpt-5.1-reasoning: 5 identical tool_use blocks with the
1972
+ // SAME call_id reached the orchestrator). Each duplicate
1973
+ // pushed to accumulatedToolCalls AND yielded as
1974
+ // tool_use_complete, causing the same tool to "execute" N
1975
+ // times.
1976
+ const alreadyEmitted = accumulatedToolCalls.some((tc) => tc.id === item.call_id);
1977
+ if (alreadyEmitted) {
1978
+ continue;
1979
+ }
1980
+ // Accumulate for finalMessage
1981
+ accumulatedToolCalls.push({
1982
+ id: item.call_id,
1983
+ name: item.name,
1984
+ arguments: item.arguments || '{}'
1985
+ });
1986
+ try {
1987
+ const input = typeof item.arguments === 'string'
1988
+ ? JSON.parse(item.arguments)
1989
+ : item.arguments;
1990
+ yield {
1991
+ type: 'tool_use_complete',
1992
+ toolUse: {
1993
+ id: item.call_id,
1994
+ name: item.name,
1995
+ input: input
1996
+ },
1997
+ data: chunk
1998
+ };
1999
+ }
2000
+ catch (error) {
2001
+ console.error(`[APIClient] Failed to parse function call arguments:`, item.arguments);
2002
+ }
2003
+ }
2004
+ }
2005
+ // Extract text deltas from output items (fallback for non-streaming format)
2006
+ if (chunk.type === 'response.output_item.added' && chunk.item) {
2007
+ const item = chunk.item;
2008
+ if (item.type === 'message' && item.content) {
2009
+ for (const block of item.content) {
2010
+ if (block.type === 'output_text' && block.text) {
2011
+ fullContent += block.text;
2012
+ yield {
2013
+ type: 'text_delta',
2014
+ delta: block.text,
2015
+ data: chunk
2016
+ };
2017
+ }
2018
+ }
2019
+ }
2020
+ }
2021
+ else if (chunk.type === 'response.output_item.done' && chunk.item) {
2022
+ const item = chunk.item;
2023
+ if (item.type === 'message' && item.content) {
2024
+ for (const block of item.content) {
2025
+ if (block.type === 'output_text' && block.text) {
2026
+ const text = block.text;
2027
+ if (text && !fullContent.includes(text)) {
2028
+ fullContent += text;
2029
+ yield {
2030
+ type: 'text_delta',
2031
+ delta: text,
2032
+ data: chunk
2033
+ };
2034
+ }
2035
+ }
2036
+ }
2037
+ }
2038
+ }
2039
+ }
2040
+ }
2041
+ catch (error) {
2042
+ throw new Error(`Responses API streaming error: ${error.message}`);
2043
+ }
2044
+ // Log summary
2045
+ if (process.env.DEBUG === 'true' || process.env.DEBUG_THINKING === 'true') {
2046
+ console.log(`[DEBUG APIClient] Responses stream complete - chunks: ${chunkCount}, reasoning: ${fullReasoningContent.length}, content: ${fullContent.length}`);
2047
+ }
2048
+ // Resolve final message in Responses API format
2049
+ // Build output array with message and any function calls
2050
+ const outputItems = [];
2051
+ // Add function calls first (they come before the message in the response)
2052
+ for (const toolCall of accumulatedToolCalls) {
2053
+ outputItems.push({
2054
+ type: 'function_call',
2055
+ call_id: toolCall.id,
2056
+ name: toolCall.name,
2057
+ arguments: toolCall.arguments
2058
+ });
2059
+ }
2060
+ // Add message if there's content
2061
+ if (fullContent) {
2062
+ outputItems.push({
2063
+ type: 'message',
2064
+ role: 'assistant',
2065
+ content: [
2066
+ {
2067
+ type: 'output_text',
2068
+ text: fullContent
2069
+ }
2070
+ ]
2071
+ });
2072
+ }
2073
+ finalMessageResolve({
2074
+ id: responseId || 'resp-' + Date.now(),
2075
+ object: 'response',
2076
+ created: finalResponse?.created_at || Math.floor(Date.now() / 1000),
2077
+ model: request.modelId,
2078
+ output: outputItems.length > 0 ? outputItems : [
2079
+ {
2080
+ type: 'message',
2081
+ role: 'assistant',
2082
+ content: [{ type: 'output_text', text: '' }]
2083
+ }
2084
+ ],
2085
+ usage: finalResponse?.usage || {
2086
+ prompt_tokens: 0,
2087
+ completion_tokens: 0,
2088
+ total_tokens: 0
2089
+ }
2090
+ });
2091
+ }();
2092
+ return {
2093
+ chunks,
2094
+ finalMessage: finalMessagePromise
2095
+ };
2096
+ }
2097
+ /**
2098
+ * Stream request using Google GenerateContent API pattern
2099
+ *
2100
+ * Used by: Google Gemini (Vertex AI, AI Studio)
2101
+ * Format: Google GenerateContent API
2102
+ * SDK: Uses Google SDK's generateContentStream()
2103
+ */
2104
+ streamGenerateContentAPI(request, modelConfig) {
2105
+ const apiKey = process.env[modelConfig.api.apiKeyEnvVar];
2106
+ if (!apiKey) {
2107
+ throw new Error(`Missing API key: ${modelConfig.api.apiKeyEnvVar}`);
2108
+ }
2109
+ // For models with tools, use direct HTTP streaming to ensure v1beta endpoint
2110
+ // The SDK sometimes uses v1 which doesn't support tools for newer models
2111
+ if (request.tools && request.tools.length > 0) {
2112
+ return this.streamGenerateContentHTTP(request, modelConfig, apiKey);
2113
+ }
2114
+ // For non-tool requests, use SDK streaming
2115
+ if (!this.googleClient) {
2116
+ this.googleClient = new GoogleGenerativeAI(apiKey);
2117
+ }
2118
+ const modelName = request.modelId.startsWith('models/') ? request.modelId : `models/${request.modelId}`;
2119
+ const model = this.googleClient.getGenerativeModel({ model: modelName });
2120
+ // Filter out internal flags and non-generation parameters
2121
+ // NOTE: disableThinking is NOT an API parameter - it's a UI-level flag
2122
+ const { model: _model, stream, tools: _tools, ...validGenerationConfig } = request.parameters;
2123
+ const geminiRequest = {
2124
+ contents: request.messages,
2125
+ generationConfig: validGenerationConfig
2126
+ };
2127
+ // Google SDK has generateContentStream
2128
+ const streamPromise = model.generateContentStream(geminiRequest);
2129
+ const chunks = async function* () {
2130
+ const { stream } = await streamPromise;
2131
+ for await (const chunk of stream) {
2132
+ const text = chunk.text();
2133
+ if (text) {
2134
+ yield {
2135
+ type: 'text_delta',
2136
+ delta: text,
2137
+ data: chunk
2138
+ };
2139
+ }
2140
+ }
2141
+ }();
2142
+ const finalMessage = (async () => {
2143
+ const { response } = await streamPromise;
2144
+ return response;
2145
+ })();
2146
+ return {
2147
+ chunks,
2148
+ finalMessage
2149
+ };
2150
+ }
2151
+ /**
2152
+ * Stream GenerateContent request via direct HTTP with tools
2153
+ * Ensures v1beta endpoint is used for tool support
2154
+ */
2155
+ streamGenerateContentHTTP(request, modelConfig, apiKey) {
2156
+ // Get model ID (no models/ prefix - endpoint already includes it)
2157
+ const modelId = request.modelId.startsWith('models/')
2158
+ ? request.modelId.replace('models/', '')
2159
+ : request.modelId;
2160
+ // Build URL using configured endpoint (should be v1beta)
2161
+ const url = `${modelConfig.api.endpoint}/${modelId}:streamGenerateContent?alt=sse&key=${apiKey}`;
2162
+ // Build generation config (exclude stream, tools, and model - these are handled separately)
2163
+ // NOTE: disableThinking is NOT an API parameter - it's a UI-level flag
2164
+ // Extract the nested generationConfig object from request.parameters
2165
+ const { generationConfig } = request.parameters;
2166
+ // Build request body (REST API uses snake_case)
2167
+ const requestBody = {
2168
+ contents: request.messages,
2169
+ generation_config: generationConfig // Use the nested object directly
2170
+ };
2171
+ // Add tools if present - REST API uses snake_case "function_declarations"
2172
+ if (request.tools && request.tools.length > 0) {
2173
+ requestBody.tools = [{ function_declarations: request.tools }];
2174
+ // DEBUG: Log Gemini streaming tool request details
2175
+ if (process.env.DEBUG === 'true') {
2176
+ console.log(`[DEBUG APIClient] Gemini streaming request with ${request.tools.length} tools:`);
2177
+ console.log(`[DEBUG APIClient] Tool names: ${request.tools.map((t) => t.name).join(', ')}`);
2178
+ }
2179
+ }
2180
+ // Add system instruction if present
2181
+ if (request.systemMessage) {
2182
+ requestBody.system_instruction = {
2183
+ parts: [{ text: request.systemMessage }]
2184
+ };
2185
+ }
2186
+ // DEBUG: Log the request body for diagnosing empty responses
2187
+ if (process.env.DEBUG === 'true') {
2188
+ console.log(`[DEBUG APIClient HTTP] Request URL: ${url.replace(/key=[^&]+/, 'key=***')}`);
2189
+ console.log(`[DEBUG APIClient HTTP] generation_config: ${JSON.stringify(requestBody.generation_config)}`);
2190
+ console.log(`[DEBUG APIClient HTTP] tools count: ${requestBody.tools?.[0]?.function_declarations?.length ?? 0}`);
2191
+ console.log(`[DEBUG APIClient HTTP] system_instruction present: ${!!requestBody.system_instruction}`);
2192
+ console.log(`[DEBUG APIClient HTTP] contents length: ${requestBody.contents?.length ?? 0}`);
2193
+ // Dump contents structure (roles and parts types, not full text)
2194
+ for (let i = 0; i < (requestBody.contents?.length ?? 0); i++) {
2195
+ const c = requestBody.contents[i];
2196
+ const partsInfo = (c.parts || []).map((p) => {
2197
+ if (p.text)
2198
+ return `text(${p.text.length}chars)`;
2199
+ if (p.functionCall)
2200
+ return `functionCall(${p.functionCall.name})`;
2201
+ if (p.functionResponse)
2202
+ return `functionResponse(${p.functionResponse.name})`;
2203
+ return Object.keys(p).join(',');
2204
+ });
2205
+ if (process.env.DEBUG === 'true')
2206
+ console.log(`[DEBUG APIClient HTTP] contents[${i}]: role=${c.role}, parts=[${partsInfo.join(', ')}]`);
2207
+ }
2208
+ // Write full request body to file for inspection
2209
+ import('fs').then(fs => fs.writeFileSync('/tmp/gemini-request-' + modelId + '.json', JSON.stringify(requestBody, null, 2)));
2210
+ }
2211
+ // Start the fetch request
2212
+ const fetchPromise = fetch(url, {
2213
+ method: 'POST',
2214
+ headers: {
2215
+ 'Content-Type': 'application/json'
2216
+ },
2217
+ body: JSON.stringify(requestBody)
2218
+ });
2219
+ // Shared state for collecting all chunks
2220
+ const allChunks = [];
2221
+ let fullText = '';
2222
+ let lastCandidate = null;
2223
+ let streamingError = null;
2224
+ // Resolve function for completion signal
2225
+ let resolveCompletion = null;
2226
+ const completionPromise = new Promise((resolve) => {
2227
+ resolveCompletion = resolve;
2228
+ });
2229
+ // Create async generator for streaming chunks
2230
+ const chunks = async function* () {
2231
+ try {
2232
+ const response = await fetchPromise;
2233
+ if (!response.ok) {
2234
+ const errorText = await response.text();
2235
+ console.error(`[APIClient] Gemini API error ${response.status}:`, errorText);
2236
+ throw new Error(`Gemini API error: ${response.status} - ${errorText}`);
2237
+ }
2238
+ if (!response.body) {
2239
+ throw new Error('Response body is null');
2240
+ }
2241
+ const reader = response.body.getReader();
2242
+ const decoder = new TextDecoder();
2243
+ let buffer = '';
2244
+ while (true) {
2245
+ const { done, value } = await reader.read();
2246
+ if (done) {
2247
+ if (process.env.DEBUG === 'true') {
2248
+ console.log('[DEBUG APIClient] Stream reader done, exiting loop');
2249
+ }
2250
+ break;
2251
+ }
2252
+ buffer += decoder.decode(value, { stream: true });
2253
+ // Process complete SSE messages
2254
+ const lines = buffer.split('\n');
2255
+ buffer = lines.pop() || ''; // Keep incomplete line in buffer
2256
+ for (const line of lines) {
2257
+ if (line.startsWith('data: ')) {
2258
+ const jsonStr = line.slice(6); // Remove 'data: ' prefix
2259
+ if (jsonStr.trim() === '')
2260
+ continue;
2261
+ try {
2262
+ const chunk = JSON.parse(jsonStr);
2263
+ // DEBUG: Log chunk structure
2264
+ if (process.env.DEBUG === 'true') {
2265
+ console.log('[DEBUG APIClient] Gemini chunk:', JSON.stringify(chunk).substring(0, 200));
2266
+ if (chunk.candidates?.[0]?.finishReason) {
2267
+ console.log(`[DEBUG APIClient] finishReason: ${chunk.candidates[0].finishReason}`);
2268
+ }
2269
+ }
2270
+ // Store last candidate for final response
2271
+ if (chunk.candidates?.[0]) {
2272
+ lastCandidate = chunk.candidates[0];
2273
+ }
2274
+ // Extract parts from candidates
2275
+ const parts = chunk.candidates?.[0]?.content?.parts;
2276
+ if (parts && Array.isArray(parts)) {
2277
+ for (const part of parts) {
2278
+ // Handle thinking parts (reasoning blocks)
2279
+ // Following gemini-cli pattern: yield ALL chunks including thinking
2280
+ // UI will filter based on disableThinking flag
2281
+ if (part.thought && part.text) {
2282
+ const thinkingChunk = {
2283
+ type: 'thinking_delta',
2284
+ delta: part.text,
2285
+ data: chunk
2286
+ };
2287
+ allChunks.push(thinkingChunk);
2288
+ // Don't add to fullText - thinking is filtered from final response
2289
+ yield thinkingChunk;
2290
+ }
2291
+ // Handle regular text (non-thinking)
2292
+ else if (part.text && !part.thought) {
2293
+ const chunkData = {
2294
+ type: 'text_delta',
2295
+ delta: part.text,
2296
+ data: chunk
2297
+ };
2298
+ allChunks.push(chunkData);
2299
+ fullText += part.text;
2300
+ yield chunkData;
2301
+ }
2302
+ // Handle function calls (tool uses)
2303
+ if (part.functionCall) {
2304
+ // R19c: preserve thoughtSignature for Gemini 2.5+/3+
2305
+ // multi-turn function calling. SDK streaming path (~line
2306
+ // 2944) already does this; the raw-fetch streaming path
2307
+ // (used by gemini-3-pro-preview via apiPattern
2308
+ // 'generateContent') was dropping it, causing Gemini 3 to
2309
+ // 400 with "Function call is missing a thought_signature"
2310
+ // on every continuation and looping until MAX_TOOL_ITER.
2311
+ const thoughtSig = part.thoughtSignature;
2312
+ const toolUse = {
2313
+ // R19a: uuidv4 instead of Date.now()+Math.random — same
2314
+ // collision-free reasoning as adapters.
2315
+ id: `call_${uuidv4()}`,
2316
+ name: part.functionCall.name,
2317
+ input: part.functionCall.args
2318
+ };
2319
+ if (thoughtSig) {
2320
+ toolUse.metadata = { thoughtSignature: thoughtSig };
2321
+ }
2322
+ const toolChunk = {
2323
+ type: 'tool_use_complete',
2324
+ toolUse,
2325
+ data: chunk
2326
+ };
2327
+ allChunks.push(toolChunk);
2328
+ yield toolChunk;
2329
+ }
2330
+ }
2331
+ }
2332
+ }
2333
+ catch (parseError) {
2334
+ console.error('Error parsing SSE chunk:', parseError);
2335
+ }
2336
+ }
2337
+ }
2338
+ }
2339
+ }
2340
+ catch (error) {
2341
+ streamingError = error;
2342
+ throw error;
2343
+ }
2344
+ finally {
2345
+ // Signal that streaming is complete (success or error)
2346
+ if (resolveCompletion) {
2347
+ resolveCompletion();
2348
+ }
2349
+ }
2350
+ }();
2351
+ // Final message promise that waits for streaming to complete
2352
+ const finalMessage = (async () => {
2353
+ // Wait for streaming to complete (without consuming the chunks)
2354
+ await completionPromise;
2355
+ // If there was an error, throw it
2356
+ if (streamingError) {
2357
+ throw streamingError;
2358
+ }
2359
+ // Return final response structure matching Google SDK format
2360
+ return {
2361
+ text: () => fullText,
2362
+ candidates: lastCandidate ? [lastCandidate] : [],
2363
+ usageMetadata: lastCandidate?.usageMetadata
2364
+ };
2365
+ })();
2366
+ return {
2367
+ chunks,
2368
+ finalMessage
2369
+ };
2370
+ }
2371
+ /**
2372
+ * Validate and enhance tools for XAI Messages API
2373
+ * XAI requires ALL tools and parameters to have descriptions
2374
+ */
2375
+ validateXAITools(tools) {
2376
+ return tools.map((tool, index) => {
2377
+ const enhancedTool = { ...tool };
2378
+ // Ensure tool has a name
2379
+ if (!enhancedTool.name || typeof enhancedTool.name !== 'string') {
2380
+ enhancedTool.name = `tool_${index}`;
2381
+ }
2382
+ // REQUIRED: Ensure tool has a description
2383
+ if (!enhancedTool.description || typeof enhancedTool.description !== 'string') {
2384
+ enhancedTool.description = enhancedTool.name ?
2385
+ `Execute ${enhancedTool.name} tool` :
2386
+ `Tool ${index}`;
2387
+ if (process.env.DEBUG === 'true')
2388
+ console.log(`[XAI Validation] Added missing description for tool: ${enhancedTool.name}`);
2389
+ }
2390
+ // REQUIRED: Ensure input_schema exists
2391
+ if (!enhancedTool.input_schema) {
2392
+ console.error(`[XAI Validation] Tool ${enhancedTool.name} missing input_schema! Creating default.`);
2393
+ enhancedTool.input_schema = {
2394
+ type: 'object',
2395
+ properties: {},
2396
+ required: []
2397
+ };
2398
+ }
2399
+ // Ensure input_schema has proper structure
2400
+ if (!enhancedTool.input_schema.type) {
2401
+ enhancedTool.input_schema.type = 'object';
2402
+ }
2403
+ if (!enhancedTool.input_schema.properties) {
2404
+ enhancedTool.input_schema.properties = {};
2405
+ }
2406
+ // REQUIRED: Ensure all parameters have descriptions
2407
+ if (enhancedTool.input_schema.properties) {
2408
+ const properties = enhancedTool.input_schema.properties;
2409
+ for (const [key, prop] of Object.entries(properties)) {
2410
+ if (!prop.description || typeof prop.description !== 'string') {
2411
+ prop.description = `Parameter ${key} for ${enhancedTool.name || 'tool'}`;
2412
+ if (process.env.DEBUG === 'true')
2413
+ console.log(`[XAI Validation] Added missing description for parameter: ${key}`);
2414
+ }
2415
+ }
2416
+ // Ensure required field exists (XAI expects it)
2417
+ if (!enhancedTool.input_schema.required) {
2418
+ enhancedTool.input_schema.required = [];
2419
+ }
2420
+ }
2421
+ return enhancedTool;
2422
+ });
2423
+ }
2424
+ /**
2425
+ * Send non-streaming request using Google GenAI SDK
2426
+ * Mirrors streamGoogleSDK() but uses generateContent() instead of generateContentStream()
2427
+ */
2428
+ async sendGoogleSDK(request, _modelConfig) {
2429
+ // Initialize Google GenAI client (same as streaming path)
2430
+ if (!this.googleGenAIClient) {
2431
+ const apiKey = process.env['GEMINI_API_KEY'];
2432
+ if (!apiKey) {
2433
+ throw new Error('GEMINI_API_KEY environment variable is required for Google SDK models');
2434
+ }
2435
+ const oldGoogleKey = process.env['GOOGLE_API_KEY'];
2436
+ delete process.env['GOOGLE_API_KEY'];
2437
+ try {
2438
+ this.googleGenAIClient = new GoogleGenAI({ apiKey });
2439
+ }
2440
+ finally {
2441
+ if (oldGoogleKey) {
2442
+ process.env['GOOGLE_API_KEY'] = oldGoogleKey;
2443
+ }
2444
+ }
2445
+ }
2446
+ // Strip -sdk suffix for actual API model ID
2447
+ let modelId = request.modelId;
2448
+ if (modelId.endsWith('-sdk')) {
2449
+ modelId = modelId.replace(/-sdk$/, '');
2450
+ }
2451
+ const { generationConfig, disableThinking } = request.parameters;
2452
+ const config = {};
2453
+ if (generationConfig) {
2454
+ Object.assign(config, generationConfig);
2455
+ }
2456
+ // CRITICAL: thinkingConfig and tools CANNOT coexist
2457
+ const hasTools = request.tools && request.tools.length > 0;
2458
+ if (_modelConfig.reasoning?.supported && _modelConfig.reasoning?.pattern === 'interleaved' && !disableThinking && !hasTools) {
2459
+ config.thinkingConfig = {
2460
+ includeThoughts: true,
2461
+ thinkingBudget: 10000
2462
+ };
2463
+ }
2464
+ // Add tools to config if present
2465
+ if (hasTools && request.tools) {
2466
+ config.tools = request.tools.map((tool) => ({
2467
+ functionDeclarations: [{
2468
+ name: tool.name,
2469
+ description: tool.description,
2470
+ parameters: tool.input_schema
2471
+ }]
2472
+ }));
2473
+ }
2474
+ const sdkRequest = {
2475
+ model: modelId,
2476
+ contents: request.messages,
2477
+ config
2478
+ };
2479
+ if (request.systemMessage) {
2480
+ sdkRequest.systemInstruction = request.systemMessage;
2481
+ }
2482
+ if (process.env.DEBUG === 'true') {
2483
+ console.log(`[DEBUG APIClient SDK] Non-streaming request for model: ${modelId}`);
2484
+ }
2485
+ const response = await this.googleGenAIClient.models.generateContent(sdkRequest);
2486
+ return {
2487
+ data: response,
2488
+ status: 200,
2489
+ headers: {}
2490
+ };
2491
+ }
2492
+ /**
2493
+ * Stream using Google GenAI SDK (EXPERIMENTAL)
2494
+ * Uses @google/genai SDK directly instead of REST API
2495
+ *
2496
+ * Key differences from streamGenerateContentAPI:
2497
+ * - Uses new @google/genai package (not @google/generative-ai)
2498
+ * - Automatically reads GEMINI_API_KEY from environment
2499
+ * - Simpler API with better stability
2500
+ * - Matches Google's official documentation examples
2501
+ */
2502
+ streamGoogleSDK(request, _modelConfig) {
2503
+ // Initialize Google GenAI client (explicitly use GEMINI_API_KEY per docs)
2504
+ if (!this.googleGenAIClient) {
2505
+ const apiKey = process.env['GEMINI_API_KEY'];
2506
+ if (!apiKey) {
2507
+ throw new Error('GEMINI_API_KEY environment variable is required for Google SDK models');
2508
+ }
2509
+ // Temporarily unset GOOGLE_API_KEY to prevent SDK from preferring it
2510
+ // The SDK checks both GEMINI_API_KEY and GOOGLE_API_KEY, but prefers GOOGLE_API_KEY
2511
+ const oldGoogleKey = process.env['GOOGLE_API_KEY'];
2512
+ delete process.env['GOOGLE_API_KEY'];
2513
+ try {
2514
+ this.googleGenAIClient = new GoogleGenAI({ apiKey });
2515
+ }
2516
+ finally {
2517
+ // Restore GOOGLE_API_KEY for other providers
2518
+ if (oldGoogleKey) {
2519
+ process.env['GOOGLE_API_KEY'] = oldGoogleKey;
2520
+ }
2521
+ }
2522
+ }
2523
+ // Use actual Google model ID (strip our custom suffix if present)
2524
+ // e.g., "gemini-2.5-flash-sdk" -> "gemini-2.5-flash"
2525
+ let modelId = request.modelId;
2526
+ if (modelId.endsWith('-sdk')) {
2527
+ modelId = modelId.replace(/-sdk$/, '');
2528
+ }
2529
+ // Extract parameters
2530
+ const { generationConfig, disableThinking } = request.parameters;
2531
+ // Build config object (tools go inside config per Google SDK docs)
2532
+ const config = {};
2533
+ // Add generation parameters to config
2534
+ if (generationConfig) {
2535
+ Object.assign(config, generationConfig);
2536
+ }
2537
+ // Enable extended thinking for models with reasoning support (Gemini 2.5+)
2538
+ // Following Claude/Grok pattern: Skip if disableThinking flag is set (used for continuation requests)
2539
+ // CRITICAL: thinkingConfig and tools CANNOT coexist — Google API returns empty responses when both present
2540
+ const hasTools = request.tools && request.tools.length > 0;
2541
+ if (_modelConfig.reasoning?.supported && _modelConfig.reasoning?.pattern === 'interleaved' && !disableThinking && !hasTools) {
2542
+ config.thinkingConfig = {
2543
+ includeThoughts: true, // Enable thought summaries in response
2544
+ // Gemini 2.5 Flash supports thinkingBudget (0-24576)
2545
+ // -1 = dynamic (model decides), or set explicit budget like Claude's 10000
2546
+ // Set to 10000 tokens to encourage verbose reasoning like Claude
2547
+ thinkingBudget: 10000
2548
+ };
2549
+ if (process.env.DEBUG === 'true') {
2550
+ console.log(`[DEBUG APIClient SDK] Extended thinking enabled for ${modelId} with budget: 10000`);
2551
+ }
2552
+ }
2553
+ else if (hasTools && process.env.DEBUG === 'true') {
2554
+ console.log(`[DEBUG APIClient SDK] Skipping thinkingConfig for ${modelId} — incompatible with tools`);
2555
+ }
2556
+ // Add tools to config if present (per SDK docs, tools are inside config)
2557
+ if (request.tools && request.tools.length > 0) {
2558
+ config.tools = request.tools.map((tool) => ({
2559
+ functionDeclarations: [{
2560
+ name: tool.name,
2561
+ description: tool.description,
2562
+ parameters: tool.input_schema
2563
+ }]
2564
+ }));
2565
+ if (process.env.DEBUG === 'true') {
2566
+ console.log(`[DEBUG APIClient SDK] Gemini SDK request with ${request.tools.length} tools`);
2567
+ console.log(`[DEBUG APIClient SDK] Tool names: ${request.tools.map((t) => t.name).join(', ')}`);
2568
+ }
2569
+ }
2570
+ // Build request for new SDK
2571
+ const sdkRequest = {
2572
+ model: modelId,
2573
+ contents: request.messages,
2574
+ config // Config contains both generation params and tools
2575
+ };
2576
+ // Add system instruction if present (top level, not in config)
2577
+ if (request.systemMessage) {
2578
+ sdkRequest.systemInstruction = request.systemMessage;
2579
+ }
2580
+ if (process.env.DEBUG === 'true') {
2581
+ console.log(`[DEBUG APIClient SDK] Using model: ${modelId}`);
2582
+ console.log(`[DEBUG APIClient SDK] Request keys: ${Object.keys(sdkRequest).join(', ')}`);
2583
+ if (config.tools) {
2584
+ console.log(`[DEBUG APIClient SDK] Config has ${config.tools.length} tool(s)`);
2585
+ }
2586
+ }
2587
+ // Shared state between chunks generator and finalMessage
2588
+ let lastChunk = null;
2589
+ let fullText = '';
2590
+ let chunkCount = 0; // Track number of chunks for debugging
2591
+ let resolveComplete;
2592
+ const streamCompletePromise = new Promise((resolve) => {
2593
+ resolveComplete = resolve;
2594
+ });
2595
+ const chunks = async function* (client) {
2596
+ try {
2597
+ // Stream using new SDK (SINGLE API call)
2598
+ const stream = await client.models.generateContentStream(sdkRequest);
2599
+ if (process.env.DEBUG === 'true') {
2600
+ console.log(`[DEBUG APIClient SDK] Stream started for model: ${modelId}`);
2601
+ }
2602
+ for await (const chunk of stream) {
2603
+ // Store for final message
2604
+ lastChunk = chunk;
2605
+ chunkCount++;
2606
+ if (process.env.DEBUG === 'true') {
2607
+ console.log(`[DEBUG APIClient SDK] Chunk ${chunkCount}: candidates=${chunk.candidates?.length || 0}, finishReason=${chunk.candidates?.[0]?.finishReason || 'none'}`);
2608
+ }
2609
+ // Process candidates array (similar to REST API approach)
2610
+ const candidates = chunk.candidates;
2611
+ if (candidates && Array.isArray(candidates)) {
2612
+ for (const candidate of candidates) {
2613
+ const parts = candidate.content?.parts;
2614
+ if (parts && Array.isArray(parts)) {
2615
+ for (const part of parts) {
2616
+ // Handle thinking parts (extended reasoning) - similar to Claude's extended thinking
2617
+ // Following gemini-cli pattern: yield ALL chunks including thinking
2618
+ if (part.thought && part.text) {
2619
+ if (process.env.DEBUG === 'true') {
2620
+ console.log(`[DEBUG APIClient SDK] Thinking chunk length: ${part.text.length}`);
2621
+ }
2622
+ yield {
2623
+ type: 'thinking_delta',
2624
+ delta: part.text,
2625
+ data: chunk
2626
+ };
2627
+ continue; // Skip adding to fullText (thinking is separate)
2628
+ }
2629
+ // Handle regular text
2630
+ if (part.text && !part.functionCall) {
2631
+ const text = part.text;
2632
+ fullText += text;
2633
+ if (process.env.DEBUG === 'true') {
2634
+ console.log(`[DEBUG APIClient SDK] Chunk text length: ${text.length}`);
2635
+ }
2636
+ // BREAK DOWN LARGE TEXT CHUNKS FOR SMOOTH STREAMING
2637
+ // SDK yields larger chunks (full lines/sentences) unlike HTTP SSE which is more granular
2638
+ // Split into smaller pieces to provide smoother streaming experience
2639
+ if (text.length > 50) {
2640
+ // For large chunks, yield in smaller pieces
2641
+ const words = text.split(/(\s+)/); // Split on whitespace but keep delimiters
2642
+ let currentChunk = '';
2643
+ for (const word of words) {
2644
+ currentChunk += word;
2645
+ // Yield when we have a reasonable chunk size or hit natural breaks
2646
+ if (currentChunk.length >= 20 || word.includes('\n') || word.includes('.') || word.includes('?') || word.includes('!')) {
2647
+ yield {
2648
+ type: 'text_delta',
2649
+ delta: currentChunk,
2650
+ data: chunk
2651
+ };
2652
+ currentChunk = '';
2653
+ }
2654
+ }
2655
+ // Yield any remaining text
2656
+ if (currentChunk.length > 0) {
2657
+ yield {
2658
+ type: 'text_delta',
2659
+ delta: currentChunk,
2660
+ data: chunk
2661
+ };
2662
+ }
2663
+ }
2664
+ else {
2665
+ // For smaller chunks, yield as-is
2666
+ yield {
2667
+ type: 'text_delta',
2668
+ delta: text,
2669
+ data: chunk
2670
+ };
2671
+ }
2672
+ }
2673
+ // Handle function calls (tool uses)
2674
+ if (part.functionCall) {
2675
+ if (process.env.DEBUG === 'true') {
2676
+ console.log(`[DEBUG APIClient SDK] Function call: ${part.functionCall.name}`);
2677
+ if (part.thoughtSignature) {
2678
+ console.log(`[DEBUG APIClient SDK] Has thought signature: ${part.thoughtSignature.substring(0, 50)}...`);
2679
+ }
2680
+ }
2681
+ // Build toolUse with thought signature preserved in metadata
2682
+ const rand = Math.random();
2683
+ const toolUse = {
2684
+ id: `call_${Date.now()}_${rand.toString(36).substring(2, 11)}`,
2685
+ name: part.functionCall.name || 'unknown', // Ensure name is always string
2686
+ input: part.functionCall.args || {} // Ensure input is always object
2687
+ };
2688
+ // CRITICAL: Preserve thought signature for multi-turn function calling (Gemini 2.5+/3+)
2689
+ const thoughtSig = part.thoughtSignature;
2690
+ if (thoughtSig) {
2691
+ toolUse.metadata = { thoughtSignature: thoughtSig };
2692
+ }
2693
+ yield {
2694
+ type: 'tool_use_complete',
2695
+ toolUse,
2696
+ data: chunk
2697
+ };
2698
+ }
2699
+ }
2700
+ }
2701
+ }
2702
+ }
2703
+ }
2704
+ if (process.env.DEBUG === 'true') {
2705
+ console.log(`[DEBUG APIClient SDK] Stream complete after ${chunkCount} chunks`);
2706
+ console.log(`[DEBUG APIClient SDK] Full text length: ${fullText.length}`);
2707
+ console.log(`[DEBUG APIClient SDK] lastChunk keys: ${Object.keys(lastChunk || {}).join(', ')}`);
2708
+ if (lastChunk?.candidates) {
2709
+ console.log(`[DEBUG APIClient SDK] candidates length: ${lastChunk.candidates.length}`);
2710
+ if (lastChunk.candidates.length > 0) {
2711
+ if (process.env.DEBUG === 'true')
2712
+ console.log(`[DEBUG APIClient SDK] candidates[0] keys: ${Object.keys(lastChunk.candidates[0] || {}).join(', ')}`);
2713
+ console.log(`[DEBUG APIClient SDK] finishReason: ${lastChunk.candidates[0]?.finishReason || 'none'}`);
2714
+ if (lastChunk.candidates[0]?.content) {
2715
+ console.log(`[DEBUG APIClient SDK] content.parts length: ${lastChunk.candidates[0].content.parts?.length || 0}`);
2716
+ }
2717
+ }
2718
+ }
2719
+ else {
2720
+ console.warn(`[DEBUG APIClient SDK] No candidates in final chunk!`);
2721
+ }
2722
+ if (lastChunk?.usageMetadata) {
2723
+ if (process.env.DEBUG === 'true')
2724
+ console.log(`[DEBUG APIClient SDK] Token usage: ${JSON.stringify(lastChunk.usageMetadata)}`);
2725
+ }
2726
+ }
2727
+ // Check for problematic finish reasons
2728
+ const finishReason = lastChunk?.candidates?.[0]?.finishReason;
2729
+ if (finishReason && finishReason !== 'STOP') {
2730
+ console.warn(`[APIClient SDK] Unexpected finishReason: ${finishReason}`);
2731
+ if (finishReason === 'SAFETY' || finishReason === 'RECITATION') {
2732
+ console.warn(`[APIClient SDK] Response was blocked. Check safety ratings.`);
2733
+ }
2734
+ else if (finishReason === 'MAX_TOKENS') {
2735
+ console.warn(`[APIClient SDK] Response truncated due to token limit.`);
2736
+ }
2737
+ }
2738
+ // Yield message_stop chunk to signal completion (triggers markdown flush in CLI)
2739
+ yield {
2740
+ type: 'message_stop',
2741
+ data: lastChunk
2742
+ };
2743
+ // Signal that stream is complete
2744
+ resolveComplete();
2745
+ }
2746
+ catch (error) {
2747
+ console.error('[APIClient SDK] Streaming error:', error);
2748
+ // Signal completion even on error
2749
+ resolveComplete();
2750
+ throw error;
2751
+ }
2752
+ }(this.googleGenAIClient);
2753
+ const finalMessage = (async () => {
2754
+ // Wait for chunks generator to complete
2755
+ await streamCompletePromise;
2756
+ // Return final response structure matching Google SDK format
2757
+ // This matches the structure expected by the orchestrator
2758
+ return {
2759
+ text: () => fullText,
2760
+ candidates: lastChunk?.candidates || [],
2761
+ usageMetadata: lastChunk?.usageMetadata
2762
+ };
2763
+ })();
2764
+ return {
2765
+ chunks,
2766
+ finalMessage
2767
+ };
2768
+ }
2769
+ }
2770
+ //# sourceMappingURL=APIClient.js.map