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