whale-code 6.5.4 → 6.5.6

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 (853) hide show
  1. package/README.md +39 -31
  2. package/bin/{swagmanager-mcp.js → whale-code.js} +17 -2
  3. package/dist/cli/app.js +148 -72
  4. package/dist/cli/app.js.map +1 -0
  5. package/dist/cli/chat/AgentSelector.js +105 -10
  6. package/dist/cli/chat/AgentSelector.js.map +1 -0
  7. package/dist/cli/chat/ChatApp.d.ts +31 -0
  8. package/dist/cli/chat/ChatApp.js +539 -286
  9. package/dist/cli/chat/ChatApp.js.map +1 -0
  10. package/dist/cli/chat/ChatInput.js +1088 -770
  11. package/dist/cli/chat/ChatInput.js.map +1 -0
  12. package/dist/cli/chat/MarkdownText.js +39 -14
  13. package/dist/cli/chat/MarkdownText.js.map +1 -0
  14. package/dist/cli/chat/MemoryManager.js +181 -46
  15. package/dist/cli/chat/MemoryManager.js.map +1 -0
  16. package/dist/cli/chat/MessageList.d.ts +2 -3
  17. package/dist/cli/chat/MessageList.js +186 -45
  18. package/dist/cli/chat/MessageList.js.map +1 -0
  19. package/dist/cli/chat/ModelSelector.js +282 -63
  20. package/dist/cli/chat/ModelSelector.js.map +1 -0
  21. package/dist/cli/chat/NodeManager.js +165 -75
  22. package/dist/cli/chat/NodeManager.js.map +1 -0
  23. package/dist/cli/chat/NodeSelector.js +171 -30
  24. package/dist/cli/chat/NodeSelector.js.map +1 -0
  25. package/dist/cli/chat/PlanApproval.js +281 -57
  26. package/dist/cli/chat/PlanApproval.js.map +1 -0
  27. package/dist/cli/chat/RewindViewer.js +559 -144
  28. package/dist/cli/chat/RewindViewer.js.map +1 -0
  29. package/dist/cli/chat/SessionManager.js +137 -30
  30. package/dist/cli/chat/SessionManager.js.map +1 -0
  31. package/dist/cli/chat/SlashMenu.js +293 -164
  32. package/dist/cli/chat/SlashMenu.js.map +1 -0
  33. package/dist/cli/chat/StatusBar.js +172 -9
  34. package/dist/cli/chat/StatusBar.js.map +1 -0
  35. package/dist/cli/chat/StoreSelector.js +147 -18
  36. package/dist/cli/chat/StoreSelector.js.map +1 -0
  37. package/dist/cli/chat/StreamingText.d.ts +1 -5
  38. package/dist/cli/chat/StreamingText.js +22 -7
  39. package/dist/cli/chat/StreamingText.js.map +1 -0
  40. package/dist/cli/chat/SubagentPanel.d.ts +1 -2
  41. package/dist/cli/chat/SubagentPanel.js +612 -72
  42. package/dist/cli/chat/SubagentPanel.js.map +1 -0
  43. package/dist/cli/chat/TeamPanel.d.ts +1 -0
  44. package/dist/cli/chat/TeamPanel.js +230 -30
  45. package/dist/cli/chat/TeamPanel.js.map +1 -0
  46. package/dist/cli/chat/ThemeSelector.js +84 -24
  47. package/dist/cli/chat/ThemeSelector.js.map +1 -0
  48. package/dist/cli/chat/ToolIndicator.js +1476 -371
  49. package/dist/cli/chat/ToolIndicator.js.map +1 -0
  50. package/dist/cli/chat/hooks/useAgentLoop.d.ts +1 -0
  51. package/dist/cli/chat/hooks/useAgentLoop.js +481 -367
  52. package/dist/cli/chat/hooks/useAgentLoop.js.map +1 -0
  53. package/dist/cli/chat/hooks/useSlashCommands.d.ts +3 -14
  54. package/dist/cli/chat/hooks/useSlashCommands.js +744 -572
  55. package/dist/cli/chat/hooks/useSlashCommands.js.map +1 -0
  56. package/dist/cli/commands/config-cmd.js +56 -57
  57. package/dist/cli/commands/config-cmd.js.map +1 -0
  58. package/dist/cli/commands/db.js +184 -169
  59. package/dist/cli/commands/db.js.map +1 -0
  60. package/dist/cli/commands/doctor.js +212 -122
  61. package/dist/cli/commands/doctor.js.map +1 -0
  62. package/dist/cli/commands/init.js +211 -244
  63. package/dist/cli/commands/init.js.map +1 -0
  64. package/dist/cli/commands/mcp.js +127 -122
  65. package/dist/cli/commands/mcp.js.map +1 -0
  66. package/dist/cli/login/LoginApp.js +355 -141
  67. package/dist/cli/login/LoginApp.js.map +1 -0
  68. package/dist/cli/print-mode.js +196 -177
  69. package/dist/cli/print-mode.js.map +1 -0
  70. package/dist/cli/serve-mode.js +615 -530
  71. package/dist/cli/serve-mode.js.map +1 -0
  72. package/dist/cli/services/agent-config.d.ts +29 -0
  73. package/dist/cli/services/agent-config.js +91 -0
  74. package/dist/cli/services/agent-config.js.map +1 -0
  75. package/dist/cli/services/agent-definitions.d.ts +4 -1
  76. package/dist/cli/services/agent-definitions.js +97 -56
  77. package/dist/cli/services/agent-definitions.js.map +1 -0
  78. package/dist/cli/services/agent-events.js +225 -162
  79. package/dist/cli/services/agent-events.js.map +1 -0
  80. package/dist/cli/services/agent-loop.js +978 -669
  81. package/dist/cli/services/agent-loop.js.map +1 -0
  82. package/dist/cli/services/agent-worker-base.d.ts +35 -5
  83. package/dist/cli/services/agent-worker-base.js +337 -153
  84. package/dist/cli/services/agent-worker-base.js.map +1 -0
  85. package/dist/cli/services/api-retry.js +69 -64
  86. package/dist/cli/services/api-retry.js.map +1 -0
  87. package/dist/cli/services/auth-service.d.ts +3 -3
  88. package/dist/cli/services/auth-service.js +209 -132
  89. package/dist/cli/services/auth-service.js.map +1 -0
  90. package/dist/cli/services/background-processes.js +343 -267
  91. package/dist/cli/services/background-processes.js.map +1 -0
  92. package/dist/cli/services/browser-auth.d.ts +2 -2
  93. package/dist/cli/services/browser-auth.js +159 -118
  94. package/dist/cli/services/browser-auth.js.map +1 -0
  95. package/dist/cli/services/claude-md-loader.js +40 -36
  96. package/dist/cli/services/claude-md-loader.js.map +1 -0
  97. package/dist/cli/services/config-store.d.ts +9 -4
  98. package/dist/cli/services/config-store.js +164 -117
  99. package/dist/cli/services/config-store.js.map +1 -0
  100. package/dist/cli/services/debug-log.d.ts +1 -1
  101. package/dist/cli/services/debug-log.js +34 -35
  102. package/dist/cli/services/debug-log.js.map +1 -0
  103. package/dist/cli/services/env-detect.d.ts +7 -0
  104. package/dist/cli/services/env-detect.js +9 -0
  105. package/dist/cli/services/env-detect.js.map +1 -0
  106. package/dist/cli/services/error-logger.d.ts +2 -3
  107. package/dist/cli/services/error-logger.js +189 -180
  108. package/dist/cli/services/error-logger.js.map +1 -0
  109. package/dist/cli/services/file-history.d.ts +1 -1
  110. package/dist/cli/services/file-history.js +50 -54
  111. package/dist/cli/services/file-history.js.map +1 -0
  112. package/dist/cli/services/format-server-response.js +332 -372
  113. package/dist/cli/services/format-server-response.js.map +1 -0
  114. package/dist/cli/services/git-context.js +61 -45
  115. package/dist/cli/services/git-context.js.map +1 -0
  116. package/dist/cli/services/hooks.d.ts +2 -2
  117. package/dist/cli/services/hooks.js +195 -180
  118. package/dist/cli/services/hooks.js.map +1 -0
  119. package/dist/cli/services/ink-incremental.d.ts +19 -0
  120. package/dist/cli/services/ink-incremental.js +59 -0
  121. package/dist/cli/services/ink-incremental.js.map +1 -0
  122. package/dist/cli/services/ink-resize-fix.js +54 -44
  123. package/dist/cli/services/ink-resize-fix.js.map +1 -0
  124. package/dist/cli/services/ink-sync-output.d.ts +12 -0
  125. package/dist/cli/services/ink-sync-output.js +16 -0
  126. package/dist/cli/services/ink-sync-output.js.map +1 -0
  127. package/dist/cli/services/interactive-tools.js +268 -212
  128. package/dist/cli/services/interactive-tools.js.map +1 -0
  129. package/dist/cli/services/keybinding-manager.d.ts +11 -1
  130. package/dist/cli/services/keybinding-manager.js +126 -63
  131. package/dist/cli/services/keybinding-manager.js.map +1 -0
  132. package/dist/cli/services/local-tools.d.ts +1 -1
  133. package/dist/cli/services/local-tools.js +939 -656
  134. package/dist/cli/services/local-tools.js.map +1 -0
  135. package/dist/cli/services/lsp-manager.js +757 -594
  136. package/dist/cli/services/lsp-manager.js.map +1 -0
  137. package/dist/cli/services/mcp-client.d.ts +1 -1
  138. package/dist/cli/services/mcp-client.js +173 -134
  139. package/dist/cli/services/mcp-client.js.map +1 -0
  140. package/dist/cli/services/memory-manager.js +53 -40
  141. package/dist/cli/services/memory-manager.js.map +1 -0
  142. package/dist/cli/services/model-manager.js +55 -40
  143. package/dist/cli/services/model-manager.js.map +1 -0
  144. package/dist/cli/services/model-router.js +115 -85
  145. package/dist/cli/services/model-router.js.map +1 -0
  146. package/dist/cli/services/paths.d.ts +30 -0
  147. package/dist/cli/services/paths.js +81 -0
  148. package/dist/cli/services/paths.js.map +1 -0
  149. package/dist/cli/services/permission-modes.js +32 -25
  150. package/dist/cli/services/permission-modes.js.map +1 -0
  151. package/dist/cli/services/rewind.js +182 -168
  152. package/dist/cli/services/rewind.js.map +1 -0
  153. package/dist/cli/services/ripgrep.js +115 -115
  154. package/dist/cli/services/ripgrep.js.map +1 -0
  155. package/dist/cli/services/sandbox.d.ts +1 -1
  156. package/dist/cli/services/sandbox.js +58 -37
  157. package/dist/cli/services/sandbox.js.map +1 -0
  158. package/dist/cli/services/server-tools.js +738 -565
  159. package/dist/cli/services/server-tools.js.map +1 -0
  160. package/dist/cli/services/session-persistence.js +69 -74
  161. package/dist/cli/services/session-persistence.js.map +1 -0
  162. package/dist/cli/services/subagent-worker.js +42 -27
  163. package/dist/cli/services/subagent-worker.js.map +1 -0
  164. package/dist/cli/services/subagent.d.ts +2 -0
  165. package/dist/cli/services/subagent.js +606 -430
  166. package/dist/cli/services/subagent.js.map +1 -0
  167. package/dist/cli/services/system-prompt.js +86 -78
  168. package/dist/cli/services/system-prompt.js.map +1 -0
  169. package/dist/cli/services/task-decomposer.d.ts +1 -1
  170. package/dist/cli/services/task-decomposer.js +172 -139
  171. package/dist/cli/services/task-decomposer.js.map +1 -0
  172. package/dist/cli/services/team-lead.d.ts +2 -2
  173. package/dist/cli/services/team-lead.js +727 -529
  174. package/dist/cli/services/team-lead.js.map +1 -0
  175. package/dist/cli/services/team-state.js +319 -319
  176. package/dist/cli/services/team-state.js.map +1 -0
  177. package/dist/cli/services/teammate.d.ts +8 -2
  178. package/dist/cli/services/teammate.js +862 -560
  179. package/dist/cli/services/teammate.js.map +1 -0
  180. package/dist/cli/services/telemetry.d.ts +6 -1
  181. package/dist/cli/services/telemetry.js +180 -157
  182. package/dist/cli/services/telemetry.js.map +1 -0
  183. package/dist/cli/services/tools/agent-tools.d.ts +3 -3
  184. package/dist/cli/services/tools/agent-tools.js +480 -322
  185. package/dist/cli/services/tools/agent-tools.js.map +1 -0
  186. package/dist/cli/services/tools/file-ops.js +563 -450
  187. package/dist/cli/services/tools/file-ops.js.map +1 -0
  188. package/dist/cli/services/tools/search-tools.js +231 -162
  189. package/dist/cli/services/tools/search-tools.js.map +1 -0
  190. package/dist/cli/services/tools/shell-exec.js +197 -151
  191. package/dist/cli/services/tools/shell-exec.js.map +1 -0
  192. package/dist/cli/services/tools/task-manager.js +206 -173
  193. package/dist/cli/services/tools/task-manager.js.map +1 -0
  194. package/dist/cli/services/tools/web-tools.js +388 -341
  195. package/dist/cli/services/tools/web-tools.js.map +1 -0
  196. package/dist/cli/setup/SetupApp.d.ts +2 -2
  197. package/dist/cli/setup/SetupApp.js +608 -160
  198. package/dist/cli/setup/SetupApp.js.map +1 -0
  199. package/dist/cli/shared/ErrorBoundary.d.ts +22 -0
  200. package/dist/cli/shared/ErrorBoundary.js +73 -0
  201. package/dist/cli/shared/ErrorBoundary.js.map +1 -0
  202. package/dist/cli/shared/MatrixIntro.js +66 -69
  203. package/dist/cli/shared/MatrixIntro.js.map +1 -0
  204. package/dist/cli/shared/SpinnerSlot.d.ts +14 -0
  205. package/dist/cli/shared/SpinnerSlot.js +63 -0
  206. package/dist/cli/shared/SpinnerSlot.js.map +1 -0
  207. package/dist/cli/shared/Theme.d.ts +1 -1
  208. package/dist/cli/shared/Theme.js +136 -92
  209. package/dist/cli/shared/Theme.js.map +1 -0
  210. package/dist/cli/shared/WhaleBanner.js +99 -11
  211. package/dist/cli/shared/WhaleBanner.js.map +1 -0
  212. package/dist/cli/shared/markdown.d.ts +3 -1
  213. package/dist/cli/shared/markdown.js +736 -674
  214. package/dist/cli/shared/markdown.js.map +1 -0
  215. package/dist/cli/shared/marked-terminal.d.js +2 -0
  216. package/dist/cli/shared/marked-terminal.d.js.map +1 -0
  217. package/dist/cli/shared/theme-manager.js +99 -90
  218. package/dist/cli/shared/theme-manager.js.map +1 -0
  219. package/dist/cli/shared/theme-presets.js +256 -254
  220. package/dist/cli/shared/theme-presets.js.map +1 -0
  221. package/dist/cli/status/StatusApp.js +235 -86
  222. package/dist/cli/status/StatusApp.js.map +1 -0
  223. package/dist/cli/stores/StoreApp.js +275 -65
  224. package/dist/cli/stores/StoreApp.js.map +1 -0
  225. package/dist/index.d.ts +2 -2
  226. package/dist/index.js +509 -396
  227. package/dist/index.js.map +1 -0
  228. package/dist/local-agent/connection.d.ts +2 -2
  229. package/dist/local-agent/connection.js +352 -293
  230. package/dist/local-agent/connection.js.map +1 -0
  231. package/dist/local-agent/discovery.js +259 -122
  232. package/dist/local-agent/discovery.js.map +1 -0
  233. package/dist/local-agent/executor.js +216 -193
  234. package/dist/local-agent/executor.js.map +1 -0
  235. package/dist/local-agent/index.d.ts +2 -2
  236. package/dist/local-agent/index.js +156 -156
  237. package/dist/local-agent/index.js.map +1 -0
  238. package/dist/node/adapters/base.js +18 -8
  239. package/dist/node/adapters/base.js.map +1 -0
  240. package/dist/node/adapters/discord.js +286 -275
  241. package/dist/node/adapters/discord.js.map +1 -0
  242. package/dist/node/adapters/email.js +189 -202
  243. package/dist/node/adapters/email.js.map +1 -0
  244. package/dist/node/adapters/imessage.js +145 -142
  245. package/dist/node/adapters/imessage.js.map +1 -0
  246. package/dist/node/adapters/slack.js +237 -236
  247. package/dist/node/adapters/slack.js.map +1 -0
  248. package/dist/node/adapters/sms.js +149 -151
  249. package/dist/node/adapters/sms.js.map +1 -0
  250. package/dist/node/adapters/telegram.js +88 -92
  251. package/dist/node/adapters/telegram.js.map +1 -0
  252. package/dist/node/adapters/webchat.js +160 -136
  253. package/dist/node/adapters/webchat.js.map +1 -0
  254. package/dist/node/adapters/whatsapp.js +212 -215
  255. package/dist/node/adapters/whatsapp.js.map +1 -0
  256. package/dist/node/cli.js +884 -653
  257. package/dist/node/cli.js.map +1 -0
  258. package/dist/node/config.js +20 -18
  259. package/dist/node/config.js.map +1 -0
  260. package/dist/node/gateway-client.js +191 -181
  261. package/dist/node/gateway-client.js.map +1 -0
  262. package/dist/node/portal/clipboard.js +161 -130
  263. package/dist/node/portal/clipboard.js.map +1 -0
  264. package/dist/node/portal/discovery.js +51 -45
  265. package/dist/node/portal/discovery.js.map +1 -0
  266. package/dist/node/portal/forward.js +64 -58
  267. package/dist/node/portal/forward.js.map +1 -0
  268. package/dist/node/portal/index.js +246 -221
  269. package/dist/node/portal/index.js.map +1 -0
  270. package/dist/node/portal/multiplexer.js +192 -182
  271. package/dist/node/portal/multiplexer.js.map +1 -0
  272. package/dist/node/portal/permissions.js +102 -70
  273. package/dist/node/portal/permissions.js.map +1 -0
  274. package/dist/node/portal/protocol.js +153 -116
  275. package/dist/node/portal/protocol.js.map +1 -0
  276. package/dist/node/portal/screen.js +80 -69
  277. package/dist/node/portal/screen.js.map +1 -0
  278. package/dist/node/portal/session.js +124 -117
  279. package/dist/node/portal/session.js.map +1 -0
  280. package/dist/node/portal/shell.js +140 -113
  281. package/dist/node/portal/shell.js.map +1 -0
  282. package/dist/node/portal/stream.js +77 -75
  283. package/dist/node/portal/stream.js.map +1 -0
  284. package/dist/node/portal/transfer.js +190 -167
  285. package/dist/node/portal/transfer.js.map +1 -0
  286. package/dist/node/portal/ui.js +124 -99
  287. package/dist/node/portal/ui.js.map +1 -0
  288. package/dist/node/remote-desktop/compile-helper.js +50 -45
  289. package/dist/node/remote-desktop/compile-helper.js.map +1 -0
  290. package/dist/node/remote-desktop/index.js +215 -187
  291. package/dist/node/remote-desktop/index.js.map +1 -0
  292. package/dist/node/remote-desktop/protocol.js +45 -29
  293. package/dist/node/remote-desktop/protocol.js.map +1 -0
  294. package/dist/node/runtime.js +493 -410
  295. package/dist/node/runtime.js.map +1 -0
  296. package/dist/server/handlers/__test-utils__/test-db.js +39 -89
  297. package/dist/server/handlers/__test-utils__/test-db.js.map +1 -0
  298. package/dist/server/handlers/analytics.js +467 -261
  299. package/dist/server/handlers/analytics.js.map +1 -0
  300. package/dist/server/handlers/api-docs.d.ts +6 -0
  301. package/dist/server/handlers/api-docs.js +1613 -0
  302. package/dist/server/handlers/api-docs.js.map +1 -0
  303. package/dist/server/handlers/api-keys.js +295 -232
  304. package/dist/server/handlers/api-keys.js.map +1 -0
  305. package/dist/server/handlers/billing.js +330 -239
  306. package/dist/server/handlers/billing.js.map +1 -0
  307. package/dist/server/handlers/browser.js +468 -395
  308. package/dist/server/handlers/browser.js.map +1 -0
  309. package/dist/server/handlers/catalog.js +1377 -978
  310. package/dist/server/handlers/catalog.js.map +1 -0
  311. package/dist/server/handlers/clickhouse.js +157 -109
  312. package/dist/server/handlers/clickhouse.js.map +1 -0
  313. package/dist/server/handlers/comms.d.ts +0 -53
  314. package/dist/server/handlers/comms.js +1443 -970
  315. package/dist/server/handlers/comms.js.map +1 -0
  316. package/dist/server/handlers/creations.js +461 -394
  317. package/dist/server/handlers/creations.js.map +1 -0
  318. package/dist/server/handlers/crm.js +1082 -791
  319. package/dist/server/handlers/crm.js.map +1 -0
  320. package/dist/server/handlers/discovery.js +251 -232
  321. package/dist/server/handlers/discovery.js.map +1 -0
  322. package/dist/server/handlers/embeddings.js +241 -164
  323. package/dist/server/handlers/embeddings.js.map +1 -0
  324. package/dist/server/handlers/enrichment.js +887 -718
  325. package/dist/server/handlers/enrichment.js.map +1 -0
  326. package/dist/server/handlers/image-gen.js +467 -376
  327. package/dist/server/handlers/image-gen.js.map +1 -0
  328. package/dist/server/handlers/inventory.js +797 -424
  329. package/dist/server/handlers/inventory.js.map +1 -0
  330. package/dist/server/handlers/kali.js +272 -230
  331. package/dist/server/handlers/kali.js.map +1 -0
  332. package/dist/server/handlers/llm-providers.js +803 -580
  333. package/dist/server/handlers/llm-providers.js.map +1 -0
  334. package/dist/server/handlers/local-agent.js +133 -105
  335. package/dist/server/handlers/local-agent.js.map +1 -0
  336. package/dist/server/handlers/media.js +1179 -857
  337. package/dist/server/handlers/media.js.map +1 -0
  338. package/dist/server/handlers/meta-ads.js +2669 -2093
  339. package/dist/server/handlers/meta-ads.js.map +1 -0
  340. package/dist/server/handlers/nodes.js +1321 -913
  341. package/dist/server/handlers/nodes.js.map +1 -0
  342. package/dist/server/handlers/operations.js +183 -157
  343. package/dist/server/handlers/operations.js.map +1 -0
  344. package/dist/server/handlers/platform.js +346 -210
  345. package/dist/server/handlers/platform.js.map +1 -0
  346. package/dist/server/handlers/remove-bg.js +118 -86
  347. package/dist/server/handlers/remove-bg.js.map +1 -0
  348. package/dist/server/handlers/storefront.js +586 -446
  349. package/dist/server/handlers/storefront.js.map +1 -0
  350. package/dist/server/handlers/supply-chain.js +546 -326
  351. package/dist/server/handlers/supply-chain.js.map +1 -0
  352. package/dist/server/handlers/transcription.js +106 -97
  353. package/dist/server/handlers/transcription.js.map +1 -0
  354. package/dist/server/handlers/video-gen.js +593 -424
  355. package/dist/server/handlers/video-gen.js.map +1 -0
  356. package/dist/server/handlers/voice.js +1458 -1017
  357. package/dist/server/handlers/voice.js.map +1 -0
  358. package/dist/server/handlers/workflow-steps.js +2837 -2116
  359. package/dist/server/handlers/workflow-steps.js.map +1 -0
  360. package/dist/server/handlers/workflows.js +1630 -933
  361. package/dist/server/handlers/workflows.js.map +1 -0
  362. package/dist/server/index.js +3166 -2390
  363. package/dist/server/index.js.map +1 -0
  364. package/dist/server/lib/batch-client.js +471 -409
  365. package/dist/server/lib/batch-client.js.map +1 -0
  366. package/dist/server/lib/clickhouse-buffer.js +118 -104
  367. package/dist/server/lib/clickhouse-buffer.js.map +1 -0
  368. package/dist/server/lib/clickhouse-client.js +107 -107
  369. package/dist/server/lib/clickhouse-client.js.map +1 -0
  370. package/dist/server/lib/coa-renderer.js +1786 -356
  371. package/dist/server/lib/coa-renderer.js.map +1 -0
  372. package/dist/server/lib/code-worker-pool.js +227 -177
  373. package/dist/server/lib/code-worker-pool.js.map +1 -0
  374. package/dist/server/lib/code-worker.js +174 -164
  375. package/dist/server/lib/code-worker.js.map +1 -0
  376. package/dist/server/lib/compaction-service.d.ts +2 -12
  377. package/dist/server/lib/compaction-service.js +74 -184
  378. package/dist/server/lib/compaction-service.js.map +1 -0
  379. package/dist/server/lib/logger.js +36 -24
  380. package/dist/server/lib/logger.js.map +1 -0
  381. package/dist/server/lib/otel.js +101 -80
  382. package/dist/server/lib/otel.js.map +1 -0
  383. package/dist/server/lib/pdf-renderer.d.ts +1 -1
  384. package/dist/server/lib/pdf-renderer.js +954 -776
  385. package/dist/server/lib/pdf-renderer.js.map +1 -0
  386. package/dist/server/lib/prompt-sanitizer.js +188 -108
  387. package/dist/server/lib/prompt-sanitizer.js.map +1 -0
  388. package/dist/server/lib/provider-capabilities.js +136 -138
  389. package/dist/server/lib/provider-capabilities.js.map +1 -0
  390. package/dist/server/lib/provider-failover.js +190 -168
  391. package/dist/server/lib/provider-failover.js.map +1 -0
  392. package/dist/server/lib/rate-limiter.js +186 -117
  393. package/dist/server/lib/rate-limiter.js.map +1 -0
  394. package/dist/server/lib/react-pdf-layout.js +551 -382
  395. package/dist/server/lib/react-pdf-layout.js.map +1 -0
  396. package/dist/server/lib/server-agent-loop.d.ts +9 -0
  397. package/dist/server/lib/server-agent-loop.js +906 -624
  398. package/dist/server/lib/server-agent-loop.js.map +1 -0
  399. package/dist/server/lib/server-subagent.d.ts +2 -0
  400. package/dist/server/lib/server-subagent.js +260 -162
  401. package/dist/server/lib/server-subagent.js.map +1 -0
  402. package/dist/server/lib/session-checkpoint.js +105 -96
  403. package/dist/server/lib/session-checkpoint.js.map +1 -0
  404. package/dist/server/lib/ssrf-guard.js +193 -184
  405. package/dist/server/lib/ssrf-guard.js.map +1 -0
  406. package/dist/server/lib/supabase-client.js +94 -82
  407. package/dist/server/lib/supabase-client.js.map +1 -0
  408. package/dist/server/lib/template-resolver.js +154 -176
  409. package/dist/server/lib/template-resolver.js.map +1 -0
  410. package/dist/server/lib/utils.js +242 -133
  411. package/dist/server/lib/utils.js.map +1 -0
  412. package/dist/server/local-agent-gateway.d.ts +2 -2
  413. package/dist/server/local-agent-gateway.js +785 -627
  414. package/dist/server/local-agent-gateway.js.map +1 -0
  415. package/dist/server/providers/anthropic.js +254 -176
  416. package/dist/server/providers/anthropic.js.map +1 -0
  417. package/dist/server/providers/bedrock.js +221 -162
  418. package/dist/server/providers/bedrock.js.map +1 -0
  419. package/dist/server/providers/gemini.js +548 -418
  420. package/dist/server/providers/gemini.js.map +1 -0
  421. package/dist/server/providers/openai.js +571 -437
  422. package/dist/server/providers/openai.js.map +1 -0
  423. package/dist/server/providers/registry.js +23 -18
  424. package/dist/server/providers/registry.js.map +1 -0
  425. package/dist/server/providers/shared.js +123 -95
  426. package/dist/server/providers/shared.js.map +1 -0
  427. package/dist/server/providers/types.js +1 -11
  428. package/dist/server/providers/types.js.map +1 -0
  429. package/dist/server/proxy-handlers.js +209 -165
  430. package/dist/server/proxy-handlers.js.map +1 -0
  431. package/dist/server/tool-router.d.ts +13 -0
  432. package/dist/server/tool-router.js +960 -598
  433. package/dist/server/tool-router.js.map +1 -0
  434. package/dist/server/validation.js +248 -188
  435. package/dist/server/validation.js.map +1 -0
  436. package/dist/server/worker.js +202 -133
  437. package/dist/server/worker.js.map +1 -0
  438. package/dist/setup.d.ts +2 -2
  439. package/dist/setup.js +151 -147
  440. package/dist/setup.js.map +1 -0
  441. package/dist/shared/agent-core.d.ts +191 -24
  442. package/dist/shared/agent-core.js +971 -462
  443. package/dist/shared/agent-core.js.map +1 -0
  444. package/dist/shared/anthropic-types.js +1 -6
  445. package/dist/shared/anthropic-types.js.map +1 -0
  446. package/dist/shared/api-client.d.ts +17 -9
  447. package/dist/shared/api-client.js +419 -327
  448. package/dist/shared/api-client.js.map +1 -0
  449. package/dist/shared/compaction.d.ts +36 -0
  450. package/dist/shared/compaction.js +138 -0
  451. package/dist/shared/compaction.js.map +1 -0
  452. package/dist/shared/constants.js +67 -64
  453. package/dist/shared/constants.js.map +1 -0
  454. package/dist/shared/sse-parser.js +221 -219
  455. package/dist/shared/sse-parser.js.map +1 -0
  456. package/dist/shared/tool-dispatch.d.ts +4 -2
  457. package/dist/shared/tool-dispatch.js +226 -165
  458. package/dist/shared/tool-dispatch.js.map +1 -0
  459. package/dist/shared/types.js +1 -6
  460. package/dist/shared/types.js.map +1 -0
  461. package/dist/types/cli-highlight.d.js +2 -0
  462. package/dist/types/cli-highlight.d.js.map +1 -0
  463. package/dist/types/diff.d.js +2 -0
  464. package/dist/types/diff.d.js.map +1 -0
  465. package/dist/types/pdf-parse.d.js +2 -0
  466. package/dist/types/pdf-parse.d.js.map +1 -0
  467. package/dist/updater.d.ts +1 -1
  468. package/dist/updater.js +118 -92
  469. package/dist/updater.js.map +1 -0
  470. package/dist/webchat/widget.js +227 -380
  471. package/dist/webchat/widget.js.map +1 -0
  472. package/package.json +22 -10
  473. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  474. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  475. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  476. package/vendor/ink/build/apply-styles.js +175 -0
  477. package/vendor/ink/build/build-layout.js +77 -0
  478. package/vendor/ink/build/calculate-wrapped-text.js +53 -0
  479. package/vendor/ink/build/colorize.d.ts +3 -0
  480. package/vendor/ink/build/colorize.js +48 -0
  481. package/vendor/ink/build/colorize.js.map +1 -0
  482. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  483. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  484. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  485. package/vendor/ink/build/components/App.d.ts +18 -0
  486. package/vendor/ink/build/components/App.js +351 -0
  487. package/vendor/ink/build/components/App.js.map +1 -0
  488. package/vendor/ink/build/components/AppContext.d.ts +15 -0
  489. package/vendor/ink/build/components/AppContext.js +11 -0
  490. package/vendor/ink/build/components/AppContext.js.map +1 -0
  491. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  492. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  493. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  494. package/vendor/ink/build/components/Box.d.ts +117 -0
  495. package/vendor/ink/build/components/Box.js +34 -0
  496. package/vendor/ink/build/components/Box.js.map +1 -0
  497. package/vendor/ink/build/components/Color.js +62 -0
  498. package/vendor/ink/build/components/Cursor.d.ts +83 -0
  499. package/vendor/ink/build/components/Cursor.js +53 -0
  500. package/vendor/ink/build/components/Cursor.js.map +1 -0
  501. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  502. package/vendor/ink/build/components/CursorContext.js +8 -0
  503. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  504. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  505. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  506. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  507. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  508. package/vendor/ink/build/components/ErrorOverview.js +84 -0
  509. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  510. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  511. package/vendor/ink/build/components/FocusContext.js +17 -0
  512. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  513. package/vendor/ink/build/components/Newline.d.ts +13 -0
  514. package/vendor/ink/build/components/Newline.js +8 -0
  515. package/vendor/ink/build/components/Newline.js.map +1 -0
  516. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  517. package/vendor/ink/build/components/Spacer.js +11 -0
  518. package/vendor/ink/build/components/Spacer.js.map +1 -0
  519. package/vendor/ink/build/components/Static.d.ts +24 -0
  520. package/vendor/ink/build/components/Static.js +28 -0
  521. package/vendor/ink/build/components/Static.js.map +1 -0
  522. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  523. package/vendor/ink/build/components/StderrContext.js +13 -0
  524. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  525. package/vendor/ink/build/components/StdinContext.d.ts +22 -0
  526. package/vendor/ink/build/components/StdinContext.js +19 -0
  527. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  528. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  529. package/vendor/ink/build/components/StdoutContext.js +13 -0
  530. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  531. package/vendor/ink/build/components/Text.d.ts +55 -0
  532. package/vendor/ink/build/components/Text.js +50 -0
  533. package/vendor/ink/build/components/Text.js.map +1 -0
  534. package/vendor/ink/build/components/Transform.d.ts +16 -0
  535. package/vendor/ink/build/components/Transform.js +15 -0
  536. package/vendor/ink/build/components/Transform.js.map +1 -0
  537. package/vendor/ink/build/cursor-helpers.d.ts +38 -0
  538. package/vendor/ink/build/cursor-helpers.js +56 -0
  539. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  540. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  541. package/vendor/ink/build/devtools-window-polyfill.js +65 -0
  542. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  543. package/vendor/ink/build/devtools.d.ts +1 -0
  544. package/vendor/ink/build/devtools.js +11 -0
  545. package/vendor/ink/build/devtools.js.map +1 -0
  546. package/vendor/ink/build/dom.d.ts +56 -0
  547. package/vendor/ink/build/dom.js +124 -0
  548. package/vendor/ink/build/dom.js.map +1 -0
  549. package/vendor/ink/build/experimental/apply-style.js +140 -0
  550. package/vendor/ink/build/experimental/dom.js +123 -0
  551. package/vendor/ink/build/experimental/output.js +91 -0
  552. package/vendor/ink/build/experimental/reconciler.js +141 -0
  553. package/vendor/ink/build/experimental/renderer.js +81 -0
  554. package/vendor/ink/build/get-max-width.d.ts +3 -0
  555. package/vendor/ink/build/get-max-width.js +10 -0
  556. package/vendor/ink/build/get-max-width.js.map +1 -0
  557. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  558. package/vendor/ink/build/hooks/use-app.js +8 -0
  559. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  560. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  561. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  562. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  563. package/vendor/ink/build/hooks/use-focus-manager.d.ts +28 -0
  564. package/vendor/ink/build/hooks/use-focus-manager.js +17 -0
  565. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  566. package/vendor/ink/build/hooks/use-focus.d.ts +29 -0
  567. package/vendor/ink/build/hooks/use-focus.js +42 -0
  568. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  569. package/vendor/ink/build/hooks/use-input.d.ts +131 -0
  570. package/vendor/ink/build/hooks/use-input.js +124 -0
  571. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  572. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +5 -0
  573. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +11 -0
  574. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  575. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  576. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  577. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  578. package/vendor/ink/build/hooks/use-stdin.d.ts +5 -0
  579. package/vendor/ink/build/hooks/use-stdin.js +8 -0
  580. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  581. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  582. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  583. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  584. package/vendor/ink/build/hooks/useInput.js +38 -0
  585. package/vendor/ink/build/index.d.ts +34 -0
  586. package/vendor/ink/build/index.js +20 -0
  587. package/vendor/ink/build/index.js.map +1 -0
  588. package/vendor/ink/build/ink.d.ts +90 -0
  589. package/vendor/ink/build/ink.js +654 -0
  590. package/vendor/ink/build/ink.js.map +1 -0
  591. package/vendor/ink/build/input-parser.d.ts +7 -0
  592. package/vendor/ink/build/input-parser.js +154 -0
  593. package/vendor/ink/build/input-parser.js.map +1 -0
  594. package/vendor/ink/build/instance.js +205 -0
  595. package/vendor/ink/build/instances.d.ts +3 -0
  596. package/vendor/ink/build/instances.js +8 -0
  597. package/vendor/ink/build/instances.js.map +1 -0
  598. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  599. package/vendor/ink/build/kitty-keyboard.js +32 -0
  600. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  601. package/vendor/ink/build/layout.d.ts +7 -0
  602. package/vendor/ink/build/layout.js +33 -0
  603. package/vendor/ink/build/layout.js.map +1 -0
  604. package/vendor/ink/build/log-update.d.ts +19 -0
  605. package/vendor/ink/build/log-update.js +243 -0
  606. package/vendor/ink/build/log-update.js.map +1 -0
  607. package/vendor/ink/build/measure-element.d.ts +16 -0
  608. package/vendor/ink/build/measure-element.js +9 -0
  609. package/vendor/ink/build/measure-element.js.map +1 -0
  610. package/vendor/ink/build/measure-text.d.ts +6 -0
  611. package/vendor/ink/build/measure-text.js +21 -0
  612. package/vendor/ink/build/measure-text.js.map +1 -0
  613. package/vendor/ink/build/options.d.ts +52 -0
  614. package/vendor/ink/build/options.js +2 -0
  615. package/vendor/ink/build/options.js.map +1 -0
  616. package/vendor/ink/build/output.d.ts +35 -0
  617. package/vendor/ink/build/output.js +183 -0
  618. package/vendor/ink/build/output.js.map +1 -0
  619. package/vendor/ink/build/parse-keypress.d.ts +22 -0
  620. package/vendor/ink/build/parse-keypress.js +493 -0
  621. package/vendor/ink/build/parse-keypress.js.map +1 -0
  622. package/vendor/ink/build/reconciler.d.ts +4 -0
  623. package/vendor/ink/build/reconciler.js +274 -0
  624. package/vendor/ink/build/reconciler.js.map +1 -0
  625. package/vendor/ink/build/render-background.d.ts +4 -0
  626. package/vendor/ink/build/render-background.js +25 -0
  627. package/vendor/ink/build/render-background.js.map +1 -0
  628. package/vendor/ink/build/render-border.d.ts +4 -0
  629. package/vendor/ink/build/render-border.js +73 -0
  630. package/vendor/ink/build/render-border.js.map +1 -0
  631. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  632. package/vendor/ink/build/render-node-to-output.js +147 -0
  633. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  634. package/vendor/ink/build/render-to-string.d.ts +38 -0
  635. package/vendor/ink/build/render-to-string.js +115 -0
  636. package/vendor/ink/build/render-to-string.js.map +1 -0
  637. package/vendor/ink/build/render.d.ts +121 -0
  638. package/vendor/ink/build/render.js +55 -0
  639. package/vendor/ink/build/render.js.map +1 -0
  640. package/vendor/ink/build/renderer.d.ts +8 -0
  641. package/vendor/ink/build/renderer.js +55 -0
  642. package/vendor/ink/build/renderer.js.map +1 -0
  643. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  644. package/vendor/ink/build/sanitize-ansi.js +27 -0
  645. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  646. package/vendor/ink/build/screen-reader-update.d.ts +13 -0
  647. package/vendor/ink/build/screen-reader-update.js +38 -0
  648. package/vendor/ink/build/screen-reader-update.js.map +1 -0
  649. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  650. package/vendor/ink/build/squash-text-nodes.js +36 -0
  651. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  652. package/vendor/ink/build/styles.d.ts +240 -0
  653. package/vendor/ink/build/styles.js +232 -0
  654. package/vendor/ink/build/styles.js.map +1 -0
  655. package/vendor/ink/build/utils.d.ts +2 -0
  656. package/vendor/ink/build/utils.js +4 -0
  657. package/vendor/ink/build/utils.js.map +1 -0
  658. package/vendor/ink/build/wrap-text.d.ts +3 -0
  659. package/vendor/ink/build/wrap-text.js +31 -0
  660. package/vendor/ink/build/wrap-text.js.map +1 -0
  661. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  662. package/vendor/ink/build/write-synchronized.js +7 -0
  663. package/vendor/ink/build/write-synchronized.js.map +1 -0
  664. package/vendor/ink/license +10 -0
  665. package/vendor/ink/node_modules/@types/node/LICENSE +21 -0
  666. package/vendor/ink/node_modules/@types/node/README.md +15 -0
  667. package/vendor/ink/node_modules/@types/node/assert/strict.d.ts +105 -0
  668. package/vendor/ink/node_modules/@types/node/assert.d.ts +955 -0
  669. package/vendor/ink/node_modules/@types/node/async_hooks.d.ts +623 -0
  670. package/vendor/ink/node_modules/@types/node/buffer.buffer.d.ts +466 -0
  671. package/vendor/ink/node_modules/@types/node/buffer.d.ts +1810 -0
  672. package/vendor/ink/node_modules/@types/node/child_process.d.ts +1428 -0
  673. package/vendor/ink/node_modules/@types/node/cluster.d.ts +486 -0
  674. package/vendor/ink/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
  675. package/vendor/ink/node_modules/@types/node/console.d.ts +151 -0
  676. package/vendor/ink/node_modules/@types/node/constants.d.ts +20 -0
  677. package/vendor/ink/node_modules/@types/node/crypto.d.ts +4065 -0
  678. package/vendor/ink/node_modules/@types/node/dgram.d.ts +564 -0
  679. package/vendor/ink/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
  680. package/vendor/ink/node_modules/@types/node/dns/promises.d.ts +503 -0
  681. package/vendor/ink/node_modules/@types/node/dns.d.ts +922 -0
  682. package/vendor/ink/node_modules/@types/node/domain.d.ts +166 -0
  683. package/vendor/ink/node_modules/@types/node/events.d.ts +1054 -0
  684. package/vendor/ink/node_modules/@types/node/fs/promises.d.ts +1329 -0
  685. package/vendor/ink/node_modules/@types/node/fs.d.ts +4676 -0
  686. package/vendor/ink/node_modules/@types/node/globals.d.ts +150 -0
  687. package/vendor/ink/node_modules/@types/node/globals.typedarray.d.ts +101 -0
  688. package/vendor/ink/node_modules/@types/node/http.d.ts +2167 -0
  689. package/vendor/ink/node_modules/@types/node/http2.d.ts +2480 -0
  690. package/vendor/ink/node_modules/@types/node/https.d.ts +405 -0
  691. package/vendor/ink/node_modules/@types/node/index.d.ts +115 -0
  692. package/vendor/ink/node_modules/@types/node/inspector/promises.d.ts +41 -0
  693. package/vendor/ink/node_modules/@types/node/inspector.d.ts +224 -0
  694. package/vendor/ink/node_modules/@types/node/inspector.generated.d.ts +4226 -0
  695. package/vendor/ink/node_modules/@types/node/module.d.ts +819 -0
  696. package/vendor/ink/node_modules/@types/node/net.d.ts +933 -0
  697. package/vendor/ink/node_modules/@types/node/os.d.ts +507 -0
  698. package/vendor/ink/node_modules/@types/node/package.json +155 -0
  699. package/vendor/ink/node_modules/@types/node/path/posix.d.ts +8 -0
  700. package/vendor/ink/node_modules/@types/node/path/win32.d.ts +8 -0
  701. package/vendor/ink/node_modules/@types/node/path.d.ts +187 -0
  702. package/vendor/ink/node_modules/@types/node/perf_hooks.d.ts +643 -0
  703. package/vendor/ink/node_modules/@types/node/process.d.ts +2156 -0
  704. package/vendor/ink/node_modules/@types/node/punycode.d.ts +117 -0
  705. package/vendor/ink/node_modules/@types/node/querystring.d.ts +152 -0
  706. package/vendor/ink/node_modules/@types/node/quic.d.ts +910 -0
  707. package/vendor/ink/node_modules/@types/node/readline/promises.d.ts +161 -0
  708. package/vendor/ink/node_modules/@types/node/readline.d.ts +541 -0
  709. package/vendor/ink/node_modules/@types/node/repl.d.ts +415 -0
  710. package/vendor/ink/node_modules/@types/node/sea.d.ts +162 -0
  711. package/vendor/ink/node_modules/@types/node/sqlite.d.ts +955 -0
  712. package/vendor/ink/node_modules/@types/node/stream/consumers.d.ts +38 -0
  713. package/vendor/ink/node_modules/@types/node/stream/promises.d.ts +211 -0
  714. package/vendor/ink/node_modules/@types/node/stream/web.d.ts +296 -0
  715. package/vendor/ink/node_modules/@types/node/stream.d.ts +1760 -0
  716. package/vendor/ink/node_modules/@types/node/string_decoder.d.ts +67 -0
  717. package/vendor/ink/node_modules/@types/node/test/reporters.d.ts +96 -0
  718. package/vendor/ink/node_modules/@types/node/test.d.ts +2240 -0
  719. package/vendor/ink/node_modules/@types/node/timers/promises.d.ts +108 -0
  720. package/vendor/ink/node_modules/@types/node/timers.d.ts +159 -0
  721. package/vendor/ink/node_modules/@types/node/tls.d.ts +1198 -0
  722. package/vendor/ink/node_modules/@types/node/trace_events.d.ts +197 -0
  723. package/vendor/ink/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +462 -0
  724. package/vendor/ink/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
  725. package/vendor/ink/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
  726. package/vendor/ink/node_modules/@types/node/ts5.6/index.d.ts +117 -0
  727. package/vendor/ink/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
  728. package/vendor/ink/node_modules/@types/node/ts5.7/index.d.ts +117 -0
  729. package/vendor/ink/node_modules/@types/node/tty.d.ts +250 -0
  730. package/vendor/ink/node_modules/@types/node/url.d.ts +519 -0
  731. package/vendor/ink/node_modules/@types/node/util/types.d.ts +558 -0
  732. package/vendor/ink/node_modules/@types/node/util.d.ts +1662 -0
  733. package/vendor/ink/node_modules/@types/node/v8.d.ts +983 -0
  734. package/vendor/ink/node_modules/@types/node/vm.d.ts +1208 -0
  735. package/vendor/ink/node_modules/@types/node/wasi.d.ts +202 -0
  736. package/vendor/ink/node_modules/@types/node/web-globals/abortcontroller.d.ts +59 -0
  737. package/vendor/ink/node_modules/@types/node/web-globals/blob.d.ts +23 -0
  738. package/vendor/ink/node_modules/@types/node/web-globals/console.d.ts +9 -0
  739. package/vendor/ink/node_modules/@types/node/web-globals/crypto.d.ts +39 -0
  740. package/vendor/ink/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  741. package/vendor/ink/node_modules/@types/node/web-globals/encoding.d.ts +11 -0
  742. package/vendor/ink/node_modules/@types/node/web-globals/events.d.ts +106 -0
  743. package/vendor/ink/node_modules/@types/node/web-globals/fetch.d.ts +69 -0
  744. package/vendor/ink/node_modules/@types/node/web-globals/importmeta.d.ts +13 -0
  745. package/vendor/ink/node_modules/@types/node/web-globals/messaging.d.ts +23 -0
  746. package/vendor/ink/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
  747. package/vendor/ink/node_modules/@types/node/web-globals/performance.d.ts +45 -0
  748. package/vendor/ink/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  749. package/vendor/ink/node_modules/@types/node/web-globals/streams.d.ts +115 -0
  750. package/vendor/ink/node_modules/@types/node/web-globals/timers.d.ts +44 -0
  751. package/vendor/ink/node_modules/@types/node/web-globals/url.d.ts +24 -0
  752. package/vendor/ink/node_modules/@types/node/worker_threads.d.ts +717 -0
  753. package/vendor/ink/node_modules/@types/node/zlib.d.ts +618 -0
  754. package/vendor/ink/node_modules/node-pty/LICENSE +69 -0
  755. package/vendor/ink/node_modules/node-pty/README.md +164 -0
  756. package/vendor/ink/node_modules/node-pty/binding.gyp +150 -0
  757. package/vendor/ink/node_modules/node-pty/lib/conpty_console_list_agent.js +25 -0
  758. package/vendor/ink/node_modules/node-pty/lib/eventEmitter2.js +47 -0
  759. package/vendor/ink/node_modules/node-pty/lib/index.js +52 -0
  760. package/vendor/ink/node_modules/node-pty/lib/interfaces.js +7 -0
  761. package/vendor/ink/node_modules/node-pty/lib/shared/conout.js +11 -0
  762. package/vendor/ink/node_modules/node-pty/lib/terminal.js +190 -0
  763. package/vendor/ink/node_modules/node-pty/lib/types.js +7 -0
  764. package/vendor/ink/node_modules/node-pty/lib/unixTerminal.js +349 -0
  765. package/vendor/ink/node_modules/node-pty/lib/utils.js +39 -0
  766. package/vendor/ink/node_modules/node-pty/lib/windowsConoutConnection.js +125 -0
  767. package/vendor/ink/node_modules/node-pty/lib/windowsPtyAgent.js +287 -0
  768. package/vendor/ink/node_modules/node-pty/lib/windowsTerminal.js +201 -0
  769. package/vendor/ink/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  770. package/vendor/ink/node_modules/node-pty/package.json +65 -0
  771. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
  772. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
  773. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
  774. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
  775. package/vendor/ink/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
  776. package/vendor/ink/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
  777. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  778. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  779. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  780. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.pdb +0 -0
  781. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  782. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
  783. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  784. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  785. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  786. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.pdb +0 -0
  787. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  788. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
  789. package/vendor/ink/node_modules/node-pty/scripts/post-install.js +76 -0
  790. package/vendor/ink/node_modules/node-pty/scripts/prebuild.js +34 -0
  791. package/vendor/ink/node_modules/node-pty/src/unix/pty.cc +875 -0
  792. package/vendor/ink/node_modules/node-pty/src/unix/spawn-helper.cc +23 -0
  793. package/vendor/ink/node_modules/node-pty/src/win/conpty.cc +582 -0
  794. package/vendor/ink/node_modules/node-pty/src/win/conpty.h +41 -0
  795. package/vendor/ink/node_modules/node-pty/src/win/conpty_console_list.cc +44 -0
  796. package/vendor/ink/node_modules/node-pty/src/win/path_util.cc +95 -0
  797. package/vendor/ink/node_modules/node-pty/src/win/path_util.h +26 -0
  798. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/OpenConsole.exe +0 -0
  799. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/conpty.dll +0 -0
  800. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/OpenConsole.exe +0 -0
  801. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/conpty.dll +0 -0
  802. package/vendor/ink/node_modules/node-pty/typings/node-pty.d.ts +215 -0
  803. package/vendor/ink/node_modules/undici-types/LICENSE +21 -0
  804. package/vendor/ink/node_modules/undici-types/README.md +6 -0
  805. package/vendor/ink/node_modules/undici-types/agent.d.ts +32 -0
  806. package/vendor/ink/node_modules/undici-types/api.d.ts +43 -0
  807. package/vendor/ink/node_modules/undici-types/balanced-pool.d.ts +30 -0
  808. package/vendor/ink/node_modules/undici-types/cache-interceptor.d.ts +173 -0
  809. package/vendor/ink/node_modules/undici-types/cache.d.ts +36 -0
  810. package/vendor/ink/node_modules/undici-types/client-stats.d.ts +15 -0
  811. package/vendor/ink/node_modules/undici-types/client.d.ts +108 -0
  812. package/vendor/ink/node_modules/undici-types/connector.d.ts +34 -0
  813. package/vendor/ink/node_modules/undici-types/content-type.d.ts +21 -0
  814. package/vendor/ink/node_modules/undici-types/cookies.d.ts +30 -0
  815. package/vendor/ink/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
  816. package/vendor/ink/node_modules/undici-types/dispatcher.d.ts +276 -0
  817. package/vendor/ink/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
  818. package/vendor/ink/node_modules/undici-types/errors.d.ts +161 -0
  819. package/vendor/ink/node_modules/undici-types/eventsource.d.ts +66 -0
  820. package/vendor/ink/node_modules/undici-types/fetch.d.ts +211 -0
  821. package/vendor/ink/node_modules/undici-types/formdata.d.ts +108 -0
  822. package/vendor/ink/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  823. package/vendor/ink/node_modules/undici-types/global-origin.d.ts +7 -0
  824. package/vendor/ink/node_modules/undici-types/h2c-client.d.ts +73 -0
  825. package/vendor/ink/node_modules/undici-types/handlers.d.ts +15 -0
  826. package/vendor/ink/node_modules/undici-types/header.d.ts +160 -0
  827. package/vendor/ink/node_modules/undici-types/index.d.ts +88 -0
  828. package/vendor/ink/node_modules/undici-types/interceptors.d.ts +73 -0
  829. package/vendor/ink/node_modules/undici-types/mock-agent.d.ts +68 -0
  830. package/vendor/ink/node_modules/undici-types/mock-call-history.d.ts +111 -0
  831. package/vendor/ink/node_modules/undici-types/mock-client.d.ts +27 -0
  832. package/vendor/ink/node_modules/undici-types/mock-errors.d.ts +12 -0
  833. package/vendor/ink/node_modules/undici-types/mock-interceptor.d.ts +94 -0
  834. package/vendor/ink/node_modules/undici-types/mock-pool.d.ts +27 -0
  835. package/vendor/ink/node_modules/undici-types/package.json +55 -0
  836. package/vendor/ink/node_modules/undici-types/patch.d.ts +29 -0
  837. package/vendor/ink/node_modules/undici-types/pool-stats.d.ts +19 -0
  838. package/vendor/ink/node_modules/undici-types/pool.d.ts +41 -0
  839. package/vendor/ink/node_modules/undici-types/proxy-agent.d.ts +29 -0
  840. package/vendor/ink/node_modules/undici-types/readable.d.ts +68 -0
  841. package/vendor/ink/node_modules/undici-types/retry-agent.d.ts +8 -0
  842. package/vendor/ink/node_modules/undici-types/retry-handler.d.ts +125 -0
  843. package/vendor/ink/node_modules/undici-types/round-robin-pool.d.ts +41 -0
  844. package/vendor/ink/node_modules/undici-types/snapshot-agent.d.ts +109 -0
  845. package/vendor/ink/node_modules/undici-types/util.d.ts +18 -0
  846. package/vendor/ink/node_modules/undici-types/utility.d.ts +7 -0
  847. package/vendor/ink/node_modules/undici-types/webidl.d.ts +341 -0
  848. package/vendor/ink/node_modules/undici-types/websocket.d.ts +186 -0
  849. package/vendor/ink/package.json +201 -0
  850. package/vendor/ink/readme.md +2636 -0
  851. package/bin/swag-agent.js +0 -9
  852. package/dist/server/lib/pg-rate-limiter.d.ts +0 -21
  853. package/dist/server/lib/pg-rate-limiter.js +0 -86
@@ -16,6 +16,7 @@
16
16
  * 3. Add row to ai_tool_registry table (defines schema for all clients)
17
17
  * That's it — MCP, WhaleChat, workflows, CLI all pick it up automatically.
18
18
  */
19
+
19
20
  import { sanitizeError } from "../shared/agent-core.js";
20
21
  import { validateToolArgs } from "./validation.js";
21
22
  import { sanitizeToolDescription } from "./lib/prompt-sanitizer.js";
@@ -45,749 +46,1110 @@ import { handleKali } from "./handlers/kali.js";
45
46
  import { handleLocalAgent } from "./handlers/local-agent.js";
46
47
  import { handleEnrichment } from "./handlers/enrichment.js";
47
48
  import { handleStorefront } from "./handlers/storefront.js";
49
+ import { handleApiDocs } from "./handlers/api-docs.js";
48
50
  import { handleClickHouse } from "./handlers/clickhouse.js";
49
51
  import { summarizeResult, withTimeout } from "./lib/utils.js";
52
+
50
53
  // ============================================================================
51
54
  // TELEMETRY — ClickHouse span buffer (replaces Postgres audit_logs buffer)
52
55
  // ============================================================================
56
+
53
57
  import { queueSpan, flushSpans, auditRowToSpan, classifyErrorType } from "./lib/clickhouse-buffer.js";
58
+
54
59
  // Re-export for callers that used flushAuditLogs (e.g. index.ts shutdown)
55
60
  export { flushSpans };
61
+
56
62
  // ============================================================================
57
63
  // IN-MEMORY EXECUTION METRICS
58
64
  // ============================================================================
65
+
59
66
  const toolMetrics = new Map();
60
67
  export function getToolMetrics() {
61
- const result = {};
62
- for (const [name, m] of toolMetrics) {
63
- result[name] = { invocations: m.invocations, errors: m.errors, avgMs: m.invocations > 0 ? Math.round(m.totalMs / m.invocations) : 0, lastMs: m.lastMs };
64
- }
65
- return result;
68
+ const result = {};
69
+ for (const [name, m] of toolMetrics) {
70
+ result[name] = {
71
+ invocations: m.invocations,
72
+ errors: m.errors,
73
+ avgMs: m.invocations > 0 ? Math.round(m.totalMs / m.invocations) : 0,
74
+ lastMs: m.lastMs
75
+ };
76
+ }
77
+ return result;
66
78
  }
67
79
  function recordToolMetric(toolName, durationMs, success) {
68
- let m = toolMetrics.get(toolName);
69
- if (!m) {
70
- m = { invocations: 0, errors: 0, totalMs: 0, lastMs: 0 };
71
- toolMetrics.set(toolName, m);
72
- }
73
- m.invocations++;
74
- m.totalMs += durationMs;
75
- m.lastMs = durationMs;
76
- if (!success)
77
- m.errors++;
80
+ let m = toolMetrics.get(toolName);
81
+ if (!m) {
82
+ m = {
83
+ invocations: 0,
84
+ errors: 0,
85
+ totalMs: 0,
86
+ lastMs: 0
87
+ };
88
+ toolMetrics.set(toolName, m);
89
+ }
90
+ m.invocations++;
91
+ m.totalMs += durationMs;
92
+ m.lastMs = durationMs;
93
+ if (!success) m.errors++;
78
94
  }
95
+
96
+ // ============================================================================
97
+ // TYPES
98
+ // ============================================================================
99
+
100
+ // ============================================================================
101
+ // TOOL REGISTRY (loaded from database — same as CLI and edge function)
102
+ // ============================================================================
103
+
79
104
  let cachedResult = null;
80
105
  let cacheTime = 0;
106
+
81
107
  /** Pre-computed API-ready tool defs (name + truncated description + input_schema).
82
108
  * Computed once at load time, reused every turn without re-serialization. */
83
109
  let cachedApiToolDefs = null;
110
+
84
111
  /** Truncate a description to maxLen characters, ending at a word boundary with ellipsis. */
85
112
  function truncateDescription(desc, maxLen = 150) {
86
- if (desc.length <= maxLen)
87
- return desc;
88
- const cut = desc.lastIndexOf(" ", maxLen - 3);
89
- return desc.substring(0, cut > 0 ? cut : maxLen - 3) + "...";
113
+ if (desc.length <= maxLen) return desc;
114
+ const cut = desc.lastIndexOf(" ", maxLen - 3);
115
+ return desc.substring(0, cut > 0 ? cut : maxLen - 3) + "...";
90
116
  }
117
+
91
118
  /**
92
119
  * Load tools from ai_tool_registry, split into core (auto_load=true) and extended.
93
120
  * The `discover_tools` meta-tool is always injected into core.
94
121
  * Descriptions are truncated to 150 chars at load time.
95
122
  */
96
123
  export async function loadTools(supabase, forceRefresh = false) {
97
- if (!forceRefresh && cachedResult && Date.now() - cacheTime < 60_000)
98
- return cachedResult;
99
- const { data, error } = await supabase
100
- .from("ai_tool_registry")
101
- .select("name, description, definition, auto_load")
102
- .eq("is_active", true)
103
- .neq("tool_mode", "code");
104
- if (error || !data) {
105
- return cachedResult || { core: [], extended: [], all: [] };
106
- }
107
- const allTools = data.map((t) => ({
108
- name: t.name,
109
- description: sanitizeToolDescription(truncateDescription(t.description || t.definition?.description || t.name)),
110
- input_schema: t.definition?.input_schema || { type: "object", properties: {} },
111
- }));
112
- const core = [];
113
- const extended = [];
114
- // Check if any row has auto_load set — if the column doesn't exist yet
115
- // (migration not run), all values will be null/undefined. In that case,
116
- // treat ALL tools as core to preserve pre-migration behavior.
117
- const migrationApplied = data.some((t) => t.auto_load === true || t.auto_load === false);
118
- if (!migrationApplied) {
119
- // Pre-migration: all tools are core (original behavior)
120
- core.push(...allTools);
121
- }
122
- else {
123
- for (let i = 0; i < data.length; i++) {
124
- if (data[i].auto_load) {
125
- core.push(allTools[i]);
126
- }
127
- else {
128
- extended.push(allTools[i]);
129
- }
130
- }
124
+ if (!forceRefresh && cachedResult && Date.now() - cacheTime < 60_000) return cachedResult;
125
+ const {
126
+ data,
127
+ error
128
+ } = await supabase.from("ai_tool_registry").select("name, description, definition, auto_load").eq("is_active", true).neq("tool_mode", "code");
129
+ if (error || !data) {
130
+ return cachedResult || {
131
+ core: [],
132
+ extended: [],
133
+ all: []
134
+ };
135
+ }
136
+ const allTools = data.map(t => ({
137
+ name: t.name,
138
+ description: sanitizeToolDescription(truncateDescription(t.description || t.definition?.description || t.name)),
139
+ input_schema: t.definition?.input_schema || {
140
+ type: "object",
141
+ properties: {}
131
142
  }
132
- // Always inject discover_tools into core set
133
- if (!core.some(t => t.name === "discover_tools")) {
134
- core.push(DISCOVER_TOOLS_DEF);
143
+ }));
144
+ const core = [];
145
+ const extended = [];
146
+
147
+ // Check if any row has auto_load set — if the column doesn't exist yet
148
+ // (migration not run), all values will be null/undefined. In that case,
149
+ // treat ALL tools as core to preserve pre-migration behavior.
150
+ const migrationApplied = data.some(t => t.auto_load === true || t.auto_load === false);
151
+ if (!migrationApplied) {
152
+ // Pre-migration: all tools are core (original behavior)
153
+ core.push(...allTools);
154
+ } else {
155
+ for (let i = 0; i < data.length; i++) {
156
+ if (data[i].auto_load) {
157
+ core.push(allTools[i]);
158
+ } else {
159
+ extended.push(allTools[i]);
160
+ }
135
161
  }
136
- // Pre-compute API-ready tool defs keyed by name — avoids per-turn .map()
137
- cachedApiToolDefs = new Map();
138
- for (const t of [...core, ...extended]) {
139
- cachedApiToolDefs.set(t.name, {
140
- name: t.name,
141
- description: t.description,
142
- input_schema: t.input_schema,
143
- });
144
- }
145
- cachedResult = { core, extended, all: allTools };
146
- cacheTime = Date.now();
147
- return cachedResult;
162
+ }
163
+
164
+ // Always inject discover_tools into core set
165
+ if (!core.some(t => t.name === "discover_tools")) {
166
+ core.push(DISCOVER_TOOLS_DEF);
167
+ }
168
+
169
+ // Pre-compute API-ready tool defs keyed by name — avoids per-turn .map()
170
+ cachedApiToolDefs = new Map();
171
+ for (const t of [...core, ...extended]) {
172
+ cachedApiToolDefs.set(t.name, {
173
+ name: t.name,
174
+ description: t.description,
175
+ input_schema: t.input_schema
176
+ });
177
+ }
178
+ cachedResult = {
179
+ core,
180
+ extended,
181
+ all: allTools
182
+ };
183
+ cacheTime = Date.now();
184
+ return cachedResult;
148
185
  }
186
+
149
187
  /**
150
188
  * Get pre-computed API-ready tool definitions. Returns frozen objects keyed by name
151
189
  * so the agent loop can look up defs without re-mapping every turn.
152
190
  * Falls back to building from a ToolDef[] if cache not yet populated.
153
191
  */
154
192
  export function getCachedToolDefs(tools) {
155
- if (cachedApiToolDefs) {
156
- // Fast path: look up each active tool in the pre-computed map
157
- const result = [];
158
- for (const t of tools) {
159
- const cached = cachedApiToolDefs.get(t.name);
160
- if (cached) {
161
- result.push(cached);
162
- }
163
- else {
164
- // Dynamic tool (e.g. delegate_task, user tools, discovered tools) — build on the fly
165
- result.push({
166
- name: t.name,
167
- description: truncateDescription(t.description),
168
- input_schema: t.input_schema,
169
- });
170
- }
171
- }
172
- return result;
193
+ if (cachedApiToolDefs) {
194
+ // Fast path: look up each active tool in the pre-computed map
195
+ const result = [];
196
+ for (const t of tools) {
197
+ const cached = cachedApiToolDefs.get(t.name);
198
+ if (cached) {
199
+ result.push(cached);
200
+ } else {
201
+ // Dynamic tool (e.g. delegate_task, user tools, discovered tools) — build on the fly
202
+ result.push({
203
+ name: t.name,
204
+ description: truncateDescription(t.description),
205
+ input_schema: t.input_schema
206
+ });
207
+ }
173
208
  }
174
- // Fallback: cache not populated yet — build from scratch with truncation
175
- return tools.map((t) => ({
176
- name: t.name,
177
- description: truncateDescription(t.description),
178
- input_schema: t.input_schema,
179
- }));
209
+ return result;
210
+ }
211
+ // Fallback: cache not populated yet — build from scratch with truncation
212
+ return tools.map(t => ({
213
+ name: t.name,
214
+ description: truncateDescription(t.description),
215
+ input_schema: t.input_schema
216
+ }));
180
217
  }
218
+
181
219
  /** discover_tools meta-tool — lets the model load extended tool schemas on demand */
182
220
  const DISCOVER_TOOLS_DEF = {
183
- name: "discover_tools",
184
- description: "Load full schemas for extended tools not in your core set. Call this before using a tool that is listed under 'Extended Tools' in your system prompt. You can load tools by name or by category.",
185
- input_schema: {
186
- type: "object",
187
- properties: {
188
- names: {
189
- type: "array",
190
- items: { type: "string" },
191
- description: "Specific tool names to load (e.g. ['kali', 'browser', 'voice'])",
192
- },
193
- category: {
194
- type: "string",
195
- description: "Load all tools in this category (e.g. 'security', 'media', 'operations')",
196
- },
197
- refresh: {
198
- type: "boolean",
199
- description: "Force reload tool definitions from DB (bust cache). Use when tools may have been updated mid-conversation.",
200
- },
221
+ name: "discover_tools",
222
+ description: "Load full schemas for extended tools not in your core set. Call this before using a tool that is listed under 'Extended Tools' in your system prompt. You can load tools by name or by category.",
223
+ input_schema: {
224
+ type: "object",
225
+ properties: {
226
+ names: {
227
+ type: "array",
228
+ items: {
229
+ type: "string"
201
230
  },
202
- },
231
+ description: "Specific tool names to load (e.g. ['kali', 'browser', 'voice'])"
232
+ },
233
+ category: {
234
+ type: "string",
235
+ description: "Load all tools in this category (e.g. 'security', 'media', 'operations')"
236
+ },
237
+ refresh: {
238
+ type: "boolean",
239
+ description: "Force reload tool definitions from DB (bust cache). Use when tools may have been updated mid-conversation."
240
+ }
241
+ }
242
+ }
203
243
  };
244
+
204
245
  // ============================================================================
205
246
  // USER TOOLS (per-store custom tools from user_tools table)
206
247
  // ============================================================================
248
+
207
249
  const userToolCache = new Map();
208
250
  const USER_TOOL_CACHE_MAX = 100;
209
251
  function evictUserToolCache() {
210
- if (userToolCache.size <= USER_TOOL_CACHE_MAX)
211
- return;
212
- const entries = [...userToolCache.entries()].sort((a, b) => a[1].lastAccessed - b[1].lastAccessed);
213
- const excess = userToolCache.size - USER_TOOL_CACHE_MAX;
214
- for (let i = 0; i < excess; i++) {
215
- userToolCache.delete(entries[i][0]);
216
- }
252
+ if (userToolCache.size <= USER_TOOL_CACHE_MAX) return;
253
+ const entries = [...userToolCache.entries()].sort((a, b) => a[1].lastAccessed - b[1].lastAccessed);
254
+ const excess = userToolCache.size - USER_TOOL_CACHE_MAX;
255
+ for (let i = 0; i < excess; i++) {
256
+ userToolCache.delete(entries[i][0]);
257
+ }
217
258
  }
218
259
  export async function loadUserTools(supabase, storeId) {
219
- const cached = userToolCache.get(storeId);
220
- if (cached && Date.now() - cached.time < 60_000) {
221
- cached.lastAccessed = Date.now();
222
- return { rows: cached.tools, defs: cached.defs };
260
+ const cached = userToolCache.get(storeId);
261
+ if (cached && Date.now() - cached.time < 60_000) {
262
+ cached.lastAccessed = Date.now();
263
+ return {
264
+ rows: cached.tools,
265
+ defs: cached.defs
266
+ };
267
+ }
268
+ const {
269
+ data,
270
+ error
271
+ } = await supabase.from("user_tools").select("id, name, display_name, description, input_schema, execution_type, is_read_only, requires_approval, http_config, rpc_function, sql_template, allowed_tables, max_execution_time_ms").eq("store_id", storeId).eq("is_active", true);
272
+ if (error || !data?.length) return {
273
+ rows: [],
274
+ defs: []
275
+ };
276
+ const rows = data;
277
+ const defs = rows.map(t => ({
278
+ name: `user_tool__${t.name}`,
279
+ description: sanitizeToolDescription(`[Custom Tool] ${t.display_name}: ${t.description}${t.requires_approval ? " (requires approval)" : ""}`),
280
+ input_schema: t.input_schema || {
281
+ type: "object",
282
+ properties: {}
223
283
  }
224
- const { data, error } = await supabase
225
- .from("user_tools")
226
- .select("id, name, display_name, description, input_schema, execution_type, is_read_only, requires_approval, http_config, rpc_function, sql_template, allowed_tables, max_execution_time_ms")
227
- .eq("store_id", storeId)
228
- .eq("is_active", true);
229
- if (error || !data?.length)
230
- return { rows: [], defs: [] };
231
- const rows = data;
232
- const defs = rows.map((t) => ({
233
- name: `user_tool__${t.name}`,
234
- description: sanitizeToolDescription(`[Custom Tool] ${t.display_name}: ${t.description}${t.requires_approval ? " (requires approval)" : ""}`),
235
- input_schema: t.input_schema || { type: "object", properties: {} },
236
- }));
237
- userToolCache.set(storeId, { tools: rows, defs, time: Date.now(), lastAccessed: Date.now() });
238
- evictUserToolCache();
239
- return { rows, defs };
284
+ }));
285
+ userToolCache.set(storeId, {
286
+ tools: rows,
287
+ defs,
288
+ time: Date.now(),
289
+ lastAccessed: Date.now()
290
+ });
291
+ evictUserToolCache();
292
+ return {
293
+ rows,
294
+ defs
295
+ };
240
296
  }
241
297
  export function getUserToolByPrefixedName(rows, prefixedName) {
242
- const toolName = prefixedName.replace(/^user_tool__/, "");
243
- return rows.find((t) => t.name === toolName);
298
+ const toolName = prefixedName.replace(/^user_tool__/, "");
299
+ return rows.find(t => t.name === toolName);
244
300
  }
245
301
  export function getToolsForAgent(agent, coreTools, userToolDefs = []) {
246
- // Core registry tools are always available (matches MCP server behavior).
247
- // enabled_tools only restricts custom user tools.
248
- if (agent.enabled_tools?.length > 0) {
249
- const filteredUserTools = userToolDefs.filter((t) => agent.enabled_tools.includes(t.name));
250
- return [...coreTools, ...filteredUserTools];
251
- }
252
- return [...coreTools, ...userToolDefs];
302
+ // Core registry tools are always available (matches MCP server behavior).
303
+ // enabled_tools only restricts custom user tools.
304
+ if (agent.enabled_tools?.length > 0) {
305
+ const filteredUserTools = userToolDefs.filter(t => agent.enabled_tools.includes(t.name));
306
+ return [...coreTools, ...filteredUserTools];
307
+ }
308
+ return [...coreTools, ...userToolDefs];
253
309
  }
310
+
311
+ // ============================================================================
312
+ // UNIFIED HANDLER REGISTRY — single source of truth for all tool dispatch
313
+ // ============================================================================
314
+
254
315
  const DEFAULT_TIMEOUT = 30_000;
316
+
255
317
  /**
256
318
  * Every built-in tool MUST be registered here. This map is the single source
257
319
  * of truth for handler routing, timeouts, and store requirements.
258
320
  * Adding a tool to ai_tool_registry without an entry here → "Unknown tool" error.
259
321
  */
260
322
  export const TOOL_HANDLERS = {
261
- // --- Business Data ---
262
- inventory: { handler: (sb, args, sid) => {
263
- const a = args.action || "";
264
- if (a.startsWith("audit_"))
265
- return handleInventoryAudit(sb, { ...args, action: a.slice(6) }, sid);
266
- if (["summary", "velocity", "by_location", "in_stock", "out_of_stock", "by_category"].includes(a))
267
- return handleInventoryQuery(sb, args, sid);
268
- return handleInventory(sb, args, sid);
269
- }, timeout: DEFAULT_TIMEOUT, requiresStore: true },
270
- purchase_orders: { handler: handlePurchaseOrders, timeout: DEFAULT_TIMEOUT, requiresStore: true },
271
- transfers: { handler: handleTransfers, timeout: DEFAULT_TIMEOUT, requiresStore: true },
272
- products: { handler: handleProducts, timeout: DEFAULT_TIMEOUT, requiresStore: true },
273
- collections: { handler: handleCollections, timeout: DEFAULT_TIMEOUT, requiresStore: true },
274
- customers: { handler: handleCustomers, timeout: DEFAULT_TIMEOUT, requiresStore: true },
275
- orders: { handler: handleOrders, timeout: DEFAULT_TIMEOUT, requiresStore: true },
276
- analytics: { handler: handleAnalytics, timeout: DEFAULT_TIMEOUT, requiresStore: true },
277
- locations: { handler: handleLocations, timeout: DEFAULT_TIMEOUT, requiresStore: true },
278
- suppliers: { handler: handleSuppliers, timeout: DEFAULT_TIMEOUT, requiresStore: true },
279
- store: { handler: handleStore, timeout: DEFAULT_TIMEOUT, requiresStore: true },
280
- storefront: { handler: handleStorefront, timeout: DEFAULT_TIMEOUT, requiresStore: true },
281
- // --- Communication ---
282
- email: { handler: handleEmail, timeout: DEFAULT_TIMEOUT, requiresStore: true },
283
- documents: { handler: handleDocuments, timeout: 120_000, requiresStore: true },
284
- // --- Operations ---
285
- alerts: { handler: handleAlerts, timeout: DEFAULT_TIMEOUT, requiresStore: true },
286
- audit_trail: { handler: handleAuditTrail, timeout: DEFAULT_TIMEOUT, requiresStore: true },
287
- workflows: { handler: handleWorkflows, timeout: DEFAULT_TIMEOUT, requiresStore: true },
288
- // --- AI & Generation ---
289
- voice: { handler: handleVoice, timeout: 120_000, requiresStore: true },
290
- image_gen: { handler: handleImageGen, timeout: 60_000, requiresStore: true },
291
- remove_bg: { handler: handleRemoveBg, timeout: 60_000, requiresStore: true },
292
- media: { handler: handleMedia, timeout: 60_000, requiresStore: true },
293
- video_gen: { handler: handleVideoGen, timeout: 600_000, requiresStore: true },
294
- llm: { handler: handleLLM, timeout: 120_000, requiresStore: true },
295
- embeddings: { handler: handleEmbeddings, timeout: 60_000, requiresStore: true },
296
- creations: { handler: handleCreations, timeout: 60_000, requiresStore: true },
297
- // --- Platform & Infrastructure (no store required) ---
298
- web_search: { handler: handleWebSearch, timeout: DEFAULT_TIMEOUT, requiresStore: false },
299
- telemetry: { handler: handleTelemetry, timeout: DEFAULT_TIMEOUT, requiresStore: true },
300
- browser: { handler: handleBrowser, timeout: 120_000, requiresStore: true },
301
- discovery: { handler: handleDiscovery, timeout: DEFAULT_TIMEOUT, requiresStore: false },
302
- api_keys: { handler: handleAPIKeys, timeout: DEFAULT_TIMEOUT, requiresStore: true },
303
- // --- Advertising ---
304
- meta_ads: { handler: handleMetaAds, timeout: 300_000, requiresStore: true },
305
- // --- Security & Local ---
306
- kali: { handler: handleKali, timeout: 600_000, requiresStore: true, supportsProgress: true },
307
- local_agent: { handler: handleLocalAgent, timeout: 600_000, requiresStore: false },
308
- // --- Customer Data Protection ---
309
- enrichment: { handler: handleEnrichment, timeout: 60_000, requiresStore: true },
310
- // --- Observability (ClickHouse) ---
311
- clickhouse: { handler: handleClickHouse, timeout: 60_000, requiresStore: false },
312
- // --- Meta: Tool Discovery (lazy loading) ---
313
- discover_tools: { handler: handleDiscoverTools, timeout: 5000, requiresStore: false },
323
+ // --- Business Data ---
324
+ inventory: {
325
+ handler: (sb, args, sid) => {
326
+ const a = args.action || "";
327
+ if (a.startsWith("audit_")) return handleInventoryAudit(sb, {
328
+ ...args,
329
+ action: a.slice(6)
330
+ }, sid);
331
+ if (["summary", "velocity", "by_location", "in_stock", "out_of_stock", "by_category"].includes(a)) return handleInventoryQuery(sb, args, sid);
332
+ return handleInventory(sb, args, sid);
333
+ },
334
+ timeout: DEFAULT_TIMEOUT,
335
+ requiresStore: true
336
+ },
337
+ purchase_orders: {
338
+ handler: handlePurchaseOrders,
339
+ timeout: DEFAULT_TIMEOUT,
340
+ requiresStore: true
341
+ },
342
+ transfers: {
343
+ handler: handleTransfers,
344
+ timeout: DEFAULT_TIMEOUT,
345
+ requiresStore: true
346
+ },
347
+ products: {
348
+ handler: handleProducts,
349
+ timeout: DEFAULT_TIMEOUT,
350
+ requiresStore: true
351
+ },
352
+ collections: {
353
+ handler: handleCollections,
354
+ timeout: DEFAULT_TIMEOUT,
355
+ requiresStore: true
356
+ },
357
+ customers: {
358
+ handler: handleCustomers,
359
+ timeout: DEFAULT_TIMEOUT,
360
+ requiresStore: true
361
+ },
362
+ orders: {
363
+ handler: handleOrders,
364
+ timeout: DEFAULT_TIMEOUT,
365
+ requiresStore: true
366
+ },
367
+ analytics: {
368
+ handler: handleAnalytics,
369
+ timeout: DEFAULT_TIMEOUT,
370
+ requiresStore: true
371
+ },
372
+ locations: {
373
+ handler: handleLocations,
374
+ timeout: DEFAULT_TIMEOUT,
375
+ requiresStore: true
376
+ },
377
+ suppliers: {
378
+ handler: handleSuppliers,
379
+ timeout: DEFAULT_TIMEOUT,
380
+ requiresStore: true
381
+ },
382
+ store: {
383
+ handler: handleStore,
384
+ timeout: DEFAULT_TIMEOUT,
385
+ requiresStore: true
386
+ },
387
+ storefront: {
388
+ handler: handleStorefront,
389
+ timeout: DEFAULT_TIMEOUT,
390
+ requiresStore: true
391
+ },
392
+ // --- Communication ---
393
+ email: {
394
+ handler: handleEmail,
395
+ timeout: DEFAULT_TIMEOUT,
396
+ requiresStore: true
397
+ },
398
+ documents: {
399
+ handler: handleDocuments,
400
+ timeout: 120_000,
401
+ requiresStore: true
402
+ },
403
+ // --- Operations ---
404
+ alerts: {
405
+ handler: handleAlerts,
406
+ timeout: DEFAULT_TIMEOUT,
407
+ requiresStore: true
408
+ },
409
+ audit_trail: {
410
+ handler: handleAuditTrail,
411
+ timeout: DEFAULT_TIMEOUT,
412
+ requiresStore: true
413
+ },
414
+ workflows: {
415
+ handler: handleWorkflows,
416
+ timeout: DEFAULT_TIMEOUT,
417
+ requiresStore: true
418
+ },
419
+ // --- AI & Generation ---
420
+ voice: {
421
+ handler: handleVoice,
422
+ timeout: 120_000,
423
+ requiresStore: true
424
+ },
425
+ image_gen: {
426
+ handler: handleImageGen,
427
+ timeout: 60_000,
428
+ requiresStore: true
429
+ },
430
+ remove_bg: {
431
+ handler: handleRemoveBg,
432
+ timeout: 60_000,
433
+ requiresStore: true
434
+ },
435
+ media: {
436
+ handler: handleMedia,
437
+ timeout: 60_000,
438
+ requiresStore: true
439
+ },
440
+ video_gen: {
441
+ handler: handleVideoGen,
442
+ timeout: 600_000,
443
+ requiresStore: true
444
+ },
445
+ llm: {
446
+ handler: handleLLM,
447
+ timeout: 120_000,
448
+ requiresStore: true
449
+ },
450
+ embeddings: {
451
+ handler: handleEmbeddings,
452
+ timeout: 60_000,
453
+ requiresStore: true
454
+ },
455
+ creations: {
456
+ handler: handleCreations,
457
+ timeout: 60_000,
458
+ requiresStore: true
459
+ },
460
+ // --- Platform & Infrastructure (no store required) ---
461
+ web_search: {
462
+ handler: handleWebSearch,
463
+ timeout: DEFAULT_TIMEOUT,
464
+ requiresStore: false
465
+ },
466
+ telemetry: {
467
+ handler: handleTelemetry,
468
+ timeout: DEFAULT_TIMEOUT,
469
+ requiresStore: true
470
+ },
471
+ browser: {
472
+ handler: handleBrowser,
473
+ timeout: 120_000,
474
+ requiresStore: true
475
+ },
476
+ discovery: {
477
+ handler: handleDiscovery,
478
+ timeout: DEFAULT_TIMEOUT,
479
+ requiresStore: false
480
+ },
481
+ api_keys: {
482
+ handler: handleAPIKeys,
483
+ timeout: DEFAULT_TIMEOUT,
484
+ requiresStore: true
485
+ },
486
+ api_docs: {
487
+ handler: handleApiDocs,
488
+ timeout: 5000,
489
+ requiresStore: false
490
+ },
491
+ // --- Advertising ---
492
+ meta_ads: {
493
+ handler: handleMetaAds,
494
+ timeout: 300_000,
495
+ requiresStore: true
496
+ },
497
+ // --- Security & Local ---
498
+ kali: {
499
+ handler: handleKali,
500
+ timeout: 600_000,
501
+ requiresStore: true,
502
+ supportsProgress: true
503
+ },
504
+ local_agent: {
505
+ handler: handleLocalAgent,
506
+ timeout: 600_000,
507
+ requiresStore: false
508
+ },
509
+ // --- Customer Data Protection ---
510
+ enrichment: {
511
+ handler: handleEnrichment,
512
+ timeout: 60_000,
513
+ requiresStore: true
514
+ },
515
+ // --- Observability (ClickHouse) ---
516
+ clickhouse: {
517
+ handler: handleClickHouse,
518
+ timeout: 60_000,
519
+ requiresStore: false
520
+ },
521
+ // --- Meta: Tool Discovery (lazy loading) ---
522
+ discover_tools: {
523
+ handler: handleDiscoverTools,
524
+ timeout: 5000,
525
+ requiresStore: false
526
+ }
314
527
  };
315
528
  Object.freeze(TOOL_HANDLERS);
529
+
316
530
  /** Get all registered built-in tool names */
317
531
  export function getRegisteredToolNames() {
318
- return Object.keys(TOOL_HANDLERS);
532
+ return Object.keys(TOOL_HANDLERS);
319
533
  }
534
+
320
535
  // ============================================================================
321
536
  // DISCOVER_TOOLS HANDLER — returns full schemas for extended tools on demand
322
537
  // ============================================================================
538
+
323
539
  /** Full extended tool defs (with schemas) — used by handleDiscoverTools to return schemas on demand */
324
540
  let _extendedToolsCache = [];
541
+
325
542
  /** Lightweight extended tool index — name + first-sentence description only (for system prompt) */
326
543
  let _extendedToolsIndex = [];
544
+
327
545
  /** Called by index.ts after loadTools() to populate the discover_tools cache.
328
546
  * Stores full schemas for on-demand loading, plus a lightweight index for the system prompt. */
329
547
  export function setExtendedToolsCache(tools) {
330
- _extendedToolsCache = tools;
331
- // Pre-compute lightweight index: name + first sentence only (no schemas)
332
- _extendedToolsIndex = tools.map(t => ({
333
- name: t.name,
334
- description: t.description.split(".")[0],
335
- }));
548
+ _extendedToolsCache = tools;
549
+ // Pre-compute lightweight index: name + first sentence only (no schemas)
550
+ _extendedToolsIndex = tools.map(t => ({
551
+ name: t.name,
552
+ description: t.description.split(".")[0]
553
+ }));
336
554
  }
555
+
337
556
  /** Get full extended tools with schemas (for discover_tools handler) */
338
557
  export function getExtendedToolsCache() {
339
- return _extendedToolsCache;
558
+ return _extendedToolsCache;
340
559
  }
560
+
341
561
  /** Get lightweight extended tools index — name + short description only (for system prompt).
342
562
  * Avoids serializing full schemas into the prompt. */
343
563
  export function getExtendedToolsIndex() {
344
- return _extendedToolsIndex;
564
+ return _extendedToolsIndex;
345
565
  }
566
+
346
567
  /**
347
568
  * Get full tool schemas for specific tool names from the extended tools cache.
348
569
  * Used by the agent loop to inject discovered tool schemas into the active tool set.
349
570
  * Returns only tools that exist in the cache; unknown names are silently skipped.
350
571
  */
351
572
  export function getFullToolSchemas(toolNames) {
352
- if (!toolNames.length || !_extendedToolsCache.length)
353
- return [];
354
- const nameSet = new Set(toolNames);
355
- return _extendedToolsCache.filter(t => nameSet.has(t.name));
573
+ if (!toolNames.length || !_extendedToolsCache.length) return [];
574
+ const nameSet = new Set(toolNames);
575
+ return _extendedToolsCache.filter(t => nameSet.has(t.name));
356
576
  }
577
+
357
578
  // Tool category heuristics — maps tool names to categories for category-based discovery
358
579
  const TOOL_CATEGORIES = {
359
- // Business Data
360
- inventory: "business", purchase_orders: "business", transfers: "business",
361
- products: "business", collections: "business", customers: "business",
362
- orders: "business", analytics: "business", locations: "business",
363
- suppliers: "business", store: "business", storefront: "business",
364
- // Communication
365
- email: "communication", documents: "communication",
366
- // Operations
367
- alerts: "operations", audit_trail: "operations", workflows: "operations",
368
- telemetry: "operations",
369
- // Media & AI
370
- voice: "media", image_gen: "media", video_gen: "media", remove_bg: "media", media: "media",
371
- llm: "ai", embeddings: "ai", creations: "media",
372
- // Platform
373
- web_search: "platform", browser: "platform", discovery: "platform",
374
- api_keys: "platform",
375
- // Security
376
- kali: "security", local_agent: "platform",
377
- // Advertising
378
- meta_ads: "advertising",
379
- // Data
380
- enrichment: "data",
580
+ // Business Data
581
+ inventory: "business",
582
+ purchase_orders: "business",
583
+ transfers: "business",
584
+ products: "business",
585
+ collections: "business",
586
+ customers: "business",
587
+ orders: "business",
588
+ analytics: "business",
589
+ locations: "business",
590
+ suppliers: "business",
591
+ store: "business",
592
+ storefront: "business",
593
+ // Communication
594
+ email: "communication",
595
+ documents: "communication",
596
+ // Operations
597
+ alerts: "operations",
598
+ audit_trail: "operations",
599
+ workflows: "operations",
600
+ telemetry: "operations",
601
+ // Media & AI
602
+ voice: "media",
603
+ image_gen: "media",
604
+ video_gen: "media",
605
+ remove_bg: "media",
606
+ media: "media",
607
+ llm: "ai",
608
+ embeddings: "ai",
609
+ creations: "media",
610
+ // Platform
611
+ web_search: "platform",
612
+ browser: "platform",
613
+ discovery: "platform",
614
+ api_keys: "platform",
615
+ api_docs: "platform",
616
+ // Security
617
+ kali: "security",
618
+ local_agent: "platform",
619
+ // Advertising
620
+ meta_ads: "advertising",
621
+ // Data
622
+ enrichment: "data"
381
623
  };
382
624
  async function handleDiscoverTools(sb, args) {
383
- const names = args.names;
384
- const category = args.category;
385
- const refresh = args.refresh;
386
- // Force reload from DB if refresh requested — busts the 60s cache
387
- if (refresh) {
388
- try {
389
- const freshResult = await loadTools(sb, true);
390
- setExtendedToolsCache(freshResult.extended);
391
- }
392
- catch {
393
- // If refresh fails, continue with stale cache — better than erroring
394
- }
395
- }
396
- if (!names?.length && !category) {
397
- return { success: false, error: "Provide 'names' (array of tool names) or 'category' to discover tools." };
398
- }
399
- let matching = [];
400
- if (names?.length) {
401
- const nameSet = new Set(names);
402
- matching = _extendedToolsCache.filter(t => nameSet.has(t.name));
403
- }
404
- if (category) {
405
- const cat = category.toLowerCase();
406
- const categoryTools = _extendedToolsCache.filter(t => TOOL_CATEGORIES[t.name] === cat);
407
- // Merge without duplicates
408
- const existingNames = new Set(matching.map(t => t.name));
409
- for (const t of categoryTools) {
410
- if (!existingNames.has(t.name))
411
- matching.push(t);
412
- }
625
+ const names = args.names;
626
+ const category = args.category;
627
+ const refresh = args.refresh;
628
+
629
+ // Force reload from DB if refresh requested — busts the 60s cache
630
+ if (refresh) {
631
+ try {
632
+ const freshResult = await loadTools(sb, true);
633
+ setExtendedToolsCache(freshResult.extended);
634
+ } catch {
635
+ // If refresh fails, continue with stale cache — better than erroring
413
636
  }
414
- if (matching.length === 0) {
415
- const available = _extendedToolsCache.map(t => t.name).join(", ");
416
- return { success: false, error: `No matching extended tools found. Available: ${available}` };
637
+ }
638
+ if (!names?.length && !category) {
639
+ return {
640
+ success: false,
641
+ error: "Provide 'names' (array of tool names) or 'category' to discover tools."
642
+ };
643
+ }
644
+ let matching = [];
645
+ if (names?.length) {
646
+ const nameSet = new Set(names);
647
+ matching = _extendedToolsCache.filter(t => nameSet.has(t.name));
648
+ }
649
+ if (category) {
650
+ const cat = category.toLowerCase();
651
+ const categoryTools = _extendedToolsCache.filter(t => TOOL_CATEGORIES[t.name] === cat);
652
+ // Merge without duplicates
653
+ const existingNames = new Set(matching.map(t => t.name));
654
+ for (const t of categoryTools) {
655
+ if (!existingNames.has(t.name)) matching.push(t);
417
656
  }
657
+ }
658
+ if (matching.length === 0) {
659
+ const available = _extendedToolsCache.map(t => t.name).join(", ");
418
660
  return {
419
- success: true,
420
- data: {
421
- tools: matching.map(t => ({ name: t.name, description: t.description, input_schema: t.input_schema })),
422
- count: matching.length,
423
- refreshed: !!refresh,
424
- },
661
+ success: false,
662
+ error: `No matching extended tools found. Available: ${available}`
425
663
  };
664
+ }
665
+ return {
666
+ success: true,
667
+ data: {
668
+ tools: matching.map(t => ({
669
+ name: t.name,
670
+ description: t.description,
671
+ input_schema: t.input_schema
672
+ })),
673
+ count: matching.length,
674
+ refreshed: !!refresh
675
+ }
676
+ };
426
677
  }
678
+
427
679
  // ============================================================================
428
680
  // USER TOOL EXECUTOR — handles RPC, HTTP, SQL execution types
429
681
  // ============================================================================
682
+
430
683
  async function executeUserTool(supabase, userTool, args, storeId, agentId, conversationId) {
431
- const timeout = userTool.max_execution_time_ms || 5000;
432
- if (userTool.execution_type === "http") {
433
- return executeHTTPUserTool(supabase, userTool, args, storeId, timeout);
434
- }
435
- try {
436
- const { data, error } = await supabase.rpc("execute_user_tool", {
437
- p_tool_id: userTool.id,
438
- p_store_id: storeId,
439
- p_args: args,
440
- p_agent_id: agentId || null,
441
- p_conversation_id: conversationId || null,
442
- });
443
- if (error)
444
- return { success: false, error: error.message };
445
- const result = data;
446
- if (result.pending_approval) {
447
- return { success: false, error: `Tool requires approval. Execution ID: ${result.execution_id}. ${result.message}` };
448
- }
449
- if (result.success && result.data && result.data.execute_sql) {
450
- return executeSQLUserTool(supabase, result.data, args, storeId);
451
- }
452
- return result.success
453
- ? { success: true, data: result.data }
454
- : { success: false, error: result.error || "Unknown error" };
684
+ const timeout = userTool.max_execution_time_ms || 5000;
685
+ if (userTool.execution_type === "http") {
686
+ return executeHTTPUserTool(supabase, userTool, args, storeId, timeout);
687
+ }
688
+ try {
689
+ const {
690
+ data,
691
+ error
692
+ } = await supabase.rpc("execute_user_tool", {
693
+ p_tool_id: userTool.id,
694
+ p_store_id: storeId,
695
+ p_args: args,
696
+ p_agent_id: agentId || null,
697
+ p_conversation_id: conversationId || null
698
+ });
699
+ if (error) return {
700
+ success: false,
701
+ error: error.message
702
+ };
703
+ const result = data;
704
+ if (result.pending_approval) {
705
+ return {
706
+ success: false,
707
+ error: `Tool requires approval. Execution ID: ${result.execution_id}. ${result.message}`
708
+ };
455
709
  }
456
- catch (err) {
457
- return { success: false, error: sanitizeError(err) };
710
+ if (result.success && result.data && result.data.execute_sql) {
711
+ return executeSQLUserTool(supabase, result.data, args, storeId);
458
712
  }
713
+ return result.success ? {
714
+ success: true,
715
+ data: result.data
716
+ } : {
717
+ success: false,
718
+ error: result.error || "Unknown error"
719
+ };
720
+ } catch (err) {
721
+ return {
722
+ success: false,
723
+ error: sanitizeError(err)
724
+ };
725
+ }
459
726
  }
460
727
  async function executeHTTPUserTool(supabase, userTool, args, storeId, timeout) {
461
- const config = userTool.http_config;
462
- if (!config || !config.url) {
463
- return { success: false, error: "HTTP tool has no URL configured" };
464
- }
465
- const httpCfg = config;
466
- let url = httpCfg.url;
467
- let headers = { ...(httpCfg.headers || {}) };
468
- // Collect secret names referenced in the URL, headers, and body template
469
- const configStr = JSON.stringify({ url: httpCfg.url, headers: httpCfg.headers, body: httpCfg.body_template });
470
- const secretRefs = [...configStr.matchAll(/\{\{secret:(\w+)\}\}/g)].map(m => m[1]);
471
- // Decrypt each referenced secret via RPC (consistent with all other handlers)
472
- const secretMap = new Map();
473
- await Promise.all([...new Set(secretRefs)].map(async (name) => {
474
- try {
475
- const { data } = await supabase.rpc("decrypt_secret", { p_name: name, p_store_id: storeId });
476
- if (data)
477
- secretMap.set(name, data);
478
- }
479
- catch { /* secret not found — will remain as {{secret:NAME}} placeholder */ }
480
- }));
481
- const resolveSecrets = (text) => {
482
- return text.replace(/\{\{secret:(\w+)\}\}/g, (_, name) => secretMap.get(name) || `{{secret:${name}}}`);
483
- };
484
- const resolveArgs = (text) => {
485
- return text.replace(/\{\{(\w+)\}\}/g, (_, name) => {
486
- if (name === "secret")
487
- return `{{${name}}}`;
488
- const val = args[name];
489
- return val !== undefined ? String(val) : `{{${name}}}`;
490
- });
728
+ const config = userTool.http_config;
729
+ if (!config || !config.url) {
730
+ return {
731
+ success: false,
732
+ error: "HTTP tool has no URL configured"
491
733
  };
492
- const resolve = (text) => resolveSecrets(resolveArgs(text));
493
- url = resolve(url);
494
- for (const [key, val] of Object.entries(headers)) {
495
- headers[key] = resolve(val);
496
- }
497
- let body;
498
- const method = (httpCfg.method || "GET").toUpperCase();
499
- if (method !== "GET" && method !== "HEAD") {
500
- if (httpCfg.body_template) {
501
- const resolvedBody = {};
502
- for (const [key, val] of Object.entries(httpCfg.body_template)) {
503
- if (typeof val === "string") {
504
- resolvedBody[key] = resolve(val);
505
- }
506
- else {
507
- resolvedBody[key] = val;
508
- }
509
- }
510
- for (const [key, val] of Object.entries(args)) {
511
- if (!(key in resolvedBody)) {
512
- resolvedBody[key] = val;
513
- }
514
- }
515
- body = JSON.stringify(resolvedBody);
516
- }
517
- else {
518
- body = JSON.stringify(args);
519
- }
520
- if (!headers["Content-Type"] && !headers["content-type"]) {
521
- headers["Content-Type"] = "application/json";
522
- }
523
- }
524
- // P0 FIX: Use shared SSRF guard with DNS resolve-then-check (replaces inline regex)
525
- const ssrfError = await validateUrl(url);
526
- if (ssrfError) {
527
- return { success: false, error: `Blocked: ${ssrfError}` };
528
- }
734
+ }
735
+ const httpCfg = config;
736
+ let url = httpCfg.url;
737
+ let headers = {
738
+ ...(httpCfg.headers || {})
739
+ };
740
+
741
+ // Collect secret names referenced in the URL, headers, and body template
742
+ const configStr = JSON.stringify({
743
+ url: httpCfg.url,
744
+ headers: httpCfg.headers,
745
+ body: httpCfg.body_template
746
+ });
747
+ const secretRefs = [...configStr.matchAll(/\{\{secret:(\w+)\}\}/g)].map(m => m[1]);
748
+
749
+ // Decrypt each referenced secret via RPC (consistent with all other handlers)
750
+ const secretMap = new Map();
751
+ await Promise.all([...new Set(secretRefs)].map(async name => {
529
752
  try {
530
- const controller = new AbortController();
531
- const timer = setTimeout(() => controller.abort(), timeout);
532
- const resp = await fetch(url, { method, headers, body, signal: controller.signal });
533
- clearTimeout(timer);
534
- // Clear secrets from memory as soon as the request is sent
535
- secretMap.clear();
536
- const contentType = resp.headers.get("content-type") || "";
537
- let data;
538
- if (contentType.includes("json")) {
539
- data = await resp.json();
753
+ const {
754
+ data
755
+ } = await supabase.rpc("decrypt_secret", {
756
+ p_name: name,
757
+ p_store_id: storeId
758
+ });
759
+ if (data) secretMap.set(name, data);
760
+ } catch {/* secret not found — will remain as {{secret:NAME}} placeholder */}
761
+ }));
762
+ const resolveSecrets = text => {
763
+ return text.replace(/\{\{secret:(\w+)\}\}/g, (_, name) => secretMap.get(name) || `{{secret:${name}}}`);
764
+ };
765
+ const resolveArgs = text => {
766
+ return text.replace(/\{\{(\w+)\}\}/g, (_, name) => {
767
+ if (name === "secret") return `{{${name}}}`;
768
+ const val = args[name];
769
+ return val !== undefined ? String(val) : `{{${name}}}`;
770
+ });
771
+ };
772
+ const resolve = text => resolveSecrets(resolveArgs(text));
773
+ url = resolve(url);
774
+ for (const [key, val] of Object.entries(headers)) {
775
+ headers[key] = resolve(val);
776
+ }
777
+ let body;
778
+ const method = (httpCfg.method || "GET").toUpperCase();
779
+ if (method !== "GET" && method !== "HEAD") {
780
+ if (httpCfg.body_template) {
781
+ const resolvedBody = {};
782
+ for (const [key, val] of Object.entries(httpCfg.body_template)) {
783
+ if (typeof val === "string") {
784
+ resolvedBody[key] = resolve(val);
785
+ } else {
786
+ resolvedBody[key] = val;
540
787
  }
541
- else {
542
- data = await resp.text();
788
+ }
789
+ for (const [key, val] of Object.entries(args)) {
790
+ if (!(key in resolvedBody)) {
791
+ resolvedBody[key] = val;
543
792
  }
544
- if (!resp.ok) {
545
- return { success: false, error: `HTTP ${resp.status}: ${typeof data === "string" ? data.substring(0, 500) : JSON.stringify(data).substring(0, 500)}` };
546
- }
547
- return { success: true, data };
793
+ }
794
+ body = JSON.stringify(resolvedBody);
795
+ } else {
796
+ body = JSON.stringify(args);
548
797
  }
549
- catch (err) {
550
- // Clear secrets from memory even on error
551
- secretMap.clear();
552
- if (err.name === "AbortError") {
553
- return { success: false, error: `HTTP request timed out after ${timeout}ms` };
554
- }
555
- return { success: false, error: sanitizeError(err) };
798
+ if (!headers["Content-Type"] && !headers["content-type"]) {
799
+ headers["Content-Type"] = "application/json";
556
800
  }
557
- }
558
- async function executeSQLUserTool(supabase, sqlConfig, args, storeId) {
559
- if (!sqlConfig.is_read_only) {
560
- return { success: false, error: "Write SQL tools are not supported in server execution" };
801
+ }
802
+
803
+ // P0 FIX: Use shared SSRF guard with DNS resolve-then-check (replaces inline regex)
804
+ const ssrfError = await validateUrl(url);
805
+ if (ssrfError) {
806
+ return {
807
+ success: false,
808
+ error: `Blocked: ${ssrfError}`
809
+ };
810
+ }
811
+ try {
812
+ const controller = new AbortController();
813
+ const timer = setTimeout(() => controller.abort(), timeout);
814
+ const resp = await fetch(url, {
815
+ method,
816
+ headers,
817
+ body,
818
+ signal: controller.signal
819
+ });
820
+ clearTimeout(timer);
821
+
822
+ // Clear secrets from memory as soon as the request is sent
823
+ secretMap.clear();
824
+ const contentType = resp.headers.get("content-type") || "";
825
+ let data;
826
+ if (contentType.includes("json")) {
827
+ data = await resp.json();
828
+ } else {
829
+ data = await resp.text();
561
830
  }
562
- if (!sqlConfig.template) {
563
- return { success: false, error: "No SQL template configured" };
831
+ if (!resp.ok) {
832
+ return {
833
+ success: false,
834
+ error: `HTTP ${resp.status}: ${typeof data === "string" ? data.substring(0, 500) : JSON.stringify(data).substring(0, 500)}`
835
+ };
564
836
  }
565
- try {
566
- const { data, error } = await supabase.rpc("execute_safe_sql", {
567
- p_sql: sqlConfig.template,
568
- p_params: args,
569
- p_store_id: storeId,
570
- p_allowed_tables: sqlConfig.allowed_tables || [],
571
- });
572
- if (error)
573
- return { success: false, error: error.message };
574
- if (data?.success) {
575
- return { success: true, data: data.data };
576
- }
577
- return { success: false, error: data?.error || "SQL execution failed" };
837
+ return {
838
+ success: true,
839
+ data
840
+ };
841
+ } catch (err) {
842
+ // Clear secrets from memory even on error
843
+ secretMap.clear();
844
+ if (err.name === "AbortError") {
845
+ return {
846
+ success: false,
847
+ error: `HTTP request timed out after ${timeout}ms`
848
+ };
578
849
  }
579
- catch (err) {
580
- return { success: false, error: sanitizeError(err) };
850
+ return {
851
+ success: false,
852
+ error: sanitizeError(err)
853
+ };
854
+ }
855
+ }
856
+ async function executeSQLUserTool(supabase, sqlConfig, args, storeId) {
857
+ if (!sqlConfig.is_read_only) {
858
+ return {
859
+ success: false,
860
+ error: "Write SQL tools are not supported in server execution"
861
+ };
862
+ }
863
+ if (!sqlConfig.template) {
864
+ return {
865
+ success: false,
866
+ error: "No SQL template configured"
867
+ };
868
+ }
869
+ try {
870
+ const {
871
+ data,
872
+ error
873
+ } = await supabase.rpc("execute_safe_sql", {
874
+ p_sql: sqlConfig.template,
875
+ p_params: args,
876
+ p_store_id: storeId,
877
+ p_allowed_tables: sqlConfig.allowed_tables || []
878
+ });
879
+ if (error) return {
880
+ success: false,
881
+ error: error.message
882
+ };
883
+ if (data?.success) {
884
+ return {
885
+ success: true,
886
+ data: data.data
887
+ };
581
888
  }
889
+ return {
890
+ success: false,
891
+ error: data?.error || "SQL execution failed"
892
+ };
893
+ } catch (err) {
894
+ return {
895
+ success: false,
896
+ error: sanitizeError(err)
897
+ };
898
+ }
582
899
  }
900
+
583
901
  // ============================================================================
584
902
  // SUPPLY CHAIN — action aliasing (LLMs omit po_/transfer_ prefix)
585
903
  // ============================================================================
904
+
586
905
  async function executeSupplyChain(supabase, args, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId) {
587
- let scAction = args.action || "";
588
- const PO_ALIASES = {
589
- create: "po_create", list: "po_list", get: "po_get",
590
- add_items: "po_add_items", approve: "po_approve", mark_ordered: "po_mark_ordered",
591
- receive: "po_receive", cancel: "po_cancel",
592
- };
593
- if (PO_ALIASES[scAction])
594
- scAction = PO_ALIASES[scAction];
595
- if (scAction === "find_suppliers") {
596
- return executeTool(supabase, "suppliers", { ...args, action: "find_suppliers" }, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId);
597
- }
598
- if (scAction.startsWith("po_")) {
599
- return executeTool(supabase, "purchase_orders", { ...args, action: scAction.slice(3) }, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId);
600
- }
601
- if (scAction.startsWith("transfer_")) {
602
- return executeTool(supabase, "transfers", { ...args, action: scAction.slice(9) }, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId);
603
- }
604
- return { success: false, error: `Unknown supply_chain action: ${scAction}. Use po_create, po_list, po_get, po_approve, po_receive, po_cancel, transfer_create, transfer_list, transfer_approve, transfer_ship, transfer_receive, transfer_cancel, find_suppliers.` };
906
+ let scAction = args.action || "";
907
+ const PO_ALIASES = {
908
+ create: "po_create",
909
+ list: "po_list",
910
+ get: "po_get",
911
+ add_items: "po_add_items",
912
+ approve: "po_approve",
913
+ mark_ordered: "po_mark_ordered",
914
+ receive: "po_receive",
915
+ cancel: "po_cancel"
916
+ };
917
+ if (PO_ALIASES[scAction]) scAction = PO_ALIASES[scAction];
918
+ if (scAction === "find_suppliers") {
919
+ return executeTool(supabase, "suppliers", {
920
+ ...args,
921
+ action: "find_suppliers"
922
+ }, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId);
923
+ }
924
+ if (scAction.startsWith("po_")) {
925
+ return executeTool(supabase, "purchase_orders", {
926
+ ...args,
927
+ action: scAction.slice(3)
928
+ }, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId);
929
+ }
930
+ if (scAction.startsWith("transfer_")) {
931
+ return executeTool(supabase, "transfers", {
932
+ ...args,
933
+ action: scAction.slice(9)
934
+ }, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId);
935
+ }
936
+ return {
937
+ success: false,
938
+ error: `Unknown supply_chain action: ${scAction}. Use po_create, po_list, po_get, po_approve, po_receive, po_cancel, transfer_create, transfer_list, transfer_approve, transfer_ship, transfer_receive, transfer_cancel, find_suppliers.`
939
+ };
605
940
  }
941
+
606
942
  // ============================================================================
607
943
  // TOOL EXECUTOR — dispatches via unified handler registry
608
944
  // ============================================================================
609
- export async function executeTool(supabase, toolName, args, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId, onToolProgress,
610
- /** Skip per-tool audit when called within a conversation — persistAgentTurn handles it */
945
+
946
+ export async function executeTool(supabase, toolName, args, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId, onToolProgress, /** Skip per-tool audit when called within a conversation — persistAgentTurn handles it */
611
947
  skipAudit) {
612
- const startTime = Date.now();
613
- const action = args.action;
614
- let result;
615
- // Handle supply_chain aliases (LLMs often omit po_/transfer_ prefix)
616
- if (toolName === "supply_chain") {
617
- return executeSupplyChain(supabase, args, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId);
618
- }
619
- // Look up handler from unified registry
620
- const entry = TOOL_HANDLERS[toolName];
621
- // Check store requirement from registry (not hardcoded)
622
- const requiresStore = entry ? entry.requiresStore : true;
623
- if (requiresStore && (!storeId || !/^[0-9a-fA-F]{8}-/.test(storeId))) {
624
- return { success: false, error: `store_id is required for ${toolName}. Ensure a store is selected.` };
625
- }
626
- // Permission enforcement check agent flags before tool execution
627
- if (agentId) {
628
- const { data: agentFlags } = await supabase.from("ai_agent_config")
629
- .select("can_query, can_modify")
630
- .eq("id", agentId).single();
631
- if (agentFlags) {
632
- // Read-only agent check — block ALL tool calls if can_query is false
633
- if (!agentFlags.can_query) {
634
- const readActions = ["list", "get", "search", "query", "summary", "stats", "count", "by_location", "in_stock", "out_of_stock", "velocity"];
635
- const action = args.action;
636
- if (action && readActions.includes(action)) {
637
- return { success: false, error: `Agent does not have query permission (can_query=false). Contact an admin.` };
638
- }
639
- }
640
- // Mutation check — already in system prompt but enforce at execution level
641
- if (!agentFlags.can_modify) {
642
- const writeActions = ["create", "update", "delete", "upsert", "send", "approve", "cancel", "add", "remove", "set", "adjust", "transfer"];
643
- const action = args.action;
644
- if (action && writeActions.some(wa => action.startsWith(wa))) {
645
- return { success: false, error: `Agent has read-only access (can_modify=false). Cannot perform "${action}".` };
646
- }
647
- }
948
+ const startTime = Date.now();
949
+ const action = args.action;
950
+ let result;
951
+
952
+ // Handle supply_chain aliases (LLMs often omit po_/transfer_ prefix)
953
+ if (toolName === "supply_chain") {
954
+ return executeSupplyChain(supabase, args, storeId, traceId, userId, userEmail, source, conversationId, userToolRows, agentId);
955
+ }
956
+
957
+ // Look up handler from unified registry
958
+ const entry = TOOL_HANDLERS[toolName];
959
+
960
+ // Check store requirement from registry (not hardcoded)
961
+ const requiresStore = entry ? entry.requiresStore : true;
962
+ if (requiresStore && (!storeId || !/^[0-9a-fA-F]{8}-/.test(storeId))) {
963
+ return {
964
+ success: false,
965
+ error: `store_id is required for ${toolName}. Ensure a store is selected.`
966
+ };
967
+ }
968
+
969
+ // Permission enforcement — check agent flags before tool execution
970
+ if (agentId) {
971
+ const {
972
+ data: agentFlags
973
+ } = await supabase.from("ai_agent_config").select("can_query, can_modify").eq("id", agentId).single();
974
+ if (agentFlags) {
975
+ // Read-only agent check — block ALL tool calls if can_query is false
976
+ if (!agentFlags.can_query) {
977
+ const readActions = ["list", "get", "search", "query", "summary", "stats", "count", "by_location", "in_stock", "out_of_stock", "velocity"];
978
+ const action = args.action;
979
+ if (action && readActions.includes(action)) {
980
+ return {
981
+ success: false,
982
+ error: `Agent does not have query permission (can_query=false). Contact an admin.`
983
+ };
648
984
  }
649
- }
650
- // User tool approval check — requires_approval enforced at execution level
651
- if (toolName.startsWith("user_tool__") && userToolRows?.length) {
652
- const userTool = getUserToolByPrefixedName(userToolRows, toolName);
653
- if (userTool?.requires_approval) {
654
- return { success: false, error: `Tool "${userTool.display_name}" requires approval before execution. Use the workflow approval system to request permission.` };
985
+ }
986
+ // Mutation check — already in system prompt but enforce at execution level
987
+ if (!agentFlags.can_modify) {
988
+ const writeActions = ["create", "update", "delete", "upsert", "send", "approve", "cancel", "add", "remove", "set", "adjust", "transfer"];
989
+ const action = args.action;
990
+ if (action && writeActions.some(wa => action.startsWith(wa))) {
991
+ return {
992
+ success: false,
993
+ error: `Agent has read-only access (can_modify=false). Cannot perform "${action}".`
994
+ };
655
995
  }
996
+ }
656
997
  }
657
- // Validate mutation args before dispatch — read-only actions pass through
658
- const validation = validateToolArgs(toolName, args);
659
- if (!validation.valid) {
660
- return { success: false, error: validation.error };
998
+ }
999
+
1000
+ // User tool approval check — requires_approval enforced at execution level
1001
+ if (toolName.startsWith("user_tool__") && userToolRows?.length) {
1002
+ const userTool = getUserToolByPrefixedName(userToolRows, toolName);
1003
+ if (userTool?.requires_approval) {
1004
+ return {
1005
+ success: false,
1006
+ error: `Tool "${userTool.display_name}" requires approval before execution. Use the workflow approval system to request permission.`
1007
+ };
661
1008
  }
662
- args = validation.data;
663
- const execStartMs = Date.now();
664
- try {
665
- let toolPromise;
666
- if (entry) {
667
- // Dispatch via unified handler registry — pass progress callback to handlers that support it
668
- const progressCb = entry.supportsProgress && onToolProgress
669
- ? (progress) => onToolProgress(toolName, progress)
670
- : undefined;
671
- toolPromise = entry.handler(supabase, args, storeId, progressCb);
672
- }
673
- else if (toolName.startsWith("user_tool__") && userToolRows && storeId) {
674
- // Custom user tools
675
- const userTool = getUserToolByPrefixedName(userToolRows, toolName);
676
- if (userTool) {
677
- toolPromise = executeUserTool(supabase, userTool, args, storeId, agentId, conversationId);
678
- }
679
- else {
680
- toolPromise = Promise.resolve({ success: false, error: `Unknown user tool: ${toolName}` });
681
- }
682
- }
683
- else {
684
- toolPromise = Promise.resolve({ success: false, error: `Unknown tool: ${toolName}. Use the discover_tools action to see available tools.` });
685
- }
686
- const timeoutMs = entry?.timeout || DEFAULT_TIMEOUT;
687
- // FIX 7: Timeout cascade validation — warn if step timeout < tool timeout
688
- const stepTimeout = args._step_timeout_seconds;
689
- if (stepTimeout && stepTimeout * 1000 < timeoutMs) {
690
- console.warn(`[timeout-cascade] Step timeout (${stepTimeout}s) < tool timeout (${timeoutMs / 1000}s) for ${toolName}. Tool may outlive step.`);
691
- }
692
- result = await withTimeout(toolPromise, timeoutMs, toolName);
1009
+ }
1010
+
1011
+ // Validate mutation args before dispatch — read-only actions pass through
1012
+ const validation = validateToolArgs(toolName, args);
1013
+ if (!validation.valid) {
1014
+ return {
1015
+ success: false,
1016
+ error: validation.error
1017
+ };
1018
+ }
1019
+ args = validation.data;
1020
+ const execStartMs = Date.now();
1021
+ try {
1022
+ let toolPromise;
1023
+ if (entry) {
1024
+ // Dispatch via unified handler registry pass progress callback to handlers that support it
1025
+ const progressCb = entry.supportsProgress && onToolProgress ? progress => onToolProgress(toolName, progress) : undefined;
1026
+ toolPromise = entry.handler(supabase, args, storeId, progressCb);
1027
+ } else if (toolName.startsWith("user_tool__") && userToolRows && storeId) {
1028
+ // Custom user tools
1029
+ const userTool = getUserToolByPrefixedName(userToolRows, toolName);
1030
+ if (userTool) {
1031
+ toolPromise = executeUserTool(supabase, userTool, args, storeId, agentId, conversationId);
1032
+ } else {
1033
+ toolPromise = Promise.resolve({
1034
+ success: false,
1035
+ error: `Unknown user tool: ${toolName}`
1036
+ });
1037
+ }
1038
+ } else {
1039
+ toolPromise = Promise.resolve({
1040
+ success: false,
1041
+ error: `Unknown tool: ${toolName}. Use the discover_tools action to see available tools.`
1042
+ });
693
1043
  }
694
- catch (err) {
695
- result = { success: false, error: sanitizeError(err) };
1044
+ const timeoutMs = entry?.timeout || DEFAULT_TIMEOUT;
1045
+
1046
+ // FIX 7: Timeout cascade validation — warn if step timeout < tool timeout
1047
+ const stepTimeout = args._step_timeout_seconds;
1048
+ if (stepTimeout && stepTimeout * 1000 < timeoutMs) {
1049
+ console.warn(`[timeout-cascade] Step timeout (${stepTimeout}s) < tool timeout (${timeoutMs / 1000}s) for ${toolName}. Tool may outlive step.`);
696
1050
  }
697
- // Record execution metrics
698
- recordToolMetric(toolName, Date.now() - execStartMs, result.success);
699
- // Audit log — enriched with OTEL fields for distributed tracing
700
- // Skipped when tool is called within a conversation (SSE chat, channel agent, workflow)
701
- // because persistAgentTurn already logs the full conversation with tool details
702
- if (skipAudit)
703
- return result;
704
- try {
705
- const endTime = Date.now();
706
- // Compute payload sizes for observability
707
- const inputJson = JSON.stringify(args);
708
- const outputJson = result.data ? JSON.stringify(result.data) : "";
709
- const inputBytes = inputJson.length;
710
- const outputBytes = outputJson.length;
711
- const details = {
712
- source: source || "fly_container",
713
- args,
714
- // Keys that SwiftUI telemetry panel reads for rich display
715
- tool_input: args,
716
- input_bytes: inputBytes,
717
- output_bytes: outputBytes,
718
- };
719
- if (result.success && result.data) {
720
- details.result_summary = summarizeResult(toolName, action, result.data);
721
- // Store full result for rich telemetry display (capped at 50KB to prevent JSONB bloat)
722
- if (outputBytes <= 50_000) {
723
- details.tool_result = result.data;
724
- }
725
- else {
726
- details.tool_result = {
727
- _truncated: true,
728
- _type: Array.isArray(result.data) ? "array" : "object",
729
- _size: outputBytes,
730
- _count: Array.isArray(result.data) ? result.data.length : Object.keys(result.data).length,
731
- };
732
- }
733
- }
734
- if (result.error) {
735
- details.tool_error = result.error;
736
- const errorType = classifyErrorType(result.error);
737
- if (errorType)
738
- details.error_type = errorType;
739
- }
740
- const bytes = new Uint8Array(8);
741
- crypto.getRandomValues(bytes);
742
- const spanId = Array.from(bytes).map(b => b.toString(16).padStart(2, "0")).join("");
743
- const auditRow = {
744
- action: `tool.${toolName}${action ? `.${action}` : ""}`,
745
- severity: result.success ? "info" : "error",
746
- store_id: storeId || null,
747
- resource_type: "mcp_tool",
748
- resource_id: toolName,
749
- request_id: traceId || null,
750
- conversation_id: conversationId || null,
751
- source: source || "fly_container",
752
- details,
753
- error_message: result.error || null,
754
- error_type: classifyErrorType(result.error) || undefined,
755
- duration_ms: endTime - startTime,
756
- user_id: userId || null,
757
- user_email: userEmail || null,
758
- input_bytes: inputBytes,
759
- output_bytes: outputBytes,
760
- // OTEL fields
761
- trace_id: traceId || null,
762
- span_id: spanId,
763
- span_kind: "INTERNAL",
764
- service_name: "agent-server",
765
- status_code: result.success ? "OK" : "ERROR",
766
- start_time: new Date(startTime).toISOString(),
767
- end_time: new Date(endTime).toISOString(),
1051
+ result = await withTimeout(toolPromise, timeoutMs, toolName);
1052
+ } catch (err) {
1053
+ result = {
1054
+ success: false,
1055
+ error: sanitizeError(err)
1056
+ };
1057
+ }
1058
+
1059
+ // Record execution metrics
1060
+ recordToolMetric(toolName, Date.now() - execStartMs, result.success);
1061
+
1062
+ // Audit log enriched with OTEL fields for distributed tracing
1063
+ // Skipped when tool is called within a conversation (SSE chat, channel agent, workflow)
1064
+ // because persistAgentTurn already logs the full conversation with tool details
1065
+ if (skipAudit) return result;
1066
+ try {
1067
+ const endTime = Date.now();
1068
+ // Compute payload sizes for observability
1069
+ const inputJson = JSON.stringify(args);
1070
+ const outputJson = result.data ? JSON.stringify(result.data) : "";
1071
+ const inputBytes = inputJson.length;
1072
+ const outputBytes = outputJson.length;
1073
+ const details = {
1074
+ source: source || "fly_container",
1075
+ args,
1076
+ // Keys that SwiftUI telemetry panel reads for rich display
1077
+ tool_input: args,
1078
+ input_bytes: inputBytes,
1079
+ output_bytes: outputBytes
1080
+ };
1081
+ if (result.success && result.data) {
1082
+ details.result_summary = summarizeResult(toolName, action, result.data);
1083
+ // Store full result for rich telemetry display (capped at 50KB to prevent JSONB bloat)
1084
+ if (outputBytes <= 50_000) {
1085
+ details.tool_result = result.data;
1086
+ } else {
1087
+ details.tool_result = {
1088
+ _truncated: true,
1089
+ _type: Array.isArray(result.data) ? "array" : "object",
1090
+ _size: outputBytes,
1091
+ _count: Array.isArray(result.data) ? result.data.length : Object.keys(result.data).length
768
1092
  };
769
- queueSpan(auditRowToSpan(auditRow));
1093
+ }
770
1094
  }
771
- catch (err) {
772
- console.error("[audit] exception:", err);
1095
+ if (result.error) {
1096
+ details.tool_error = result.error;
1097
+ const errorType = classifyErrorType(result.error);
1098
+ if (errorType) details.error_type = errorType;
773
1099
  }
774
- return result;
1100
+ const bytes = new Uint8Array(8);
1101
+ crypto.getRandomValues(bytes);
1102
+ const spanId = Array.from(bytes).map(b => b.toString(16).padStart(2, "0")).join("");
1103
+ const auditRow = {
1104
+ action: `tool.${toolName}${action ? `.${action}` : ""}`,
1105
+ severity: result.success ? "info" : "error",
1106
+ store_id: storeId || null,
1107
+ resource_type: "mcp_tool",
1108
+ resource_id: toolName,
1109
+ request_id: traceId || null,
1110
+ conversation_id: conversationId || null,
1111
+ source: source || "fly_container",
1112
+ details,
1113
+ error_message: result.error || null,
1114
+ error_type: classifyErrorType(result.error) || undefined,
1115
+ duration_ms: endTime - startTime,
1116
+ user_id: userId || null,
1117
+ user_email: userEmail || null,
1118
+ input_bytes: inputBytes,
1119
+ output_bytes: outputBytes,
1120
+ // OTEL fields
1121
+ trace_id: traceId || null,
1122
+ span_id: spanId,
1123
+ span_kind: "INTERNAL",
1124
+ service_name: "agent-server",
1125
+ status_code: result.success ? "OK" : "ERROR",
1126
+ start_time: new Date(startTime).toISOString(),
1127
+ end_time: new Date(endTime).toISOString()
1128
+ };
1129
+ queueSpan(auditRowToSpan(auditRow));
1130
+ } catch (err) {
1131
+ console.error("[audit] exception:", err);
1132
+ }
1133
+ return result;
775
1134
  }
1135
+
776
1136
  // ============================================================================
777
1137
  // AGENT LOADER
778
1138
  // ============================================================================
1139
+
779
1140
  export async function loadAgentConfig(supabase, agentId, storeId) {
780
- // storeId is required for tenant isolation — only omit for internal/migration callers
781
- let query = supabase
782
- .from("ai_agent_config")
783
- .select("*")
784
- .eq("id", agentId);
785
- // ALWAYS filter by store_id when provided (which should be always for user requests)
786
- if (storeId) {
787
- query = query.eq("store_id", storeId);
788
- }
789
- const { data, error } = await query.single();
790
- if (error || !data)
791
- return null;
792
- return data;
1141
+ // storeId is required for tenant isolation — only omit for internal/migration callers
1142
+ let query = supabase.from("ai_agent_config").select("*").eq("id", agentId);
1143
+
1144
+ // ALWAYS filter by store_id when provided (which should be always for user requests)
1145
+ if (storeId) {
1146
+ query = query.eq("store_id", storeId);
1147
+ }
1148
+ const {
1149
+ data,
1150
+ error
1151
+ } = await query.single();
1152
+ if (error || !data) return null;
1153
+ return data;
793
1154
  }
1155
+ //# sourceMappingURL=tool-router.js.map