@wingman-ai/gateway 0.1.0
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/.wingman/agents/README.md +161 -0
- package/.wingman/agents/coding/agent.md +147 -0
- package/.wingman/agents/coding/implementor.md +56 -0
- package/.wingman/agents/main/agent.md +19 -0
- package/.wingman/agents/researcher/agent.md +62 -0
- package/.wingman/agents/stock-trader/agent.md +223 -0
- package/.wingman/agents/stock-trader/chain-curator.md +24 -0
- package/.wingman/agents/stock-trader/goal-translator.md +42 -0
- package/.wingman/agents/stock-trader/guardrails-veto.md +11 -0
- package/.wingman/agents/stock-trader/path-planner.md +23 -0
- package/.wingman/agents/stock-trader/regime-analyst.md +15 -0
- package/.wingman/agents/stock-trader/risk.md +20 -0
- package/.wingman/agents/stock-trader/selection.md +22 -0
- package/.wingman/agents/stock-trader/strategy-composer.md +38 -0
- package/.wingman/agents/wingman/agent.json +12 -0
- package/bin/wingman +7 -0
- package/dist/agent/config/agentConfig.cjs +95 -0
- package/dist/agent/config/agentConfig.d.ts +187 -0
- package/dist/agent/config/agentConfig.js +52 -0
- package/dist/agent/config/agentLoader.cjs +242 -0
- package/dist/agent/config/agentLoader.d.ts +42 -0
- package/dist/agent/config/agentLoader.js +208 -0
- package/dist/agent/config/mcpClientManager.cjs +168 -0
- package/dist/agent/config/mcpClientManager.d.ts +41 -0
- package/dist/agent/config/mcpClientManager.js +134 -0
- package/dist/agent/config/modelFactory.cjs +175 -0
- package/dist/agent/config/modelFactory.d.ts +33 -0
- package/dist/agent/config/modelFactory.js +141 -0
- package/dist/agent/config/toolRegistry.cjs +111 -0
- package/dist/agent/config/toolRegistry.d.ts +25 -0
- package/dist/agent/config/toolRegistry.js +71 -0
- package/dist/agent/middleware/additional-messages.cjs +60 -0
- package/dist/agent/middleware/additional-messages.d.ts +7 -0
- package/dist/agent/middleware/additional-messages.js +26 -0
- package/dist/agent/middleware/hooks/executor.cjs +137 -0
- package/dist/agent/middleware/hooks/executor.d.ts +52 -0
- package/dist/agent/middleware/hooks/executor.js +103 -0
- package/dist/agent/middleware/hooks/input-builder.cjs +55 -0
- package/dist/agent/middleware/hooks/input-builder.d.ts +15 -0
- package/dist/agent/middleware/hooks/input-builder.js +21 -0
- package/dist/agent/middleware/hooks/matcher.cjs +59 -0
- package/dist/agent/middleware/hooks/matcher.d.ts +27 -0
- package/dist/agent/middleware/hooks/matcher.js +22 -0
- package/dist/agent/middleware/hooks/merger.cjs +54 -0
- package/dist/agent/middleware/hooks/merger.d.ts +18 -0
- package/dist/agent/middleware/hooks/merger.js +20 -0
- package/dist/agent/middleware/hooks/types.cjs +62 -0
- package/dist/agent/middleware/hooks/types.d.ts +82 -0
- package/dist/agent/middleware/hooks/types.js +19 -0
- package/dist/agent/middleware/hooks.cjs +79 -0
- package/dist/agent/middleware/hooks.d.ts +19 -0
- package/dist/agent/middleware/hooks.js +45 -0
- package/dist/agent/middleware/media-compat.cjs +80 -0
- package/dist/agent/middleware/media-compat.d.ts +7 -0
- package/dist/agent/middleware/media-compat.js +46 -0
- package/dist/agent/tests/agentConfig.test.cjs +132 -0
- package/dist/agent/tests/agentConfig.test.d.ts +1 -0
- package/dist/agent/tests/agentConfig.test.js +126 -0
- package/dist/agent/tests/agentLoader.test.cjs +235 -0
- package/dist/agent/tests/agentLoader.test.d.ts +1 -0
- package/dist/agent/tests/agentLoader.test.js +229 -0
- package/dist/agent/tests/modelFactory.test.cjs +114 -0
- package/dist/agent/tests/modelFactory.test.d.ts +1 -0
- package/dist/agent/tests/modelFactory.test.js +108 -0
- package/dist/agent/tests/test-agent-loader.cjs +33 -0
- package/dist/agent/tests/test-agent-loader.d.ts +1 -0
- package/dist/agent/tests/test-agent-loader.js +27 -0
- package/dist/agent/tests/test-subagent-loading.cjs +99 -0
- package/dist/agent/tests/test-subagent-loading.d.ts +1 -0
- package/dist/agent/tests/test-subagent-loading.js +93 -0
- package/dist/agent/tests/toolRegistry.test.cjs +109 -0
- package/dist/agent/tests/toolRegistry.test.d.ts +1 -0
- package/dist/agent/tests/toolRegistry.test.js +103 -0
- package/dist/agent/tools/code_search.cjs +108 -0
- package/dist/agent/tools/code_search.d.ts +24 -0
- package/dist/agent/tools/code_search.js +74 -0
- package/dist/agent/tools/command_execute.cjs +136 -0
- package/dist/agent/tools/command_execute.d.ts +12 -0
- package/dist/agent/tools/command_execute.js +99 -0
- package/dist/agent/tools/git_status.cjs +126 -0
- package/dist/agent/tools/git_status.d.ts +15 -0
- package/dist/agent/tools/git_status.js +92 -0
- package/dist/agent/tools/internet_search.cjs +93 -0
- package/dist/agent/tools/internet_search.d.ts +25 -0
- package/dist/agent/tools/internet_search.js +56 -0
- package/dist/agent/tools/think.cjs +53 -0
- package/dist/agent/tools/think.d.ts +26 -0
- package/dist/agent/tools/think.js +16 -0
- package/dist/agent/tools/web_crawler.cjs +180 -0
- package/dist/agent/tools/web_crawler.d.ts +31 -0
- package/dist/agent/tools/web_crawler.js +143 -0
- package/dist/agent/utils.cjs +54 -0
- package/dist/agent/utils.d.ts +1 -0
- package/dist/agent/utils.js +10 -0
- package/dist/cli/commands/agent.cjs +169 -0
- package/dist/cli/commands/agent.d.ts +15 -0
- package/dist/cli/commands/agent.js +125 -0
- package/dist/cli/commands/gateway.cjs +601 -0
- package/dist/cli/commands/gateway.d.ts +12 -0
- package/dist/cli/commands/gateway.js +567 -0
- package/dist/cli/commands/init.cjs +681 -0
- package/dist/cli/commands/init.d.ts +10 -0
- package/dist/cli/commands/init.js +634 -0
- package/dist/cli/commands/provider.cjs +208 -0
- package/dist/cli/commands/provider.d.ts +5 -0
- package/dist/cli/commands/provider.js +174 -0
- package/dist/cli/commands/skill.cjs +145 -0
- package/dist/cli/commands/skill.d.ts +10 -0
- package/dist/cli/commands/skill.js +111 -0
- package/dist/cli/config/loader.cjs +143 -0
- package/dist/cli/config/loader.d.ts +14 -0
- package/dist/cli/config/loader.js +109 -0
- package/dist/cli/config/schema.cjs +262 -0
- package/dist/cli/config/schema.d.ts +268 -0
- package/dist/cli/config/schema.js +213 -0
- package/dist/cli/core/agentInvoker.cjs +284 -0
- package/dist/cli/core/agentInvoker.d.ts +77 -0
- package/dist/cli/core/agentInvoker.js +247 -0
- package/dist/cli/core/commandHandler.cjs +257 -0
- package/dist/cli/core/commandHandler.d.ts +62 -0
- package/dist/cli/core/commandHandler.js +223 -0
- package/dist/cli/core/database/bunSqliteAdapter.cjs +87 -0
- package/dist/cli/core/database/bunSqliteAdapter.d.ts +34 -0
- package/dist/cli/core/database/bunSqliteAdapter.js +53 -0
- package/dist/cli/core/loggerBridge.cjs +42 -0
- package/dist/cli/core/loggerBridge.d.ts +8 -0
- package/dist/cli/core/loggerBridge.js +8 -0
- package/dist/cli/core/outputManager.cjs +106 -0
- package/dist/cli/core/outputManager.d.ts +43 -0
- package/dist/cli/core/outputManager.js +72 -0
- package/dist/cli/core/sessionManager.cjs +535 -0
- package/dist/cli/core/sessionManager.d.ts +111 -0
- package/dist/cli/core/sessionManager.js +486 -0
- package/dist/cli/core/streamParser.cjs +328 -0
- package/dist/cli/core/streamParser.d.ts +42 -0
- package/dist/cli/core/streamParser.js +288 -0
- package/dist/cli/index.cjs +211 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +205 -0
- package/dist/cli/services/skillRepository.cjs +178 -0
- package/dist/cli/services/skillRepository.d.ts +35 -0
- package/dist/cli/services/skillRepository.js +144 -0
- package/dist/cli/services/skillService.cjs +336 -0
- package/dist/cli/services/skillService.d.ts +48 -0
- package/dist/cli/services/skillService.js +302 -0
- package/dist/cli/types/gateway.cjs +18 -0
- package/dist/cli/types/gateway.d.ts +18 -0
- package/dist/cli/types/gateway.js +0 -0
- package/dist/cli/types/init.cjs +18 -0
- package/dist/cli/types/init.d.ts +13 -0
- package/dist/cli/types/init.js +0 -0
- package/dist/cli/types/provider.cjs +18 -0
- package/dist/cli/types/provider.d.ts +9 -0
- package/dist/cli/types/provider.js +0 -0
- package/dist/cli/types/skill.cjs +18 -0
- package/dist/cli/types/skill.d.ts +71 -0
- package/dist/cli/types/skill.js +0 -0
- package/dist/cli/types.cjs +18 -0
- package/dist/cli/types.d.ts +175 -0
- package/dist/cli/types.js +0 -0
- package/dist/cli/ui/AgentOutput.cjs +82 -0
- package/dist/cli/ui/AgentOutput.d.ts +8 -0
- package/dist/cli/ui/AgentOutput.js +38 -0
- package/dist/cli/ui/App.cjs +285 -0
- package/dist/cli/ui/App.d.ts +6 -0
- package/dist/cli/ui/App.js +241 -0
- package/dist/cli/ui/ErrorDisplay.cjs +65 -0
- package/dist/cli/ui/ErrorDisplay.d.ts +8 -0
- package/dist/cli/ui/ErrorDisplay.js +21 -0
- package/dist/cli/ui/LogDisplay.cjs +74 -0
- package/dist/cli/ui/LogDisplay.d.ts +13 -0
- package/dist/cli/ui/LogDisplay.js +30 -0
- package/dist/cli/ui/SessionListDisplay.cjs +135 -0
- package/dist/cli/ui/SessionListDisplay.d.ts +9 -0
- package/dist/cli/ui/SessionListDisplay.js +91 -0
- package/dist/cli/ui/blockHelpers.cjs +80 -0
- package/dist/cli/ui/blockHelpers.d.ts +21 -0
- package/dist/cli/ui/blockHelpers.js +40 -0
- package/dist/cli/ui/components/ToolCallDisplay.cjs +207 -0
- package/dist/cli/ui/components/ToolCallDisplay.d.ts +7 -0
- package/dist/cli/ui/components/ToolCallDisplay.js +162 -0
- package/dist/cli/ui/components/ToolResultDisplay.cjs +86 -0
- package/dist/cli/ui/components/ToolResultDisplay.d.ts +8 -0
- package/dist/cli/ui/components/ToolResultDisplay.js +42 -0
- package/dist/cli/ui/toolDisplayHelpers.cjs +112 -0
- package/dist/cli/ui/toolDisplayHelpers.d.ts +3 -0
- package/dist/cli/ui/toolDisplayHelpers.js +72 -0
- package/dist/gateway/adapters/discord.cjs +298 -0
- package/dist/gateway/adapters/discord.d.ts +42 -0
- package/dist/gateway/adapters/discord.js +246 -0
- package/dist/gateway/auth.cjs +94 -0
- package/dist/gateway/auth.d.ts +36 -0
- package/dist/gateway/auth.js +60 -0
- package/dist/gateway/broadcast.cjs +131 -0
- package/dist/gateway/broadcast.d.ts +76 -0
- package/dist/gateway/broadcast.js +97 -0
- package/dist/gateway/client.cjs +282 -0
- package/dist/gateway/client.d.ts +141 -0
- package/dist/gateway/client.js +248 -0
- package/dist/gateway/daemon.cjs +195 -0
- package/dist/gateway/daemon.d.ts +67 -0
- package/dist/gateway/daemon.js +161 -0
- package/dist/gateway/discovery/index.cjs +72 -0
- package/dist/gateway/discovery/index.d.ts +3 -0
- package/dist/gateway/discovery/index.js +3 -0
- package/dist/gateway/discovery/mdns.cjs +221 -0
- package/dist/gateway/discovery/mdns.d.ts +37 -0
- package/dist/gateway/discovery/mdns.js +177 -0
- package/dist/gateway/discovery/tailscale.cjs +140 -0
- package/dist/gateway/discovery/tailscale.d.ts +31 -0
- package/dist/gateway/discovery/tailscale.js +106 -0
- package/dist/gateway/discovery/types.cjs +18 -0
- package/dist/gateway/discovery/types.d.ts +41 -0
- package/dist/gateway/discovery/types.js +0 -0
- package/dist/gateway/env.cjs +45 -0
- package/dist/gateway/env.d.ts +2 -0
- package/dist/gateway/env.js +8 -0
- package/dist/gateway/hooks/loader.cjs +137 -0
- package/dist/gateway/hooks/loader.d.ts +10 -0
- package/dist/gateway/hooks/loader.js +103 -0
- package/dist/gateway/hooks/registry.cjs +128 -0
- package/dist/gateway/hooks/registry.d.ts +13 -0
- package/dist/gateway/hooks/registry.js +94 -0
- package/dist/gateway/hooks/types.cjs +58 -0
- package/dist/gateway/hooks/types.d.ts +50 -0
- package/dist/gateway/hooks/types.js +18 -0
- package/dist/gateway/http/agents.cjs +280 -0
- package/dist/gateway/http/agents.d.ts +2 -0
- package/dist/gateway/http/agents.js +246 -0
- package/dist/gateway/http/fs.cjs +81 -0
- package/dist/gateway/http/fs.d.ts +2 -0
- package/dist/gateway/http/fs.js +47 -0
- package/dist/gateway/http/providers.cjs +120 -0
- package/dist/gateway/http/providers.d.ts +2 -0
- package/dist/gateway/http/providers.js +86 -0
- package/dist/gateway/http/routines.cjs +196 -0
- package/dist/gateway/http/routines.d.ts +20 -0
- package/dist/gateway/http/routines.js +159 -0
- package/dist/gateway/http/sessions.cjs +241 -0
- package/dist/gateway/http/sessions.d.ts +2 -0
- package/dist/gateway/http/sessions.js +207 -0
- package/dist/gateway/http/types.cjs +18 -0
- package/dist/gateway/http/types.d.ts +25 -0
- package/dist/gateway/http/types.js +0 -0
- package/dist/gateway/http/voice.cjs +167 -0
- package/dist/gateway/http/voice.d.ts +2 -0
- package/dist/gateway/http/voice.js +133 -0
- package/dist/gateway/http/webhooks.cjs +353 -0
- package/dist/gateway/http/webhooks.d.ts +22 -0
- package/dist/gateway/http/webhooks.js +313 -0
- package/dist/gateway/index.cjs +119 -0
- package/dist/gateway/index.d.ts +8 -0
- package/dist/gateway/index.js +9 -0
- package/dist/gateway/node.cjs +218 -0
- package/dist/gateway/node.d.ts +112 -0
- package/dist/gateway/node.js +184 -0
- package/dist/gateway/router.cjs +85 -0
- package/dist/gateway/router.d.ts +9 -0
- package/dist/gateway/router.js +51 -0
- package/dist/gateway/rpcClient.cjs +152 -0
- package/dist/gateway/rpcClient.d.ts +24 -0
- package/dist/gateway/rpcClient.js +118 -0
- package/dist/gateway/server.cjs +1175 -0
- package/dist/gateway/server.d.ts +185 -0
- package/dist/gateway/server.js +1138 -0
- package/dist/gateway/transport/http.cjs +153 -0
- package/dist/gateway/transport/http.d.ts +25 -0
- package/dist/gateway/transport/http.js +119 -0
- package/dist/gateway/transport/index.cjs +40 -0
- package/dist/gateway/transport/index.d.ts +3 -0
- package/dist/gateway/transport/index.js +3 -0
- package/dist/gateway/transport/types.cjs +18 -0
- package/dist/gateway/transport/types.d.ts +59 -0
- package/dist/gateway/transport/types.js +0 -0
- package/dist/gateway/transport/websocket.cjs +132 -0
- package/dist/gateway/transport/websocket.d.ts +21 -0
- package/dist/gateway/transport/websocket.js +98 -0
- package/dist/gateway/types.cjs +18 -0
- package/dist/gateway/types.d.ts +215 -0
- package/dist/gateway/types.js +0 -0
- package/dist/gateway/validation.cjs +225 -0
- package/dist/gateway/validation.d.ts +157 -0
- package/dist/gateway/validation.js +158 -0
- package/dist/index.cjs +95 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/logger.cjs +270 -0
- package/dist/logger.d.ts +54 -0
- package/dist/logger.js +215 -0
- package/dist/providers/copilot.cjs +148 -0
- package/dist/providers/copilot.d.ts +3 -0
- package/dist/providers/copilot.js +114 -0
- package/dist/providers/credentials.cjs +154 -0
- package/dist/providers/credentials.d.ts +26 -0
- package/dist/providers/credentials.js +99 -0
- package/dist/providers/oauth.cjs +279 -0
- package/dist/providers/oauth.d.ts +13 -0
- package/dist/providers/oauth.js +245 -0
- package/dist/providers/registry.cjs +138 -0
- package/dist/providers/registry.d.ts +32 -0
- package/dist/providers/registry.js +98 -0
- package/dist/tests/additionalMessageMiddleware.test.cjs +45 -0
- package/dist/tests/additionalMessageMiddleware.test.d.ts +1 -0
- package/dist/tests/additionalMessageMiddleware.test.js +39 -0
- package/dist/tests/agent-config-voice.test.cjs +25 -0
- package/dist/tests/agent-config-voice.test.d.ts +1 -0
- package/dist/tests/agent-config-voice.test.js +19 -0
- package/dist/tests/agentInvokerAttachments.test.cjs +67 -0
- package/dist/tests/agentInvokerAttachments.test.d.ts +1 -0
- package/dist/tests/agentInvokerAttachments.test.js +61 -0
- package/dist/tests/attachments-utils.test.cjs +46 -0
- package/dist/tests/attachments-utils.test.d.ts +1 -0
- package/dist/tests/attachments-utils.test.js +40 -0
- package/dist/tests/bunSqliteAdapter.test.cjs +265 -0
- package/dist/tests/bunSqliteAdapter.test.d.ts +1 -0
- package/dist/tests/bunSqliteAdapter.test.js +259 -0
- package/dist/tests/candleRange.test.cjs +48 -0
- package/dist/tests/candleRange.test.d.ts +1 -0
- package/dist/tests/candleRange.test.js +42 -0
- package/dist/tests/cli-config-loader.test.cjs +364 -0
- package/dist/tests/cli-config-loader.test.d.ts +1 -0
- package/dist/tests/cli-config-loader.test.js +358 -0
- package/dist/tests/cli-init.test.cjs +82 -0
- package/dist/tests/cli-init.test.d.ts +1 -0
- package/dist/tests/cli-init.test.js +76 -0
- package/dist/tests/discord-adapter.test.cjs +55 -0
- package/dist/tests/discord-adapter.test.d.ts +1 -0
- package/dist/tests/discord-adapter.test.js +49 -0
- package/dist/tests/gateway.test.cjs +319 -0
- package/dist/tests/gateway.test.d.ts +1 -0
- package/dist/tests/gateway.test.js +313 -0
- package/dist/tests/hooks-matcher.test.cjs +309 -0
- package/dist/tests/hooks-matcher.test.d.ts +1 -0
- package/dist/tests/hooks-matcher.test.js +303 -0
- package/dist/tests/hooks-merger.test.cjs +528 -0
- package/dist/tests/hooks-merger.test.d.ts +1 -0
- package/dist/tests/hooks-merger.test.js +522 -0
- package/dist/tests/integration/agent-invocation.integration.test.cjs +264 -0
- package/dist/tests/integration/agent-invocation.integration.test.d.ts +1 -0
- package/dist/tests/integration/agent-invocation.integration.test.js +258 -0
- package/dist/tests/integration/finnhub-candles.integration.test.cjs +98 -0
- package/dist/tests/integration/finnhub-candles.integration.test.d.ts +1 -0
- package/dist/tests/integration/finnhub-candles.integration.test.js +92 -0
- package/dist/tests/logger.test.cjs +353 -0
- package/dist/tests/logger.test.d.ts +1 -0
- package/dist/tests/logger.test.js +347 -0
- package/dist/tests/mediaCompatibilityMiddleware.test.cjs +106 -0
- package/dist/tests/mediaCompatibilityMiddleware.test.d.ts +1 -0
- package/dist/tests/mediaCompatibilityMiddleware.test.js +100 -0
- package/dist/tests/routines-api.test.cjs +107 -0
- package/dist/tests/routines-api.test.d.ts +1 -0
- package/dist/tests/routines-api.test.js +101 -0
- package/dist/tests/sessionMessageAttachments.test.cjs +108 -0
- package/dist/tests/sessionMessageAttachments.test.d.ts +1 -0
- package/dist/tests/sessionMessageAttachments.test.js +102 -0
- package/dist/tests/sessionMessageRole.test.cjs +44 -0
- package/dist/tests/sessionMessageRole.test.d.ts +1 -0
- package/dist/tests/sessionMessageRole.test.js +38 -0
- package/dist/tests/sessionStateMessages.test.cjs +72 -0
- package/dist/tests/sessionStateMessages.test.d.ts +1 -0
- package/dist/tests/sessionStateMessages.test.js +66 -0
- package/dist/tests/sessions-api.test.cjs +68 -0
- package/dist/tests/sessions-api.test.d.ts +1 -0
- package/dist/tests/sessions-api.test.js +62 -0
- package/dist/tests/technicalIndicators.test.cjs +82 -0
- package/dist/tests/technicalIndicators.test.d.ts +1 -0
- package/dist/tests/technicalIndicators.test.js +76 -0
- package/dist/tests/toolDisplayHelpers.test.cjs +43 -0
- package/dist/tests/toolDisplayHelpers.test.d.ts +1 -0
- package/dist/tests/toolDisplayHelpers.test.js +37 -0
- package/dist/tests/voice-config.test.cjs +35 -0
- package/dist/tests/voice-config.test.d.ts +1 -0
- package/dist/tests/voice-config.test.js +29 -0
- package/dist/tests/yahooCandles.test.cjs +111 -0
- package/dist/tests/yahooCandles.test.d.ts +1 -0
- package/dist/tests/yahooCandles.test.js +105 -0
- package/dist/tools/finance/candleRange.cjs +71 -0
- package/dist/tools/finance/candleRange.d.ts +21 -0
- package/dist/tools/finance/candleRange.js +28 -0
- package/dist/tools/finance/optionsAnalytics.cjs +222 -0
- package/dist/tools/finance/optionsAnalytics.d.ts +44 -0
- package/dist/tools/finance/optionsAnalytics.js +188 -0
- package/dist/tools/finance/optionsAnalytics.test.cjs +128 -0
- package/dist/tools/finance/optionsAnalytics.test.d.ts +1 -0
- package/dist/tools/finance/optionsAnalytics.test.js +122 -0
- package/dist/tools/finance/technicalIndicators.cjs +111 -0
- package/dist/tools/finance/technicalIndicators.d.ts +15 -0
- package/dist/tools/finance/technicalIndicators.js +68 -0
- package/dist/tools/finance/yahooCandles.cjs +125 -0
- package/dist/tools/finance/yahooCandles.d.ts +41 -0
- package/dist/tools/finance/yahooCandles.js +85 -0
- package/dist/tools/mcp-finance.cjs +649 -0
- package/dist/tools/mcp-finance.d.ts +1 -0
- package/dist/tools/mcp-finance.js +631 -0
- package/dist/types/agents.cjs +18 -0
- package/dist/types/agents.d.ts +11 -0
- package/dist/types/agents.js +0 -0
- package/dist/types/hooks.cjs +18 -0
- package/dist/types/hooks.d.ts +82 -0
- package/dist/types/hooks.js +0 -0
- package/dist/types/mcp.cjs +86 -0
- package/dist/types/mcp.d.ts +107 -0
- package/dist/types/mcp.js +40 -0
- package/dist/types/voice.cjs +103 -0
- package/dist/types/voice.d.ts +117 -0
- package/dist/types/voice.js +51 -0
- package/dist/utils/attachments.cjs +46 -0
- package/dist/utils/attachments.d.ts +7 -0
- package/dist/utils/attachments.js +12 -0
- package/dist/voice/config.cjs +52 -0
- package/dist/voice/config.d.ts +8 -0
- package/dist/voice/config.js +18 -0
- package/dist/webui/assets/index-BA0HaStz.css +1 -0
- package/dist/webui/assets/index-NHgTZsWN.js +112 -0
- package/dist/webui/assets/wingman_icon-DOy91UEF.webp +0 -0
- package/dist/webui/assets/wingman_logo-Cogyt3qm.webp +0 -0
- package/dist/webui/index.html +19 -0
- package/package.json +130 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
handleWebhooksApi: ()=>handleWebhooksApi,
|
|
28
|
+
createWebhookStore: ()=>createWebhookStore,
|
|
29
|
+
handleWebhookInvoke: ()=>handleWebhookInvoke
|
|
30
|
+
});
|
|
31
|
+
const agentInvoker_cjs_namespaceObject = require("../../cli/core/agentInvoker.cjs");
|
|
32
|
+
const outputManager_cjs_namespaceObject = require("../../cli/core/outputManager.cjs");
|
|
33
|
+
const agentLoader_cjs_namespaceObject = require("../../agent/config/agentLoader.cjs");
|
|
34
|
+
const external_node_crypto_namespaceObject = require("node:crypto");
|
|
35
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
36
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
37
|
+
const WEBHOOK_PRESETS = new Set([
|
|
38
|
+
"gog-gmail"
|
|
39
|
+
]);
|
|
40
|
+
const normalizePreset = (value)=>{
|
|
41
|
+
if (!value) return;
|
|
42
|
+
const trimmed = value.trim();
|
|
43
|
+
if (!trimmed || "custom" === trimmed) return;
|
|
44
|
+
return WEBHOOK_PRESETS.has(trimmed) ? trimmed : void 0;
|
|
45
|
+
};
|
|
46
|
+
const formatGogGmailContent = (payload, webhookName, eventLabel)=>{
|
|
47
|
+
const payloadMessages = Array.isArray(payload?.messages) ? payload.messages : [];
|
|
48
|
+
const dataMessages = Array.isArray(payload?.data?.messages) ? payload.data.messages : [];
|
|
49
|
+
const candidate = payload?.message || payload?.email || payload?.data?.message || payloadMessages[0] || dataMessages[0] || null;
|
|
50
|
+
const header = `Gmail update received${eventLabel ? ` (${eventLabel})` : ""} for "${webhookName}".`;
|
|
51
|
+
if (!candidate) {
|
|
52
|
+
const fallback = payload ? JSON.stringify(payload, null, 2) : "{}";
|
|
53
|
+
return `${header}\n\nPayload:\n${fallback}`;
|
|
54
|
+
}
|
|
55
|
+
const subject = candidate.subject || candidate.headers?.subject || candidate.headers?.Subject || "(no subject)";
|
|
56
|
+
const from = candidate.from || candidate.headers?.from || candidate.headers?.From || "unknown sender";
|
|
57
|
+
const snippet = candidate.snippet || candidate.preview || "";
|
|
58
|
+
const body = candidate.body || candidate.text || candidate.html || "";
|
|
59
|
+
const id = candidate.id || candidate.messageId || "";
|
|
60
|
+
const lines = [
|
|
61
|
+
header,
|
|
62
|
+
`From: ${from}`,
|
|
63
|
+
`Subject: ${subject}`
|
|
64
|
+
];
|
|
65
|
+
if (id) lines.push(`Message ID: ${id}`);
|
|
66
|
+
if (snippet) lines.push(`Snippet: ${snippet}`);
|
|
67
|
+
if (body) lines.push("", body);
|
|
68
|
+
return lines.join("\n");
|
|
69
|
+
};
|
|
70
|
+
const createWebhookStore = (resolveConfigDirPath)=>{
|
|
71
|
+
const resolvePath = ()=>{
|
|
72
|
+
const configDir = resolveConfigDirPath();
|
|
73
|
+
(0, external_node_fs_namespaceObject.mkdirSync)(configDir, {
|
|
74
|
+
recursive: true
|
|
75
|
+
});
|
|
76
|
+
return (0, external_node_path_namespaceObject.join)(configDir, "webhooks.json");
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
load: ()=>{
|
|
80
|
+
const path = resolvePath();
|
|
81
|
+
if (!(0, external_node_fs_namespaceObject.existsSync)(path)) return [];
|
|
82
|
+
try {
|
|
83
|
+
const raw = (0, external_node_fs_namespaceObject.readFileSync)(path, "utf-8");
|
|
84
|
+
const parsed = JSON.parse(raw);
|
|
85
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
86
|
+
} catch {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
save: (webhooks)=>{
|
|
91
|
+
const path = resolvePath();
|
|
92
|
+
(0, external_node_fs_namespaceObject.writeFileSync)(path, JSON.stringify(webhooks, null, 2));
|
|
93
|
+
},
|
|
94
|
+
generateSecret: ()=>(0, external_node_crypto_namespaceObject.randomUUID)().replace(/-/g, "") + (0, external_node_crypto_namespaceObject.randomUUID)().replace(/-/g, "")
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
const agentExists = (ctx, agentId)=>{
|
|
98
|
+
const loader = new agentLoader_cjs_namespaceObject.AgentLoader(ctx.configDir, ctx.workspace, ctx.getWingmanConfig());
|
|
99
|
+
const configs = loader.loadAllAgentConfigs();
|
|
100
|
+
return Boolean(configs.find((config)=>config.name === agentId));
|
|
101
|
+
};
|
|
102
|
+
const sessionExists = async (ctx, agentId, sessionId)=>{
|
|
103
|
+
const manager = await ctx.getSessionManager(agentId);
|
|
104
|
+
return Boolean(manager.getSession(sessionId));
|
|
105
|
+
};
|
|
106
|
+
const handleWebhooksApi = async (ctx, store, req, url)=>{
|
|
107
|
+
if ("/api/webhooks" === url.pathname) {
|
|
108
|
+
if ("GET" === req.method) {
|
|
109
|
+
const webhooks = store.load();
|
|
110
|
+
return new Response(JSON.stringify(webhooks, null, 2), {
|
|
111
|
+
headers: {
|
|
112
|
+
"Content-Type": "application/json"
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if ("POST" === req.method) {
|
|
117
|
+
const body = await req.json();
|
|
118
|
+
const id = body?.id?.trim();
|
|
119
|
+
const name = body?.name?.trim();
|
|
120
|
+
const agentId = body?.agentId?.trim();
|
|
121
|
+
if (!id || !/^[a-zA-Z0-9_-]+$/.test(id)) return new Response("Invalid webhook id", {
|
|
122
|
+
status: 400
|
|
123
|
+
});
|
|
124
|
+
if (!name) return new Response("Webhook name required", {
|
|
125
|
+
status: 400
|
|
126
|
+
});
|
|
127
|
+
if (!agentId) return new Response("agentId required", {
|
|
128
|
+
status: 400
|
|
129
|
+
});
|
|
130
|
+
if (!agentExists(ctx, agentId)) return new Response("Invalid agentId", {
|
|
131
|
+
status: 400
|
|
132
|
+
});
|
|
133
|
+
const sessionId = body?.sessionId?.trim();
|
|
134
|
+
if (sessionId) {
|
|
135
|
+
const exists = await sessionExists(ctx, agentId, sessionId);
|
|
136
|
+
if (!exists) return new Response("Invalid sessionId", {
|
|
137
|
+
status: 400
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const webhooks = store.load();
|
|
141
|
+
if (webhooks.some((hook)=>hook.id === id)) return new Response("Webhook already exists", {
|
|
142
|
+
status: 409
|
|
143
|
+
});
|
|
144
|
+
const presetValue = normalizePreset(body?.preset);
|
|
145
|
+
if (body?.preset && !presetValue && "custom" !== body.preset.trim()) return new Response("Invalid preset", {
|
|
146
|
+
status: 400
|
|
147
|
+
});
|
|
148
|
+
const webhook = {
|
|
149
|
+
id,
|
|
150
|
+
name,
|
|
151
|
+
agentId,
|
|
152
|
+
secret: body?.secret?.trim() || store.generateSecret(),
|
|
153
|
+
enabled: body?.enabled ?? true,
|
|
154
|
+
eventLabel: body?.eventLabel?.trim() || void 0,
|
|
155
|
+
preset: presetValue,
|
|
156
|
+
sessionId: sessionId || void 0,
|
|
157
|
+
createdAt: Date.now()
|
|
158
|
+
};
|
|
159
|
+
webhooks.unshift(webhook);
|
|
160
|
+
store.save(webhooks);
|
|
161
|
+
return new Response(JSON.stringify(webhook, null, 2), {
|
|
162
|
+
headers: {
|
|
163
|
+
"Content-Type": "application/json"
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return new Response("Method Not Allowed", {
|
|
168
|
+
status: 405
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const webhookMatch = url.pathname.match(/^\/api\/webhooks\/([^/]+)$/);
|
|
172
|
+
if (!webhookMatch) return null;
|
|
173
|
+
const webhookId = decodeURIComponent(webhookMatch[1]);
|
|
174
|
+
const webhooks = store.load();
|
|
175
|
+
const webhook = webhooks.find((hook)=>hook.id === webhookId);
|
|
176
|
+
if ("GET" === req.method) {
|
|
177
|
+
if (!webhook) return new Response("Webhook not found", {
|
|
178
|
+
status: 404
|
|
179
|
+
});
|
|
180
|
+
return new Response(JSON.stringify(webhook, null, 2), {
|
|
181
|
+
headers: {
|
|
182
|
+
"Content-Type": "application/json"
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
if ("PUT" === req.method) {
|
|
187
|
+
if (!webhook) return new Response("Webhook not found", {
|
|
188
|
+
status: 404
|
|
189
|
+
});
|
|
190
|
+
const body = await req.json();
|
|
191
|
+
const nextAgentId = body?.agentId?.trim() || webhook.agentId;
|
|
192
|
+
if (!agentExists(ctx, nextAgentId)) return new Response("Invalid agentId", {
|
|
193
|
+
status: 400
|
|
194
|
+
});
|
|
195
|
+
const hasPreset = Object.prototype.hasOwnProperty.call(body ?? {}, "preset");
|
|
196
|
+
const presetValue = hasPreset ? normalizePreset(body?.preset) : webhook.preset;
|
|
197
|
+
if (hasPreset && body?.preset && !presetValue && "custom" !== body.preset.trim()) return new Response("Invalid preset", {
|
|
198
|
+
status: 400
|
|
199
|
+
});
|
|
200
|
+
const hasSessionId = Object.prototype.hasOwnProperty.call(body ?? {}, "sessionId");
|
|
201
|
+
let nextSessionId = webhook.sessionId;
|
|
202
|
+
if (hasSessionId) {
|
|
203
|
+
const trimmed = body?.sessionId?.trim();
|
|
204
|
+
if (trimmed) {
|
|
205
|
+
const exists = await sessionExists(ctx, nextAgentId, trimmed);
|
|
206
|
+
if (!exists) return new Response("Invalid sessionId", {
|
|
207
|
+
status: 400
|
|
208
|
+
});
|
|
209
|
+
nextSessionId = trimmed;
|
|
210
|
+
} else nextSessionId = void 0;
|
|
211
|
+
}
|
|
212
|
+
const updated = {
|
|
213
|
+
...webhook,
|
|
214
|
+
name: body?.name?.trim() || webhook.name,
|
|
215
|
+
agentId: nextAgentId,
|
|
216
|
+
secret: body?.secret?.trim() || webhook.secret,
|
|
217
|
+
enabled: body?.enabled ?? webhook.enabled,
|
|
218
|
+
eventLabel: body?.eventLabel?.trim() || void 0,
|
|
219
|
+
preset: presetValue,
|
|
220
|
+
sessionId: nextSessionId
|
|
221
|
+
};
|
|
222
|
+
const nextWebhooks = webhooks.map((hook)=>hook.id === webhookId ? updated : hook);
|
|
223
|
+
store.save(nextWebhooks);
|
|
224
|
+
return new Response(JSON.stringify(updated, null, 2), {
|
|
225
|
+
headers: {
|
|
226
|
+
"Content-Type": "application/json"
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if ("DELETE" === req.method) {
|
|
231
|
+
if (!webhook) return new Response("Webhook not found", {
|
|
232
|
+
status: 404
|
|
233
|
+
});
|
|
234
|
+
const nextWebhooks = webhooks.filter((hook)=>hook.id !== webhookId);
|
|
235
|
+
store.save(nextWebhooks);
|
|
236
|
+
return new Response(JSON.stringify({
|
|
237
|
+
ok: true
|
|
238
|
+
}, null, 2), {
|
|
239
|
+
headers: {
|
|
240
|
+
"Content-Type": "application/json"
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return new Response("Method Not Allowed", {
|
|
245
|
+
status: 405
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
const handleWebhookInvoke = async (ctx, store, req, url)=>{
|
|
249
|
+
const match = url.pathname.match(/^\/webhooks\/([^/]+)$/);
|
|
250
|
+
if (!match) return null;
|
|
251
|
+
if ("POST" !== req.method) return new Response("Method Not Allowed", {
|
|
252
|
+
status: 405
|
|
253
|
+
});
|
|
254
|
+
const webhookId = decodeURIComponent(match[1]);
|
|
255
|
+
const webhooks = store.load();
|
|
256
|
+
const webhook = webhooks.find((hook)=>hook.id === webhookId);
|
|
257
|
+
if (!webhook) return new Response("Webhook not found", {
|
|
258
|
+
status: 404
|
|
259
|
+
});
|
|
260
|
+
if (!webhook.enabled) return new Response("Webhook disabled", {
|
|
261
|
+
status: 403
|
|
262
|
+
});
|
|
263
|
+
const secret = req.headers.get("x-wingman-secret") || url.searchParams.get("secret") || "";
|
|
264
|
+
if (!secret || secret !== webhook.secret) return new Response("Unauthorized", {
|
|
265
|
+
status: 401
|
|
266
|
+
});
|
|
267
|
+
let body = null;
|
|
268
|
+
let rawText = null;
|
|
269
|
+
try {
|
|
270
|
+
body = await req.json();
|
|
271
|
+
} catch {
|
|
272
|
+
try {
|
|
273
|
+
rawText = await req.text();
|
|
274
|
+
} catch {
|
|
275
|
+
rawText = null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const eventLabel = "string" == typeof body?.event ? body.event : webhook.eventLabel;
|
|
279
|
+
const directPrompt = "string" == typeof body?.prompt ? body.prompt : "string" == typeof body?.content ? body.content : "string" == typeof body?.message ? body.message : "";
|
|
280
|
+
const payloadText = rawText || (null != body ? JSON.stringify(body, null, 2) : "");
|
|
281
|
+
const content = directPrompt || ("gog-gmail" === webhook.preset ? formatGogGmailContent(body ?? {}, webhook.name, eventLabel) : `Webhook "${webhook.name}" triggered${eventLabel ? ` (${eventLabel})` : ""}.\n\nPayload:\n${payloadText || "{}"}`);
|
|
282
|
+
const agentId = webhook.agentId;
|
|
283
|
+
const defaultSessionKey = `agent:${agentId}:webhook:${webhook.id}`;
|
|
284
|
+
let sessionKey = defaultSessionKey;
|
|
285
|
+
try {
|
|
286
|
+
const sessionManager = await ctx.getSessionManager(agentId);
|
|
287
|
+
sessionKey = webhook.sessionId || defaultSessionKey;
|
|
288
|
+
if (webhook.sessionId) {
|
|
289
|
+
const target = sessionManager.getSession(webhook.sessionId);
|
|
290
|
+
if (!target) return new Response("Target session not found", {
|
|
291
|
+
status: 404
|
|
292
|
+
});
|
|
293
|
+
} else sessionManager.getOrCreateSession(sessionKey, agentId, `Webhook: ${webhook.name}`);
|
|
294
|
+
sessionManager.updateSession(sessionKey, {
|
|
295
|
+
lastMessagePreview: content.substring(0, 200)
|
|
296
|
+
});
|
|
297
|
+
const existing = sessionManager.getSession(sessionKey);
|
|
298
|
+
if (existing) sessionManager.updateSession(sessionKey, {
|
|
299
|
+
messageCount: existing.messageCount + 1
|
|
300
|
+
});
|
|
301
|
+
sessionManager.updateSessionMetadata(sessionKey, {
|
|
302
|
+
source: "webhook",
|
|
303
|
+
webhookId: webhook.id,
|
|
304
|
+
webhookName: webhook.name,
|
|
305
|
+
eventLabel: eventLabel || void 0,
|
|
306
|
+
webhookPreset: webhook.preset
|
|
307
|
+
});
|
|
308
|
+
const outputManager = new outputManager_cjs_namespaceObject.OutputManager("interactive");
|
|
309
|
+
const workspace = ctx.resolveAgentWorkspace(agentId);
|
|
310
|
+
const session = sessionManager.getSession(sessionKey);
|
|
311
|
+
const workdir = session?.metadata?.workdir ?? null;
|
|
312
|
+
const defaultOutputDir = ctx.resolveDefaultOutputDir(agentId);
|
|
313
|
+
const invoker = new agentInvoker_cjs_namespaceObject.AgentInvoker({
|
|
314
|
+
workspace,
|
|
315
|
+
configDir: ctx.configDir,
|
|
316
|
+
outputManager,
|
|
317
|
+
logger: ctx.logger,
|
|
318
|
+
sessionManager,
|
|
319
|
+
workdir,
|
|
320
|
+
defaultOutputDir
|
|
321
|
+
});
|
|
322
|
+
invoker.invokeAgent(agentId, content, sessionKey);
|
|
323
|
+
} catch (error) {
|
|
324
|
+
ctx.logger.error("Webhook agent invocation failed", error);
|
|
325
|
+
return new Response("Webhook invocation failed", {
|
|
326
|
+
status: 500
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
const updatedWebhooks = webhooks.map((hook)=>hook.id === webhook.id ? {
|
|
330
|
+
...hook,
|
|
331
|
+
lastTriggeredAt: Date.now()
|
|
332
|
+
} : hook);
|
|
333
|
+
store.save(updatedWebhooks);
|
|
334
|
+
return new Response(JSON.stringify({
|
|
335
|
+
ok: true,
|
|
336
|
+
sessionId: sessionKey
|
|
337
|
+
}, null, 2), {
|
|
338
|
+
headers: {
|
|
339
|
+
"Content-Type": "application/json"
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
};
|
|
343
|
+
exports.createWebhookStore = __webpack_exports__.createWebhookStore;
|
|
344
|
+
exports.handleWebhookInvoke = __webpack_exports__.handleWebhookInvoke;
|
|
345
|
+
exports.handleWebhooksApi = __webpack_exports__.handleWebhooksApi;
|
|
346
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
347
|
+
"createWebhookStore",
|
|
348
|
+
"handleWebhookInvoke",
|
|
349
|
+
"handleWebhooksApi"
|
|
350
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
351
|
+
Object.defineProperty(exports, '__esModule', {
|
|
352
|
+
value: true
|
|
353
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { GatewayHttpContext } from "./types.js";
|
|
2
|
+
export type WebhookConfig = {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
agentId: string;
|
|
6
|
+
secret: string;
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
eventLabel?: string;
|
|
9
|
+
preset?: string;
|
|
10
|
+
sessionId?: string;
|
|
11
|
+
createdAt: number;
|
|
12
|
+
lastTriggeredAt?: number;
|
|
13
|
+
};
|
|
14
|
+
type WebhookStore = {
|
|
15
|
+
load: () => WebhookConfig[];
|
|
16
|
+
save: (webhooks: WebhookConfig[]) => void;
|
|
17
|
+
generateSecret: () => string;
|
|
18
|
+
};
|
|
19
|
+
export declare const createWebhookStore: (resolveConfigDirPath: () => string) => WebhookStore;
|
|
20
|
+
export declare const handleWebhooksApi: (ctx: GatewayHttpContext, store: WebhookStore, req: Request, url: URL) => Promise<Response | null>;
|
|
21
|
+
export declare const handleWebhookInvoke: (ctx: GatewayHttpContext, store: WebhookStore, req: Request, url: URL) => Promise<Response | null>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { AgentInvoker } from "../../cli/core/agentInvoker.js";
|
|
2
|
+
import { OutputManager } from "../../cli/core/outputManager.js";
|
|
3
|
+
import { AgentLoader } from "../../agent/config/agentLoader.js";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
const WEBHOOK_PRESETS = new Set([
|
|
8
|
+
"gog-gmail"
|
|
9
|
+
]);
|
|
10
|
+
const normalizePreset = (value)=>{
|
|
11
|
+
if (!value) return;
|
|
12
|
+
const trimmed = value.trim();
|
|
13
|
+
if (!trimmed || "custom" === trimmed) return;
|
|
14
|
+
return WEBHOOK_PRESETS.has(trimmed) ? trimmed : void 0;
|
|
15
|
+
};
|
|
16
|
+
const formatGogGmailContent = (payload, webhookName, eventLabel)=>{
|
|
17
|
+
const payloadMessages = Array.isArray(payload?.messages) ? payload.messages : [];
|
|
18
|
+
const dataMessages = Array.isArray(payload?.data?.messages) ? payload.data.messages : [];
|
|
19
|
+
const candidate = payload?.message || payload?.email || payload?.data?.message || payloadMessages[0] || dataMessages[0] || null;
|
|
20
|
+
const header = `Gmail update received${eventLabel ? ` (${eventLabel})` : ""} for "${webhookName}".`;
|
|
21
|
+
if (!candidate) {
|
|
22
|
+
const fallback = payload ? JSON.stringify(payload, null, 2) : "{}";
|
|
23
|
+
return `${header}\n\nPayload:\n${fallback}`;
|
|
24
|
+
}
|
|
25
|
+
const subject = candidate.subject || candidate.headers?.subject || candidate.headers?.Subject || "(no subject)";
|
|
26
|
+
const from = candidate.from || candidate.headers?.from || candidate.headers?.From || "unknown sender";
|
|
27
|
+
const snippet = candidate.snippet || candidate.preview || "";
|
|
28
|
+
const body = candidate.body || candidate.text || candidate.html || "";
|
|
29
|
+
const id = candidate.id || candidate.messageId || "";
|
|
30
|
+
const lines = [
|
|
31
|
+
header,
|
|
32
|
+
`From: ${from}`,
|
|
33
|
+
`Subject: ${subject}`
|
|
34
|
+
];
|
|
35
|
+
if (id) lines.push(`Message ID: ${id}`);
|
|
36
|
+
if (snippet) lines.push(`Snippet: ${snippet}`);
|
|
37
|
+
if (body) lines.push("", body);
|
|
38
|
+
return lines.join("\n");
|
|
39
|
+
};
|
|
40
|
+
const createWebhookStore = (resolveConfigDirPath)=>{
|
|
41
|
+
const resolvePath = ()=>{
|
|
42
|
+
const configDir = resolveConfigDirPath();
|
|
43
|
+
mkdirSync(configDir, {
|
|
44
|
+
recursive: true
|
|
45
|
+
});
|
|
46
|
+
return join(configDir, "webhooks.json");
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
load: ()=>{
|
|
50
|
+
const path = resolvePath();
|
|
51
|
+
if (!existsSync(path)) return [];
|
|
52
|
+
try {
|
|
53
|
+
const raw = readFileSync(path, "utf-8");
|
|
54
|
+
const parsed = JSON.parse(raw);
|
|
55
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
56
|
+
} catch {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
save: (webhooks)=>{
|
|
61
|
+
const path = resolvePath();
|
|
62
|
+
writeFileSync(path, JSON.stringify(webhooks, null, 2));
|
|
63
|
+
},
|
|
64
|
+
generateSecret: ()=>randomUUID().replace(/-/g, "") + randomUUID().replace(/-/g, "")
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
const agentExists = (ctx, agentId)=>{
|
|
68
|
+
const loader = new AgentLoader(ctx.configDir, ctx.workspace, ctx.getWingmanConfig());
|
|
69
|
+
const configs = loader.loadAllAgentConfigs();
|
|
70
|
+
return Boolean(configs.find((config)=>config.name === agentId));
|
|
71
|
+
};
|
|
72
|
+
const sessionExists = async (ctx, agentId, sessionId)=>{
|
|
73
|
+
const manager = await ctx.getSessionManager(agentId);
|
|
74
|
+
return Boolean(manager.getSession(sessionId));
|
|
75
|
+
};
|
|
76
|
+
const handleWebhooksApi = async (ctx, store, req, url)=>{
|
|
77
|
+
if ("/api/webhooks" === url.pathname) {
|
|
78
|
+
if ("GET" === req.method) {
|
|
79
|
+
const webhooks = store.load();
|
|
80
|
+
return new Response(JSON.stringify(webhooks, null, 2), {
|
|
81
|
+
headers: {
|
|
82
|
+
"Content-Type": "application/json"
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if ("POST" === req.method) {
|
|
87
|
+
const body = await req.json();
|
|
88
|
+
const id = body?.id?.trim();
|
|
89
|
+
const name = body?.name?.trim();
|
|
90
|
+
const agentId = body?.agentId?.trim();
|
|
91
|
+
if (!id || !/^[a-zA-Z0-9_-]+$/.test(id)) return new Response("Invalid webhook id", {
|
|
92
|
+
status: 400
|
|
93
|
+
});
|
|
94
|
+
if (!name) return new Response("Webhook name required", {
|
|
95
|
+
status: 400
|
|
96
|
+
});
|
|
97
|
+
if (!agentId) return new Response("agentId required", {
|
|
98
|
+
status: 400
|
|
99
|
+
});
|
|
100
|
+
if (!agentExists(ctx, agentId)) return new Response("Invalid agentId", {
|
|
101
|
+
status: 400
|
|
102
|
+
});
|
|
103
|
+
const sessionId = body?.sessionId?.trim();
|
|
104
|
+
if (sessionId) {
|
|
105
|
+
const exists = await sessionExists(ctx, agentId, sessionId);
|
|
106
|
+
if (!exists) return new Response("Invalid sessionId", {
|
|
107
|
+
status: 400
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const webhooks = store.load();
|
|
111
|
+
if (webhooks.some((hook)=>hook.id === id)) return new Response("Webhook already exists", {
|
|
112
|
+
status: 409
|
|
113
|
+
});
|
|
114
|
+
const presetValue = normalizePreset(body?.preset);
|
|
115
|
+
if (body?.preset && !presetValue && "custom" !== body.preset.trim()) return new Response("Invalid preset", {
|
|
116
|
+
status: 400
|
|
117
|
+
});
|
|
118
|
+
const webhook = {
|
|
119
|
+
id,
|
|
120
|
+
name,
|
|
121
|
+
agentId,
|
|
122
|
+
secret: body?.secret?.trim() || store.generateSecret(),
|
|
123
|
+
enabled: body?.enabled ?? true,
|
|
124
|
+
eventLabel: body?.eventLabel?.trim() || void 0,
|
|
125
|
+
preset: presetValue,
|
|
126
|
+
sessionId: sessionId || void 0,
|
|
127
|
+
createdAt: Date.now()
|
|
128
|
+
};
|
|
129
|
+
webhooks.unshift(webhook);
|
|
130
|
+
store.save(webhooks);
|
|
131
|
+
return new Response(JSON.stringify(webhook, null, 2), {
|
|
132
|
+
headers: {
|
|
133
|
+
"Content-Type": "application/json"
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return new Response("Method Not Allowed", {
|
|
138
|
+
status: 405
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const webhookMatch = url.pathname.match(/^\/api\/webhooks\/([^/]+)$/);
|
|
142
|
+
if (!webhookMatch) return null;
|
|
143
|
+
const webhookId = decodeURIComponent(webhookMatch[1]);
|
|
144
|
+
const webhooks = store.load();
|
|
145
|
+
const webhook = webhooks.find((hook)=>hook.id === webhookId);
|
|
146
|
+
if ("GET" === req.method) {
|
|
147
|
+
if (!webhook) return new Response("Webhook not found", {
|
|
148
|
+
status: 404
|
|
149
|
+
});
|
|
150
|
+
return new Response(JSON.stringify(webhook, null, 2), {
|
|
151
|
+
headers: {
|
|
152
|
+
"Content-Type": "application/json"
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if ("PUT" === req.method) {
|
|
157
|
+
if (!webhook) return new Response("Webhook not found", {
|
|
158
|
+
status: 404
|
|
159
|
+
});
|
|
160
|
+
const body = await req.json();
|
|
161
|
+
const nextAgentId = body?.agentId?.trim() || webhook.agentId;
|
|
162
|
+
if (!agentExists(ctx, nextAgentId)) return new Response("Invalid agentId", {
|
|
163
|
+
status: 400
|
|
164
|
+
});
|
|
165
|
+
const hasPreset = Object.prototype.hasOwnProperty.call(body ?? {}, "preset");
|
|
166
|
+
const presetValue = hasPreset ? normalizePreset(body?.preset) : webhook.preset;
|
|
167
|
+
if (hasPreset && body?.preset && !presetValue && "custom" !== body.preset.trim()) return new Response("Invalid preset", {
|
|
168
|
+
status: 400
|
|
169
|
+
});
|
|
170
|
+
const hasSessionId = Object.prototype.hasOwnProperty.call(body ?? {}, "sessionId");
|
|
171
|
+
let nextSessionId = webhook.sessionId;
|
|
172
|
+
if (hasSessionId) {
|
|
173
|
+
const trimmed = body?.sessionId?.trim();
|
|
174
|
+
if (trimmed) {
|
|
175
|
+
const exists = await sessionExists(ctx, nextAgentId, trimmed);
|
|
176
|
+
if (!exists) return new Response("Invalid sessionId", {
|
|
177
|
+
status: 400
|
|
178
|
+
});
|
|
179
|
+
nextSessionId = trimmed;
|
|
180
|
+
} else nextSessionId = void 0;
|
|
181
|
+
}
|
|
182
|
+
const updated = {
|
|
183
|
+
...webhook,
|
|
184
|
+
name: body?.name?.trim() || webhook.name,
|
|
185
|
+
agentId: nextAgentId,
|
|
186
|
+
secret: body?.secret?.trim() || webhook.secret,
|
|
187
|
+
enabled: body?.enabled ?? webhook.enabled,
|
|
188
|
+
eventLabel: body?.eventLabel?.trim() || void 0,
|
|
189
|
+
preset: presetValue,
|
|
190
|
+
sessionId: nextSessionId
|
|
191
|
+
};
|
|
192
|
+
const nextWebhooks = webhooks.map((hook)=>hook.id === webhookId ? updated : hook);
|
|
193
|
+
store.save(nextWebhooks);
|
|
194
|
+
return new Response(JSON.stringify(updated, null, 2), {
|
|
195
|
+
headers: {
|
|
196
|
+
"Content-Type": "application/json"
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
if ("DELETE" === req.method) {
|
|
201
|
+
if (!webhook) return new Response("Webhook not found", {
|
|
202
|
+
status: 404
|
|
203
|
+
});
|
|
204
|
+
const nextWebhooks = webhooks.filter((hook)=>hook.id !== webhookId);
|
|
205
|
+
store.save(nextWebhooks);
|
|
206
|
+
return new Response(JSON.stringify({
|
|
207
|
+
ok: true
|
|
208
|
+
}, null, 2), {
|
|
209
|
+
headers: {
|
|
210
|
+
"Content-Type": "application/json"
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return new Response("Method Not Allowed", {
|
|
215
|
+
status: 405
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
const handleWebhookInvoke = async (ctx, store, req, url)=>{
|
|
219
|
+
const match = url.pathname.match(/^\/webhooks\/([^/]+)$/);
|
|
220
|
+
if (!match) return null;
|
|
221
|
+
if ("POST" !== req.method) return new Response("Method Not Allowed", {
|
|
222
|
+
status: 405
|
|
223
|
+
});
|
|
224
|
+
const webhookId = decodeURIComponent(match[1]);
|
|
225
|
+
const webhooks = store.load();
|
|
226
|
+
const webhook = webhooks.find((hook)=>hook.id === webhookId);
|
|
227
|
+
if (!webhook) return new Response("Webhook not found", {
|
|
228
|
+
status: 404
|
|
229
|
+
});
|
|
230
|
+
if (!webhook.enabled) return new Response("Webhook disabled", {
|
|
231
|
+
status: 403
|
|
232
|
+
});
|
|
233
|
+
const secret = req.headers.get("x-wingman-secret") || url.searchParams.get("secret") || "";
|
|
234
|
+
if (!secret || secret !== webhook.secret) return new Response("Unauthorized", {
|
|
235
|
+
status: 401
|
|
236
|
+
});
|
|
237
|
+
let body = null;
|
|
238
|
+
let rawText = null;
|
|
239
|
+
try {
|
|
240
|
+
body = await req.json();
|
|
241
|
+
} catch {
|
|
242
|
+
try {
|
|
243
|
+
rawText = await req.text();
|
|
244
|
+
} catch {
|
|
245
|
+
rawText = null;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const eventLabel = "string" == typeof body?.event ? body.event : webhook.eventLabel;
|
|
249
|
+
const directPrompt = "string" == typeof body?.prompt ? body.prompt : "string" == typeof body?.content ? body.content : "string" == typeof body?.message ? body.message : "";
|
|
250
|
+
const payloadText = rawText || (null != body ? JSON.stringify(body, null, 2) : "");
|
|
251
|
+
const content = directPrompt || ("gog-gmail" === webhook.preset ? formatGogGmailContent(body ?? {}, webhook.name, eventLabel) : `Webhook "${webhook.name}" triggered${eventLabel ? ` (${eventLabel})` : ""}.\n\nPayload:\n${payloadText || "{}"}`);
|
|
252
|
+
const agentId = webhook.agentId;
|
|
253
|
+
const defaultSessionKey = `agent:${agentId}:webhook:${webhook.id}`;
|
|
254
|
+
let sessionKey = defaultSessionKey;
|
|
255
|
+
try {
|
|
256
|
+
const sessionManager = await ctx.getSessionManager(agentId);
|
|
257
|
+
sessionKey = webhook.sessionId || defaultSessionKey;
|
|
258
|
+
if (webhook.sessionId) {
|
|
259
|
+
const target = sessionManager.getSession(webhook.sessionId);
|
|
260
|
+
if (!target) return new Response("Target session not found", {
|
|
261
|
+
status: 404
|
|
262
|
+
});
|
|
263
|
+
} else sessionManager.getOrCreateSession(sessionKey, agentId, `Webhook: ${webhook.name}`);
|
|
264
|
+
sessionManager.updateSession(sessionKey, {
|
|
265
|
+
lastMessagePreview: content.substring(0, 200)
|
|
266
|
+
});
|
|
267
|
+
const existing = sessionManager.getSession(sessionKey);
|
|
268
|
+
if (existing) sessionManager.updateSession(sessionKey, {
|
|
269
|
+
messageCount: existing.messageCount + 1
|
|
270
|
+
});
|
|
271
|
+
sessionManager.updateSessionMetadata(sessionKey, {
|
|
272
|
+
source: "webhook",
|
|
273
|
+
webhookId: webhook.id,
|
|
274
|
+
webhookName: webhook.name,
|
|
275
|
+
eventLabel: eventLabel || void 0,
|
|
276
|
+
webhookPreset: webhook.preset
|
|
277
|
+
});
|
|
278
|
+
const outputManager = new OutputManager("interactive");
|
|
279
|
+
const workspace = ctx.resolveAgentWorkspace(agentId);
|
|
280
|
+
const session = sessionManager.getSession(sessionKey);
|
|
281
|
+
const workdir = session?.metadata?.workdir ?? null;
|
|
282
|
+
const defaultOutputDir = ctx.resolveDefaultOutputDir(agentId);
|
|
283
|
+
const invoker = new AgentInvoker({
|
|
284
|
+
workspace,
|
|
285
|
+
configDir: ctx.configDir,
|
|
286
|
+
outputManager,
|
|
287
|
+
logger: ctx.logger,
|
|
288
|
+
sessionManager,
|
|
289
|
+
workdir,
|
|
290
|
+
defaultOutputDir
|
|
291
|
+
});
|
|
292
|
+
invoker.invokeAgent(agentId, content, sessionKey);
|
|
293
|
+
} catch (error) {
|
|
294
|
+
ctx.logger.error("Webhook agent invocation failed", error);
|
|
295
|
+
return new Response("Webhook invocation failed", {
|
|
296
|
+
status: 500
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
const updatedWebhooks = webhooks.map((hook)=>hook.id === webhook.id ? {
|
|
300
|
+
...hook,
|
|
301
|
+
lastTriggeredAt: Date.now()
|
|
302
|
+
} : hook);
|
|
303
|
+
store.save(updatedWebhooks);
|
|
304
|
+
return new Response(JSON.stringify({
|
|
305
|
+
ok: true,
|
|
306
|
+
sessionId: sessionKey
|
|
307
|
+
}, null, 2), {
|
|
308
|
+
headers: {
|
|
309
|
+
"Content-Type": "application/json"
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
};
|
|
313
|
+
export { createWebhookStore, handleWebhookInvoke, handleWebhooksApi };
|