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