whale-code 6.5.6 → 6.5.8

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 (1369) hide show
  1. package/README.md +15 -3
  2. package/bin/whale-code.js +23 -0
  3. package/dist/cli/__tests__/print-mode-streaming.test.js +270 -0
  4. package/dist/cli/__tests__/print-mode.basic-output.test.js +230 -0
  5. package/dist/cli/__tests__/print-mode.session-errors.test.js +252 -0
  6. package/dist/cli/__tests__/print-mode.test.js +273 -0
  7. package/dist/cli/__tests__/serve-mode-messages.test.js +338 -0
  8. package/dist/cli/__tests__/serve-mode.messages.part2.test.js +266 -0
  9. package/dist/cli/__tests__/serve-mode.messages.test.js +277 -0
  10. package/dist/cli/__tests__/serve-mode.startup-http.test.js +279 -0
  11. package/dist/cli/__tests__/serve-mode.test.js +345 -0
  12. package/dist/cli/app.d.ts +1 -0
  13. package/dist/cli/app.js +8 -2
  14. package/dist/cli/app.js.map +1 -1
  15. package/dist/cli/chat/ChatApp.d.ts +8 -36
  16. package/dist/cli/chat/ChatApp.js +135 -450
  17. package/dist/cli/chat/ChatApp.js.map +1 -1
  18. package/dist/cli/chat/ChatInput.d.ts +3 -2
  19. package/dist/cli/chat/ChatInput.js +37 -14
  20. package/dist/cli/chat/ChatInput.js.map +1 -1
  21. package/dist/cli/chat/ImsgManager.d.ts +20 -0
  22. package/dist/cli/chat/ImsgManager.js +341 -0
  23. package/dist/cli/chat/ImsgManager.js.map +1 -0
  24. package/dist/cli/chat/MarkdownText.d.ts +2 -1
  25. package/dist/cli/chat/MarkdownText.js +12 -8
  26. package/dist/cli/chat/MarkdownText.js.map +1 -1
  27. package/dist/cli/chat/MemoryManager.js +3 -2
  28. package/dist/cli/chat/MemoryManager.js.map +1 -1
  29. package/dist/cli/chat/MessageList.d.ts +1 -1
  30. package/dist/cli/chat/MessageList.js +119 -114
  31. package/dist/cli/chat/MessageList.js.map +1 -1
  32. package/dist/cli/chat/NodeManager.js +57 -170
  33. package/dist/cli/chat/NodeManager.js.map +1 -1
  34. package/dist/cli/chat/OverlayContext.d.ts +27 -0
  35. package/dist/cli/chat/OverlayContext.js +2 -0
  36. package/dist/cli/chat/OverlayContext.js.map +1 -0
  37. package/dist/cli/chat/PlanApproval.js +3 -2
  38. package/dist/cli/chat/PlanApproval.js.map +1 -1
  39. package/dist/cli/chat/RewindConfirmation.d.ts +12 -0
  40. package/dist/cli/chat/RewindConfirmation.js +243 -0
  41. package/dist/cli/chat/RewindConfirmation.js.map +1 -0
  42. package/dist/cli/chat/RewindViewer.js +5 -4
  43. package/dist/cli/chat/RewindViewer.js.map +1 -1
  44. package/dist/cli/chat/SessionManager.js +3 -2
  45. package/dist/cli/chat/SessionManager.js.map +1 -1
  46. package/dist/cli/chat/SlashMenu.d.ts +7 -24
  47. package/dist/cli/chat/SlashMenu.js +14 -183
  48. package/dist/cli/chat/SlashMenu.js.map +1 -1
  49. package/dist/cli/chat/StatusBar.d.ts +5 -2
  50. package/dist/cli/chat/StatusBar.js +80 -65
  51. package/dist/cli/chat/StatusBar.js.map +1 -1
  52. package/dist/cli/chat/StreamingText.d.ts +2 -1
  53. package/dist/cli/chat/StreamingText.js +2 -2
  54. package/dist/cli/chat/StreamingText.js.map +1 -1
  55. package/dist/cli/chat/SubagentPanel.d.ts +6 -6
  56. package/dist/cli/chat/SubagentPanel.js +159 -537
  57. package/dist/cli/chat/SubagentPanel.js.map +1 -1
  58. package/dist/cli/chat/TeamPanel.js +2 -30
  59. package/dist/cli/chat/TeamPanel.js.map +1 -1
  60. package/dist/cli/chat/ToolIndicator.d.ts +7 -23
  61. package/dist/cli/chat/ToolIndicator.js +543 -1443
  62. package/dist/cli/chat/ToolIndicator.js.map +1 -1
  63. package/dist/cli/chat/chat-input-menu-handler.d.ts +32 -0
  64. package/dist/cli/chat/components/LiveArea.d.ts +12 -0
  65. package/dist/cli/chat/components/LiveArea.js +252 -0
  66. package/dist/cli/chat/components/LiveArea.js.map +1 -0
  67. package/dist/cli/chat/components/OverlayRouter.d.ts +13 -0
  68. package/dist/cli/chat/components/OverlayRouter.js +257 -0
  69. package/dist/cli/chat/components/OverlayRouter.js.map +1 -0
  70. package/dist/cli/chat/components/StaticMessages.d.ts +9 -0
  71. package/dist/cli/chat/components/StaticMessages.js +132 -0
  72. package/dist/cli/chat/components/StaticMessages.js.map +1 -0
  73. package/dist/cli/chat/hooks/agent-loop-events.d.ts +77 -0
  74. package/dist/cli/chat/hooks/agent-loop-events.js +171 -0
  75. package/dist/cli/chat/hooks/agent-loop-events.js.map +1 -0
  76. package/dist/cli/chat/hooks/slash-command-config-system.d.ts +11 -0
  77. package/dist/cli/chat/hooks/slash-command-config-system.js +177 -0
  78. package/dist/cli/chat/hooks/slash-command-config-system.js.map +1 -0
  79. package/dist/cli/chat/hooks/slash-command-handlers-system.d.ts +12 -0
  80. package/dist/cli/chat/hooks/slash-command-handlers-system.js +127 -0
  81. package/dist/cli/chat/hooks/slash-command-handlers-system.js.map +1 -0
  82. package/dist/cli/chat/hooks/slash-command-handlers.d.ts +21 -0
  83. package/dist/cli/chat/hooks/slash-command-handlers.js +222 -0
  84. package/dist/cli/chat/hooks/slash-command-handlers.js.map +1 -0
  85. package/dist/cli/chat/hooks/slash-imsg-handlers.js +148 -0
  86. package/dist/cli/chat/hooks/slash-imsg-handlers.js.map +1 -0
  87. package/dist/cli/chat/hooks/slash-node-handlers.d.ts +26 -0
  88. package/dist/cli/chat/hooks/slash-node-handlers.js +226 -0
  89. package/dist/cli/chat/hooks/slash-node-handlers.js.map +1 -0
  90. package/dist/cli/chat/hooks/useAgentLoop.d.ts +2 -21
  91. package/dist/cli/chat/hooks/useAgentLoop.js +258 -401
  92. package/dist/cli/chat/hooks/useAgentLoop.js.map +1 -1
  93. package/dist/cli/chat/hooks/useElapsedClock.d.ts +19 -0
  94. package/dist/cli/chat/hooks/useElapsedClock.js +80 -0
  95. package/dist/cli/chat/hooks/useElapsedClock.js.map +1 -0
  96. package/dist/cli/chat/hooks/useOverlayHandlers.d.ts +23 -0
  97. package/dist/cli/chat/hooks/useOverlayHandlers.js +125 -0
  98. package/dist/cli/chat/hooks/useOverlayHandlers.js.map +1 -0
  99. package/dist/cli/chat/hooks/useSlashCommands.d.ts +14 -22
  100. package/dist/cli/chat/hooks/useSlashCommands.js +99 -720
  101. package/dist/cli/chat/hooks/useSlashCommands.js.map +1 -1
  102. package/dist/cli/chat/hooks/useStreamingReducer.d.ts +66 -0
  103. package/dist/cli/chat/imsg-manager-render.d.ts +29 -0
  104. package/dist/cli/chat/imsg-manager-render.js +294 -0
  105. package/dist/cli/chat/imsg-manager-render.js.map +1 -0
  106. package/dist/cli/chat/slash-commands.d.ts +37 -0
  107. package/dist/cli/chat/slash-commands.js +194 -0
  108. package/dist/cli/chat/slash-commands.js.map +1 -0
  109. package/dist/cli/chat/store.d.ts +115 -0
  110. package/dist/cli/chat/store.js +177 -0
  111. package/dist/cli/chat/store.js.map +1 -0
  112. package/dist/cli/chat/tool-indicator-helpers.d.ts +14 -0
  113. package/dist/cli/chat/tool-indicator-helpers.js +167 -0
  114. package/dist/cli/chat/tool-indicator-helpers.js.map +1 -0
  115. package/dist/cli/chat/tool-indicator-summary.d.ts +6 -0
  116. package/dist/cli/chat/tool-indicator-summary.js +103 -0
  117. package/dist/cli/chat/tool-indicator-summary.js.map +1 -0
  118. package/dist/cli/chat/tool-indicator-types.d.ts +66 -0
  119. package/dist/cli/chat/tool-indicator-types.js +177 -0
  120. package/dist/cli/chat/tool-indicator-types.js.map +1 -0
  121. package/dist/cli/commands/__tests__/config-cmd.test.js +270 -0
  122. package/dist/cli/commands/__tests__/doctor.test.js +257 -0
  123. package/dist/cli/commands/__tests__/imsg-node-bridge.test.js +99 -0
  124. package/dist/cli/commands/__tests__/imsg-utils.test.js +73 -0
  125. package/dist/cli/commands/__tests__/init.test.js +214 -0
  126. package/dist/cli/commands/__tests__/mcp.test.js +287 -0
  127. package/dist/cli/commands/imsg-config.d.ts +31 -0
  128. package/dist/cli/commands/imsg-config.js +104 -0
  129. package/dist/cli/commands/imsg-config.js.map +1 -0
  130. package/dist/cli/commands/imsg-node-bridge.d.ts +25 -0
  131. package/dist/cli/commands/imsg-node-bridge.js +229 -0
  132. package/dist/cli/commands/imsg-node-bridge.js.map +1 -0
  133. package/dist/cli/commands/imsg-utils.d.ts +14 -0
  134. package/dist/cli/commands/imsg-utils.js +42 -0
  135. package/dist/cli/commands/imsg-utils.js.map +1 -0
  136. package/dist/cli/commands/imsg-watcher-helpers.d.ts +40 -0
  137. package/dist/cli/commands/imsg-watcher-helpers.js +184 -0
  138. package/dist/cli/commands/imsg-watcher-helpers.js.map +1 -0
  139. package/dist/cli/commands/imsg-watcher.d.ts +11 -0
  140. package/dist/cli/commands/imsg-watcher.js +230 -0
  141. package/dist/cli/commands/imsg-watcher.js.map +1 -0
  142. package/dist/cli/commands/imsg.d.ts +14 -0
  143. package/dist/cli/commands/imsg.js +181 -0
  144. package/dist/cli/commands/imsg.js.map +1 -0
  145. package/dist/cli/commands/sessions.d.ts +9 -0
  146. package/dist/cli/commands/sessions.js +93 -0
  147. package/dist/cli/commands/sessions.js.map +1 -0
  148. package/dist/cli/login/LoginApp.js +3 -0
  149. package/dist/cli/login/LoginApp.js.map +1 -1
  150. package/dist/cli/serve-mode-persistence.d.ts +18 -0
  151. package/dist/cli/serve-mode-persistence.js +157 -0
  152. package/dist/cli/serve-mode-persistence.js.map +1 -0
  153. package/dist/cli/serve-mode-query.d.ts +9 -0
  154. package/dist/cli/serve-mode-query.js +247 -0
  155. package/dist/cli/serve-mode-query.js.map +1 -0
  156. package/dist/cli/serve-mode-types.d.ts +29 -0
  157. package/dist/cli/serve-mode-types.js +56 -0
  158. package/dist/cli/serve-mode-types.js.map +1 -0
  159. package/dist/cli/services/__tests__/agent-definitions.test.js +153 -0
  160. package/dist/cli/services/__tests__/agent-events-global.test.js +39 -0
  161. package/dist/cli/services/__tests__/agent-events.part2.test.js +113 -0
  162. package/dist/cli/services/__tests__/agent-events.test.js +157 -0
  163. package/dist/cli/services/__tests__/agent-loop-auth.test.js +392 -0
  164. package/dist/cli/services/__tests__/agent-loop-budget.test.js +389 -0
  165. package/dist/cli/services/__tests__/agent-loop-tools-lifecycle.test.js +430 -0
  166. package/dist/cli/services/__tests__/agent-loop-tools-maxturns.test.js +486 -0
  167. package/dist/cli/services/__tests__/agent-loop-utils-execution.test.js +528 -0
  168. package/dist/cli/services/__tests__/agent-loop-utils-helpers.test.js +466 -0
  169. package/dist/cli/services/__tests__/agent-worker-base-execute.test.js +257 -0
  170. package/dist/cli/services/__tests__/agent-worker-base-helpers.test.js +198 -0
  171. package/dist/cli/services/__tests__/agent-worker-base.test.js +278 -0
  172. package/dist/cli/services/__tests__/auth-service-exports.test.js +41 -0
  173. package/dist/cli/services/__tests__/auth-service.part2.test.js +169 -0
  174. package/dist/cli/services/__tests__/auth-service.test.js +242 -0
  175. package/dist/cli/services/__tests__/background-processes.test.js +282 -0
  176. package/dist/cli/services/__tests__/claude-md-loader.test.js +134 -0
  177. package/dist/cli/services/__tests__/config-store.test.js +247 -0
  178. package/dist/cli/services/__tests__/debug-log.test.js +199 -0
  179. package/dist/cli/services/__tests__/edge-cases-caching.test.js +174 -0
  180. package/dist/cli/services/__tests__/edge-cases-compaction-core.test.js +226 -0
  181. package/dist/cli/services/__tests__/edge-cases-compaction-openai.test.js +152 -0
  182. package/dist/cli/services/__tests__/edge-cases-compaction-shapes.test.js +53 -0
  183. package/dist/cli/services/__tests__/edge-cases-compaction-thinking.test.js +226 -0
  184. package/dist/cli/services/__tests__/edge-cases-compaction.test.js +131 -0
  185. package/dist/cli/services/__tests__/edge-cases-paths.test.js +86 -0
  186. package/dist/cli/services/__tests__/error-logger-messages.test.js +81 -0
  187. package/dist/cli/services/__tests__/error-logger-transport.test.js +119 -0
  188. package/dist/cli/services/__tests__/error-logger.test.js +264 -0
  189. package/dist/cli/services/__tests__/file-history.test.js +136 -0
  190. package/dist/cli/services/__tests__/git-context-cache-reset.test.js +223 -0
  191. package/dist/cli/services/__tests__/git-context.test.js +241 -0
  192. package/dist/cli/services/__tests__/interactive-tools-execute.test.js +166 -0
  193. package/dist/cli/services/__tests__/interactive-tools-plan.test.js +197 -0
  194. package/dist/cli/services/__tests__/interactive-tools.part2.test.js +168 -0
  195. package/dist/cli/services/__tests__/interactive-tools.test.js +179 -0
  196. package/dist/cli/services/__tests__/keybinding-manager.test.js +205 -0
  197. package/dist/cli/services/__tests__/local-tools-dispatch.test.js +404 -0
  198. package/dist/cli/services/__tests__/local-tools.test.js +238 -0
  199. package/dist/cli/services/__tests__/lsp-manager.test.js +364 -0
  200. package/dist/cli/services/__tests__/mcp-client-connect-disconnect.test.js +310 -0
  201. package/dist/cli/services/__tests__/mcp-client.test.js +93 -0
  202. package/dist/cli/services/__tests__/memory-manager.test.js +154 -0
  203. package/dist/cli/services/__tests__/model-manager-utils.test.js +154 -0
  204. package/dist/cli/services/__tests__/model-manager.test.js +175 -0
  205. package/dist/cli/services/__tests__/permission-modes.test.js +222 -0
  206. package/dist/cli/services/__tests__/ripgrep.test.js +328 -0
  207. package/dist/cli/services/__tests__/server-tools-execute.test.js +317 -0
  208. package/dist/cli/services/__tests__/server-tools.test.js +272 -0
  209. package/dist/cli/services/__tests__/session-persistence.test.js +245 -0
  210. package/dist/cli/services/__tests__/subagent-basic.test.js +489 -0
  211. package/dist/cli/services/__tests__/subagent-edge.test.js +545 -0
  212. package/dist/cli/services/__tests__/subagent-prompts.test.js +558 -0
  213. package/dist/cli/services/__tests__/subagent-worker-errors.test.js +255 -0
  214. package/dist/cli/services/__tests__/subagent-worker.test.js +242 -0
  215. package/dist/cli/services/__tests__/system-prompt.test.js +210 -0
  216. package/dist/cli/services/__tests__/team-lead-comms-messaging.test.js +250 -0
  217. package/dist/cli/services/__tests__/team-lead-comms-result.test.js +232 -0
  218. package/dist/cli/services/__tests__/team-lead-comms-stop.test.js +344 -0
  219. package/dist/cli/services/__tests__/team-lead-comms.test.js +285 -0
  220. package/dist/cli/services/__tests__/team-lead-create.test.js +327 -0
  221. package/dist/cli/services/__tests__/team-lead-run.test.js +318 -0
  222. package/dist/cli/services/__tests__/team-lead-stop.test.js +199 -0
  223. package/dist/cli/services/__tests__/team-state-comms.test.js +240 -0
  224. package/dist/cli/services/__tests__/team-state-core.test.js +230 -0
  225. package/dist/cli/services/__tests__/team-state-tasks-complete-fail-available.test.js +224 -0
  226. package/dist/cli/services/__tests__/team-state-tasks.test.js +184 -0
  227. package/dist/cli/services/__tests__/telemetry-ai-metadata.test.js +116 -0
  228. package/dist/cli/services/__tests__/telemetry.part2.test.js +195 -0
  229. package/dist/cli/services/__tests__/telemetry.test.js +176 -0
  230. package/dist/cli/services/agent-event-types.d.ts +148 -0
  231. package/dist/cli/services/agent-event-types.js +2 -0
  232. package/dist/cli/services/agent-event-types.js.map +1 -0
  233. package/dist/cli/services/agent-loop-iteration.d.ts +13 -0
  234. package/dist/cli/services/agent-loop-setup.d.ts +32 -0
  235. package/dist/cli/services/agent-loop-shell-summarize.d.ts +11 -0
  236. package/dist/cli/services/agent-loop-shell-summarize.js +94 -0
  237. package/dist/cli/services/agent-loop-shell-summarize.js.map +1 -0
  238. package/dist/cli/services/agent-loop-tools.d.ts +37 -0
  239. package/dist/cli/services/agent-loop-tools.js +243 -0
  240. package/dist/cli/services/agent-loop-tools.js.map +1 -0
  241. package/dist/cli/services/agent-loop-types.d.ts +52 -0
  242. package/dist/cli/services/agent-loop-types.js +25 -0
  243. package/dist/cli/services/agent-loop-types.js.map +1 -0
  244. package/dist/cli/services/agent-loop.d.ts +2 -2
  245. package/dist/cli/services/agent-loop.js +162 -17
  246. package/dist/cli/services/agent-loop.js.map +1 -1
  247. package/dist/cli/services/agent-worker-base-api.d.ts +19 -0
  248. package/dist/cli/services/agent-worker-base-helpers.d.ts +27 -0
  249. package/dist/cli/services/agent-worker-base-tools.d.ts +16 -0
  250. package/dist/cli/services/agent-worker-base-types.d.ts +81 -0
  251. package/dist/cli/services/agent-worker-base.js +1 -1
  252. package/dist/cli/services/agent-worker-base.js.map +1 -1
  253. package/dist/cli/services/auth-service.js +19 -19
  254. package/dist/cli/services/auth-service.js.map +1 -1
  255. package/dist/cli/services/background-agents.d.ts +26 -0
  256. package/dist/cli/services/background-processes-ops.d.ts +24 -0
  257. package/dist/cli/services/background-processes.d.ts +2 -1
  258. package/dist/cli/services/background-processes.js +7 -3
  259. package/dist/cli/services/background-processes.js.map +1 -1
  260. package/dist/cli/services/background-tool-defs.d.ts +50 -0
  261. package/dist/cli/services/cli-agent-loop.d.ts +41 -0
  262. package/dist/cli/services/cli-agent-loop.js +104 -0
  263. package/dist/cli/services/cli-agent-loop.js.map +1 -0
  264. package/dist/cli/services/config-modules-model.test.js +133 -0
  265. package/dist/cli/services/config-modules-permission.test.js +85 -0
  266. package/dist/cli/services/config-modules-permissions.test.js +85 -0
  267. package/dist/cli/services/config-modules-session.test.js +297 -0
  268. package/dist/cli/services/config-store.d.ts +5 -0
  269. package/dist/cli/services/config-store.js +90 -5
  270. package/dist/cli/services/config-store.js.map +1 -1
  271. package/dist/cli/services/error-logger-internals.d.ts +25 -0
  272. package/dist/cli/services/error-logger-internals.js +111 -0
  273. package/dist/cli/services/error-logger-internals.js.map +1 -0
  274. package/dist/cli/services/format-server-response-columns.test.js +265 -0
  275. package/dist/cli/services/format-server-response-fallback.test.js +65 -0
  276. package/dist/cli/services/format-server-response-formatters.d.ts +18 -0
  277. package/dist/cli/services/format-server-response-formatters.js +195 -0
  278. package/dist/cli/services/format-server-response-formatters.js.map +1 -0
  279. package/dist/cli/services/format-server-response-primitives-basic.test.js +261 -0
  280. package/dist/cli/services/format-server-response-primitives-nested.test.js +188 -0
  281. package/dist/cli/services/format-server-response-primitives.test.js +300 -0
  282. package/dist/cli/services/format-server-response-realworld.test.js +248 -0
  283. package/dist/cli/services/format-server-response-values.test.js +247 -0
  284. package/dist/cli/services/format-server-response.js +5 -3
  285. package/dist/cli/services/format-server-response.js.map +1 -1
  286. package/dist/cli/services/hooks-execute.d.ts +47 -0
  287. package/dist/cli/services/hooks-execute.js +181 -0
  288. package/dist/cli/services/hooks-execute.js.map +1 -0
  289. package/dist/cli/services/hooks-runners.test.js +184 -0
  290. package/dist/cli/services/hooks.glob-load.test.js +233 -0
  291. package/dist/cli/services/hooks.run-hooks.test.js +184 -0
  292. package/dist/cli/services/hooks.test.js +233 -0
  293. package/dist/cli/services/interactive-tool-defs.d.ts +80 -0
  294. package/dist/cli/services/interactive-tools.d.ts +5 -2
  295. package/dist/cli/services/interactive-tools.js +47 -33
  296. package/dist/cli/services/interactive-tools.js.map +1 -1
  297. package/dist/cli/services/keybinding-manager.d.ts +2 -0
  298. package/dist/cli/services/keybinding-manager.js +5 -0
  299. package/dist/cli/services/keybinding-manager.js.map +1 -1
  300. package/dist/cli/services/local-tools-agent-defs-tasks.d.ts +6 -0
  301. package/dist/cli/services/local-tools-agent-defs-tasks.js +245 -0
  302. package/dist/cli/services/local-tools-agent-defs-tasks.js.map +1 -0
  303. package/dist/cli/services/local-tools-agent-defs-utils.d.ts +6 -0
  304. package/dist/cli/services/local-tools-agent-defs-utils.js +198 -0
  305. package/dist/cli/services/local-tools-agent-defs-utils.js.map +1 -0
  306. package/dist/cli/services/local-tools-agent-defs.d.ts +10 -0
  307. package/dist/cli/services/local-tools-agent-defs.js +13 -0
  308. package/dist/cli/services/local-tools-agent-defs.js.map +1 -0
  309. package/dist/cli/services/local-tools-definitions.d.ts +6 -0
  310. package/dist/cli/services/local-tools-files.test.js +256 -0
  311. package/dist/cli/services/local-tools-read-many.d.ts +6 -0
  312. package/dist/cli/services/local-tools.js +7 -9
  313. package/dist/cli/services/local-tools.js.map +1 -1
  314. package/dist/cli/services/lsp-config.d.ts +13 -0
  315. package/dist/cli/services/lsp-config.js +72 -0
  316. package/dist/cli/services/lsp-config.js.map +1 -0
  317. package/dist/cli/services/lsp-formatters.d.ts +11 -0
  318. package/dist/cli/services/lsp-formatters.js +209 -0
  319. package/dist/cli/services/lsp-formatters.js.map +1 -0
  320. package/dist/cli/services/lsp-protocol.d.ts +9 -0
  321. package/dist/cli/services/lsp-protocol.js +40 -0
  322. package/dist/cli/services/lsp-protocol.js.map +1 -0
  323. package/dist/cli/services/lsp-server-docs.d.ts +8 -0
  324. package/dist/cli/services/lsp-server-docs.js +132 -0
  325. package/dist/cli/services/lsp-server-docs.js.map +1 -0
  326. package/dist/cli/services/lsp-server-documents.d.ts +8 -0
  327. package/dist/cli/services/lsp-server-documents.js +132 -0
  328. package/dist/cli/services/lsp-server-documents.js.map +1 -0
  329. package/dist/cli/services/lsp-server.d.ts +40 -0
  330. package/dist/cli/services/lsp-server.js +270 -0
  331. package/dist/cli/services/lsp-server.js.map +1 -0
  332. package/dist/cli/services/model-router.test.js +245 -0
  333. package/dist/cli/services/permission-modes.js +16 -3
  334. package/dist/cli/services/permission-modes.js.map +1 -1
  335. package/dist/cli/services/project-index.d.ts +41 -0
  336. package/dist/cli/services/project-index.js +286 -0
  337. package/dist/cli/services/project-index.js.map +1 -0
  338. package/dist/cli/services/rewind-rewindTo.test.js +202 -0
  339. package/dist/cli/services/rewind.test.js +175 -0
  340. package/dist/cli/services/sandbox.test.js +198 -0
  341. package/dist/cli/services/server-tools-client.d.ts +46 -0
  342. package/dist/cli/services/server-tools-client.js +211 -0
  343. package/dist/cli/services/server-tools-client.js.map +1 -0
  344. package/dist/cli/services/server-tools-media.d.ts +21 -0
  345. package/dist/cli/services/server-tools-media.js +163 -0
  346. package/dist/cli/services/server-tools-media.js.map +1 -0
  347. package/dist/cli/services/server-tools-preprocess.d.ts +23 -0
  348. package/dist/cli/services/server-tools-preprocess.js +386 -0
  349. package/dist/cli/services/server-tools-preprocess.js.map +1 -0
  350. package/dist/cli/services/server-tools.d.ts +2 -0
  351. package/dist/cli/services/server-tools.js +40 -15
  352. package/dist/cli/services/server-tools.js.map +1 -1
  353. package/dist/cli/services/session-client.d.ts +78 -0
  354. package/dist/cli/services/session-client.js +197 -0
  355. package/dist/cli/services/session-client.js.map +1 -0
  356. package/dist/cli/services/session-persistence.d.ts +3 -0
  357. package/dist/cli/services/session-persistence.js +12 -0
  358. package/dist/cli/services/session-persistence.js.map +1 -1
  359. package/dist/cli/services/subagent-execution.d.ts +12 -0
  360. package/dist/cli/services/subagent-loop-v2.d.ts +36 -0
  361. package/dist/cli/services/subagent-loop-v2.js +238 -0
  362. package/dist/cli/services/subagent-loop-v2.js.map +1 -0
  363. package/dist/cli/services/subagent-tools.d.ts +10 -0
  364. package/dist/cli/services/subagent-tools.js +96 -0
  365. package/dist/cli/services/subagent-tools.js.map +1 -0
  366. package/dist/cli/services/subagent-types.d.ts +57 -0
  367. package/dist/cli/services/subagent-types.js +218 -0
  368. package/dist/cli/services/subagent-types.js.map +1 -0
  369. package/dist/cli/services/subagent.js +3 -2
  370. package/dist/cli/services/subagent.js.map +1 -1
  371. package/dist/cli/services/system-prompt.js +26 -3
  372. package/dist/cli/services/system-prompt.js.map +1 -1
  373. package/dist/cli/services/team-lead-auto.d.ts +11 -0
  374. package/dist/cli/services/team-lead-execution.d.ts +28 -0
  375. package/dist/cli/services/team-lead-types.d.ts +37 -0
  376. package/dist/cli/services/team-lead-types.js +2 -0
  377. package/dist/cli/services/team-lead-types.js.map +1 -0
  378. package/dist/cli/services/team-lead.d.ts +60 -0
  379. package/dist/cli/services/team-lead.js +148 -11
  380. package/dist/cli/services/team-lead.js.map +1 -1
  381. package/dist/cli/services/team-state-members.d.ts +11 -0
  382. package/dist/cli/services/team-state-members.js +185 -0
  383. package/dist/cli/services/team-state-members.js.map +1 -0
  384. package/dist/cli/services/team-state-messaging.d.ts +16 -0
  385. package/dist/cli/services/team-state-messaging.js +90 -0
  386. package/dist/cli/services/team-state-messaging.js.map +1 -0
  387. package/dist/cli/services/team-state-tasks.d.ts +12 -0
  388. package/dist/cli/services/team-state-tasks.js +23 -0
  389. package/dist/cli/services/team-state-tasks.js.map +1 -0
  390. package/dist/cli/services/team-state-types.d.ts +54 -0
  391. package/dist/cli/services/team-state-types.js +129 -0
  392. package/dist/cli/services/team-state-types.js.map +1 -0
  393. package/dist/cli/services/team-state.d.ts +5 -0
  394. package/dist/cli/services/team-state.js +29 -0
  395. package/dist/cli/services/team-state.js.map +1 -1
  396. package/dist/cli/services/teammate-loop.js +557 -0
  397. package/dist/cli/services/teammate-loop.js.map +1 -0
  398. package/dist/cli/services/teammate-prompt.d.ts +2 -0
  399. package/dist/cli/services/teammate-prompt.js +68 -0
  400. package/dist/cli/services/teammate-prompt.js.map +1 -0
  401. package/dist/cli/services/teammate-tools.d.ts +6 -0
  402. package/dist/cli/services/teammate-tools.js +158 -0
  403. package/dist/cli/services/teammate-tools.js.map +1 -0
  404. package/dist/cli/services/teammate-types.d.ts +36 -0
  405. package/dist/cli/services/teammate-types.js +43 -0
  406. package/dist/cli/services/teammate-types.js.map +1 -0
  407. package/dist/cli/services/teammate-worker-helpers.d.ts +71 -0
  408. package/dist/cli/services/teammate-worker-helpers.js +183 -0
  409. package/dist/cli/services/teammate-worker-helpers.js.map +1 -0
  410. package/dist/cli/services/teammate-worker-task-cleanup.d.ts +27 -0
  411. package/dist/cli/services/teammate-worker-task-cleanup.js +91 -0
  412. package/dist/cli/services/teammate-worker-task-cleanup.js.map +1 -0
  413. package/dist/cli/services/teammate-worker-task-loop.d.ts +35 -0
  414. package/dist/cli/services/teammate-worker-task-loop.js +273 -0
  415. package/dist/cli/services/teammate-worker-task-loop.js.map +1 -0
  416. package/dist/cli/services/teammate-worker.d.ts +13 -0
  417. package/dist/cli/services/teammate-worker.js +294 -0
  418. package/dist/cli/services/teammate-worker.js.map +1 -0
  419. package/dist/cli/services/telemetry-spans.d.ts +17 -0
  420. package/dist/cli/services/telemetry-spans.js +172 -0
  421. package/dist/cli/services/telemetry-spans.js.map +1 -0
  422. package/dist/cli/services/tools/__tests__/agent-tools-tasks-teams.test.js +250 -0
  423. package/dist/cli/services/tools/__tests__/agent-tools-teams.test.js +200 -0
  424. package/dist/cli/services/tools/__tests__/agent-tools.test.js +340 -0
  425. package/dist/cli/services/tools/__tests__/file-ops-cache.test.js +152 -0
  426. package/dist/cli/services/tools/__tests__/file-ops-notebook.test.js +249 -0
  427. package/dist/cli/services/tools/__tests__/file-ops-read.test.js +261 -0
  428. package/dist/cli/services/tools/__tests__/file-ops-write.test.js +292 -0
  429. package/dist/cli/services/tools/__tests__/search-tools-rg.test.js +92 -0
  430. package/dist/cli/services/tools/__tests__/search-tools.part2.test.js +174 -0
  431. package/dist/cli/services/tools/__tests__/search-tools.test.js +227 -0
  432. package/dist/cli/services/tools/__tests__/shell-exec-allowed-core.test.js +163 -0
  433. package/dist/cli/services/tools/__tests__/shell-exec-allowed-extended.test.js +220 -0
  434. package/dist/cli/services/tools/__tests__/shell-exec-allowed.part2.test.js +215 -0
  435. package/dist/cli/services/tools/__tests__/shell-exec-allowed.test.js +154 -0
  436. package/dist/cli/services/tools/__tests__/shell-exec-blocked.test.js +132 -0
  437. package/dist/cli/services/tools/__tests__/shell-exec-execution.test.js +245 -0
  438. package/dist/cli/services/tools/__tests__/task-manager-create.test.js +110 -0
  439. package/dist/cli/services/tools/__tests__/task-manager-crud.test.js +339 -0
  440. package/dist/cli/services/tools/__tests__/task-manager-list-get.test.js +343 -0
  441. package/dist/cli/services/tools/__tests__/task-manager-query.test.js +346 -0
  442. package/dist/cli/services/tools/__tests__/task-manager-routing.test.js +58 -0
  443. package/dist/cli/services/tools/__tests__/task-manager-update.test.js +224 -0
  444. package/dist/cli/services/tools/__tests__/task-manager.test.js +159 -0
  445. package/dist/cli/services/tools/__tests__/web-tools-html-search.test.js +227 -0
  446. package/dist/cli/services/tools/__tests__/web-tools.test.js +285 -0
  447. package/dist/cli/services/tools/agent-tools-tasks.d.ts +10 -0
  448. package/dist/cli/services/tools/agent-tools-tasks.js +216 -0
  449. package/dist/cli/services/tools/agent-tools-tasks.js.map +1 -0
  450. package/dist/cli/services/tools/agent-tools-team.d.ts +8 -0
  451. package/dist/cli/services/tools/agent-tools-team.js +101 -0
  452. package/dist/cli/services/tools/agent-tools-team.js.map +1 -0
  453. package/dist/cli/services/tools/agent-tools.js +115 -42
  454. package/dist/cli/services/tools/agent-tools.js.map +1 -1
  455. package/dist/cli/services/tools/file-ops-notebook.d.ts +9 -0
  456. package/dist/cli/services/tools/file-ops-notebook.js +186 -0
  457. package/dist/cli/services/tools/file-ops-notebook.js.map +1 -0
  458. package/dist/cli/services/tools/file-ops-read.d.ts +11 -0
  459. package/dist/cli/services/tools/file-ops-read.js +237 -0
  460. package/dist/cli/services/tools/file-ops-read.js.map +1 -0
  461. package/dist/cli/services/tools/file-ops-write.d.ts +8 -0
  462. package/dist/cli/services/tools/file-ops-write.js +260 -0
  463. package/dist/cli/services/tools/file-ops-write.js.map +1 -0
  464. package/dist/cli/services/tools/file-ops.d.ts +1 -0
  465. package/dist/cli/services/tools/file-ops.js +167 -0
  466. package/dist/cli/services/tools/file-ops.js.map +1 -1
  467. package/dist/cli/services/tools/html-to-text.d.ts +6 -0
  468. package/dist/cli/services/tools/html-to-text.js +118 -0
  469. package/dist/cli/services/tools/html-to-text.js.map +1 -0
  470. package/dist/cli/services/tools/shell-exec.test.js +148 -0
  471. package/dist/cli/services/tools/ssrf-guard.d.ts +6 -0
  472. package/dist/cli/services/tools/ssrf-guard.js +80 -0
  473. package/dist/cli/services/tools/ssrf-guard.js.map +1 -0
  474. package/dist/cli/setup/SetupComponents.d.ts +10 -0
  475. package/dist/cli/setup/SetupComponents.js +144 -0
  476. package/dist/cli/setup/SetupComponents.js.map +1 -0
  477. package/dist/cli/setup/setup-cli-targets.d.ts +9 -0
  478. package/dist/cli/setup/setup-cli-targets.js +49 -0
  479. package/dist/cli/setup/setup-cli-targets.js.map +1 -0
  480. package/dist/cli/shared/InlineErrorBoundary.d.ts +22 -0
  481. package/dist/cli/shared/InlineErrorBoundary.js +35 -0
  482. package/dist/cli/shared/InlineErrorBoundary.js.map +1 -0
  483. package/dist/cli/shared/MatrixIntro.js +2 -1
  484. package/dist/cli/shared/MatrixIntro.js.map +1 -1
  485. package/dist/cli/shared/SharedTick.d.ts +10 -0
  486. package/dist/cli/shared/SpinnerSlot.d.ts +16 -8
  487. package/dist/cli/shared/SpinnerSlot.js +122 -29
  488. package/dist/cli/shared/SpinnerSlot.js.map +1 -1
  489. package/dist/cli/shared/WhaleBanner.js +3 -2
  490. package/dist/cli/shared/WhaleBanner.js.map +1 -1
  491. package/dist/cli/shared/__tests__/markdown.test.js +188 -0
  492. package/dist/cli/shared/format-utils.d.ts +16 -0
  493. package/dist/cli/shared/format-utils.js +121 -0
  494. package/dist/cli/shared/format-utils.js.map +1 -0
  495. package/dist/cli/shared/markdown-chart.d.ts +8 -0
  496. package/dist/cli/shared/markdown-chart.js +92 -0
  497. package/dist/cli/shared/markdown-chart.js.map +1 -0
  498. package/dist/cli/shared/markdown-diff.d.ts +15 -0
  499. package/dist/cli/shared/markdown-diff.js +205 -0
  500. package/dist/cli/shared/markdown-diff.js.map +1 -0
  501. package/dist/cli/shared/markdown-helpers.d.ts +33 -0
  502. package/dist/cli/shared/markdown-helpers.js +129 -0
  503. package/dist/cli/shared/markdown-helpers.js.map +1 -0
  504. package/dist/cli/shared/markdown-table.d.ts +10 -0
  505. package/dist/cli/shared/markdown-table.js +227 -0
  506. package/dist/cli/shared/markdown-table.js.map +1 -0
  507. package/dist/cli/shared/markdown.d.ts +2 -6
  508. package/dist/cli/shared/markdown.js +8 -115
  509. package/dist/cli/shared/markdown.js.map +1 -1
  510. package/dist/cli/shared/useLatestRef.d.ts +11 -0
  511. package/dist/cli/shared/useLatestRef.js +34 -0
  512. package/dist/cli/shared/useLatestRef.js.map +1 -0
  513. package/dist/cli/shared/useSyncState.d.ts +11 -0
  514. package/dist/cli/shared/useSyncState.js +39 -0
  515. package/dist/cli/shared/useSyncState.js.map +1 -0
  516. package/dist/cli/stores/StoreApp.js +3 -1
  517. package/dist/cli/stores/StoreApp.js.map +1 -1
  518. package/dist/index-agent.d.ts +11 -0
  519. package/dist/index-agent.js +83 -0
  520. package/dist/index-agent.js.map +1 -0
  521. package/dist/index-auth.d.ts +22 -0
  522. package/dist/index-auth.js +114 -0
  523. package/dist/index-auth.js.map +1 -0
  524. package/dist/index-handlers.d.ts +25 -0
  525. package/dist/index-handlers.js +164 -0
  526. package/dist/index-handlers.js.map +1 -0
  527. package/dist/index-tools.d.ts +22 -0
  528. package/dist/index-tools.js +115 -0
  529. package/dist/index-tools.js.map +1 -0
  530. package/dist/local-agent/__tests__/connection-disconnect.test.js +201 -0
  531. package/dist/local-agent/__tests__/connection-lifecycle.test.js +289 -0
  532. package/dist/local-agent/__tests__/connection-msghandling.test.js +311 -0
  533. package/dist/local-agent/__tests__/connection-reconnect.test.js +230 -0
  534. package/dist/local-agent/__tests__/connection-toolexec.test.js +253 -0
  535. package/dist/local-agent/__tests__/discovery.test.js +328 -0
  536. package/dist/local-agent/__tests__/executor-background.test.js +219 -0
  537. package/dist/local-agent/__tests__/executor-exec.test.js +221 -0
  538. package/dist/local-agent/__tests__/executor-jobs-sessions.test.js +220 -0
  539. package/dist/local-agent/__tests__/executor-system-info.test.js +133 -0
  540. package/dist/local-agent/__tests__/executor-systeminfo.test.js +109 -0
  541. package/dist/local-agent/__tests__/executor.test.js +235 -0
  542. package/dist/local-agent/__tests__/index.test.js +139 -0
  543. package/dist/local-agent/connection-handlers.d.ts +8 -0
  544. package/dist/local-agent/connection-handlers.js +112 -0
  545. package/dist/local-agent/connection-handlers.js.map +1 -0
  546. package/dist/local-agent/connection-tools.d.ts +8 -0
  547. package/dist/local-agent/connection-tools.js +111 -0
  548. package/dist/local-agent/connection-tools.js.map +1 -0
  549. package/dist/local-agent/executor-jobs.d.ts +12 -0
  550. package/dist/local-agent/executor-jobs.js +143 -0
  551. package/dist/local-agent/executor-jobs.js.map +1 -0
  552. package/dist/local-agent/executor.d.ts +3 -0
  553. package/dist/local-agent/executor.js +2 -2
  554. package/dist/local-agent/executor.js.map +1 -1
  555. package/dist/node/__tests__/cli-channels.test.js +293 -0
  556. package/dist/node/__tests__/cli-config-edge.test.js +154 -0
  557. package/dist/node/__tests__/cli-config.test.js +215 -0
  558. package/dist/node/__tests__/config.test.js +292 -0
  559. package/dist/node/__tests__/runtime-heartbeat.test.js +153 -0
  560. package/dist/node/__tests__/runtime-lifecycle-init.test.js +263 -0
  561. package/dist/node/__tests__/runtime-lifecycle-stats.test.js +180 -0
  562. package/dist/node/__tests__/runtime-lifecycle.test.js +305 -0
  563. package/dist/node/__tests__/runtime-relay.test.js +341 -0
  564. package/dist/node/adapters/__tests__/base.test.js +286 -0
  565. package/dist/node/adapters/__tests__/discord.test.js +284 -0
  566. package/dist/node/adapters/__tests__/email-send.test.js +295 -0
  567. package/dist/node/adapters/__tests__/email.inbound-send.test.js +217 -0
  568. package/dist/node/adapters/__tests__/email.lifecycle.test.js +211 -0
  569. package/dist/node/adapters/__tests__/email.test.js +290 -0
  570. package/dist/node/adapters/__tests__/email.webhook-send.test.js +251 -0
  571. package/dist/node/adapters/__tests__/imessage-filter.test.js +183 -0
  572. package/dist/node/adapters/__tests__/imessage-lifecycle.test.js +215 -0
  573. package/dist/node/adapters/__tests__/imessage-send-restart.test.js +227 -0
  574. package/dist/node/adapters/__tests__/slack.part2.test.js +135 -0
  575. package/dist/node/adapters/__tests__/slack.test.js +241 -0
  576. package/dist/node/adapters/__tests__/sms-extras.test.js +108 -0
  577. package/dist/node/adapters/__tests__/sms-lifecycle.test.js +203 -0
  578. package/dist/node/adapters/__tests__/sms-messaging.test.js +266 -0
  579. package/dist/node/adapters/__tests__/sms.part2.test.js +174 -0
  580. package/dist/node/adapters/__tests__/sms.test.js +253 -0
  581. package/dist/node/adapters/__tests__/telegram-polling.test.js +256 -0
  582. package/dist/node/adapters/__tests__/telegram-send.test.js +166 -0
  583. package/dist/node/adapters/__tests__/webchat-inbound.test.js +188 -0
  584. package/dist/node/adapters/__tests__/webchat-outbound.test.js +178 -0
  585. package/dist/node/adapters/__tests__/whatsapp-inbound.test.js +200 -0
  586. package/dist/node/adapters/__tests__/whatsapp-send.test.js +212 -0
  587. package/dist/node/adapters/__tests__/whatsapp.test.js +280 -0
  588. package/dist/node/adapters/discord-gateway.d.ts +42 -0
  589. package/dist/node/adapters/discord-gateway.js +169 -0
  590. package/dist/node/adapters/discord-gateway.js.map +1 -0
  591. package/dist/node/adapters/imessage.d.ts +11 -0
  592. package/dist/node/adapters/imessage.js +23 -6
  593. package/dist/node/adapters/imessage.js.map +1 -1
  594. package/dist/node/cli-channels.d.ts +6 -0
  595. package/dist/node/cli-channels.js +229 -0
  596. package/dist/node/cli-channels.js.map +1 -0
  597. package/dist/node/cli-node.d.ts +9 -0
  598. package/dist/node/cli-node.js +186 -0
  599. package/dist/node/cli-node.js.map +1 -0
  600. package/dist/node/cli-portal.d.ts +11 -0
  601. package/dist/node/cli-portal.js +503 -0
  602. package/dist/node/cli-portal.js.map +1 -0
  603. package/dist/node/portal/portal-target.d.ts +16 -0
  604. package/dist/node/portal/portal-target.js +102 -0
  605. package/dist/node/portal/portal-target.js.map +1 -0
  606. package/dist/node/portal/protocol-frames.d.ts +33 -0
  607. package/dist/node/portal/protocol-frames.js +170 -0
  608. package/dist/node/portal/protocol-frames.js.map +1 -0
  609. package/dist/node/runtime-network.d.ts +25 -0
  610. package/dist/node/runtime-network.js +226 -0
  611. package/dist/node/runtime-network.js.map +1 -0
  612. package/dist/node/runtime-utils.d.ts +27 -0
  613. package/dist/node/runtime-utils.js +99 -0
  614. package/dist/node/runtime-utils.js.map +1 -0
  615. package/dist/node/runtime.d.ts +1 -0
  616. package/dist/node/runtime.js +71 -1
  617. package/dist/node/runtime.js.map +1 -1
  618. package/dist/node/task-runner.d.ts +33 -0
  619. package/dist/node/task-runner.js +276 -0
  620. package/dist/node/task-runner.js.map +1 -0
  621. package/dist/server/__tests__/gateway-fast-fail.test.js +160 -0
  622. package/dist/server/__tests__/local-agent-gateway.test.js +186 -0
  623. package/dist/server/__tests__/proxy-handlers-delegation.test.js +240 -0
  624. package/dist/server/__tests__/proxy-handlers-validation.test.js +211 -0
  625. package/dist/server/__tests__/proxy-handlers.part2.test.js +240 -0
  626. package/dist/server/__tests__/proxy-handlers.test.js +213 -0
  627. package/dist/server/__tests__/strip-base64-e2e.test.js +303 -0
  628. package/dist/server/__tests__/strip-base64.test.js +256 -0
  629. package/dist/server/__tests__/tool-router-agent-tools.test.js +324 -0
  630. package/dist/server/__tests__/tool-router-execute-core.test.js +357 -0
  631. package/dist/server/__tests__/tool-router-execute-permissions.test.js +332 -0
  632. package/dist/server/__tests__/tool-router-execute.test.js +348 -0
  633. package/dist/server/__tests__/tool-router-load.test.js +432 -0
  634. package/dist/server/__tests__/tool-router-permissions.test.js +359 -0
  635. package/dist/server/__tests__/tool-router-registry-cache.test.js +383 -0
  636. package/dist/server/__tests__/tool-router-registry-handlers.test.js +272 -0
  637. package/dist/server/__tests__/tool-router-registry.test.js +331 -0
  638. package/dist/server/__tests__/validation-inventory.test.js +250 -0
  639. package/dist/server/__tests__/validation-misc.test.js +243 -0
  640. package/dist/server/__tests__/validation-supply-chain.test.js +188 -0
  641. package/dist/server/__tests__/worker.test.js +265 -0
  642. package/dist/server/handlers/__test-utils__/test-db.d.ts +2 -0
  643. package/dist/server/handlers/__test-utils__/test-db.js +14 -1
  644. package/dist/server/handlers/__test-utils__/test-db.js.map +1 -1
  645. package/dist/server/handlers/__tests__/conversation-lock.test.js +117 -0
  646. package/dist/server/handlers/__tests__/e2e/auth-cross-platform-login.e2e.test.js +268 -0
  647. package/dist/server/handlers/__tests__/e2e/auth-cross-platform-tokens.e2e.test.js +264 -0
  648. package/dist/server/handlers/__tests__/e2e/email-pipeline-send.e2e.test.js +214 -0
  649. package/dist/server/handlers/__tests__/e2e/email-pipeline-threads.e2e.test.js +168 -0
  650. package/dist/server/handlers/__tests__/e2e/error-logging-pipeline-dedup.e2e.test.js +229 -0
  651. package/dist/server/handlers/__tests__/e2e/error-logging-pipeline.e2e.test.js +239 -0
  652. package/dist/server/handlers/__tests__/e2e/error-logging-rate-limit.e2e.test.js +150 -0
  653. package/dist/server/handlers/__tests__/e2e/inventory-sync-guards.e2e.test.js +177 -0
  654. package/dist/server/handlers/__tests__/e2e/inventory-sync.e2e.test.js +228 -0
  655. package/dist/server/handlers/__tests__/e2e/inventory-sync.part2.e2e.test.js +188 -0
  656. package/dist/server/handlers/__tests__/e2e/order-lifecycle-fulfillment.e2e.test.js +295 -0
  657. package/dist/server/handlers/__tests__/e2e/order-lifecycle.e2e.test.js +277 -0
  658. package/dist/server/handlers/__tests__/e2e/order-lifecycle.fulfillment.e2e.test.js +307 -0
  659. package/dist/server/handlers/__tests__/e2e/order-lifecycle.setup.e2e.test.js +177 -0
  660. package/dist/server/handlers/__tests__/e2e/storefront-checkout-cart.e2e.test.js +255 -0
  661. package/dist/server/handlers/__tests__/e2e/storefront-checkout-webhook.e2e.test.js +231 -0
  662. package/dist/server/handlers/__tests__/e2e/workflow-execution-failures.e2e.test.js +235 -0
  663. package/dist/server/handlers/__tests__/e2e/workflow-execution.e2e.test.js +294 -0
  664. package/dist/server/handlers/__tests__/e2e/workflow-security.e2e.test.js +311 -0
  665. package/dist/server/handlers/__tests__/e2e/workflow-security.part2.e2e.test.js +267 -0
  666. package/dist/server/handlers/__tests__/workflow-cache.test.js +237 -0
  667. package/dist/server/handlers/analytics-errors-edge.test.js +173 -0
  668. package/dist/server/handlers/analytics.js +88 -1
  669. package/dist/server/handlers/analytics.js.map +1 -1
  670. package/dist/server/handlers/analytics.test.js +280 -0
  671. package/dist/server/handlers/api-docs-examples-ext.d.ts +9 -0
  672. package/dist/server/handlers/api-docs-examples-ext.js +278 -0
  673. package/dist/server/handlers/api-docs-examples-ext.js.map +1 -0
  674. package/dist/server/handlers/api-docs-examples.d.ts +8 -0
  675. package/dist/server/handlers/api-docs-examples.js +221 -0
  676. package/dist/server/handlers/api-docs-examples.js.map +1 -0
  677. package/dist/server/handlers/api-docs-sections-ext.d.ts +2 -0
  678. package/dist/server/handlers/api-docs-sections-ext.js +497 -0
  679. package/dist/server/handlers/api-docs-sections-ext.js.map +1 -0
  680. package/dist/server/handlers/api-docs-sections.d.ts +21 -0
  681. package/dist/server/handlers/api-docs-sections.js +293 -0
  682. package/dist/server/handlers/api-docs-sections.js.map +1 -0
  683. package/dist/server/handlers/api-docs.d.ts +2 -0
  684. package/dist/server/handlers/api-docs.js +177 -0
  685. package/dist/server/handlers/api-docs.js.map +1 -1
  686. package/dist/server/handlers/api-keys.part2.test.js +157 -0
  687. package/dist/server/handlers/api-keys.test.js +161 -0
  688. package/dist/server/handlers/billing-core.d.ts +28 -0
  689. package/dist/server/handlers/billing-core.js +126 -0
  690. package/dist/server/handlers/billing-core.js.map +1 -0
  691. package/dist/server/handlers/billing-routes.d.ts +9 -0
  692. package/dist/server/handlers/billing-routes.js +243 -0
  693. package/dist/server/handlers/billing-routes.js.map +1 -0
  694. package/dist/server/handlers/billing-routes.test.js +123 -0
  695. package/dist/server/handlers/billing.test.js +215 -0
  696. package/dist/server/handlers/browser-actions-errors.test.js +94 -0
  697. package/dist/server/handlers/browser-actions.d.ts +35 -0
  698. package/dist/server/handlers/browser-actions.js +171 -0
  699. package/dist/server/handlers/browser-actions.js.map +1 -0
  700. package/dist/server/handlers/browser-actions.part2.test.js +190 -0
  701. package/dist/server/handlers/browser-actions.test.js +190 -0
  702. package/dist/server/handlers/browser-captcha.d.ts +6 -0
  703. package/dist/server/handlers/browser-captcha.js +172 -0
  704. package/dist/server/handlers/browser-captcha.js.map +1 -0
  705. package/dist/server/handlers/browser-lifecycle.d.ts +9 -0
  706. package/dist/server/handlers/browser-lifecycle.js +142 -0
  707. package/dist/server/handlers/browser-lifecycle.js.map +1 -0
  708. package/dist/server/handlers/browser-validation.test.js +257 -0
  709. package/dist/server/handlers/catalog-advanced.d.ts +9 -0
  710. package/dist/server/handlers/catalog-advanced.js +352 -0
  711. package/dist/server/handlers/catalog-advanced.js.map +1 -0
  712. package/dist/server/handlers/catalog-categories.d.ts +5 -0
  713. package/dist/server/handlers/catalog-categories.js +181 -0
  714. package/dist/server/handlers/catalog-categories.js.map +1 -0
  715. package/dist/server/handlers/catalog-products.d.ts +5 -0
  716. package/dist/server/handlers/catalog-products.js +404 -0
  717. package/dist/server/handlers/catalog-products.js.map +1 -0
  718. package/dist/server/handlers/catalog-schemas.d.ts +5 -0
  719. package/dist/server/handlers/catalog-schemas.js +426 -0
  720. package/dist/server/handlers/catalog-schemas.js.map +1 -0
  721. package/dist/server/handlers/catalog.test.js +297 -0
  722. package/dist/server/handlers/comms-documents-advanced.d.ts +8 -0
  723. package/dist/server/handlers/comms-documents-advanced.js +159 -0
  724. package/dist/server/handlers/comms-documents-advanced.js.map +1 -0
  725. package/dist/server/handlers/comms-documents.d.ts +10 -0
  726. package/dist/server/handlers/comms-documents.js +445 -0
  727. package/dist/server/handlers/comms-documents.js.map +1 -0
  728. package/dist/server/handlers/comms-email.d.ts +10 -0
  729. package/dist/server/handlers/comms-email.js +492 -0
  730. package/dist/server/handlers/comms-email.js.map +1 -0
  731. package/dist/server/handlers/comms-pdf-generation.d.ts +8 -0
  732. package/dist/server/handlers/comms-pdf-generation.js +327 -0
  733. package/dist/server/handlers/comms-pdf-generation.js.map +1 -0
  734. package/dist/server/handlers/comms-pdf-helpers.d.ts +9 -0
  735. package/dist/server/handlers/comms-pdf-helpers.js +126 -0
  736. package/dist/server/handlers/comms-pdf-helpers.js.map +1 -0
  737. package/dist/server/handlers/comms-shared.d.ts +3 -0
  738. package/dist/server/handlers/comms-shared.js +28 -0
  739. package/dist/server/handlers/comms-shared.js.map +1 -0
  740. package/dist/server/handlers/comms.test.js +289 -0
  741. package/dist/server/handlers/creations-actions.d.ts +21 -0
  742. package/dist/server/handlers/creations-actions.js +250 -0
  743. package/dist/server/handlers/creations-actions.js.map +1 -0
  744. package/dist/server/handlers/creations-advanced-collections.test.js +214 -0
  745. package/dist/server/handlers/creations-advanced-generate.test.js +142 -0
  746. package/dist/server/handlers/creations-advanced.test.js +171 -0
  747. package/dist/server/handlers/creations-collections-preview.test.js +214 -0
  748. package/dist/server/handlers/creations-crud.d.ts +35 -0
  749. package/dist/server/handlers/creations-crud.js +248 -0
  750. package/dist/server/handlers/creations-crud.js.map +1 -0
  751. package/dist/server/handlers/creations-crud.test.js +260 -0
  752. package/dist/server/handlers/creations-generate.d.ts +21 -0
  753. package/dist/server/handlers/creations-generate.js +256 -0
  754. package/dist/server/handlers/creations-generate.js.map +1 -0
  755. package/dist/server/handlers/creations-mutations.test.js +197 -0
  756. package/dist/server/handlers/crm-customers-read.d.ts +58 -0
  757. package/dist/server/handlers/crm-customers-read.js +208 -0
  758. package/dist/server/handlers/crm-customers-read.js.map +1 -0
  759. package/dist/server/handlers/crm-customers-write.d.ts +54 -0
  760. package/dist/server/handlers/crm-customers-write.js +414 -0
  761. package/dist/server/handlers/crm-customers-write.js.map +1 -0
  762. package/dist/server/handlers/crm-utils.d.ts +6 -0
  763. package/dist/server/handlers/crm-utils.js +19 -0
  764. package/dist/server/handlers/crm-utils.js.map +1 -0
  765. package/dist/server/handlers/crm.test.js +179 -0
  766. package/dist/server/handlers/discovery-advertise.d.ts +18 -0
  767. package/dist/server/handlers/discovery-advertise.js +101 -0
  768. package/dist/server/handlers/discovery-advertise.js.map +1 -0
  769. package/dist/server/handlers/discovery-advertise.test.js +185 -0
  770. package/dist/server/handlers/discovery-scan.d.ts +19 -0
  771. package/dist/server/handlers/discovery-scan.js +107 -0
  772. package/dist/server/handlers/discovery-scan.js.map +1 -0
  773. package/dist/server/handlers/discovery-scan.test.js +233 -0
  774. package/dist/server/handlers/embeddings-embed-search.test.js +196 -0
  775. package/dist/server/handlers/embeddings-index-delete-stats.test.js +140 -0
  776. package/dist/server/handlers/embeddings-search.test.js +221 -0
  777. package/dist/server/handlers/embeddings.test.js +137 -0
  778. package/dist/server/handlers/enrichment-breach.d.ts +8 -0
  779. package/dist/server/handlers/enrichment-breach.js +266 -0
  780. package/dist/server/handlers/enrichment-breach.js.map +1 -0
  781. package/dist/server/handlers/enrichment-data.d.ts +13 -0
  782. package/dist/server/handlers/enrichment-data.js +145 -0
  783. package/dist/server/handlers/enrichment-data.js.map +1 -0
  784. package/dist/server/handlers/enrichment-enrich.d.ts +6 -0
  785. package/dist/server/handlers/enrichment-enrich.js +235 -0
  786. package/dist/server/handlers/enrichment-enrich.js.map +1 -0
  787. package/dist/server/handlers/enrichment-helpers.d.ts +10 -0
  788. package/dist/server/handlers/enrichment-helpers.js +17 -0
  789. package/dist/server/handlers/enrichment-helpers.js.map +1 -0
  790. package/dist/server/handlers/enrichment-mutations.test.js +240 -0
  791. package/dist/server/handlers/enrichment-queries.test.js +181 -0
  792. package/dist/server/handlers/enrichment-validation.test.js +177 -0
  793. package/dist/server/handlers/enrichment-writes.d.ts +16 -0
  794. package/dist/server/handlers/enrichment-writes.js +226 -0
  795. package/dist/server/handlers/enrichment-writes.js.map +1 -0
  796. package/dist/server/handlers/image-gen-actions.d.ts +18 -0
  797. package/dist/server/handlers/image-gen-actions.js +183 -0
  798. package/dist/server/handlers/image-gen-actions.js.map +1 -0
  799. package/dist/server/handlers/image-gen-providers.d.ts +29 -0
  800. package/dist/server/handlers/image-gen-providers.js +161 -0
  801. package/dist/server/handlers/image-gen-providers.js.map +1 -0
  802. package/dist/server/handlers/image-gen.test.js +205 -0
  803. package/dist/server/handlers/inventory-audit.d.ts +10 -0
  804. package/dist/server/handlers/inventory-audit.js +90 -0
  805. package/dist/server/handlers/inventory-audit.js.map +1 -0
  806. package/dist/server/handlers/inventory-helpers.d.ts +8 -0
  807. package/dist/server/handlers/inventory-helpers.js +19 -0
  808. package/dist/server/handlers/inventory-helpers.js.map +1 -0
  809. package/dist/server/handlers/inventory-query.d.ts +67 -0
  810. package/dist/server/handlers/inventory-query.js +299 -0
  811. package/dist/server/handlers/inventory-query.js.map +1 -0
  812. package/dist/server/handlers/inventory.test.js +380 -0
  813. package/dist/server/handlers/kali-background.test.js +222 -0
  814. package/dist/server/handlers/kali-errors.test.js +92 -0
  815. package/dist/server/handlers/kali-validation.test.js +234 -0
  816. package/dist/server/handlers/llm-providers-actions.test.js +220 -0
  817. package/dist/server/handlers/llm-providers-anthropic.test.js +239 -0
  818. package/dist/server/handlers/llm-providers-clients.d.ts +6 -0
  819. package/dist/server/handlers/llm-providers-clients.js +296 -0
  820. package/dist/server/handlers/llm-providers-clients.js.map +1 -0
  821. package/dist/server/handlers/llm-providers-credentials.d.ts +3 -0
  822. package/dist/server/handlers/llm-providers-credentials.js +109 -0
  823. package/dist/server/handlers/llm-providers-credentials.js.map +1 -0
  824. package/dist/server/handlers/llm-providers-failover.test.js +232 -0
  825. package/dist/server/handlers/llm-providers-models.d.ts +67 -0
  826. package/dist/server/handlers/llm-providers-models.js +213 -0
  827. package/dist/server/handlers/llm-providers-models.js.map +1 -0
  828. package/dist/server/handlers/llm-providers-providers.test.js +300 -0
  829. package/dist/server/handlers/llm-providers-validation.test.js +239 -0
  830. package/dist/server/handlers/local-agent-tools.test.js +224 -0
  831. package/dist/server/handlers/local-agent.test.js +198 -0
  832. package/dist/server/handlers/local-agent.tools-status.test.js +204 -0
  833. package/dist/server/handlers/local-agent.validation-exec.test.js +182 -0
  834. package/dist/server/handlers/media-actions.d.ts +14 -0
  835. package/dist/server/handlers/media-actions.js +398 -0
  836. package/dist/server/handlers/media-actions.js.map +1 -0
  837. package/dist/server/handlers/media-crud.d.ts +9 -0
  838. package/dist/server/handlers/media-crud.js +365 -0
  839. package/dist/server/handlers/media-crud.js.map +1 -0
  840. package/dist/server/handlers/media-upload.d.ts +4 -0
  841. package/dist/server/handlers/media-upload.js +179 -0
  842. package/dist/server/handlers/media-upload.js.map +1 -0
  843. package/dist/server/handlers/media-utils.d.ts +14 -0
  844. package/dist/server/handlers/media-utils.js +33 -0
  845. package/dist/server/handlers/media-utils.js.map +1 -0
  846. package/dist/server/handlers/meta-ads-advanced.d.ts +46 -0
  847. package/dist/server/handlers/meta-ads-advanced.js +222 -0
  848. package/dist/server/handlers/meta-ads-advanced.js.map +1 -0
  849. package/dist/server/handlers/meta-ads-audience-rules.test.js +243 -0
  850. package/dist/server/handlers/meta-ads-audience-targeting.test.js +205 -0
  851. package/dist/server/handlers/meta-ads-audiences-targeting.test.js +383 -0
  852. package/dist/server/handlers/meta-ads-audiences.d.ts +48 -0
  853. package/dist/server/handlers/meta-ads-audiences.js +214 -0
  854. package/dist/server/handlers/meta-ads-audiences.js.map +1 -0
  855. package/dist/server/handlers/meta-ads-crud-ads.test.js +136 -0
  856. package/dist/server/handlers/meta-ads-crud-campaigns.test.js +189 -0
  857. package/dist/server/handlers/meta-ads-crud-create.test.js +303 -0
  858. package/dist/server/handlers/meta-ads-crud-list-update.test.js +259 -0
  859. package/dist/server/handlers/meta-ads-crud-read.d.ts +78 -0
  860. package/dist/server/handlers/meta-ads-crud-read.js +204 -0
  861. package/dist/server/handlers/meta-ads-crud-read.js.map +1 -0
  862. package/dist/server/handlers/meta-ads-crud-write.d.ts +105 -0
  863. package/dist/server/handlers/meta-ads-crud-write.js +390 -0
  864. package/dist/server/handlers/meta-ads-crud-write.js.map +1 -0
  865. package/dist/server/handlers/meta-ads-crud.d.ts +9 -0
  866. package/dist/server/handlers/meta-ads-crud.js +12 -0
  867. package/dist/server/handlers/meta-ads-crud.js.map +1 -0
  868. package/dist/server/handlers/meta-ads-delete-publish-sync.test.js +282 -0
  869. package/dist/server/handlers/meta-ads-graph-api.d.ts +25 -0
  870. package/dist/server/handlers/meta-ads-graph-api.js +155 -0
  871. package/dist/server/handlers/meta-ads-graph-api.js.map +1 -0
  872. package/dist/server/handlers/meta-ads-insights.test.js +80 -0
  873. package/dist/server/handlers/meta-ads-list-get.test.js +237 -0
  874. package/dist/server/handlers/meta-ads-media.d.ts +16 -0
  875. package/dist/server/handlers/meta-ads-media.js +205 -0
  876. package/dist/server/handlers/meta-ads-media.js.map +1 -0
  877. package/dist/server/handlers/meta-ads-pixels-rules.d.ts +127 -0
  878. package/dist/server/handlers/meta-ads-pixels-rules.js +463 -0
  879. package/dist/server/handlers/meta-ads-pixels-rules.js.map +1 -0
  880. package/dist/server/handlers/meta-ads-publish-ad.d.ts +11 -0
  881. package/dist/server/handlers/meta-ads-publish-ad.js +229 -0
  882. package/dist/server/handlers/meta-ads-publish-ad.js.map +1 -0
  883. package/dist/server/handlers/meta-ads-publish-delete.test.js +254 -0
  884. package/dist/server/handlers/meta-ads-publish-helpers.js +117 -0
  885. package/dist/server/handlers/meta-ads-publish-helpers.js.map +1 -0
  886. package/dist/server/handlers/meta-ads-publish-sync.test.js +205 -0
  887. package/dist/server/handlers/meta-ads-publish.d.ts +14 -0
  888. package/dist/server/handlers/meta-ads-publish.js +194 -0
  889. package/dist/server/handlers/meta-ads-publish.js.map +1 -0
  890. package/dist/server/handlers/meta-ads-publish.test.js +254 -0
  891. package/dist/server/handlers/meta-ads-sync-insights.test.js +184 -0
  892. package/dist/server/handlers/meta-ads-targeting.d.ts +27 -0
  893. package/dist/server/handlers/meta-ads-targeting.js +323 -0
  894. package/dist/server/handlers/meta-ads-targeting.js.map +1 -0
  895. package/dist/server/handlers/meta-ads-types.d.ts +49 -0
  896. package/dist/server/handlers/meta-ads-types.js +59 -0
  897. package/dist/server/handlers/meta-ads-types.js.map +1 -0
  898. package/dist/server/handlers/meta-ads-update.test.js +117 -0
  899. package/dist/server/handlers/meta-ads.d.ts +25 -0
  900. package/dist/server/handlers/meta-ads.js +392 -3
  901. package/dist/server/handlers/meta-ads.js.map +1 -1
  902. package/dist/server/handlers/nodes-channels.test.js +413 -0
  903. package/dist/server/handlers/nodes-events.test.js +131 -0
  904. package/dist/server/handlers/nodes-handlers-channels-messages.d.ts +20 -0
  905. package/dist/server/handlers/nodes-handlers-channels-messages.js +314 -0
  906. package/dist/server/handlers/nodes-handlers-channels-messages.js.map +1 -0
  907. package/dist/server/handlers/nodes-handlers-channels.d.ts +19 -0
  908. package/dist/server/handlers/nodes-handlers-channels.js +225 -0
  909. package/dist/server/handlers/nodes-handlers-channels.js.map +1 -0
  910. package/dist/server/handlers/nodes-handlers-mgmt.d.ts +33 -0
  911. package/dist/server/handlers/nodes-handlers-mgmt.js +418 -0
  912. package/dist/server/handlers/nodes-handlers-mgmt.js.map +1 -0
  913. package/dist/server/handlers/nodes-list-delete.test.js +171 -0
  914. package/dist/server/handlers/nodes-messages-delivery.test.js +208 -0
  915. package/dist/server/handlers/nodes-messages.test.js +211 -0
  916. package/dist/server/handlers/nodes-register.test.js +277 -0
  917. package/dist/server/handlers/nodes-routes-channels.d.ts +9 -0
  918. package/dist/server/handlers/nodes-routes-channels.js +217 -0
  919. package/dist/server/handlers/nodes-routes-channels.js.map +1 -0
  920. package/dist/server/handlers/nodes-routes-crud.d.ts +9 -0
  921. package/dist/server/handlers/nodes-routes-crud.js +290 -0
  922. package/dist/server/handlers/nodes-routes-crud.js.map +1 -0
  923. package/dist/server/handlers/nodes-routes-delivery.d.ts +9 -0
  924. package/dist/server/handlers/nodes-routes-delivery.js +226 -0
  925. package/dist/server/handlers/nodes-routes-delivery.js.map +1 -0
  926. package/dist/server/handlers/nodes-routes-messages.d.ts +9 -0
  927. package/dist/server/handlers/nodes-routes-messages.js +218 -0
  928. package/dist/server/handlers/nodes-routes-messages.js.map +1 -0
  929. package/dist/server/handlers/nodes-routes-register.d.ts +9 -0
  930. package/dist/server/handlers/nodes-routes-register.js +239 -0
  931. package/dist/server/handlers/nodes-routes-register.js.map +1 -0
  932. package/dist/server/handlers/nodes-types.d.ts +82 -0
  933. package/dist/server/handlers/nodes-types.js +220 -0
  934. package/dist/server/handlers/nodes-types.js.map +1 -0
  935. package/dist/server/handlers/nodes-utils.d.ts +70 -0
  936. package/dist/server/handlers/nodes-utils.js +214 -0
  937. package/dist/server/handlers/nodes-utils.js.map +1 -0
  938. package/dist/server/handlers/nodes.test.js +353 -0
  939. package/dist/server/handlers/operations.test.js +136 -0
  940. package/dist/server/handlers/platform-telemetry.d.ts +10 -0
  941. package/dist/server/handlers/platform-telemetry.js +372 -0
  942. package/dist/server/handlers/platform-telemetry.js.map +1 -0
  943. package/dist/server/handlers/platform-telemetry.test.js +200 -0
  944. package/dist/server/handlers/platform-websearch.test.js +160 -0
  945. package/dist/server/handlers/sessions-handlers.d.ts +23 -0
  946. package/dist/server/handlers/sessions-handlers.js +374 -0
  947. package/dist/server/handlers/sessions-handlers.js.map +1 -0
  948. package/dist/server/handlers/storefront-cart.d.ts +31 -0
  949. package/dist/server/handlers/storefront-cart.js +381 -0
  950. package/dist/server/handlers/storefront-cart.js.map +1 -0
  951. package/dist/server/handlers/storefront.test.js +329 -0
  952. package/dist/server/handlers/supply-chain-transfers.d.ts +10 -0
  953. package/dist/server/handlers/supply-chain-transfers.js +214 -0
  954. package/dist/server/handlers/supply-chain-transfers.js.map +1 -0
  955. package/dist/server/handlers/supply-chain-utils.d.ts +2 -0
  956. package/dist/server/handlers/supply-chain-utils.js +21 -0
  957. package/dist/server/handlers/supply-chain-utils.js.map +1 -0
  958. package/dist/server/handlers/supply-chain.test.js +347 -0
  959. package/dist/server/handlers/transcription.test.js +118 -0
  960. package/dist/server/handlers/video-gen-providers.d.ts +30 -0
  961. package/dist/server/handlers/video-gen-providers.js +205 -0
  962. package/dist/server/handlers/video-gen-providers.js.map +1 -0
  963. package/dist/server/handlers/video-gen-sora.d.ts +5 -0
  964. package/dist/server/handlers/video-gen-sora.js +87 -0
  965. package/dist/server/handlers/video-gen-sora.js.map +1 -0
  966. package/dist/server/handlers/video-gen-veo.js +114 -0
  967. package/dist/server/handlers/video-gen-veo.js.map +1 -0
  968. package/dist/server/handlers/video-gen.test.js +146 -0
  969. package/dist/server/handlers/voice-handlers-audio.d.ts +9 -0
  970. package/dist/server/handlers/voice-handlers-audio.js +229 -0
  971. package/dist/server/handlers/voice-handlers-audio.js.map +1 -0
  972. package/dist/server/handlers/voice-handlers-music.d.ts +5 -0
  973. package/dist/server/handlers/voice-handlers-music.js +124 -0
  974. package/dist/server/handlers/voice-handlers-music.js.map +1 -0
  975. package/dist/server/handlers/voice-handlers-pvc.d.ts +8 -0
  976. package/dist/server/handlers/voice-handlers-pvc.js +345 -0
  977. package/dist/server/handlers/voice-handlers-pvc.js.map +1 -0
  978. package/dist/server/handlers/voice-handlers-tts.d.ts +5 -0
  979. package/dist/server/handlers/voice-handlers-tts.js +142 -0
  980. package/dist/server/handlers/voice-handlers-tts.js.map +1 -0
  981. package/dist/server/handlers/voice-handlers-voices.d.ts +8 -0
  982. package/dist/server/handlers/voice-handlers-voices.js +321 -0
  983. package/dist/server/handlers/voice-handlers-voices.js.map +1 -0
  984. package/dist/server/handlers/voice-utils.d.ts +32 -0
  985. package/dist/server/handlers/voice-utils.js +281 -0
  986. package/dist/server/handlers/voice-utils.js.map +1 -0
  987. package/dist/server/handlers/voice.test.js +153 -0
  988. package/dist/server/handlers/workflow-crud-advanced.d.ts +8 -0
  989. package/dist/server/handlers/workflow-crud-advanced.js +275 -0
  990. package/dist/server/handlers/workflow-crud-advanced.js.map +1 -0
  991. package/dist/server/handlers/workflow-crud-core.d.ts +8 -0
  992. package/dist/server/handlers/workflow-crud-core.js +286 -0
  993. package/dist/server/handlers/workflow-crud-core.js.map +1 -0
  994. package/dist/server/handlers/workflow-crud-events.d.ts +8 -0
  995. package/dist/server/handlers/workflow-crud-events.js +483 -0
  996. package/dist/server/handlers/workflow-crud-events.js.map +1 -0
  997. package/dist/server/handlers/workflow-crud-runs-lifecycle.d.ts +8 -0
  998. package/dist/server/handlers/workflow-crud-runs-lifecycle.js +231 -0
  999. package/dist/server/handlers/workflow-crud-runs-lifecycle.js.map +1 -0
  1000. package/dist/server/handlers/workflow-crud-runs-versioning.d.ts +8 -0
  1001. package/dist/server/handlers/workflow-crud-runs-versioning.js +319 -0
  1002. package/dist/server/handlers/workflow-crud-runs-versioning.js.map +1 -0
  1003. package/dist/server/handlers/workflow-crud-runs.d.ts +8 -0
  1004. package/dist/server/handlers/workflow-crud-runs.js +18 -0
  1005. package/dist/server/handlers/workflow-crud-runs.js.map +1 -0
  1006. package/dist/server/handlers/workflow-steps-advancement.d.ts +13 -0
  1007. package/dist/server/handlers/workflow-steps-advancement.js +197 -0
  1008. package/dist/server/handlers/workflow-steps-advancement.js.map +1 -0
  1009. package/dist/server/handlers/workflow-steps-circuit-breaker.d.ts +7 -0
  1010. package/dist/server/handlers/workflow-steps-circuit-breaker.js +131 -0
  1011. package/dist/server/handlers/workflow-steps-circuit-breaker.js.map +1 -0
  1012. package/dist/server/handlers/workflow-steps-completion.d.ts +5 -0
  1013. package/dist/server/handlers/workflow-steps-completion.js +254 -0
  1014. package/dist/server/handlers/workflow-steps-completion.js.map +1 -0
  1015. package/dist/server/handlers/workflow-steps-cron.d.ts +4 -0
  1016. package/dist/server/handlers/workflow-steps-cron.js +259 -0
  1017. package/dist/server/handlers/workflow-steps-cron.js.map +1 -0
  1018. package/dist/server/handlers/workflow-steps-engine-execute.d.ts +3 -0
  1019. package/dist/server/handlers/workflow-steps-engine-execute.js +388 -0
  1020. package/dist/server/handlers/workflow-steps-engine-execute.js.map +1 -0
  1021. package/dist/server/handlers/workflow-steps-engine-inline.d.ts +2 -0
  1022. package/dist/server/handlers/workflow-steps-engine-inline.js +91 -0
  1023. package/dist/server/handlers/workflow-steps-engine-inline.js.map +1 -0
  1024. package/dist/server/handlers/workflow-steps-engine-persist.d.ts +5 -0
  1025. package/dist/server/handlers/workflow-steps-engine-persist.js +192 -0
  1026. package/dist/server/handlers/workflow-steps-engine-persist.js.map +1 -0
  1027. package/dist/server/handlers/workflow-steps-engine-process.d.ts +7 -0
  1028. package/dist/server/handlers/workflow-steps-engine-process.js +290 -0
  1029. package/dist/server/handlers/workflow-steps-engine-process.js.map +1 -0
  1030. package/dist/server/handlers/workflow-steps-engine.d.ts +3 -0
  1031. package/dist/server/handlers/workflow-steps-engine.js +10 -0
  1032. package/dist/server/handlers/workflow-steps-engine.js.map +1 -0
  1033. package/dist/server/handlers/workflow-steps-executors-llm.d.ts +7 -0
  1034. package/dist/server/handlers/workflow-steps-executors-llm.js +265 -0
  1035. package/dist/server/handlers/workflow-steps-executors-llm.js.map +1 -0
  1036. package/dist/server/handlers/workflow-steps-executors.d.ts +9 -0
  1037. package/dist/server/handlers/workflow-steps-executors.js +188 -0
  1038. package/dist/server/handlers/workflow-steps-executors.js.map +1 -0
  1039. package/dist/server/handlers/workflow-steps-maintenance.d.ts +4 -0
  1040. package/dist/server/handlers/workflow-steps-maintenance.js +256 -0
  1041. package/dist/server/handlers/workflow-steps-maintenance.js.map +1 -0
  1042. package/dist/server/handlers/workflow-steps-types.d.ts +84 -0
  1043. package/dist/server/handlers/workflow-steps-types.js +179 -0
  1044. package/dist/server/handlers/workflow-steps-types.js.map +1 -0
  1045. package/dist/server/handlers/workflow-steps-webhook.d.ts +5 -0
  1046. package/dist/server/handlers/workflow-steps-webhook.js +179 -0
  1047. package/dist/server/handlers/workflow-steps-webhook.js.map +1 -0
  1048. package/dist/server/handlers/workflow-steps.test.js +330 -0
  1049. package/dist/server/handlers/workflows-extras.test.js +65 -0
  1050. package/dist/server/handlers/workflows.part2.test.js +170 -0
  1051. package/dist/server/handlers/workflows.test.js +281 -0
  1052. package/dist/server/index.js +81 -1720
  1053. package/dist/server/index.js.map +1 -1
  1054. package/dist/server/lib/__tests__/batch-client-conversion-jsonl.test.js +171 -0
  1055. package/dist/server/lib/__tests__/batch-client-polling.test.js +292 -0
  1056. package/dist/server/lib/__tests__/batch-client-queue.test.js +270 -0
  1057. package/dist/server/lib/__tests__/clickhouse-buffer.test.js +236 -0
  1058. package/dist/server/lib/__tests__/code-worker-edge-cases.test.js +118 -0
  1059. package/dist/server/lib/__tests__/code-worker-pool-execute.test.js +193 -0
  1060. package/dist/server/lib/__tests__/code-worker-pool-execution.test.js +165 -0
  1061. package/dist/server/lib/__tests__/code-worker-pool-init.test.js +131 -0
  1062. package/dist/server/lib/__tests__/code-worker-pool.test.js +194 -0
  1063. package/dist/server/lib/__tests__/code-worker-sandbox-ops.test.js +123 -0
  1064. package/dist/server/lib/__tests__/code-worker-sandbox.test.js +217 -0
  1065. package/dist/server/lib/__tests__/code-worker.test.js +179 -0
  1066. package/dist/server/lib/__tests__/compaction-service-generate.test.js +229 -0
  1067. package/dist/server/lib/__tests__/compaction-service.test.js +319 -0
  1068. package/dist/server/lib/__tests__/otel.test.js +146 -0
  1069. package/dist/server/lib/__tests__/prompt-sanitizer-validation.test.js +165 -0
  1070. package/dist/server/lib/__tests__/prompt-sanitizer.sanitize.test.js +343 -0
  1071. package/dist/server/lib/__tests__/prompt-sanitizer.test.js +328 -0
  1072. package/dist/server/lib/__tests__/prompt-sanitizer.validate-tool.test.js +145 -0
  1073. package/dist/server/lib/__tests__/provider-capabilities.test.js +263 -0
  1074. package/dist/server/lib/__tests__/provider-failover-routing.test.js +145 -0
  1075. package/dist/server/lib/__tests__/provider-failover-state.test.js +131 -0
  1076. package/dist/server/lib/__tests__/rate-limiter-budgets.test.js +216 -0
  1077. package/dist/server/lib/__tests__/rate-limiter.budgets-tools.test.js +113 -0
  1078. package/dist/server/lib/__tests__/rate-limiter.check-request.test.js +141 -0
  1079. package/dist/server/lib/__tests__/rate-limiter.stats-lifecycle.test.js +135 -0
  1080. package/dist/server/lib/__tests__/rate-limiter.test.js +207 -0
  1081. package/dist/server/lib/__tests__/server-agent-loop-abort-conditions.test.js +544 -0
  1082. package/dist/server/lib/__tests__/server-agent-loop-abort.part2.test.js +504 -0
  1083. package/dist/server/lib/__tests__/server-agent-loop-abort.test.js +396 -0
  1084. package/dist/server/lib/__tests__/server-agent-loop-compaction.test.js +397 -0
  1085. package/dist/server/lib/__tests__/server-agent-loop-failover.test.js +356 -0
  1086. package/dist/server/lib/__tests__/server-agent-loop-features-caching.test.js +519 -0
  1087. package/dist/server/lib/__tests__/server-agent-loop-features-edges.test.js +512 -0
  1088. package/dist/server/lib/__tests__/server-subagent-bailout.test.js +194 -0
  1089. package/dist/server/lib/__tests__/server-subagent-basics.test.js +348 -0
  1090. package/dist/server/lib/__tests__/server-subagent-errors-abort.test.js +319 -0
  1091. package/dist/server/lib/__tests__/server-subagent-errors-progress.test.js +253 -0
  1092. package/dist/server/lib/__tests__/server-subagent-errors.part2.test.js +253 -0
  1093. package/dist/server/lib/__tests__/server-subagent-errors.test.js +319 -0
  1094. package/dist/server/lib/__tests__/session-checkpoint-load.test.js +275 -0
  1095. package/dist/server/lib/__tests__/session-checkpoint-save.test.js +159 -0
  1096. package/dist/server/lib/__tests__/ssrf-guard.test.js +93 -0
  1097. package/dist/server/lib/__tests__/supabase-client.test.js +111 -0
  1098. package/dist/server/lib/__tests__/template-resolver.test.js +317 -0
  1099. package/dist/server/lib/__tests__/utils-timeout.test.js +49 -0
  1100. package/dist/server/lib/__tests__/utils.test.js +322 -0
  1101. package/dist/server/lib/agent-loop-executor.d.ts +7 -0
  1102. package/dist/server/lib/agent-loop-executor.js +224 -0
  1103. package/dist/server/lib/agent-loop-executor.js.map +1 -0
  1104. package/dist/server/lib/agent-loop-turn.d.ts +53 -0
  1105. package/dist/server/lib/agent-loop-turn.js +166 -0
  1106. package/dist/server/lib/agent-loop-turn.js.map +1 -0
  1107. package/dist/server/lib/agent-loop-types.d.ts +118 -0
  1108. package/dist/server/lib/agent-loop-types.js +53 -0
  1109. package/dist/server/lib/agent-loop-types.js.map +1 -0
  1110. package/dist/server/lib/batch-client-anthropic.d.ts +10 -0
  1111. package/dist/server/lib/batch-client-anthropic.js +144 -0
  1112. package/dist/server/lib/batch-client-anthropic.js.map +1 -0
  1113. package/dist/server/lib/batch-client-openai.d.ts +10 -0
  1114. package/dist/server/lib/batch-client-openai.js +172 -0
  1115. package/dist/server/lib/batch-client-openai.js.map +1 -0
  1116. package/dist/server/lib/batch-client-types.d.ts +54 -0
  1117. package/dist/server/lib/batch-client-types.js +27 -0
  1118. package/dist/server/lib/batch-client-types.js.map +1 -0
  1119. package/dist/server/lib/coa-renderer-components.d.ts +15 -0
  1120. package/dist/server/lib/coa-renderer-components.js +361 -0
  1121. package/dist/server/lib/coa-renderer-components.js.map +1 -0
  1122. package/dist/server/lib/coa-renderer-pages.d.ts +15 -0
  1123. package/dist/server/lib/coa-renderer-pages.js +467 -0
  1124. package/dist/server/lib/coa-renderer-pages.js.map +1 -0
  1125. package/dist/server/lib/coa-renderer-styles.d.ts +525 -0
  1126. package/dist/server/lib/coa-renderer-styles.js +540 -0
  1127. package/dist/server/lib/coa-renderer-styles.js.map +1 -0
  1128. package/dist/server/lib/coa-renderer-tokens.d.ts +107 -0
  1129. package/dist/server/lib/coa-renderer-tokens.js +46 -0
  1130. package/dist/server/lib/coa-renderer-tokens.js.map +1 -0
  1131. package/dist/server/lib/pdf-renderer-calc.d.ts +7 -0
  1132. package/dist/server/lib/pdf-renderer-calc.js +272 -0
  1133. package/dist/server/lib/pdf-renderer-calc.js.map +1 -0
  1134. package/dist/server/lib/pdf-renderer-generation.d.ts +73 -0
  1135. package/dist/server/lib/pdf-renderer-generation.js +298 -0
  1136. package/dist/server/lib/pdf-renderer-generation.js.map +1 -0
  1137. package/dist/server/lib/pdf-renderer-layout.d.ts +2 -0
  1138. package/dist/server/lib/pdf-renderer-layout.js +144 -0
  1139. package/dist/server/lib/pdf-renderer-layout.js.map +1 -0
  1140. package/dist/server/lib/pdf-renderer-validation.d.ts +14 -0
  1141. package/dist/server/lib/pdf-renderer-validation.js +220 -0
  1142. package/dist/server/lib/pdf-renderer-validation.js.map +1 -0
  1143. package/dist/server/lib/react-pdf-layout-elements.d.ts +8 -0
  1144. package/dist/server/lib/react-pdf-layout-elements.js +366 -0
  1145. package/dist/server/lib/react-pdf-layout-elements.js.map +1 -0
  1146. package/dist/server/lib/react-pdf-layout-labels.d.ts +38 -0
  1147. package/dist/server/lib/react-pdf-layout-labels.js +217 -0
  1148. package/dist/server/lib/react-pdf-layout-labels.js.map +1 -0
  1149. package/dist/server/lib/server-agent-loop-init.d.ts +28 -0
  1150. package/dist/server/lib/server-agent-loop-init.js +138 -0
  1151. package/dist/server/lib/server-agent-loop-init.js.map +1 -0
  1152. package/dist/server/lib/server-agent-loop-v2.d.ts +110 -0
  1153. package/dist/server/lib/server-agent-loop-v2.js +340 -0
  1154. package/dist/server/lib/server-agent-loop-v2.js.map +1 -0
  1155. package/dist/server/lib/server-agent-loop.js +2 -1
  1156. package/dist/server/lib/server-agent-loop.js.map +1 -1
  1157. package/dist/server/lib/server-subagent-loop.d.ts +3 -0
  1158. package/dist/server/lib/server-subagent-loop.js +267 -0
  1159. package/dist/server/lib/server-subagent-loop.js.map +1 -0
  1160. package/dist/server/lib/session-types.d.ts +106 -0
  1161. package/dist/server/lib/session-types.js +2 -0
  1162. package/dist/server/lib/session-types.js.map +1 -0
  1163. package/dist/server/local-agent-gateway-api.d.ts +34 -0
  1164. package/dist/server/local-agent-gateway-api.js +156 -0
  1165. package/dist/server/local-agent-gateway-api.js.map +1 -0
  1166. package/dist/server/local-agent-gateway-handler.d.ts +3 -0
  1167. package/dist/server/local-agent-gateway-handler.js +292 -0
  1168. package/dist/server/local-agent-gateway-handler.js.map +1 -0
  1169. package/dist/server/local-agent-gateway-init.d.ts +21 -0
  1170. package/dist/server/local-agent-gateway-init.js +143 -0
  1171. package/dist/server/local-agent-gateway-init.js.map +1 -0
  1172. package/dist/server/local-agent-gateway-messages.d.ts +12 -0
  1173. package/dist/server/local-agent-gateway-messages.js +108 -0
  1174. package/dist/server/local-agent-gateway-messages.js.map +1 -0
  1175. package/dist/server/local-agent-gateway-stats.d.ts +53 -0
  1176. package/dist/server/local-agent-gateway-stats.js +129 -0
  1177. package/dist/server/local-agent-gateway-stats.js.map +1 -0
  1178. package/dist/server/local-agent-gateway-types.d.ts +94 -0
  1179. package/dist/server/local-agent-gateway-types.js +78 -0
  1180. package/dist/server/local-agent-gateway-types.js.map +1 -0
  1181. package/dist/server/local-agent-gateway.d.ts +6 -0
  1182. package/dist/server/local-agent-gateway.js +40 -0
  1183. package/dist/server/local-agent-gateway.js.map +1 -1
  1184. package/dist/server/providers/__tests__/anthropic-adapter.test.js +228 -0
  1185. package/dist/server/providers/__tests__/anthropic-betas-toolchoice.test.js +257 -0
  1186. package/dist/server/providers/__tests__/anthropic-errors.test.js +262 -0
  1187. package/dist/server/providers/__tests__/anthropic-stream-core.test.js +275 -0
  1188. package/dist/server/providers/__tests__/anthropic-streaming-betas.test.js +247 -0
  1189. package/dist/server/providers/__tests__/anthropic-streaming-core.test.js +275 -0
  1190. package/dist/server/providers/__tests__/bedrock-config.test.js +177 -0
  1191. package/dist/server/providers/__tests__/bedrock-stream-behavior-streaming.test.js +272 -0
  1192. package/dist/server/providers/__tests__/bedrock-stream-behavior-toolchoice.test.js +214 -0
  1193. package/dist/server/providers/__tests__/bedrock-stream-behavior.part2.test.js +165 -0
  1194. package/dist/server/providers/__tests__/bedrock-stream-behavior.test.js +309 -0
  1195. package/dist/server/providers/__tests__/bedrock-stream-body-credentials.test.js +170 -0
  1196. package/dist/server/providers/__tests__/bedrock-stream-body-extras.test.js +183 -0
  1197. package/dist/server/providers/__tests__/bedrock-stream-body-request.test.js +305 -0
  1198. package/dist/server/providers/__tests__/bedrock-stream-body.part2.test.js +305 -0
  1199. package/dist/server/providers/__tests__/bedrock-stream-body.test.js +175 -0
  1200. package/dist/server/providers/__tests__/bedrock-stream-errors.test.js +165 -0
  1201. package/dist/server/providers/__tests__/gemini-config-methods.test.js +182 -0
  1202. package/dist/server/providers/__tests__/gemini-config-streaming.test.js +257 -0
  1203. package/dist/server/providers/__tests__/gemini-conversion-messages.test.js +247 -0
  1204. package/dist/server/providers/__tests__/gemini-conversion-schema.test.js +365 -0
  1205. package/dist/server/providers/__tests__/gemini-tools-choice.test.js +221 -0
  1206. package/dist/server/providers/__tests__/gemini-tools-fn.test.js +252 -0
  1207. package/dist/server/providers/__tests__/openai-config.test.js +194 -0
  1208. package/dist/server/providers/__tests__/openai-conversion.test.js +276 -0
  1209. package/dist/server/providers/__tests__/openai-messages.test.js +261 -0
  1210. package/dist/server/providers/__tests__/openai-streaming.test.js +394 -0
  1211. package/dist/server/providers/__tests__/openai-tools-cache.test.js +227 -0
  1212. package/dist/server/providers/__tests__/registry.test.js +183 -0
  1213. package/dist/server/providers/__tests__/shared.test.js +297 -0
  1214. package/dist/server/providers/gemini-conversion.d.ts +17 -0
  1215. package/dist/server/providers/gemini-conversion.js +185 -0
  1216. package/dist/server/providers/gemini-conversion.js.map +1 -0
  1217. package/dist/server/providers/gemini-streaming.d.ts +18 -0
  1218. package/dist/server/providers/gemini-streaming.js +187 -0
  1219. package/dist/server/providers/gemini-streaming.js.map +1 -0
  1220. package/dist/server/providers/openai-adapter.d.ts +15 -0
  1221. package/dist/server/providers/openai-adapter.js +423 -0
  1222. package/dist/server/providers/openai-adapter.js.map +1 -0
  1223. package/dist/server/providers/openai-conversion.d.ts +21 -0
  1224. package/dist/server/providers/openai-conversion.js +191 -0
  1225. package/dist/server/providers/openai-conversion.js.map +1 -0
  1226. package/dist/server/server-agent.d.ts +21 -0
  1227. package/dist/server/server-agent.js +162 -0
  1228. package/dist/server/server-agent.js.map +1 -0
  1229. package/dist/server/server-chat.d.ts +6 -0
  1230. package/dist/server/server-chat.js +210 -0
  1231. package/dist/server/server-chat.js.map +1 -0
  1232. package/dist/server/server-cost-guard.d.ts +16 -0
  1233. package/dist/server/server-cost-guard.js +141 -0
  1234. package/dist/server/server-cost-guard.js.map +1 -0
  1235. package/dist/server/server-executors.d.ts +10 -0
  1236. package/dist/server/server-executors.js +110 -0
  1237. package/dist/server/server-executors.js.map +1 -0
  1238. package/dist/server/server-helpers.d.ts +49 -0
  1239. package/dist/server/server-helpers.js +210 -0
  1240. package/dist/server/server-helpers.js.map +1 -0
  1241. package/dist/server/server-persist.d.ts +43 -0
  1242. package/dist/server/server-persist.js +249 -0
  1243. package/dist/server/server-persist.js.map +1 -0
  1244. package/dist/server/server-rate-limit.d.ts +9 -0
  1245. package/dist/server/server-rate-limit.js +77 -0
  1246. package/dist/server/server-rate-limit.js.map +1 -0
  1247. package/dist/server/server-routes-approvals.d.ts +4 -0
  1248. package/dist/server/server-routes-approvals.js +238 -0
  1249. package/dist/server/server-routes-approvals.js.map +1 -0
  1250. package/dist/server/server-routes-auth.d.ts +7 -0
  1251. package/dist/server/server-routes-auth.js +532 -0
  1252. package/dist/server/server-routes-auth.js.map +1 -0
  1253. package/dist/server/server-routes-events.d.ts +4 -0
  1254. package/dist/server/server-routes-events.js +167 -0
  1255. package/dist/server/server-routes-events.js.map +1 -0
  1256. package/dist/server/server-routes-public.d.ts +24 -0
  1257. package/dist/server/server-routes-public.js +453 -0
  1258. package/dist/server/server-routes-public.js.map +1 -0
  1259. package/dist/server/server-routes-waitpoints.d.ts +4 -0
  1260. package/dist/server/server-routes-waitpoints.js +190 -0
  1261. package/dist/server/server-routes-waitpoints.js.map +1 -0
  1262. package/dist/server/server-routes-webchat.d.ts +14 -0
  1263. package/dist/server/server-routes-webchat.js +307 -0
  1264. package/dist/server/server-routes-webchat.js.map +1 -0
  1265. package/dist/server/server-routes-workflows.d.ts +5 -0
  1266. package/dist/server/server-routes-workflows.js +289 -0
  1267. package/dist/server/server-routes-workflows.js.map +1 -0
  1268. package/dist/server/server-sse.d.ts +13 -0
  1269. package/dist/server/server-sse.js +197 -0
  1270. package/dist/server/server-sse.js.map +1 -0
  1271. package/dist/server/server-store-circuit-breaker.d.ts +32 -0
  1272. package/dist/server/server-store-circuit-breaker.js +211 -0
  1273. package/dist/server/server-store-circuit-breaker.js.map +1 -0
  1274. package/dist/server/server-store.d.ts +5 -0
  1275. package/dist/server/server-store.js +71 -0
  1276. package/dist/server/server-store.js.map +1 -0
  1277. package/dist/server/server-trace.d.ts +41 -0
  1278. package/dist/server/server-trace.js +133 -0
  1279. package/dist/server/server-trace.js.map +1 -0
  1280. package/dist/server/server-worker.d.ts +4 -0
  1281. package/dist/server/server-worker.js +127 -0
  1282. package/dist/server/server-worker.js.map +1 -0
  1283. package/dist/server/session-events.d.ts +27 -0
  1284. package/dist/server/session-events.js +69 -0
  1285. package/dist/server/session-events.js.map +1 -0
  1286. package/dist/server/session-manager.d.ts +52 -0
  1287. package/dist/server/session-manager.js +502 -0
  1288. package/dist/server/session-manager.js.map +1 -0
  1289. package/dist/server/tool-router-discovery.d.ts +33 -0
  1290. package/dist/server/tool-router-discovery.js +218 -0
  1291. package/dist/server/tool-router-discovery.js.map +1 -0
  1292. package/dist/server/tool-router-types.d.ts +91 -0
  1293. package/dist/server/tool-router-types.js +336 -0
  1294. package/dist/server/tool-router-types.js.map +1 -0
  1295. package/dist/server/tool-router-user-tools.d.ts +16 -0
  1296. package/dist/server/tool-router-user-tools.js +269 -0
  1297. package/dist/server/tool-router-user-tools.js.map +1 -0
  1298. package/dist/server/validation-schemas.d.ts +12 -0
  1299. package/dist/server/validation-schemas.js +251 -0
  1300. package/dist/server/validation-schemas.js.map +1 -0
  1301. package/dist/shared/agent-core-config.d.ts +12 -0
  1302. package/dist/shared/agent-core-config.js +77 -0
  1303. package/dist/shared/agent-core-config.js.map +1 -0
  1304. package/dist/shared/agent-core-config.test.js +132 -0
  1305. package/dist/shared/agent-core-context-thinking.test.js +293 -0
  1306. package/dist/shared/agent-core-loop-calls.test.js +174 -0
  1307. package/dist/shared/agent-core-loop-detector-bail.test.js +201 -0
  1308. package/dist/shared/agent-core-loop-detector.test.js +195 -0
  1309. package/dist/shared/agent-core-loop-errors.test.js +258 -0
  1310. package/dist/shared/agent-core-loop.d.ts +53 -0
  1311. package/dist/shared/agent-core-loop.js +251 -0
  1312. package/dist/shared/agent-core-loop.js.map +1 -0
  1313. package/dist/shared/agent-core-pricing.test.js +191 -0
  1314. package/dist/shared/agent-core-sanitize-retry.test.js +129 -0
  1315. package/dist/shared/agent-core-tools.d.ts +32 -0
  1316. package/dist/shared/agent-core-tools.js +323 -0
  1317. package/dist/shared/agent-core-tools.js.map +1 -0
  1318. package/dist/shared/agent-core-types.d.ts +182 -0
  1319. package/dist/shared/agent-core-types.js +265 -0
  1320. package/dist/shared/agent-core-types.js.map +1 -0
  1321. package/dist/shared/agent-core.js +1 -1
  1322. package/dist/shared/agent-core.js.map +1 -1
  1323. package/dist/shared/agent-loop-base.d.ts +130 -0
  1324. package/dist/shared/agent-loop-base.js +347 -0
  1325. package/dist/shared/agent-loop-base.js.map +1 -0
  1326. package/dist/shared/api-client-build-request.test.js +228 -0
  1327. package/dist/shared/api-client-build-system-caching.test.js +107 -0
  1328. package/dist/shared/api-client-build.test.js +223 -0
  1329. package/dist/shared/api-client-config.d.ts +21 -0
  1330. package/dist/shared/api-client-helpers.d.ts +57 -0
  1331. package/dist/shared/api-client-helpers.test.js +261 -0
  1332. package/dist/shared/api-client-proxy-happy.test.js +255 -0
  1333. package/dist/shared/api-client-proxy-retry.test.js +307 -0
  1334. package/dist/shared/api-client-proxy.d.ts +26 -0
  1335. package/dist/shared/api-client-proxy.test.js +255 -0
  1336. package/dist/shared/api-client-retry.test.js +307 -0
  1337. package/dist/shared/api-client-system-trimming.test.js +261 -0
  1338. package/dist/shared/api-client-trimming.d.ts +36 -0
  1339. package/dist/shared/api-client.js.map +1 -1
  1340. package/dist/shared/api-client.test.js +228 -0
  1341. package/dist/shared/compaction-thinking.test.js +315 -0
  1342. package/dist/shared/compaction-trimming.test.js +223 -0
  1343. package/dist/shared/exec-validator.d.ts +29 -0
  1344. package/dist/shared/exec-validator.js +106 -0
  1345. package/dist/shared/exec-validator.js.map +1 -0
  1346. package/dist/shared/imsg-constants.d.ts +8 -0
  1347. package/dist/shared/imsg-constants.js +13 -0
  1348. package/dist/shared/imsg-constants.js.map +1 -0
  1349. package/dist/shared/sse-parser-callbacks.test.js +422 -0
  1350. package/dist/shared/sse-parser-collect.test.js +252 -0
  1351. package/dist/shared/sse-parser-e2e.test.js +558 -0
  1352. package/dist/shared/sse-parser-parse.test.js +253 -0
  1353. package/dist/shared/tool-dispatch-advanced-batch-build.test.js +405 -0
  1354. package/dist/shared/tool-dispatch-advanced.test.js +320 -0
  1355. package/dist/shared/tool-dispatch-basic.test.js +278 -0
  1356. package/dist/shared/tool-dispatch-content.d.ts +14 -0
  1357. package/dist/shared/tool-dispatch-parallel.test.js +378 -0
  1358. package/dist/shared/tool-dispatch.js +1 -1
  1359. package/dist/shared/tool-dispatch.js.map +1 -1
  1360. package/dist/webchat/__tests__/widget-messaging.test.js +323 -0
  1361. package/dist/webchat/__tests__/widget.test.js +273 -0
  1362. package/dist/webchat/widget-styles.d.ts +7 -0
  1363. package/dist/webchat/widget-styles.js +11 -0
  1364. package/dist/webchat/widget-styles.js.map +1 -0
  1365. package/package.json +7 -5
  1366. package/src/cli/services/builtin-skills/verify.md +72 -0
  1367. package/vendor/ink/build/ink.js +33 -10
  1368. package/vendor/ink/build/log-update.js +11 -4
  1369. package/whale-logo.png +0 -0
@@ -5,27 +5,36 @@
5
5
  // Shares agent-core with CLI via src/shared/agent-core.ts
6
6
 
7
7
  import http from "node:http";
8
- import { randomUUID, timingSafeEqual, createHash } from "node:crypto";
8
+ import { randomUUID } from "node:crypto";
9
9
  import Anthropic from "@anthropic-ai/sdk";
10
10
  import { createLogger } from "./lib/logger.js";
11
11
  const log = createLogger("server");
12
- import { sanitizeError, resolveAgentLoopConfig } from "../shared/agent-core.js";
13
- import { MODELS } from "../shared/constants.js";
12
+ import { sanitizeError } from "../shared/agent-core.js";
14
13
  import { handleProxy } from "./proxy-handlers.js";
15
14
  import { handleNodeRoutes, setNodeAgentInvoker } from "./handlers/nodes.js";
16
15
  import { handleTranscribe } from "./handlers/transcription.js";
17
16
  import { handleBillingRoutes, incrementUsage, checkPlanLimits } from "./handlers/billing.js";
17
+ import { handleSessionRoutes } from "./handlers/sessions-handlers.js";
18
18
  import { generateCompaction } from "./lib/compaction-service.js";
19
19
  import { initLocalAgentGateway, shutdownGateway as shutdownAgentGateway, getGatewayStats } from "./local-agent-gateway.js";
20
20
  import { initSupabase, getServiceClient } from "./lib/supabase-client.js";
21
21
  import { loadCheckpoint, markOrphaned } from "./lib/session-checkpoint.js";
22
22
  import { rateLimiter } from "./lib/rate-limiter.js";
23
23
  import { sanitizeAndLog } from "./lib/prompt-sanitizer.js";
24
- import { processWorkflowSteps, processWaitingSteps, handleWebhookIngestion, executeInlineChain, setToolExecutor, setAgentExecutor, setTokenBroadcaster, setStepErrorBroadcaster, verifyGuestApprovalSignature, initWorkerPool, getPoolStats, shutdownPool, processScheduleTriggers, enforceWorkflowTimeouts, processEventTriggers, cleanupOrphanedSteps, processDlqRetries } from "./handlers/workflows.js";
25
- import { runServerAgentLoop } from "./lib/server-agent-loop.js";
26
- import { loadTools, loadUserTools, getToolsForAgent, executeTool, loadAgentConfig, setExtendedToolsCache, getExtendedToolsIndex, flushSpans } from "./tool-router.js";
27
- import { queueSpan, auditRowToSpan, classifyErrorType } from "./lib/clickhouse-buffer.js";
28
- import pg from "pg";
24
+ import { generateOpenApiSpec } from "./handlers/api-docs.js";
25
+ import { processWorkflowSteps, handleWebhookIngestion, executeInlineChain, initWorkerPool, getPoolStats, shutdownPool, verifyGuestApprovalSignature } from "./handlers/workflows.js";
26
+ import { loadUserTools, executeTool, flushSpans } from "./tool-router.js";
27
+ import { queueSpan, auditRowToSpan } from "./lib/clickhouse-buffer.js";
28
+
29
+ // Extracted modules — single source of truth (no inline duplicates)
30
+ import { safeCompare, getCorsHeaders, jsonResponse, readBody } from "./server-helpers.js";
31
+ import { sendIpRateLimit } from "./server-rate-limit.js";
32
+ import { resolveAndValidateStoreId } from "./server-store.js";
33
+ import { getSseClients, safeSseWrite, sendWorkflowSSE, getTotalSseClients, sseCleanupInterval, MAX_SSE_CLIENTS_PER_RUN, MAX_SSE_TOTAL_CLIENTS, setupPgListen, closePgClient, pgListenReady } from "./server-sse.js";
34
+ import { handleAgentChat } from "./server-chat.js";
35
+ import { wireToolExecutor, wireAgentExecutor, wireBroadcasters, invokeAgentForChannel } from "./server-executors.js";
36
+ import { startWorkerLoop, stopWorkerLoop } from "./server-worker.js";
37
+ import { getCircuitBreakerStats } from "./server-store-circuit-breaker.js";
29
38
 
30
39
  // ============================================================================
31
40
  // PROCESS ERROR HANDLERS
@@ -52,7 +61,6 @@ const SUPABASE_URL = process.env.SUPABASE_URL;
52
61
  const SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY;
53
62
  const SERVICE_ROLE_JWT = process.env.SERVICE_ROLE_JWT || "";
54
63
  const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
55
- const ALLOWED_ORIGINS = (process.env.ALLOWED_ORIGINS || "http://localhost:3000,http://127.0.0.1:3000").split(",").map(s => s.trim());
56
64
  const FLY_INTERNAL_SECRET = process.env.FLY_INTERNAL_SECRET || "";
57
65
  if (!FLY_INTERNAL_SECRET) {
58
66
  console.warn("[SECURITY] FLY_INTERNAL_SECRET is not set — internal endpoints are unprotected");
@@ -62,7 +70,6 @@ if (!FLY_INTERNAL_SECRET) {
62
70
  // READINESS STATE
63
71
  // ============================================================================
64
72
 
65
- let pgListenReady = false;
66
73
  let workerPoolReady = false;
67
74
  function isReady() {
68
75
  return workerPoolReady; // PG listen is optional (SSE only)
@@ -71,1311 +78,6 @@ function isReady() {
71
78
  // Webchat agent invoker — set later to avoid circular deps (same as node agent invoker)
72
79
  let webchatAgentInvoker = null;
73
80
 
74
- // ============================================================================
75
- // RATE LIMITING — Phase 7.2 token-bucket (see lib/rate-limiter.ts)
76
- // ============================================================================
77
-
78
- /** Check IP rate limit and send 429 with proper headers if exceeded */
79
- function sendIpRateLimit(res, ip, headers) {
80
- const result = rateLimiter.checkRequest(`ip:${ip}`, "unauthenticated");
81
- if (result.allowed) return false; // not rate-limited
82
- res.writeHead(429, {
83
- "Retry-After": String(Math.ceil(result.retryAfterMs / 1000) || 1),
84
- "X-RateLimit-Remaining": "0",
85
- "Content-Type": "application/json",
86
- ...headers
87
- });
88
- res.end(JSON.stringify({
89
- error: "Too many requests"
90
- }));
91
- return true; // was rate-limited
92
- }
93
-
94
- // Agent chat rate limiting — per-store + global concurrent cap
95
- const agentChatLimiter = new Map();
96
- const AGENT_CHAT_MAX_PER_MIN = 60;
97
- const AGENT_CHAT_MAX_CONCURRENT = 10;
98
- let agentChatConcurrent = 0;
99
-
100
- // Periodically clean up stale entries from agentChatLimiter to prevent unbounded Map growth
101
- setInterval(() => {
102
- const now = Date.now();
103
- for (const [key, entry] of agentChatLimiter) {
104
- if (now - entry.windowStart > 120_000) {
105
- agentChatLimiter.delete(key);
106
- }
107
- }
108
- }, 60_000);
109
- function checkAgentChatRateLimit(storeId) {
110
- // Concurrent check
111
- if (agentChatConcurrent >= AGENT_CHAT_MAX_CONCURRENT) {
112
- return {
113
- allowed: false,
114
- error: "Too many concurrent agent sessions. Please wait."
115
- };
116
- }
117
-
118
- // Per-store per-minute check
119
- const now = Date.now();
120
- let entry = agentChatLimiter.get(storeId);
121
- if (!entry || now - entry.windowStart > 60_000) {
122
- entry = {
123
- count: 0,
124
- windowStart: now
125
- };
126
- agentChatLimiter.set(storeId, entry);
127
- }
128
- entry.count++;
129
- if (entry.count > AGENT_CHAT_MAX_PER_MIN) {
130
- return {
131
- allowed: false,
132
- error: `Rate limit exceeded: ${AGENT_CHAT_MAX_PER_MIN}/min for agent chat`
133
- };
134
- }
135
- return {
136
- allowed: true
137
- };
138
- }
139
-
140
- // Timing-safe secret comparison to prevent timing attacks
141
- // Hash both values to fixed length before comparing — avoids leaking secret length
142
- function safeCompare(a, b) {
143
- if (!a || !b) return false;
144
- const hashA = createHash("sha256").update(a).digest();
145
- const hashB = createHash("sha256").update(b).digest();
146
- return timingSafeEqual(hashA, hashB);
147
- }
148
-
149
- // ============================================================================
150
- // TYPES
151
- // ============================================================================
152
-
153
- // Tool registry, user tools, executor, and agent loader are in ./tool-router.ts
154
-
155
- // ============================================================================
156
- // STORE CONTEXT — Server-derived store resolution (Apple-style)
157
- // The server NEVER blindly trusts a client-supplied storeId. Instead it:
158
- // 1. Resolves the user's stores from the `users` table via auth.uid()
159
- // 2. Validates the client hint against the resolved set
160
- // 3. Falls back to the user's first store if no hint provided
161
- // 4. Returns null if no store can be resolved (caller must fail closed)
162
- // ============================================================================
163
-
164
- async function resolveAndValidateStoreId(supabase, clientStoreId, user, isServiceRole, _token, requestUserId) {
165
- // Service-role callers: trusted ONLY for internal server-to-server calls
166
- // (workflows, cron jobs) that have NO associated user. When a userId is
167
- // present (e.g. MCP CLI using env-var service role key), we MUST still
168
- // validate store membership to prevent cross-tenant access.
169
- if (isServiceRole) {
170
- const srUserId = user?.id || requestUserId;
171
- if (!srUserId) return clientStoreId || null; // true internal call — pass through
172
- if (!clientStoreId) return null; // user-context call without store hint
173
-
174
- // Validate the user actually belongs to the requested store
175
- const {
176
- data: membership
177
- } = await supabase.from("store_members").select("id").eq("store_id", clientStoreId).eq("user_id", srUserId).limit(1).maybeSingle();
178
- if (membership) return clientStoreId;
179
-
180
- // Fallback: check users table (legacy single-store pattern)
181
- const {
182
- data: userRow
183
- } = await supabase.from("users").select("store_id").eq("auth_user_id", srUserId).eq("store_id", clientStoreId).maybeSingle();
184
- if (userRow) return clientStoreId;
185
- log.warn({
186
- userId: srUserId,
187
- clientStoreId
188
- }, "resolveStoreId: service-role caller userId not authorized for store");
189
- return null;
190
- }
191
- if (!user?.id) return null;
192
-
193
- // Resolve user's actual stores from the `users` table (auth_user_id = auth.uid())
194
- const {
195
- data: userStores,
196
- error
197
- } = await supabase.from("users").select("store_id").eq("auth_user_id", user.id).not("store_id", "is", null);
198
- if (error || !userStores?.length) {
199
- log.warn({
200
- userId: user.id,
201
- error
202
- }, "resolveStoreId: user has no stores");
203
- return null;
204
- }
205
- const storeIds = userStores.map(r => r.store_id);
206
-
207
- // If client provided a hint, validate it's in the user's set
208
- if (clientStoreId) {
209
- if (storeIds.includes(clientStoreId)) {
210
- return clientStoreId;
211
- }
212
- log.warn({
213
- userId: user.id,
214
- clientStoreId,
215
- userStores: storeIds
216
- }, "resolveStoreId: client storeId not in user's stores");
217
- return null; // Reject — don't silently fall back
218
- }
219
-
220
- // No client hint — use first store (single-store users), or require explicit selection
221
- if (storeIds.length === 1) {
222
- return storeIds[0];
223
- }
224
-
225
- // Multi-store user without a hint — can't guess
226
- log.warn({
227
- userId: user.id,
228
- storeCount: storeIds.length
229
- }, "resolveStoreId: multi-store user must specify storeId");
230
- return null;
231
- }
232
-
233
- // ============================================================================
234
- // CORS
235
- // ============================================================================
236
-
237
- function getCorsHeaders(origin) {
238
- const headers = {
239
- "X-Content-Type-Options": "nosniff",
240
- "X-Frame-Options": "DENY",
241
- "X-XSS-Protection": "0",
242
- "Referrer-Policy": "strict-origin-when-cross-origin"
243
- };
244
- if (ALLOWED_ORIGINS.includes("*")) {
245
- headers["Access-Control-Allow-Origin"] = "*";
246
- } else if (origin && ALLOWED_ORIGINS.includes(origin)) {
247
- headers["Access-Control-Allow-Origin"] = origin;
248
- headers["Vary"] = "Origin";
249
- }
250
- // If origin doesn't match, no CORS header = browser blocks the request
251
-
252
- headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS";
253
- headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization, X-Store-Id";
254
- return headers;
255
- }
256
-
257
- // ============================================================================
258
- // PHASE 3: SSE STREAMING — real-time workflow run progress
259
- // ============================================================================
260
-
261
- // Map<runId, Set<ServerResponse>> for multiplexing SSE clients
262
- const sseClients = new Map();
263
- const MAX_SSE_CLIENTS_PER_RUN = 10;
264
- const MAX_SSE_TOTAL_CLIENTS = 100;
265
-
266
- /** Safe SSE write — returns false and calls cleanup if the connection is dead */
267
- function safeSseWrite(res, data, cleanup) {
268
- try {
269
- if (res.destroyed || res.writableEnded) {
270
- cleanup();
271
- return false;
272
- }
273
- res.write(data);
274
- return true;
275
- } catch {
276
- cleanup();
277
- return false;
278
- }
279
- }
280
- function sendWorkflowSSE(res, data) {
281
- try {
282
- if (res.destroyed || res.writableEnded) return;
283
- res.write(`data: ${JSON.stringify(data)}\n\n`);
284
- } catch {/* client disconnected — benign */}
285
- }
286
- function broadcastToRun(runId, data) {
287
- const clients = sseClients.get(runId);
288
- if (!clients?.size) return;
289
- // H6 FIX: Prune dead connections during broadcast
290
- for (const res of clients) {
291
- if (res.destroyed || res.writableEnded) {
292
- clients.delete(res);
293
- continue;
294
- }
295
- sendWorkflowSSE(res, data);
296
- }
297
- if (clients.size === 0) sseClients.delete(runId);
298
- }
299
- function getTotalSseClients() {
300
- let total = 0;
301
- for (const clients of sseClients.values()) total += clients.size;
302
- return total;
303
- }
304
-
305
- // H6 FIX: Periodic stale connection cleanup (every 60s)
306
- const sseCleanupInterval = setInterval(() => {
307
- for (const [rid, clients] of sseClients) {
308
- for (const res of clients) {
309
- if (res.destroyed || res.writableEnded) {
310
- clients.delete(res);
311
- }
312
- }
313
- if (clients.size === 0) sseClients.delete(rid);
314
- }
315
- }, 60_000);
316
-
317
- // pg LISTEN for real-time notifications
318
- const DATABASE_URL = process.env.DATABASE_URL || "";
319
- let pgClient = null;
320
- let pgReconnectAttempts = 0;
321
- const MAX_PG_RECONNECT_DELAY = 10_000; // 10s max — keep SSE reconnect snappy
322
-
323
- async function setupPgListen() {
324
- if (!DATABASE_URL) {
325
- log.info("DATABASE_URL not set — SSE streaming disabled, using worker-only mode");
326
- return;
327
- }
328
- try {
329
- // Strip sslmode from URL (pg v8 treats sslmode=require as verify-full) and set ssl manually
330
- const cleanUrl = DATABASE_URL.replace(/[?&]sslmode=[^&]*/g, "").replace(/\?$/, "");
331
- pgClient = new pg.Client({
332
- connectionString: cleanUrl,
333
- ssl: {
334
- rejectUnauthorized: false
335
- }
336
- });
337
- await pgClient.connect();
338
- await pgClient.query("LISTEN workflow_step_event");
339
- await pgClient.query("LISTEN workflow_run_event");
340
- await pgClient.query("LISTEN workflow_step_pending");
341
- await pgClient.query("LISTEN workflow_event");
342
- await pgClient.query("LISTEN automation_event");
343
-
344
- // Reset reconnect counter on successful connection
345
- pgReconnectAttempts = 0;
346
- pgListenReady = true;
347
-
348
- // Debounced event trigger processing — fires at most once per 100ms
349
- let eventTriggerTimer = null;
350
- function debouncedEventProcess() {
351
- if (eventTriggerTimer) return;
352
- eventTriggerTimer = setTimeout(async () => {
353
- eventTriggerTimer = null;
354
- try {
355
- const sb = getServiceClient();
356
- const count = await processEventTriggers(sb);
357
- if (count > 0) log.info({
358
- count
359
- }, "instant event processing");
360
- } catch (err) {
361
- log.error({
362
- err: err.message
363
- }, "event trigger processing error");
364
- }
365
- }, 100);
366
- }
367
- pgClient.on("notification", msg => {
368
- if (!msg.payload) return;
369
- try {
370
- const data = JSON.parse(msg.payload);
371
-
372
- // Automation event — trigger immediate processing
373
- if (msg.channel === "automation_event") {
374
- debouncedEventProcess();
375
- return;
376
- }
377
- const runId = data.run_id;
378
- if (!runId) return;
379
- if (msg.channel === "workflow_step_event") {
380
- broadcastToRun(runId, {
381
- type: "step_update",
382
- ...data
383
- });
384
- } else if (msg.channel === "workflow_run_event") {
385
- broadcastToRun(runId, {
386
- type: "run_update",
387
- ...data
388
- });
389
- } else if (msg.channel === "workflow_event") {
390
- broadcastToRun(runId, {
391
- type: "event",
392
- event_type: data.event_type,
393
- ...data
394
- });
395
- } else if (msg.channel === "workflow_step_pending") {
396
- // Phase 3.1: NOTIFY-driven step execution — immediate pickup (~50ms vs 5s polling)
397
- const sb = getServiceClient();
398
- processWorkflowSteps(sb, 1).catch(err => {
399
- log.error({
400
- err: err.message,
401
- runId
402
- }, "NOTIFY-driven step processing failed");
403
- });
404
- }
405
- } catch (err) {
406
- log.error({
407
- err: err.message
408
- }, "failed to parse pg notification");
409
- }
410
- });
411
- pgClient.on("error", err => {
412
- log.error({
413
- err: err.message
414
- }, "pg-listen connection error");
415
- pgClient = null;
416
- // Reconnect with exponential backoff
417
- pgReconnectAttempts++;
418
- const delay = Math.min(1000 * Math.pow(2, pgReconnectAttempts - 1), MAX_PG_RECONNECT_DELAY);
419
- log.warn({
420
- delayMs: delay,
421
- attempt: pgReconnectAttempts
422
- }, "pg-listen reconnecting");
423
- setTimeout(() => setupPgListen(), delay);
424
- });
425
- log.info("pg-listen active on workflow_step_event, workflow_run_event, workflow_step_pending, workflow_event, automation_event");
426
- } catch (err) {
427
- log.error({
428
- err: err.message
429
- }, "pg-listen failed to connect");
430
- pgClient = null;
431
- // Reconnect with exponential backoff on initial connection failure too
432
- pgReconnectAttempts++;
433
- const delay = Math.min(1000 * Math.pow(2, pgReconnectAttempts - 1), MAX_PG_RECONNECT_DELAY);
434
- log.warn({
435
- delayMs: delay,
436
- attempt: pgReconnectAttempts
437
- }, "pg-listen reconnecting");
438
- setTimeout(() => setupPgListen(), delay);
439
- }
440
- }
441
-
442
- // ============================================================================
443
- // HELPERS
444
- // ============================================================================
445
-
446
- function getAnthropicClient(agent) {
447
- const key = agent.api_key || ANTHROPIC_API_KEY;
448
- return new Anthropic({
449
- apiKey: key,
450
- timeout: 15 * 60 * 1000
451
- }); // 15 min for tool-heavy requests
452
- }
453
- function sendSSE(res, event) {
454
- try {
455
- if (res.destroyed || res.writableEnded) return;
456
- res.write(`data: ${JSON.stringify(event)}\n\n`);
457
- } catch {/* client disconnected — benign */}
458
- }
459
- function jsonResponse(res, status, data, corsHeaders) {
460
- res.writeHead(status, {
461
- "Content-Type": "application/json",
462
- ...corsHeaders
463
- });
464
- res.end(JSON.stringify(data));
465
- }
466
-
467
- /**
468
- * Strip large base64 data fields from a JSON string up to `keepFrom` offset.
469
- * Uses a linear indexOf scan — safe on strings of any size (no regex stack overflow).
470
- * Handles both `"data":"<base64>"` (Anthropic image blocks) and
471
- * `"__IMAGE__<mime>__<base64>"` text values (Read tool marker format).
472
- */
473
- function stripLargeBase64Fields(raw, keepFrom) {
474
- const MIN_DATA_LEN = 8_000;
475
-
476
- // ── Pass 1: Strip "data":"<large base64>" fields (Anthropic image source blocks) ──
477
- let result = raw;
478
- {
479
- const DATA_MARKER = '"data":"';
480
- const parts = [];
481
- let pos = 0;
482
- while (pos < keepFrom) {
483
- const idx = result.indexOf(DATA_MARKER, pos);
484
- if (idx === -1 || idx >= keepFrom) {
485
- parts.push(result.slice(pos, keepFrom));
486
- pos = keepFrom;
487
- break;
488
- }
489
- parts.push(result.slice(pos, idx + DATA_MARKER.length));
490
- pos = idx + DATA_MARKER.length;
491
-
492
- // Find closing quote (base64 has no backslashes, so simple scan is safe)
493
- let end = pos;
494
- while (end < result.length && result[end] !== '"') end++;
495
- if (end - pos >= MIN_DATA_LEN && end <= keepFrom) {
496
- // Large data field in the prune zone — replace with empty
497
- parts.push('"');
498
- pos = end + 1; // skip past the original closing quote (already replaced)
499
- }
500
- // else: small field or near keepFrom boundary — leave intact
501
- }
502
- parts.push(result.slice(keepFrom)); // always keep tail intact
503
- result = parts.join("");
504
- }
505
-
506
- // ── Pass 2: Strip __IMAGE__<mime>__<large base64> text markers ──
507
- // If the client-side tool-dispatch regex failed to convert these to image
508
- // content blocks, they stay as huge text strings in tool_result content.
509
- // They appear in JSON as: "__IMAGE__image/png__iVBOR...very long..."
510
- {
511
- const IMG_MARKER = "__IMAGE__";
512
- const adjustedKeepFrom = Math.min(keepFrom, result.length);
513
- const parts = [];
514
- let pos = 0;
515
- while (pos < adjustedKeepFrom) {
516
- const idx = result.indexOf(IMG_MARKER, pos);
517
- if (idx === -1 || idx >= adjustedKeepFrom) {
518
- parts.push(result.slice(pos, adjustedKeepFrom));
519
- pos = adjustedKeepFrom;
520
- break;
521
- }
522
- parts.push(result.slice(pos, idx));
523
-
524
- // Find the end of this text value (closing quote of the JSON string)
525
- let end = idx;
526
- while (end < result.length && result[end] !== '"') end++;
527
- if (end - idx >= MIN_DATA_LEN && end <= adjustedKeepFrom) {
528
- // Large __IMAGE__ marker in the prune zone — replace with placeholder
529
- parts.push("[image pruned]");
530
- pos = end; // land on closing quote; next iteration emits it
531
- } else {
532
- // Small or near boundary — keep intact
533
- parts.push(result.slice(idx, idx + IMG_MARKER.length));
534
- pos = idx + IMG_MARKER.length;
535
- }
536
- }
537
- parts.push(result.slice(adjustedKeepFrom));
538
- result = parts.join("");
539
- }
540
- return result;
541
- }
542
- async function readBody(req) {
543
- // 500MB hard limit — conversation history with many large images can be very large.
544
- // For bodies over 10MB we prune old base64 image data from the raw string before
545
- // JSON.parse, so subsequent requests in the same conversation stay bounded.
546
- const MAX_BODY = 524_288_000; // 500MB
547
- return new Promise((resolve, reject) => {
548
- const chunks = [];
549
- let size = 0;
550
- let rejected = false;
551
- req.on("data", chunk => {
552
- size += chunk.length;
553
- if (size > MAX_BODY && !rejected) {
554
- rejected = true;
555
- req.resume(); // drain to avoid Fly proxy 502
556
- reject(new Error("Request body too large (max 500MB)"));
557
- return;
558
- }
559
- if (!rejected) chunks.push(chunk);
560
- });
561
- req.on("end", () => {
562
- if (rejected) return;
563
-
564
- // Detect body truncation: if Content-Length was sent and we received less
565
- const declaredLen = parseInt(req.headers["content-length"] || "0", 10);
566
- if (declaredLen > 0 && size < declaredLen) {
567
- log.error({
568
- declaredLen,
569
- receivedLen: size
570
- }, "Request body truncated during transmission");
571
- reject(new Error(`Body truncated: expected ${declaredLen} bytes, got ${size}`));
572
- return;
573
- }
574
- let raw = Buffer.concat(chunks).toString("utf8");
575
-
576
- // Strip old base64 data from history when body is large.
577
- // Threshold lowered to 1MB — image-heavy conversations (e.g. reading
578
- // product photos) easily exceed 10MB with just a few images.
579
- // Keep the last 1MB intact (current user message with fresh images).
580
- // Uses a linear scan to avoid String.replace() stack overflow on huge strings.
581
- if (raw.length > 1_000_000) {
582
- const keepFrom = Math.max(0, raw.length - 1_048_576); // keep last 1MB
583
- raw = stripLargeBase64Fields(raw, keepFrom);
584
- log.info({
585
- originalBytes: size,
586
- prunedBytes: Buffer.byteLength(raw)
587
- }, "Pruned old base64 data from request body");
588
- }
589
- resolve(raw);
590
- });
591
- req.on("error", reject);
592
- });
593
- }
594
-
595
- // ============================================================================
596
- // HISTORY COMPACTION
597
- // ============================================================================
598
-
599
- /**
600
- * Compact conversation history to fit within a total character budget.
601
- *
602
- * Does NOT truncate individual messages or tool results — Anthropic's
603
- * context_management API handles clearing old tool uses (clear_tool_uses_20250919)
604
- * and compacting context (compact_20260112) when the context window grows.
605
- *
606
- * This function only enforces a total budget by walking newest→oldest and
607
- * dropping the oldest messages that don't fit.
608
- */
609
- function compactHistory(history, maxHistoryChars) {
610
- if (!history?.length) return [];
611
- let totalChars = 0;
612
- const compacted = [];
613
- for (let i = history.length - 1; i >= 0; i--) {
614
- const msg = history[i];
615
- const msgChars = JSON.stringify(msg.content).length;
616
- if (totalChars + msgChars > maxHistoryChars) break;
617
- totalChars += msgChars;
618
- compacted.unshift(msg);
619
- }
620
- // Ensure starts with user message
621
- while (compacted.length > 0 && compacted[0].role !== "user") compacted.shift();
622
- return compacted;
623
- }
624
-
625
- // ============================================================================
626
- // SHARED AGENT HELPERS — used by both SSE chat and channel agent paths
627
- // ============================================================================
628
-
629
- /** Build the full system prompt for an agent. Both SSE chat and channel paths
630
- * call this so the prompt logic is never duplicated. */
631
- async function buildAgentSystemPrompt(supabase, agent, storeId, message, tools, opts) {
632
- // --- STATIC portion (cache-friendly, same across conversations) ---
633
- // Sanitize the DB-stored agent system prompt to prevent injection attacks
634
- const rawAgentPrompt = agent.system_prompt || "You are a helpful assistant.";
635
- let systemPrompt = sanitizeAndLog(rawAgentPrompt, "buildAgentSystemPrompt", {
636
- agentId: agent.id
637
- });
638
- if (storeId) systemPrompt += `\n\nYou are operating for store_id: ${storeId}. Always include this in tool calls that require it.`;
639
- if (!agent.can_modify) systemPrompt += "\n\nIMPORTANT: You have read-only access. Do not attempt to modify any data.";
640
- if (agent.tone && agent.tone !== "professional") systemPrompt += `\n\nTone: Respond in a ${agent.tone} tone.`;
641
- if (agent.verbosity === "concise") systemPrompt += "\n\nBe concise — short answers, minimal explanation.";else if (agent.verbosity === "verbose") systemPrompt += "\n\nBe thorough — provide detailed answers with full context.";
642
- if (agent.context_config) {
643
- const ctx = agent.context_config;
644
- if (ctx.includeLocations && ctx.locationIds?.length) systemPrompt += `\n\nFocus on these locations: ${ctx.locationIds.join(", ")}`;
645
- if (ctx.includeCustomers && ctx.customerSegments?.length) systemPrompt += `\n\nFocus on these customer segments: ${ctx.customerSegments.join(", ")}`;
646
- }
647
-
648
- // Tool manifest — core tools (full schemas already loaded)
649
- const toolNames = tools.map(t => t.name);
650
- systemPrompt += `\n\n## Available Tools\nYou have ${toolNames.length} core tools available in this session:\n${toolNames.join(", ")}\n\nFor local machine operations, use the \`local_agent\` tool (exec, tools, discover actions). For cloud security tools, use \`kali\`. Do NOT reference CLI-local tools like read_file, write_file, edit_file, glob, grep, run_command — those are not available in this environment.`;
651
-
652
- // Extended tools index — names + one-line descriptions only (saves ~20K tokens)
653
- const extendedTools = opts?.extendedTools || [];
654
- if (extendedTools.length > 0) {
655
- systemPrompt += `\n\n## Extended Tools (call discover_tools to activate)\nThese tools are available but not loaded yet. Call \`discover_tools\` with the tool name(s) before using them:\n`;
656
- for (const t of extendedTools) {
657
- // First sentence only for compact display
658
- const shortDesc = t.description.split(".")[0];
659
- systemPrompt += `- **${t.name}**: ${shortDesc}\n`;
660
- }
661
- }
662
-
663
- // --- DYNAMIC portion (changes per conversation, prepended to user message) ---
664
- const dynamicParts = [];
665
-
666
- // Client-provided session context (SSE chat sends this from SwiftUI/web)
667
- if (opts?.clientContext && typeof opts.clientContext === "object") {
668
- const context = opts.clientContext;
669
- const ctxParts = [];
670
- if (context.storeName) ctxParts.push(`Store: ${context.storeName}`);
671
- if (context.locationName) {
672
- let loc = `Location: ${context.locationName}`;
673
- if (context.locationAddress) loc += ` (${context.locationAddress})`;
674
- if (context.locationType) loc += ` [${context.locationType}]`;
675
- ctxParts.push(loc);
676
- }
677
- if (context.userName) {
678
- ctxParts.push(`User: ${context.userName}${opts.userEmail ? ` (${opts.userEmail})` : ""}`);
679
- } else if (opts.userEmail) {
680
- ctxParts.push(`User: ${opts.userEmail}`);
681
- }
682
- if (context.conversationType) {
683
- ctxParts.push(`Channel: ${context.conversationTitle || context.conversationType} (${context.conversationType})`);
684
- }
685
- if (ctxParts.length) {
686
- dynamicParts.push(`## Current Session Context\n${ctxParts.join("\n")}`);
687
- }
688
- }
689
-
690
- // Parallel DB lookups: customer fetch + memory recall
691
- const customerPromise = opts?.senderContext?.customerId && storeId ? Promise.resolve(supabase.from("v_store_customers").select("first_name, last_name, email, phone, loyalty_tier, total_orders, total_spent, lifetime_value").eq("id", opts.senderContext.customerId).eq("store_id", storeId).single()).then(({
692
- data
693
- }) => data).catch(() => null) : Promise.resolve(null);
694
- const memoryPromise = storeId ? Promise.resolve(supabase.rpc("recall_memory", {
695
- p_agent_id: agent.id,
696
- p_query: message.substring(0, 200),
697
- p_type: null,
698
- p_limit: 5
699
- })).then(({
700
- data
701
- }) => data).catch(err => {
702
- log.warn({
703
- err: err.message
704
- }, "memory recall failed");
705
- return null;
706
- }) : Promise.resolve(null);
707
- const [cust, memories] = await Promise.all([customerPromise, memoryPromise]);
708
-
709
- // Channel-specific customer context injection
710
- if (cust && opts?.senderContext?.customerId) {
711
- dynamicParts.push(`## Current Customer\nName: ${cust.first_name} ${cust.last_name}\nEmail: ${cust.email || "N/A"}\nPhone: ${cust.phone || "N/A"}\nLoyalty: ${cust.loyalty_tier || "None"}\nOrders: ${cust.total_orders || 0}\nSpent: $${(cust.total_spent || 0).toFixed(2)}\nCustomer ID: ${opts.senderContext.customerId}`);
712
- } else if (opts?.senderContext) {
713
- const sc = opts.senderContext;
714
- dynamicParts.push(`## Sender\nID: ${sc.senderId}\nName: ${sc.senderName || "Unknown"}\nChannel: ${sc.channelType || "unknown"}${sc.channelName ? ` (${sc.channelName})` : ""}\n(No customer record matched — use CRM tools to look them up if needed)`);
715
- }
716
-
717
- // Memory recall — inject relevant memories (capped at 5, 100 chars each)
718
- if (memories?.length) {
719
- const memBlock = memories.map(m => `- [${m.memory_type}] ${m.key}: ${JSON.stringify(m.value).substring(0, 100)}`).join("\n");
720
- dynamicParts.push(`## Agent Memory\nRelevant memories from previous conversations:\n${memBlock}`);
721
- }
722
- const dynamicContext = dynamicParts.join("\n\n");
723
- return {
724
- systemPrompt,
725
- dynamicContext
726
- };
727
- }
728
-
729
- /** Persist everything after an agent turn — messages, audit, memory, cost.
730
- * Called by both SSE chat and channel paths so nothing is ever missed. */
731
- async function persistAgentTurn(supabase, agent, opts) {
732
- const {
733
- conversationId,
734
- storeId,
735
- agentId,
736
- agentModel,
737
- traceId,
738
- message,
739
- result,
740
- source,
741
- chatStartTime,
742
- chatEndTime,
743
- userId,
744
- userEmail,
745
- senderContext
746
- } = opts;
747
-
748
- // ── Persist user + assistant messages to ai_messages ──
749
- try {
750
- await supabase.from("ai_messages").insert([{
751
- conversation_id: conversationId,
752
- role: "user",
753
- content: [{
754
- type: "text",
755
- text: message
756
- }],
757
- token_count: Math.ceil(message.length / 4)
758
- }, {
759
- conversation_id: conversationId,
760
- role: "assistant",
761
- content: [{
762
- type: "text",
763
- text: result.finalText || ""
764
- }],
765
- is_tool_use: result.toolCallCount > 0,
766
- tool_names: result.toolsUsed?.length ? result.toolsUsed : null,
767
- token_count: result.tokens.input + result.tokens.output
768
- }]);
769
- } catch (err) {
770
- log.error({
771
- err: err.message
772
- }, "message persist failed");
773
- }
774
-
775
- // ── Update conversation metadata ──
776
- try {
777
- await supabase.from("ai_conversations").update({
778
- metadata: {
779
- agentName: agent.name,
780
- source,
781
- model: agentModel,
782
- lastTurnTokens: result.tokens.input + result.tokens.output,
783
- lastToolCalls: result.toolCallCount,
784
- lastDurationMs: chatEndTime - chatStartTime,
785
- // Channel-specific (null when SSE chat — that's fine, no clutter)
786
- ...(senderContext ? {
787
- channel_type: senderContext.channelType || null,
788
- channel_id: senderContext.channelId || null,
789
- channel_name: senderContext.channelName || null,
790
- sender_id: senderContext.senderId || null,
791
- customer_id: senderContext.customerId || null,
792
- customer_name: senderContext.customerName || null
793
- } : {})
794
- }
795
- }).eq("id", conversationId);
796
- } catch (err) {
797
- log.error({
798
- err: err.message
799
- }, "conversation update failed");
800
- }
801
-
802
- // ── Telemetry: user message → ClickHouse ──
803
- try {
804
- queueSpan(auditRowToSpan({
805
- action: "chat.user_message",
806
- severity: "info",
807
- store_id: storeId || null,
808
- resource_type: "chat_message",
809
- resource_id: agentId,
810
- request_id: traceId,
811
- conversation_id: conversationId,
812
- user_id: userId || null,
813
- user_email: userEmail || null,
814
- source,
815
- service_name: "agent-server",
816
- span_kind: "INTERNAL",
817
- status_code: "OK",
818
- start_time: new Date().toISOString(),
819
- end_time: new Date().toISOString(),
820
- duration_ms: 0,
821
- input_bytes: typeof message === "string" ? message.length : 0,
822
- details: {
823
- message_preview: message.substring(0, 200),
824
- agent_id: agentId,
825
- model: agentModel,
826
- conversation_id: conversationId,
827
- ...(senderContext ? {
828
- channel_type: senderContext.channelType || null,
829
- sender_id: senderContext.senderId || null,
830
- customer_id: senderContext.customerId || null
831
- } : {})
832
- }
833
- }));
834
- } catch (err) {
835
- log.error({
836
- err: err.message
837
- }, "audit user_message failed");
838
- }
839
-
840
- // ── Telemetry: assistant response → ClickHouse ──
841
- try {
842
- queueSpan(auditRowToSpan({
843
- action: "chat.assistant_response",
844
- severity: "info",
845
- store_id: storeId || null,
846
- resource_type: "chat_message",
847
- resource_id: agentId,
848
- request_id: traceId,
849
- conversation_id: conversationId,
850
- duration_ms: chatEndTime - chatStartTime,
851
- user_id: userId || null,
852
- user_email: userEmail || null,
853
- source,
854
- input_tokens: result.tokens.input,
855
- output_tokens: result.tokens.output,
856
- total_cost: result.costUsd,
857
- model: agentModel,
858
- trace_id: traceId,
859
- span_kind: "INTERNAL",
860
- service_name: "agent-server",
861
- status_code: "OK",
862
- start_time: new Date(chatStartTime).toISOString(),
863
- end_time: new Date(chatEndTime).toISOString(),
864
- stop_reason: result.stopReason || undefined,
865
- turn_number: result.turnCount || 1,
866
- details: {
867
- response_preview: (result.finalText || "").substring(0, 500),
868
- agent_id: agentId,
869
- model: agentModel,
870
- "gen_ai.request.model": agentModel,
871
- "gen_ai.usage.input_tokens": result.tokens.input,
872
- "gen_ai.usage.output_tokens": result.tokens.output,
873
- "gen_ai.usage.cache_creation_tokens": result.tokens.cacheCreation || 0,
874
- "gen_ai.usage.cache_read_tokens": result.tokens.cacheRead || 0,
875
- "gen_ai.usage.cost": result.costUsd,
876
- turn_count: result.turnCount || 1,
877
- tool_calls: result.toolCallCount,
878
- tool_names: result.toolsUsed,
879
- conversation_id: conversationId,
880
- session_cost_usd: result.costUsd,
881
- cache_creation_tokens: result.tokens.cacheCreation || 0,
882
- cache_read_tokens: result.tokens.cacheRead || 0,
883
- cache_hit_rate: result.tokens.input > 0 ? Math.round((result.tokens.cacheRead || 0) / ((result.tokens.cacheRead || 0) + result.tokens.input) * 10000) / 100 : 0,
884
- cache_cost_savings_pct: result.tokens.input > 0 && (result.tokens.cacheRead || 0) > 0 ? Math.round((result.tokens.cacheRead || 0) * 0.9 / ((result.tokens.cacheRead || 0) + result.tokens.input) * 10000) / 100 : 0,
885
- loop_detector_stats: result.loopDetectorStats || null,
886
- turns: result.turns || [],
887
- ...(senderContext ? {
888
- channel_type: senderContext.channelType || null,
889
- channel_id: senderContext.channelId || null,
890
- channel_name: senderContext.channelName || null,
891
- sender_id: senderContext.senderId || null,
892
- customer_id: senderContext.customerId || null,
893
- customer_name: senderContext.customerName || null
894
- } : {})
895
- }
896
- }));
897
- } catch (err) {
898
- log.error({
899
- err: err.message
900
- }, "audit assistant_response failed");
901
- }
902
-
903
- // ── Memory extraction — awaited with retry ──
904
- if (storeId && result.finalText && result.finalText.length > 50) {
905
- try {
906
- await extractAndStoreMemories(supabase, getAnthropicClient(agent), agentId, storeId, message, result.finalText);
907
- } catch (err1) {
908
- // Retry once after 2s
909
- try {
910
- await new Promise(r => setTimeout(r, 2000));
911
- await extractAndStoreMemories(supabase, getAnthropicClient(agent), agentId, storeId, message, result.finalText);
912
- } catch (err2) {
913
- log.error({
914
- err: err2.message
915
- }, "memory extract failed after retry");
916
- queueSpan(auditRowToSpan({
917
- action: "memory.extraction_failed",
918
- severity: "warning",
919
- store_id: storeId || null,
920
- resource_type: "agent_memory",
921
- resource_id: agentId,
922
- conversation_id: conversationId,
923
- user_id: userId || null,
924
- user_email: userEmail || null,
925
- error_type: classifyErrorType(err2.message) || undefined,
926
- service_name: "agent-server",
927
- span_kind: "INTERNAL",
928
- status_code: "ERROR",
929
- start_time: new Date().toISOString(),
930
- end_time: new Date().toISOString(),
931
- error_message: err2.message,
932
- details: {
933
- error: err2.message,
934
- user_message_preview: message.substring(0, 100)
935
- }
936
- }));
937
- }
938
- }
939
- }
940
-
941
- // ── Cost budget tracking — awaited with retry ──
942
- if (storeId && result.costUsd > 0) {
943
- try {
944
- await updateCostBudgets(supabase, storeId, agentId, result.costUsd);
945
- } catch (err1) {
946
- try {
947
- await new Promise(r => setTimeout(r, 1000));
948
- await updateCostBudgets(supabase, storeId, agentId, result.costUsd);
949
- } catch (err2) {
950
- log.error({
951
- err: err2.message
952
- }, "cost budget update failed after retry");
953
- // Flag conversation metadata so budget sync can be reconciled later
954
- await supabase.from("ai_conversations").update({
955
- metadata: {
956
- budget_sync_failed: true,
957
- failed_cost_usd: result.costUsd
958
- }
959
- }).eq("id", conversationId).then(() => {});
960
- }
961
- }
962
- }
963
- }
964
-
965
- // ============================================================================
966
- // AGENT CHAT HANDLER
967
- // ============================================================================
968
-
969
- async function handleAgentChat(req, res, supabase, body, user, isServiceRole, token, corsHeaders) {
970
- const {
971
- agentId,
972
- message,
973
- conversationHistory,
974
- source,
975
- conversationId,
976
- context,
977
- attachments
978
- } = body;
979
- let storeId = body.storeId;
980
- if (!agentId || !message) {
981
- jsonResponse(res, 400, {
982
- error: "agentId and message required"
983
- }, corsHeaders);
984
- return;
985
- }
986
- if (typeof message === "string" && message.length > 100_000) {
987
- jsonResponse(res, 400, {
988
- error: "Message too long (max 100K characters)"
989
- }, corsHeaders);
990
- return;
991
- }
992
-
993
- // Server-derived store resolution — never trust client blindly
994
- const resolvedStoreId = await resolveAndValidateStoreId(supabase, storeId, user, isServiceRole, token, body.userId);
995
-
996
- // For service-role callers (workflows, internal), also try body.userId fallback
997
- if (!resolvedStoreId && isServiceRole && body.userId) {
998
- const {
999
- data: srStores
1000
- } = await supabase.from("users").select("store_id").eq("auth_user_id", body.userId).not("store_id", "is", null).limit(1);
1001
- if (srStores?.length) {
1002
- storeId = srStores[0].store_id;
1003
- }
1004
- } else {
1005
- storeId = resolvedStoreId || undefined;
1006
- }
1007
-
1008
- // Fail closed: non-service-role requests MUST have a resolved store
1009
- if (!storeId && !isServiceRole) {
1010
- jsonResponse(res, 400, {
1011
- error: "storeId required for agent chat"
1012
- }, corsHeaders);
1013
- return;
1014
- }
1015
- log.info({
1016
- storeId: storeId || "NONE",
1017
- source: body.source || "unknown",
1018
- isServiceRole,
1019
- userId: user?.id || body.userId || "NONE"
1020
- }, "agent-chat request");
1021
-
1022
- // Agent chat rate limiting — per-store + concurrent cap
1023
- const rateLimitStoreId = storeId || agentId; // fallback to agentId if no store
1024
- const rateCheck = checkAgentChatRateLimit(rateLimitStoreId);
1025
- if (!rateCheck.allowed) {
1026
- res.writeHead(429, {
1027
- "Content-Type": "application/json",
1028
- ...corsHeaders
1029
- });
1030
- res.end(JSON.stringify({
1031
- error: rateCheck.error
1032
- }));
1033
- return;
1034
- }
1035
- agentChatConcurrent++;
1036
- try {
1037
- const userId = user?.id || body.userId || "";
1038
- const userEmail = user?.email || body.userEmail || null;
1039
- const agent = await loadAgentConfig(supabase, agentId, storeId);
1040
- if (!agent) {
1041
- jsonResponse(res, 404, {
1042
- error: "Agent not found"
1043
- }, corsHeaders);
1044
- return;
1045
- }
1046
- const {
1047
- core: coreTools,
1048
- extended: extendedTools
1049
- } = await loadTools(supabase);
1050
- setExtendedToolsCache(extendedTools); // Populate discover_tools handler cache
1051
- const {
1052
- rows: userToolRows,
1053
- defs: userToolDefs
1054
- } = storeId ? await loadUserTools(supabase, storeId) : {
1055
- rows: [],
1056
- defs: []
1057
- };
1058
- const tools = getToolsForAgent(agent, coreTools, userToolDefs);
1059
- const traceId = randomUUID();
1060
- const agentModel = agent.model || MODELS.SONNET;
1061
-
1062
- // Resolve or create conversation
1063
- let activeConversationId;
1064
- if (conversationId) {
1065
- activeConversationId = conversationId;
1066
- } else {
1067
- let conv = await supabase.from("ai_conversations").insert({
1068
- store_id: storeId || null,
1069
- user_id: userId || null,
1070
- agent_id: agentId,
1071
- title: message.substring(0, 100),
1072
- metadata: {
1073
- agentName: agent.name,
1074
- source: source || "whale_chat"
1075
- }
1076
- }).select("id").single();
1077
- if (conv.error) {
1078
- log.error({
1079
- err: conv.error.message,
1080
- details: conv.error.details,
1081
- hint: conv.error.hint,
1082
- storeId,
1083
- userId,
1084
- agentId
1085
- }, "conversation create failed");
1086
- // Retry without user_id (may be FK constraint)
1087
- conv = await supabase.from("ai_conversations").insert({
1088
- store_id: storeId || null,
1089
- agent_id: agentId,
1090
- title: message.substring(0, 100),
1091
- metadata: {
1092
- agentName: agent.name,
1093
- source: source || "whale_chat",
1094
- userId,
1095
- userEmail
1096
- }
1097
- }).select("id").single();
1098
- if (conv.error) {
1099
- log.error({
1100
- err: conv.error.message,
1101
- details: conv.error.details,
1102
- hint: conv.error.hint
1103
- }, "conversation retry create failed");
1104
- }
1105
- }
1106
- activeConversationId = conv.data?.id || randomUUID();
1107
- log.info({
1108
- conversationId: activeConversationId,
1109
- fromDb: !!conv.data?.id
1110
- }, "conversation resolved");
1111
- }
1112
-
1113
- // Build system prompt — shared helper ensures SSE chat + channel paths are identical
1114
- const {
1115
- systemPrompt,
1116
- dynamicContext
1117
- } = await buildAgentSystemPrompt(supabase, agent, storeId, message, tools, {
1118
- clientContext: context,
1119
- userId,
1120
- userEmail,
1121
- extendedTools: getExtendedToolsIndex()
1122
- });
1123
- const anthropic = getAnthropicClient(agent);
1124
-
1125
- // Resolve all behavioral config from DB — single source of truth
1126
- const resolved = resolveAgentLoopConfig(agent, "sse");
1127
- if (resolved.defaultsUsed.length > 0) {
1128
- log.info({
1129
- agentId,
1130
- defaults: resolved.defaultsUsed
1131
- }, "agent config defaults applied");
1132
- }
1133
- const MAX_HISTORY_CHARS = resolved.maxHistoryChars;
1134
-
1135
- // Build user message — multi-modal if image attachments present
1136
- let userContent;
1137
- if (attachments?.length) {
1138
- const contentBlocks = [];
1139
- for (const att of attachments) {
1140
- if (att.type === "image" && att.media_type && att.data) {
1141
- contentBlocks.push({
1142
- type: "image",
1143
- source: {
1144
- type: "base64",
1145
- media_type: att.media_type,
1146
- data: att.data
1147
- }
1148
- });
1149
- }
1150
- }
1151
- contentBlocks.push({
1152
- type: "text",
1153
- text: message
1154
- });
1155
- userContent = contentBlocks;
1156
- } else {
1157
- userContent = message;
1158
- }
1159
-
1160
- // Prepend dynamic context to user message to keep system prompt static (cache-friendly)
1161
- const contextPrefix = dynamicContext ? `[Context]\n${dynamicContext}\n\n[User Message]\n` : "";
1162
- const finalUserContent = typeof userContent === "string" ? contextPrefix + userContent : [...(contextPrefix ? [{
1163
- type: "text",
1164
- text: contextPrefix
1165
- }] : []), ...userContent];
1166
- const messages = [...compactHistory(conversationHistory || [], MAX_HISTORY_CHARS), {
1167
- role: "user",
1168
- content: finalUserContent
1169
- }];
1170
-
1171
- // Start SSE stream
1172
- res.writeHead(200, {
1173
- "Content-Type": "text/event-stream",
1174
- "Cache-Control": "no-cache",
1175
- Connection: "keep-alive",
1176
- ...corsHeaders
1177
- });
1178
-
1179
- // Client disconnect detection
1180
- let clientDisconnected = false;
1181
- req.on("close", () => {
1182
- clientDisconnected = true;
1183
- });
1184
- const startedAt = Date.now();
1185
- const chatStartTime = Date.now();
1186
- try {
1187
- const result = await runServerAgentLoop({
1188
- anthropic,
1189
- supabase,
1190
- model: agentModel,
1191
- systemPrompt,
1192
- messages,
1193
- tools,
1194
- extendedTools,
1195
- // All behavioral knobs from resolved config — DB is single source of truth
1196
- maxTurns: resolved.maxTurns,
1197
- temperature: resolved.temperature,
1198
- maxTokens: resolved.maxTokens,
1199
- maxConcurrentTools: resolved.maxConcurrentTools,
1200
- enableDelegation: resolved.enableDelegation,
1201
- enableModelRouting: resolved.enableModelRouting,
1202
- contextOverrides: resolved.contextOverrides,
1203
- subagentMaxTokens: resolved.subagentMaxTokens,
1204
- subagentMaxTurns: resolved.subagentMaxTurns,
1205
- subagentTemperature: resolved.subagentTemperature,
1206
- // Loop detector thresholds from DB config
1207
- loopDetectorConfig: {
1208
- identicalCallLimit: resolved.loopIdenticalCallLimit,
1209
- consecutiveErrorLimit: resolved.loopConsecutiveErrorLimit,
1210
- turnErrorLimit: resolved.loopTurnErrorLimit,
1211
- window: resolved.loopWindow,
1212
- sessionToolErrorLimit: resolved.loopSessionToolErrorLimit,
1213
- consecutiveFailedTurnLimit: resolved.loopConsecutiveFailedTurnLimit,
1214
- fileReadLimit: resolved.loopFileReadLimit
1215
- },
1216
- batchErrorLimit: resolved.loopBatchErrorLimit,
1217
- storeId,
1218
- traceId,
1219
- userId,
1220
- userEmail,
1221
- source,
1222
- conversationId: activeConversationId,
1223
- agentId,
1224
- executeTool: async (toolName, args, sourceOverride, onToolProgress) => {
1225
- const toolArgs = {
1226
- ...args
1227
- };
1228
- if (!toolArgs.store_id && storeId) toolArgs.store_id = storeId;
1229
- return executeTool(supabase, toolName, toolArgs, storeId, traceId, userId, userEmail, sourceOverride || source, activeConversationId, userToolRows, agentId, onToolProgress, true);
1230
- },
1231
- onToolProgress: (name, progress) => sendSSE(res, {
1232
- type: "tool_progress",
1233
- name,
1234
- progress
1235
- }),
1236
- onText: text => sendSSE(res, {
1237
- type: "text",
1238
- text
1239
- }),
1240
- onToolStart: (name, input) => {
1241
- // Only send when input is available — deduplicates streaming double-fire
1242
- // (sse-parser fires onToolStart twice: once on content_block_start without input,
1243
- // once on content_block_stop with parsed input)
1244
- if (input !== undefined) {
1245
- sendSSE(res, {
1246
- type: "tool_start",
1247
- name,
1248
- input
1249
- });
1250
- }
1251
- },
1252
- onToolResult: (name, success, r) => sendSSE(res, {
1253
- type: "tool_result",
1254
- name,
1255
- success,
1256
- result: r
1257
- }),
1258
- onSubagentProgress: evt => {
1259
- sendSSE(res, {
1260
- type: "subagent",
1261
- subagentId: evt.subagentId,
1262
- subagentEvent: evt.event,
1263
- name: evt.toolName
1264
- });
1265
- },
1266
- clientDisconnected: {
1267
- get value() {
1268
- return clientDisconnected;
1269
- }
1270
- },
1271
- startedAt,
1272
- maxDurationMs: resolved.maxDurationMs
1273
- });
1274
-
1275
- // Send usage SSE
1276
- sendSSE(res, {
1277
- type: "usage",
1278
- usage: {
1279
- input_tokens: result.tokens.input,
1280
- output_tokens: result.tokens.output,
1281
- cache_creation_tokens: result.tokens.cacheCreation,
1282
- cache_read_tokens: result.tokens.cacheRead,
1283
- cost_usd: result.costUsd
1284
- }
1285
- });
1286
-
1287
- // Persist everything — shared helper ensures SSE chat + channel paths are identical
1288
- await persistAgentTurn(supabase, agent, {
1289
- conversationId: activeConversationId,
1290
- storeId,
1291
- agentId,
1292
- agentModel,
1293
- traceId,
1294
- message,
1295
- result,
1296
- source: source || "whale_chat",
1297
- chatStartTime,
1298
- chatEndTime: Date.now(),
1299
- userId,
1300
- userEmail
1301
- });
1302
- sendSSE(res, {
1303
- type: "done",
1304
- conversationId: activeConversationId
1305
- });
1306
- } catch (err) {
1307
- sendSSE(res, {
1308
- type: "error",
1309
- error: sanitizeError(err)
1310
- });
1311
- }
1312
- res.end();
1313
- } finally {
1314
- agentChatConcurrent--;
1315
- }
1316
- }
1317
-
1318
- // ============================================================================
1319
- // MEMORY EXTRACTION — extract key facts after agent conversation
1320
- // ============================================================================
1321
-
1322
- async function extractAndStoreMemories(supabase, anthropic, agentId, storeId, userMessage, assistantResponse) {
1323
- const extraction = await anthropic.messages.create({
1324
- model: "claude-haiku-4-5-20251001",
1325
- max_tokens: 500,
1326
- system: `Extract key facts worth remembering from this conversation turn.
1327
- Return JSON array: [{"key": "short_key", "value": {"detail": "..."}, "type": "short_term|long_term|entity"}]
1328
- Rules:
1329
- - Only extract genuinely useful facts (preferences, decisions, corrections, entities)
1330
- - "entity" for people/businesses/products mentioned
1331
- - "long_term" for preferences, patterns, decisions
1332
- - "short_term" for context that may expire
1333
- - Return [] if nothing worth remembering
1334
- - Max 3 items per turn`,
1335
- messages: [{
1336
- role: "user",
1337
- content: `User: ${userMessage.substring(0, 500)}\n\nAssistant: ${assistantResponse.substring(0, 1000)}`
1338
- }]
1339
- });
1340
- const text = extraction.content.find(b => b.type === "text")?.text || "[]";
1341
- const match = text.match(/\[[\s\S]*\]/);
1342
- if (!match) return;
1343
- let items;
1344
- try {
1345
- items = JSON.parse(match[0]);
1346
- } catch {
1347
- return; // Malformed JSON from extraction
1348
- }
1349
- for (const item of items.slice(0, 3)) {
1350
- if (!item.key) continue;
1351
- await supabase.rpc("store_memory", {
1352
- p_agent_id: agentId,
1353
- p_store_id: storeId,
1354
- p_type: item.type || "short_term",
1355
- p_key: item.key,
1356
- p_value: item.value || {}
1357
- });
1358
- }
1359
- }
1360
-
1361
- // ============================================================================
1362
- // COST BUDGET TRACKING — increment active budgets after each conversation
1363
- // ============================================================================
1364
-
1365
- // P0 FIX: Atomic cost budget increment via RPC (fixes TOCTOU race on concurrent updates)
1366
- async function updateCostBudgets(supabase, storeId, agentId, costUsd) {
1367
- const {
1368
- error
1369
- } = await supabase.rpc("increment_cost_budget", {
1370
- p_store_id: storeId,
1371
- p_agent_id: agentId,
1372
- p_cost_usd: costUsd
1373
- });
1374
- if (error) {
1375
- console.error("[cost-budget] increment_cost_budget RPC failed:", error.message);
1376
- }
1377
- }
1378
-
1379
81
  // ============================================================================
1380
82
  // HTTP SERVER
1381
83
  // ============================================================================
@@ -1395,17 +97,31 @@ const server = http.createServer(async (req, res) => {
1395
97
  const ready = isReady();
1396
98
  const status = ready ? 200 : 503;
1397
99
  const agentStats = getGatewayStats();
100
+ const cbStats = getCircuitBreakerStats();
1398
101
  jsonResponse(res, status, {
1399
102
  status: ready ? "ok" : "starting",
1400
103
  version: process.env.npm_package_version || "6.4.0",
1401
104
  uptime: Math.floor(process.uptime()),
1402
105
  pg_listen: pgListenReady,
1403
106
  worker_pool: workerPoolReady,
1404
- local_agents: agentStats.total_agents
107
+ local_agents: agentStats.total_agents,
108
+ circuit_breakers: cbStats
1405
109
  }, corsHeaders);
1406
110
  return;
1407
111
  }
1408
112
 
113
+ // OpenAPI spec — public, no auth required (for Scalar docs viewer)
114
+ if (req.method === "GET" && req.url === "/openapi.json") {
115
+ const spec = generateOpenApiSpec();
116
+ res.writeHead(200, {
117
+ ...corsHeaders,
118
+ "Content-Type": "application/json",
119
+ "Cache-Control": "public, max-age=3600"
120
+ });
121
+ res.end(JSON.stringify(spec));
122
+ return;
123
+ }
124
+
1409
125
  // CORS preflight
1410
126
  if (req.method === "OPTIONS") {
1411
127
  res.writeHead(204, corsHeaders);
@@ -1464,6 +180,7 @@ const server = http.createServer(async (req, res) => {
1464
180
  }
1465
181
 
1466
182
  // H6 FIX: Enforce per-run and total client limits
183
+ const sseClients = getSseClients();
1467
184
  const existingClients = sseClients.get(runId)?.size || 0;
1468
185
  if (existingClients >= MAX_SSE_CLIENTS_PER_RUN) {
1469
186
  jsonResponse(res, 429, {
@@ -1985,6 +702,43 @@ const server = http.createServer(async (req, res) => {
1985
702
  }
1986
703
  return;
1987
704
  }
705
+
706
+ // ================================================================
707
+ // Session API routes (supports GET, POST)
708
+ // Must be before the method gate since GET /sessions is valid
709
+ // ================================================================
710
+ if (pathname.startsWith("/sessions")) {
711
+ const authHeader = req.headers.authorization;
712
+ const token = authHeader?.startsWith("Bearer ") ? authHeader.substring(7) : "";
713
+ if (!token) {
714
+ req.resume();
715
+ jsonResponse(res, 401, {
716
+ error: "Missing authorization"
717
+ }, corsHeaders);
718
+ return;
719
+ }
720
+ const supabase = getServiceClient();
721
+ let userId;
722
+ const isServiceRole = safeCompare(token, SUPABASE_SERVICE_ROLE_KEY) || safeCompare(token, SERVICE_ROLE_JWT);
723
+ if (!isServiceRole) {
724
+ const {
725
+ data: {
726
+ user: authUser
727
+ }
728
+ } = await supabase.auth.getUser(token);
729
+ if (authUser) userId = authUser.id;
730
+ }
731
+ const handled = await handleSessionRoutes(req, res, pathname, url, corsHeaders, supabase, {
732
+ userId,
733
+ isServiceRole
734
+ });
735
+ if (!handled) {
736
+ jsonResponse(res, 404, {
737
+ error: `No route: ${req.method} ${pathname}`
738
+ }, corsHeaders);
739
+ }
740
+ return;
741
+ }
1988
742
  if (req.method !== "POST" && req.method !== "DELETE" && req.method !== "PUT") {
1989
743
  jsonResponse(res, 405, {
1990
744
  error: "Method not allowed"
@@ -2898,406 +1652,17 @@ const server = http.createServer(async (req, res) => {
2898
1652
  }
2899
1653
  });
2900
1654
 
2901
- // Inject tool executor into workflow engine (avoids circular dependency)
2902
- setToolExecutor((supabase, toolName, args, storeId, traceId) => {
2903
- // Store boundary validation: prevent workflows from accessing other stores
2904
- if (args.store_id && args.store_id !== storeId) {
2905
- return Promise.resolve({
2906
- success: false,
2907
- error: "Store boundary violation: workflow cannot access other stores"
2908
- });
2909
- }
2910
- args.store_id = storeId; // Force the workflow's store
2911
- return executeTool(supabase, toolName, args, storeId, traceId, null, null, "workflow_engine");
2912
- });
2913
-
2914
- // Inject agent executor for "agent" step type in workflows
2915
- setAgentExecutor(async (supabase, agentId, prompt, storeId, maxTurns = 5, onToken, traceId) => {
2916
- const agent = await loadAgentConfig(supabase, agentId, storeId);
2917
- if (!agent) return {
2918
- success: false,
2919
- error: `Agent ${agentId} not found`
2920
- };
2921
-
2922
- // Workflow agents get all tools (no lazy loading — they run headless)
2923
- const {
2924
- all: allTools
2925
- } = await loadTools(supabase);
2926
- const {
2927
- rows: userToolRows,
2928
- defs: userToolDefs
2929
- } = await loadUserTools(supabase, storeId);
2930
- const tools = getToolsForAgent(agent, allTools, userToolDefs);
2931
- const agentModel = agent.model || MODELS.SONNET;
2932
-
2933
- // Resolve all behavioral config from DB — workflow maxTurns caps agent config
2934
- const resolved = resolveAgentLoopConfig(agent, "workflow", maxTurns);
2935
- if (resolved.defaultsUsed.length > 0) {
2936
- log.info({
2937
- agentId,
2938
- callPath: "workflow",
2939
- defaults: resolved.defaultsUsed
2940
- }, "workflow agent config defaults applied");
2941
- }
2942
-
2943
- // Build full system prompt — shared helper ensures workflow gets same context as SSE/channel
2944
- // (previously hand-built, missing location/customer context)
2945
- const {
2946
- systemPrompt
2947
- } = await buildAgentSystemPrompt(supabase, agent, storeId, prompt, tools);
2948
- try {
2949
- const result = await runServerAgentLoop({
2950
- anthropic: getAnthropicClient(agent),
2951
- supabase,
2952
- model: agentModel,
2953
- systemPrompt,
2954
- messages: [{
2955
- role: "user",
2956
- content: prompt
2957
- }],
2958
- tools,
2959
- // All behavioral knobs from resolved config — DB is single source of truth
2960
- maxTurns: resolved.maxTurns,
2961
- temperature: resolved.temperature,
2962
- maxTokens: resolved.maxTokens,
2963
- maxConcurrentTools: resolved.maxConcurrentTools,
2964
- enableDelegation: resolved.enableDelegation,
2965
- enableModelRouting: resolved.enableModelRouting,
2966
- contextOverrides: resolved.contextOverrides,
2967
- subagentMaxTokens: resolved.subagentMaxTokens,
2968
- subagentMaxTurns: resolved.subagentMaxTurns,
2969
- subagentTemperature: resolved.subagentTemperature,
2970
- loopDetectorConfig: {
2971
- identicalCallLimit: resolved.loopIdenticalCallLimit,
2972
- consecutiveErrorLimit: resolved.loopConsecutiveErrorLimit,
2973
- turnErrorLimit: resolved.loopTurnErrorLimit,
2974
- window: resolved.loopWindow,
2975
- sessionToolErrorLimit: resolved.loopSessionToolErrorLimit,
2976
- consecutiveFailedTurnLimit: resolved.loopConsecutiveFailedTurnLimit,
2977
- fileReadLimit: resolved.loopFileReadLimit
2978
- },
2979
- batchErrorLimit: resolved.loopBatchErrorLimit,
2980
- storeId,
2981
- source: "workflow_agent",
2982
- agentId,
2983
- traceId,
2984
- executeTool: async (toolName, args) => {
2985
- const toolArgs = {
2986
- ...args
2987
- };
2988
- if (!toolArgs.store_id) toolArgs.store_id = storeId;
2989
- return executeTool(supabase, toolName, toolArgs, storeId, traceId, null, null, "workflow_agent", undefined, userToolRows, agentId, undefined, true);
2990
- },
2991
- enableStreaming: !!onToken,
2992
- onText: onToken || undefined,
2993
- maxDurationMs: resolved.maxDurationMs
2994
- });
2995
- return {
2996
- success: true,
2997
- response: result.finalText || "(no response)"
2998
- };
2999
- } catch (err) {
3000
- return {
3001
- success: false,
3002
- error: sanitizeError(err)
3003
- };
3004
- }
3005
- });
3006
-
3007
- // Inject token broadcaster for real-time agent step streaming
3008
- setTokenBroadcaster((runId, stepKey, token) => {
3009
- broadcastToRun(runId, {
3010
- type: "agent_token",
3011
- run_id: runId,
3012
- step_key: stepKey,
3013
- token
3014
- });
3015
- });
3016
-
3017
- // Inject step error broadcaster for real-time workflow error surfacing
3018
- setStepErrorBroadcaster((runId, data) => {
3019
- broadcastToRun(runId, data);
3020
- });
3021
-
3022
- // Shared agent invoker — used by channel messages, webchat, and any source
3023
- // Uses shared helpers so it's IDENTICAL to CLI chat — same prompt, tools, memory, persistence, audit
3024
- async function invokeAgentForChannel(supabase, agentId, message, storeId, conversationId, senderContext) {
3025
- const agent = await loadAgentConfig(supabase, agentId, storeId);
3026
- if (!agent) return {
3027
- success: false,
3028
- error: `Agent ${agentId} not found`
3029
- };
3030
- const {
3031
- core: coreTools,
3032
- extended: extendedTools
3033
- } = await loadTools(supabase);
3034
- setExtendedToolsCache(extendedTools);
3035
- const {
3036
- rows: userToolRows,
3037
- defs: userToolDefs
3038
- } = await loadUserTools(supabase, storeId);
3039
- const tools = getToolsForAgent(agent, coreTools, userToolDefs);
3040
- const agentModel = agent.model || MODELS.SONNET;
3041
-
3042
- // Resolve all behavioral config from DB — channel has 15-turn safety cap built in
3043
- const resolved = resolveAgentLoopConfig(agent, "channel");
3044
- if (resolved.defaultsUsed.length > 0) {
3045
- log.info({
3046
- agentId,
3047
- callPath: "channel",
3048
- defaults: resolved.defaultsUsed
3049
- }, "channel agent config defaults applied");
3050
- }
3051
-
3052
- // Build system prompt — shared helper, identical to SSE chat
3053
- const {
3054
- systemPrompt,
3055
- dynamicContext
3056
- } = await buildAgentSystemPrompt(supabase, agent, storeId, message, tools, {
3057
- senderContext,
3058
- extendedTools: getExtendedToolsIndex()
3059
- });
3060
-
3061
- // Update ai_conversations with agent_id (fire-and-forget)
3062
- if (conversationId) {
3063
- Promise.resolve(supabase.from("ai_conversations").update({
3064
- agent_id: agentId
3065
- }).eq("id", conversationId).is("agent_id", null)).catch(() => {});
3066
- }
3067
-
3068
- // Load conversation history with size-based compaction (same as SSE chat)
3069
- const MAX_HISTORY_CHARS = resolved.maxHistoryChars;
3070
- let loadedHistory = [];
3071
- if (conversationId) {
3072
- try {
3073
- const {
3074
- data: history
3075
- } = await supabase.from("ai_messages").select("role, content").eq("conversation_id", conversationId).order("created_at", {
3076
- ascending: true
3077
- }).limit(50);
3078
- if (history?.length) {
3079
- const raw = [];
3080
- for (const m of history) {
3081
- if (m.role === "user" || m.role === "assistant") {
3082
- raw.push({
3083
- role: m.role,
3084
- content: m.content
3085
- });
3086
- }
3087
- }
3088
- loadedHistory = compactHistory(raw, MAX_HISTORY_CHARS);
3089
- }
3090
- } catch {/* history not critical */}
3091
- }
3092
- // Prepend dynamic context to user message to keep system prompt static (cache-friendly)
3093
- const contextPrefix = dynamicContext ? `[Context]\n${dynamicContext}\n\n[User Message]\n` : "";
3094
- const finalMessage = contextPrefix + message;
3095
- const messages = [...loadedHistory, {
3096
- role: "user",
3097
- content: finalMessage
3098
- }];
3099
- const traceId = randomUUID();
3100
- const chatStartTime = Date.now();
3101
- try {
3102
- const result = await runServerAgentLoop({
3103
- anthropic: getAnthropicClient(agent),
3104
- supabase,
3105
- model: agentModel,
3106
- systemPrompt,
3107
- messages,
3108
- tools,
3109
- extendedTools,
3110
- // All behavioral knobs from resolved config — DB is single source of truth
3111
- maxTurns: resolved.maxTurns,
3112
- temperature: resolved.temperature,
3113
- maxTokens: resolved.maxTokens,
3114
- maxConcurrentTools: resolved.maxConcurrentTools,
3115
- enableDelegation: resolved.enableDelegation,
3116
- enableModelRouting: resolved.enableModelRouting,
3117
- contextOverrides: resolved.contextOverrides,
3118
- subagentMaxTokens: resolved.subagentMaxTokens,
3119
- subagentMaxTurns: resolved.subagentMaxTurns,
3120
- subagentTemperature: resolved.subagentTemperature,
3121
- loopDetectorConfig: {
3122
- identicalCallLimit: resolved.loopIdenticalCallLimit,
3123
- consecutiveErrorLimit: resolved.loopConsecutiveErrorLimit,
3124
- turnErrorLimit: resolved.loopTurnErrorLimit,
3125
- window: resolved.loopWindow,
3126
- sessionToolErrorLimit: resolved.loopSessionToolErrorLimit,
3127
- consecutiveFailedTurnLimit: resolved.loopConsecutiveFailedTurnLimit,
3128
- fileReadLimit: resolved.loopFileReadLimit
3129
- },
3130
- batchErrorLimit: resolved.loopBatchErrorLimit,
3131
- storeId,
3132
- source: "channel_agent",
3133
- agentId,
3134
- traceId,
3135
- conversationId,
3136
- executeTool: async (toolName, args) => {
3137
- const toolArgs = {
3138
- ...args
3139
- };
3140
- if (!toolArgs.store_id) toolArgs.store_id = storeId;
3141
- // Pass sender context as user identity so node-triggered tool calls aren't anonymous
3142
- const senderUserId = senderContext?.customerId || null;
3143
- const senderUserLabel = senderContext?.customerName || senderContext?.senderName || (senderContext?.senderId ? `${senderContext.channelType}:${senderContext.senderId}` : null);
3144
- return executeTool(supabase, toolName, toolArgs, storeId, traceId, senderUserId, senderUserLabel, "channel_agent", conversationId, userToolRows, agentId, undefined, true);
3145
- },
3146
- enableStreaming: false,
3147
- maxDurationMs: resolved.maxDurationMs
3148
- });
3149
-
3150
- // Persist everything — shared helper, identical to SSE chat
3151
- await persistAgentTurn(supabase, agent, {
3152
- conversationId,
3153
- storeId,
3154
- agentId,
3155
- agentModel,
3156
- traceId,
3157
- message,
3158
- result,
3159
- source: "channel_agent",
3160
- chatStartTime,
3161
- chatEndTime: Date.now(),
3162
- userId: senderContext?.customerId || undefined,
3163
- userEmail: senderContext?.customerName || senderContext?.senderName || (senderContext?.senderId ? `${senderContext.channelType}:${senderContext.senderId}` : undefined),
3164
- senderContext
3165
- });
3166
- return {
3167
- success: true,
3168
- response: result.finalText || "(no response)"
3169
- };
3170
- } catch (err) {
3171
- return {
3172
- success: false,
3173
- error: err.message
3174
- };
3175
- }
3176
- }
1655
+ // Wire executors into workflow engine (extracted modules — no inline duplicates)
1656
+ wireToolExecutor();
1657
+ wireAgentExecutor();
1658
+ wireBroadcasters();
3177
1659
 
3178
1660
  // Wire both channel and webchat to the same invoker
3179
1661
  setNodeAgentInvoker(invokeAgentForChannel);
3180
1662
  webchatAgentInvoker = invokeAgentForChannel;
3181
1663
 
3182
- // ============================================================================
3183
- // NODE OFFLINE DETECTION
3184
- // ============================================================================
3185
-
3186
- async function enforceNodeOfflineStatus(supabase) {
3187
- const threshold = new Date(Date.now() - 3 * 60_000).toISOString(); // 3 missed heartbeats (60s interval)
3188
- const {
3189
- data
3190
- } = await supabase.from("nodes").update({
3191
- status: "offline"
3192
- }).eq("status", "online").lt("last_heartbeat", threshold).select("id");
3193
- return data?.length || 0;
3194
- }
3195
-
3196
- // ============================================================================
3197
- // PERSISTENT WORKFLOW WORKER LOOP (5-second interval)
3198
- // ============================================================================
3199
-
3200
- // Phase 3.1: Increased from 5s to 15s — NOTIFY-driven execution handles the fast path
3201
- // Worker loop is now a safety net for missed notifications
3202
- const BASE_WORKER_INTERVAL_MS = 15_000;
3203
- const MAX_WORKER_INTERVAL_MS = 60_000;
3204
- let workerRunning = false;
3205
- let consecutiveErrors = 0;
3206
- let currentWorkerInterval = BASE_WORKER_INTERVAL_MS;
3207
- async function workflowWorkerLoop() {
3208
- if (workerRunning) return; // Prevent concurrent runs
3209
- workerRunning = true;
3210
- try {
3211
- const supabase = getServiceClient();
3212
- const [stepResult, waitingResolved] = await Promise.all([processWorkflowSteps(supabase, 10), processWaitingSteps(supabase), Promise.resolve(supabase.rpc("expire_pending_waitpoints")).then(() => {}).catch(e => log.warn({
3213
- err: e.message
3214
- }, "expire_pending_waitpoints failed")) // Non-fatal
3215
- ]);
3216
-
3217
- // Schedule triggers + timeout enforcement + event triggers + orphan cleanup + DLQ retries + node offline detection
3218
- const [scheduled, timedOut, eventsProcessed, orphansCleaned, dlqRetried, nodesOfflined] = await Promise.all([processScheduleTriggers(supabase).catch(e => {
3219
- log.warn({
3220
- err: e.message
3221
- }, "processScheduleTriggers failed");
3222
- return 0;
3223
- }), enforceWorkflowTimeouts(supabase).catch(e => {
3224
- log.warn({
3225
- err: e.message
3226
- }, "enforceWorkflowTimeouts failed");
3227
- return 0;
3228
- }), processEventTriggers(supabase).catch(e => {
3229
- log.warn({
3230
- err: e.message
3231
- }, "processEventTriggers failed");
3232
- return 0;
3233
- }), cleanupOrphanedSteps(supabase).catch(e => {
3234
- log.warn({
3235
- err: e.message
3236
- }, "cleanupOrphanedSteps failed");
3237
- return 0;
3238
- }), processDlqRetries(supabase).catch(e => {
3239
- log.warn({
3240
- err: e.message
3241
- }, "processDlqRetries failed");
3242
- return 0;
3243
- }), enforceNodeOfflineStatus(supabase).catch(e => {
3244
- log.warn({
3245
- err: e.message
3246
- }, "enforceNodeOfflineStatus failed");
3247
- return 0;
3248
- })]);
3249
- if (stepResult.processed > 0 || waitingResolved > 0 || scheduled > 0 || timedOut > 0 || eventsProcessed > 0 || stepResult.reclaimed > 0 || orphansCleaned > 0 || dlqRetried > 0 || nodesOfflined > 0) {
3250
- log.info({
3251
- processed: stepResult.processed,
3252
- errors: stepResult.errors,
3253
- reclaimed: stepResult.reclaimed || 0,
3254
- waiting: waitingResolved,
3255
- scheduled,
3256
- timedOut,
3257
- events: eventsProcessed,
3258
- orphans: orphansCleaned,
3259
- dlqRetries: dlqRetried,
3260
- nodesOfflined
3261
- }, "worker tick");
3262
- }
3263
-
3264
- // Reset backoff on success
3265
- if (consecutiveErrors > 0) {
3266
- consecutiveErrors = 0;
3267
- if (currentWorkerInterval !== BASE_WORKER_INTERVAL_MS) {
3268
- currentWorkerInterval = BASE_WORKER_INTERVAL_MS;
3269
- clearInterval(workerInterval);
3270
- workerInterval = setInterval(workflowWorkerLoop, currentWorkerInterval);
3271
- log.info({
3272
- intervalMs: currentWorkerInterval
3273
- }, "worker interval reset after recovery");
3274
- }
3275
- }
3276
- } catch (err) {
3277
- consecutiveErrors++;
3278
- log.error({
3279
- err: sanitizeError(err),
3280
- consecutiveErrors
3281
- }, "worker error");
3282
-
3283
- // Exponential backoff: 5s → 10s → 20s → 40s → 60s (cap)
3284
- if (consecutiveErrors >= 3) {
3285
- const newInterval = Math.min(BASE_WORKER_INTERVAL_MS * Math.pow(2, consecutiveErrors - 2), MAX_WORKER_INTERVAL_MS);
3286
- if (newInterval !== currentWorkerInterval) {
3287
- currentWorkerInterval = newInterval;
3288
- clearInterval(workerInterval);
3289
- workerInterval = setInterval(workflowWorkerLoop, currentWorkerInterval);
3290
- log.warn({
3291
- intervalMs: currentWorkerInterval,
3292
- consecutiveErrors
3293
- }, "worker interval increased due to repeated errors");
3294
- }
3295
- }
3296
- } finally {
3297
- workerRunning = false;
3298
- }
3299
- }
3300
- let workerInterval = setInterval(workflowWorkerLoop, BASE_WORKER_INTERVAL_MS);
1664
+ // Start persistent workflow worker loop (extracted module)
1665
+ startWorkerLoop();
3301
1666
 
3302
1667
  // Initialize shared Supabase client with retry logic before server starts
3303
1668
  initSupabase(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY);
@@ -3305,8 +1670,7 @@ server.listen(PORT, () => {
3305
1670
  log.info({
3306
1671
  port: PORT,
3307
1672
  supabaseUrl: SUPABASE_URL,
3308
- runtime: process.version,
3309
- workerIntervalMs: BASE_WORKER_INTERVAL_MS
1673
+ runtime: process.version
3310
1674
  }, "server listening");
3311
1675
 
3312
1676
  // Initialize code worker pool for fast code step execution
@@ -3367,11 +1731,12 @@ async function gracefulShutdown(signal) {
3367
1731
  log.info("HTTP server closed");
3368
1732
  });
3369
1733
 
3370
- // 2. Clear workflow worker intervals
3371
- clearInterval(workerInterval);
1734
+ // 2. Clear workflow worker + SSE cleanup intervals
1735
+ stopWorkerLoop();
3372
1736
  clearInterval(sseCleanupInterval);
3373
1737
 
3374
1738
  // 3. Close all SSE client connections
1739
+ const sseClients = getSseClients();
3375
1740
  for (const [, clients] of sseClients) {
3376
1741
  for (const res of clients) {
3377
1742
  try {
@@ -3415,11 +1780,7 @@ async function gracefulShutdown(signal) {
3415
1780
  rateLimiter.shutdown();
3416
1781
 
3417
1782
  // 5. Close pg LISTEN connection
3418
- if (pgClient) {
3419
- pgClient.end().catch(() => {});
3420
- pgClient = null;
3421
- log.info("pg LISTEN connection closed");
3422
- }
1783
+ closePgClient();
3423
1784
 
3424
1785
  // 6. Wait for active requests to drain (up to 25 seconds)
3425
1786
  const drainStart = Date.now();