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