@elizaos/agent 0.25.8 → 2.0.0-alpha.83
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/LICENSE +1 -1
- package/package.json +994 -34
- package/packages/agent/src/actions/emote.d.ts +14 -0
- package/packages/agent/src/actions/emote.d.ts.map +1 -0
- package/packages/agent/src/actions/emote.js +91 -0
- package/packages/agent/src/actions/restart.d.ts +19 -0
- package/packages/agent/src/actions/restart.d.ts.map +1 -0
- package/packages/agent/src/actions/restart.js +86 -0
- package/packages/agent/src/actions/send-message.d.ts +3 -0
- package/packages/agent/src/actions/send-message.d.ts.map +1 -0
- package/packages/agent/src/actions/send-message.js +144 -0
- package/packages/agent/src/actions/stream-control.d.ts +15 -0
- package/packages/agent/src/actions/stream-control.d.ts.map +1 -0
- package/packages/agent/src/actions/stream-control.js +357 -0
- package/packages/agent/src/actions/switch-stream-source.d.ts +16 -0
- package/packages/agent/src/actions/switch-stream-source.d.ts.map +1 -0
- package/packages/agent/src/actions/switch-stream-source.js +94 -0
- package/packages/agent/src/actions/terminal.d.ts +14 -0
- package/packages/agent/src/actions/terminal.d.ts.map +1 -0
- package/packages/agent/src/actions/terminal.js +154 -0
- package/packages/agent/src/api/agent-admin-routes.d.ts +38 -0
- package/packages/agent/src/api/agent-admin-routes.d.ts.map +1 -0
- package/packages/agent/src/api/agent-admin-routes.js +93 -0
- package/packages/agent/src/api/agent-lifecycle-routes.d.ts +16 -0
- package/packages/agent/src/api/agent-lifecycle-routes.d.ts.map +1 -0
- package/packages/agent/src/api/agent-lifecycle-routes.js +80 -0
- package/packages/agent/src/api/agent-model.d.ts +12 -0
- package/packages/agent/src/api/agent-model.d.ts.map +1 -0
- package/packages/agent/src/api/agent-model.js +123 -0
- package/packages/agent/src/api/agent-transfer-routes.d.ts +16 -0
- package/packages/agent/src/api/agent-transfer-routes.d.ts.map +1 -0
- package/packages/agent/src/api/agent-transfer-routes.js +124 -0
- package/packages/agent/src/api/apps-routes.d.ts +19 -0
- package/packages/agent/src/api/apps-routes.d.ts.map +1 -0
- package/packages/agent/src/api/apps-routes.js +128 -0
- package/packages/agent/src/api/auth-routes.d.ts +11 -0
- package/packages/agent/src/api/auth-routes.d.ts.map +1 -0
- package/packages/agent/src/api/auth-routes.js +54 -0
- package/packages/agent/src/api/bsc-trade.d.ts +34 -0
- package/packages/agent/src/api/bsc-trade.d.ts.map +1 -0
- package/packages/agent/src/api/bsc-trade.js +567 -0
- package/packages/agent/src/api/bug-report-routes.d.ts +7 -0
- package/packages/agent/src/api/bug-report-routes.d.ts.map +1 -0
- package/packages/agent/src/api/bug-report-routes.js +124 -0
- package/packages/agent/src/api/character-routes.d.ts +50 -0
- package/packages/agent/src/api/character-routes.d.ts.map +1 -0
- package/packages/agent/src/api/character-routes.js +302 -0
- package/packages/agent/src/api/cloud-billing-routes.d.ts +14 -0
- package/packages/agent/src/api/cloud-billing-routes.d.ts.map +1 -0
- package/packages/agent/src/api/cloud-billing-routes.js +400 -0
- package/packages/agent/src/api/cloud-compat-routes.d.ts +15 -0
- package/packages/agent/src/api/cloud-compat-routes.d.ts.map +1 -0
- package/packages/agent/src/api/cloud-compat-routes.js +131 -0
- package/packages/agent/src/api/cloud-routes.d.ts +62 -0
- package/packages/agent/src/api/cloud-routes.d.ts.map +1 -0
- package/packages/agent/src/api/cloud-routes.js +339 -0
- package/packages/agent/src/api/cloud-status-routes.d.ts +15 -0
- package/packages/agent/src/api/cloud-status-routes.d.ts.map +1 -0
- package/packages/agent/src/api/cloud-status-routes.js +165 -0
- package/packages/agent/src/api/compat-utils.d.ts +49 -0
- package/packages/agent/src/api/compat-utils.d.ts.map +1 -0
- package/packages/agent/src/api/compat-utils.js +126 -0
- package/packages/agent/src/api/connector-health.d.ts +34 -0
- package/packages/agent/src/api/connector-health.d.ts.map +1 -0
- package/packages/agent/src/api/connector-health.js +109 -0
- package/packages/agent/src/api/coordinator-wiring.d.ts +46 -0
- package/packages/agent/src/api/coordinator-wiring.d.ts.map +1 -0
- package/packages/agent/src/api/coordinator-wiring.js +101 -0
- package/packages/agent/src/api/credit-detection.d.ts +9 -0
- package/packages/agent/src/api/credit-detection.d.ts.map +1 -0
- package/packages/agent/src/api/credit-detection.js +41 -0
- package/packages/agent/src/api/database.d.ts +33 -0
- package/packages/agent/src/api/database.d.ts.map +1 -0
- package/packages/agent/src/api/database.js +1019 -0
- package/packages/agent/src/api/diagnostics-routes.d.ts +46 -0
- package/packages/agent/src/api/diagnostics-routes.d.ts.map +1 -0
- package/packages/agent/src/api/diagnostics-routes.js +241 -0
- package/packages/agent/src/api/drop-service.d.ts +26 -0
- package/packages/agent/src/api/drop-service.d.ts.map +1 -0
- package/packages/agent/src/api/drop-service.js +134 -0
- package/packages/agent/src/api/early-logs.d.ts +29 -0
- package/packages/agent/src/api/early-logs.d.ts.map +1 -0
- package/packages/agent/src/api/early-logs.js +96 -0
- package/packages/agent/src/api/http-helpers.d.ts +50 -0
- package/packages/agent/src/api/http-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/http-helpers.js +145 -0
- package/packages/agent/src/api/index.d.ts +61 -0
- package/packages/agent/src/api/index.d.ts.map +1 -0
- package/packages/agent/src/api/index.js +59 -0
- package/packages/agent/src/api/knowledge-routes.d.ts +23 -0
- package/packages/agent/src/api/knowledge-routes.d.ts.map +1 -0
- package/packages/agent/src/api/knowledge-routes.js +931 -0
- package/packages/agent/src/api/knowledge-service-loader.d.ts +51 -0
- package/packages/agent/src/api/knowledge-service-loader.d.ts.map +1 -0
- package/packages/agent/src/api/knowledge-service-loader.js +34 -0
- package/packages/agent/src/api/memory-bounds.d.ts +51 -0
- package/packages/agent/src/api/memory-bounds.d.ts.map +1 -0
- package/packages/agent/src/api/memory-bounds.js +81 -0
- package/packages/agent/src/api/memory-routes.d.ts +9 -0
- package/packages/agent/src/api/memory-routes.d.ts.map +1 -0
- package/packages/agent/src/api/memory-routes.js +241 -0
- package/packages/agent/src/api/merkle-tree.d.ts +90 -0
- package/packages/agent/src/api/merkle-tree.d.ts.map +1 -0
- package/packages/agent/src/api/merkle-tree.js +174 -0
- package/packages/agent/src/api/models-routes.d.ts +14 -0
- package/packages/agent/src/api/models-routes.d.ts.map +1 -0
- package/packages/agent/src/api/models-routes.js +37 -0
- package/packages/agent/src/api/nfa-routes.d.ts +5 -0
- package/packages/agent/src/api/nfa-routes.d.ts.map +1 -0
- package/packages/agent/src/api/nfa-routes.js +125 -0
- package/packages/agent/src/api/og-tracker.d.ts +28 -0
- package/packages/agent/src/api/og-tracker.d.ts.map +1 -0
- package/packages/agent/src/api/og-tracker.js +60 -0
- package/packages/agent/src/api/parse-action-block.d.ts +36 -0
- package/packages/agent/src/api/parse-action-block.d.ts.map +1 -0
- package/packages/agent/src/api/parse-action-block.js +110 -0
- package/packages/agent/src/api/permissions-routes.d.ts +32 -0
- package/packages/agent/src/api/permissions-routes.d.ts.map +1 -0
- package/packages/agent/src/api/permissions-routes.js +149 -0
- package/packages/agent/src/api/plugin-validation.d.ts +86 -0
- package/packages/agent/src/api/plugin-validation.d.ts.map +1 -0
- package/packages/agent/src/api/plugin-validation.js +259 -0
- package/packages/agent/src/api/provider-switch-config.d.ts +37 -0
- package/packages/agent/src/api/provider-switch-config.d.ts.map +1 -0
- package/packages/agent/src/api/provider-switch-config.js +317 -0
- package/packages/agent/src/api/registry-routes.d.ts +26 -0
- package/packages/agent/src/api/registry-routes.d.ts.map +1 -0
- package/packages/agent/src/api/registry-routes.js +90 -0
- package/packages/agent/src/api/registry-service.d.ts +77 -0
- package/packages/agent/src/api/registry-service.d.ts.map +1 -0
- package/packages/agent/src/api/registry-service.js +190 -0
- package/packages/agent/src/api/route-helpers.d.ts +16 -0
- package/packages/agent/src/api/route-helpers.d.ts.map +1 -0
- package/packages/agent/src/api/route-helpers.js +1 -0
- package/packages/agent/src/api/sandbox-routes.d.ts +12 -0
- package/packages/agent/src/api/sandbox-routes.d.ts.map +1 -0
- package/packages/agent/src/api/sandbox-routes.js +1334 -0
- package/packages/agent/src/api/server.d.ts +418 -0
- package/packages/agent/src/api/server.d.ts.map +1 -0
- package/packages/agent/src/api/server.js +13614 -0
- package/packages/agent/src/api/signal-routes.d.ts +39 -0
- package/packages/agent/src/api/signal-routes.d.ts.map +1 -0
- package/packages/agent/src/api/signal-routes.js +168 -0
- package/packages/agent/src/api/stream-persistence.d.ts +64 -0
- package/packages/agent/src/api/stream-persistence.d.ts.map +1 -0
- package/packages/agent/src/api/stream-persistence.js +231 -0
- package/packages/agent/src/api/stream-route-state.d.ts +50 -0
- package/packages/agent/src/api/stream-route-state.d.ts.map +1 -0
- package/packages/agent/src/api/stream-route-state.js +1 -0
- package/packages/agent/src/api/stream-routes.d.ts +45 -0
- package/packages/agent/src/api/stream-routes.d.ts.map +1 -0
- package/packages/agent/src/api/stream-routes.js +809 -0
- package/packages/agent/src/api/stream-voice-routes.d.ts +36 -0
- package/packages/agent/src/api/stream-voice-routes.d.ts.map +1 -0
- package/packages/agent/src/api/stream-voice-routes.js +133 -0
- package/packages/agent/src/api/streaming-text.d.ts +9 -0
- package/packages/agent/src/api/streaming-text.d.ts.map +1 -0
- package/packages/agent/src/api/streaming-text.js +85 -0
- package/packages/agent/src/api/streaming-types.d.ts +30 -0
- package/packages/agent/src/api/streaming-types.d.ts.map +1 -0
- package/packages/agent/src/api/streaming-types.js +1 -0
- package/packages/agent/src/api/subscription-routes.d.ts +20 -0
- package/packages/agent/src/api/subscription-routes.d.ts.map +1 -0
- package/packages/agent/src/api/subscription-routes.js +191 -0
- package/packages/agent/src/api/terminal-run-limits.d.ts +5 -0
- package/packages/agent/src/api/terminal-run-limits.d.ts.map +1 -0
- package/packages/agent/src/api/terminal-run-limits.js +22 -0
- package/packages/agent/src/api/training-backend-check.d.ts +8 -0
- package/packages/agent/src/api/training-backend-check.d.ts.map +1 -0
- package/packages/agent/src/api/training-backend-check.js +28 -0
- package/packages/agent/src/api/training-routes.d.ts +44 -0
- package/packages/agent/src/api/training-routes.d.ts.map +1 -0
- package/packages/agent/src/api/training-routes.js +195 -0
- package/packages/agent/src/api/training-service-like.d.ts +38 -0
- package/packages/agent/src/api/training-service-like.d.ts.map +1 -0
- package/packages/agent/src/api/training-service-like.js +1 -0
- package/packages/agent/src/api/trajectory-routes.d.ts +17 -0
- package/packages/agent/src/api/trajectory-routes.d.ts.map +1 -0
- package/packages/agent/src/api/trajectory-routes.js +405 -0
- package/packages/agent/src/api/trigger-routes.d.ts +72 -0
- package/packages/agent/src/api/trigger-routes.d.ts.map +1 -0
- package/packages/agent/src/api/trigger-routes.js +268 -0
- package/packages/agent/src/api/twitter-verify.d.ts +25 -0
- package/packages/agent/src/api/twitter-verify.d.ts.map +1 -0
- package/packages/agent/src/api/twitter-verify.js +168 -0
- package/packages/agent/src/api/tx-service.d.ts +47 -0
- package/packages/agent/src/api/tx-service.d.ts.map +1 -0
- package/packages/agent/src/api/tx-service.js +156 -0
- package/packages/agent/src/api/wallet-dex-prices.d.ts +43 -0
- package/packages/agent/src/api/wallet-dex-prices.d.ts.map +1 -0
- package/packages/agent/src/api/wallet-dex-prices.js +149 -0
- package/packages/agent/src/api/wallet-evm-balance.d.ts +65 -0
- package/packages/agent/src/api/wallet-evm-balance.d.ts.map +1 -0
- package/packages/agent/src/api/wallet-evm-balance.js +663 -0
- package/packages/agent/src/api/wallet-routes.d.ts +33 -0
- package/packages/agent/src/api/wallet-routes.d.ts.map +1 -0
- package/packages/agent/src/api/wallet-routes.js +292 -0
- package/packages/agent/src/api/wallet-rpc.d.ts +61 -0
- package/packages/agent/src/api/wallet-rpc.d.ts.map +1 -0
- package/packages/agent/src/api/wallet-rpc.js +367 -0
- package/packages/agent/src/api/wallet-trading-profile.d.ts +51 -0
- package/packages/agent/src/api/wallet-trading-profile.d.ts.map +1 -0
- package/packages/agent/src/api/wallet-trading-profile.js +547 -0
- package/packages/agent/src/api/wallet.d.ts +31 -0
- package/packages/agent/src/api/wallet.d.ts.map +1 -0
- package/packages/agent/src/api/wallet.js +513 -0
- package/packages/agent/src/api/whatsapp-routes.d.ts +39 -0
- package/packages/agent/src/api/whatsapp-routes.d.ts.map +1 -0
- package/packages/agent/src/api/whatsapp-routes.js +182 -0
- package/packages/agent/src/api/zip-utils.d.ts +8 -0
- package/packages/agent/src/api/zip-utils.d.ts.map +1 -0
- package/packages/agent/src/api/zip-utils.js +115 -0
- package/packages/agent/src/auth/anthropic.d.ts +25 -0
- package/packages/agent/src/auth/anthropic.d.ts.map +1 -0
- package/packages/agent/src/auth/anthropic.js +40 -0
- package/packages/agent/src/auth/apply-stealth.d.ts +8 -0
- package/packages/agent/src/auth/apply-stealth.d.ts.map +1 -0
- package/packages/agent/src/auth/apply-stealth.js +35 -0
- package/packages/agent/src/auth/claude-code-stealth.d.ts +2 -0
- package/packages/agent/src/auth/claude-code-stealth.d.ts.map +1 -0
- package/packages/agent/src/auth/claude-code-stealth.js +104 -0
- package/packages/agent/src/auth/credentials.d.ts +55 -0
- package/packages/agent/src/auth/credentials.d.ts.map +1 -0
- package/packages/agent/src/auth/credentials.js +182 -0
- package/packages/agent/src/auth/index.d.ts +7 -0
- package/packages/agent/src/auth/index.d.ts.map +1 -0
- package/packages/agent/src/auth/index.js +3 -0
- package/packages/agent/src/auth/openai-codex.d.ts +27 -0
- package/packages/agent/src/auth/openai-codex.d.ts.map +1 -0
- package/packages/agent/src/auth/openai-codex.js +72 -0
- package/packages/agent/src/auth/types.d.ts +18 -0
- package/packages/agent/src/auth/types.d.ts.map +1 -0
- package/packages/agent/src/auth/types.js +8 -0
- package/packages/agent/src/awareness/registry.d.ts +27 -0
- package/packages/agent/src/awareness/registry.d.ts.map +1 -0
- package/packages/agent/src/awareness/registry.js +161 -0
- package/packages/agent/src/benchmark-server.d.ts +2 -0
- package/packages/agent/src/benchmark-server.d.ts.map +1 -0
- package/packages/agent/src/benchmark-server.js +773 -0
- package/packages/agent/src/bin.d.ts +3 -0
- package/packages/agent/src/bin.d.ts.map +1 -0
- package/packages/agent/src/bin.js +6 -0
- package/packages/agent/src/cli/index.d.ts +2 -0
- package/packages/agent/src/cli/index.d.ts.map +1 -0
- package/packages/agent/src/cli/index.js +40 -0
- package/packages/agent/src/cli/parse-duration.d.ts +5 -0
- package/packages/agent/src/cli/parse-duration.d.ts.map +1 -0
- package/packages/agent/src/cli/parse-duration.js +27 -0
- package/packages/agent/src/cloud/auth.d.ts +19 -0
- package/packages/agent/src/cloud/auth.d.ts.map +1 -0
- package/packages/agent/src/cloud/auth.js +107 -0
- package/packages/agent/src/cloud/backup.d.ts +18 -0
- package/packages/agent/src/cloud/backup.d.ts.map +1 -0
- package/packages/agent/src/cloud/backup.js +42 -0
- package/packages/agent/src/cloud/base-url.d.ts +3 -0
- package/packages/agent/src/cloud/base-url.d.ts.map +1 -0
- package/packages/agent/src/cloud/base-url.js +40 -0
- package/packages/agent/src/cloud/bridge-client.d.ts +56 -0
- package/packages/agent/src/cloud/bridge-client.d.ts.map +1 -0
- package/packages/agent/src/cloud/bridge-client.js +190 -0
- package/packages/agent/src/cloud/cloud-manager.d.ts +32 -0
- package/packages/agent/src/cloud/cloud-manager.d.ts.map +1 -0
- package/packages/agent/src/cloud/cloud-manager.js +119 -0
- package/packages/agent/src/cloud/cloud-proxy.d.ts +20 -0
- package/packages/agent/src/cloud/cloud-proxy.d.ts.map +1 -0
- package/packages/agent/src/cloud/cloud-proxy.js +34 -0
- package/packages/agent/src/cloud/index.d.ts +7 -0
- package/packages/agent/src/cloud/index.d.ts.map +1 -0
- package/packages/agent/src/cloud/index.js +6 -0
- package/packages/agent/src/cloud/reconnect.d.ts +26 -0
- package/packages/agent/src/cloud/reconnect.d.ts.map +1 -0
- package/packages/agent/src/cloud/reconnect.js +86 -0
- package/packages/agent/src/cloud/validate-url.d.ts +2 -0
- package/packages/agent/src/cloud/validate-url.d.ts.map +1 -0
- package/packages/agent/src/cloud/validate-url.js +162 -0
- package/packages/agent/src/config/character-schema.d.ts +25 -0
- package/packages/agent/src/config/character-schema.d.ts.map +1 -0
- package/packages/agent/src/config/character-schema.js +39 -0
- package/packages/agent/src/config/config.d.ts +6 -0
- package/packages/agent/src/config/config.d.ts.map +1 -0
- package/packages/agent/src/config/config.js +118 -0
- package/packages/agent/src/config/env-vars.d.ts +3 -0
- package/packages/agent/src/config/env-vars.d.ts.map +1 -0
- package/packages/agent/src/config/env-vars.js +76 -0
- package/packages/agent/src/config/includes.d.ts +26 -0
- package/packages/agent/src/config/includes.d.ts.map +1 -0
- package/packages/agent/src/config/includes.js +148 -0
- package/packages/agent/src/config/index.d.ts +16 -0
- package/packages/agent/src/config/index.d.ts.map +1 -0
- package/packages/agent/src/config/index.js +15 -0
- package/packages/agent/src/config/object-utils.d.ts +2 -0
- package/packages/agent/src/config/object-utils.d.ts.map +1 -0
- package/packages/agent/src/config/object-utils.js +6 -0
- package/packages/agent/src/config/paths.d.ts +13 -0
- package/packages/agent/src/config/paths.d.ts.map +1 -0
- package/packages/agent/src/config/paths.js +67 -0
- package/packages/agent/src/config/plugin-auto-enable.d.ts +16 -0
- package/packages/agent/src/config/plugin-auto-enable.d.ts.map +1 -0
- package/packages/agent/src/config/plugin-auto-enable.js +384 -0
- package/packages/agent/src/config/schema.d.ts +87 -0
- package/packages/agent/src/config/schema.d.ts.map +1 -0
- package/packages/agent/src/config/schema.js +928 -0
- package/packages/agent/src/config/telegram-custom-commands.d.ts +25 -0
- package/packages/agent/src/config/telegram-custom-commands.d.ts.map +1 -0
- package/packages/agent/src/config/telegram-custom-commands.js +71 -0
- package/packages/agent/src/config/types.agent-defaults.d.ts +331 -0
- package/packages/agent/src/config/types.agent-defaults.d.ts.map +1 -0
- package/packages/agent/src/config/types.agent-defaults.js +1 -0
- package/packages/agent/src/config/types.agents.d.ts +110 -0
- package/packages/agent/src/config/types.agents.d.ts.map +1 -0
- package/packages/agent/src/config/types.agents.js +1 -0
- package/packages/agent/src/config/types.d.ts +8 -0
- package/packages/agent/src/config/types.d.ts.map +1 -0
- package/packages/agent/src/config/types.eliza.d.ts +636 -0
- package/packages/agent/src/config/types.eliza.d.ts.map +1 -0
- package/packages/agent/src/config/types.eliza.js +1 -0
- package/packages/agent/src/config/types.gateway.d.ts +216 -0
- package/packages/agent/src/config/types.gateway.d.ts.map +1 -0
- package/packages/agent/src/config/types.gateway.js +1 -0
- package/packages/agent/src/config/types.hooks.d.ts +107 -0
- package/packages/agent/src/config/types.hooks.d.ts.map +1 -0
- package/packages/agent/src/config/types.hooks.js +1 -0
- package/packages/agent/src/config/types.js +7 -0
- package/packages/agent/src/config/types.messages.d.ts +176 -0
- package/packages/agent/src/config/types.messages.d.ts.map +1 -0
- package/packages/agent/src/config/types.messages.js +1 -0
- package/packages/agent/src/config/types.tools.d.ts +400 -0
- package/packages/agent/src/config/types.tools.d.ts.map +1 -0
- package/packages/agent/src/config/types.tools.js +1 -0
- package/packages/agent/src/config/zod-schema.agent-runtime.d.ts +1062 -0
- package/packages/agent/src/config/zod-schema.agent-runtime.d.ts.map +1 -0
- package/packages/agent/src/config/zod-schema.agent-runtime.js +721 -0
- package/packages/agent/src/config/zod-schema.core.d.ts +1021 -0
- package/packages/agent/src/config/zod-schema.core.d.ts.map +1 -0
- package/packages/agent/src/config/zod-schema.core.js +694 -0
- package/packages/agent/src/config/zod-schema.d.ts +4817 -0
- package/packages/agent/src/config/zod-schema.d.ts.map +1 -0
- package/packages/agent/src/config/zod-schema.hooks.d.ts +88 -0
- package/packages/agent/src/config/zod-schema.hooks.d.ts.map +1 -0
- package/packages/agent/src/config/zod-schema.hooks.js +133 -0
- package/packages/agent/src/config/zod-schema.js +778 -0
- package/packages/agent/src/config/zod-schema.providers-core.d.ts +2976 -0
- package/packages/agent/src/config/zod-schema.providers-core.d.ts.map +1 -0
- package/packages/agent/src/config/zod-schema.providers-core.js +1006 -0
- package/packages/agent/src/config/zod-schema.session.d.ts +183 -0
- package/packages/agent/src/config/zod-schema.session.d.ts.map +1 -0
- package/packages/agent/src/config/zod-schema.session.js +86 -0
- package/packages/agent/src/contracts/apps.d.ts +42 -0
- package/packages/agent/src/contracts/apps.d.ts.map +1 -0
- package/packages/agent/src/contracts/apps.js +4 -0
- package/packages/agent/src/contracts/awareness.d.ts +38 -0
- package/packages/agent/src/contracts/awareness.d.ts.map +1 -0
- package/packages/agent/src/contracts/awareness.js +7 -0
- package/packages/agent/src/contracts/config.d.ts +146 -0
- package/packages/agent/src/contracts/config.d.ts.map +1 -0
- package/packages/agent/src/contracts/config.js +4 -0
- package/packages/agent/src/contracts/drop.d.ts +20 -0
- package/packages/agent/src/contracts/drop.d.ts.map +1 -0
- package/packages/agent/src/contracts/drop.js +4 -0
- package/packages/agent/src/contracts/index.d.ts +9 -0
- package/packages/agent/src/contracts/index.d.ts.map +1 -0
- package/packages/agent/src/contracts/index.js +8 -0
- package/packages/agent/src/contracts/onboarding.d.ts +379 -0
- package/packages/agent/src/contracts/onboarding.d.ts.map +1 -0
- package/packages/agent/src/contracts/onboarding.js +290 -0
- package/packages/agent/src/contracts/permissions.d.ts +35 -0
- package/packages/agent/src/contracts/permissions.d.ts.map +1 -0
- package/packages/agent/src/contracts/permissions.js +4 -0
- package/packages/agent/src/contracts/verification.d.ts +9 -0
- package/packages/agent/src/contracts/verification.d.ts.map +1 -0
- package/packages/agent/src/contracts/verification.js +4 -0
- package/packages/agent/src/contracts/wallet.d.ts +409 -0
- package/packages/agent/src/contracts/wallet.d.ts.map +1 -0
- package/packages/agent/src/contracts/wallet.js +60 -0
- package/packages/agent/src/diagnostics/integration-observability.d.ts +40 -0
- package/packages/agent/src/diagnostics/integration-observability.d.ts.map +1 -0
- package/packages/agent/src/diagnostics/integration-observability.js +68 -0
- package/packages/agent/src/emotes/catalog.d.ts +31 -0
- package/packages/agent/src/emotes/catalog.d.ts.map +1 -0
- package/packages/agent/src/emotes/catalog.js +618 -0
- package/packages/agent/src/hooks/discovery.d.ts +13 -0
- package/packages/agent/src/hooks/discovery.d.ts.map +1 -0
- package/packages/agent/src/hooks/discovery.js +184 -0
- package/packages/agent/src/hooks/eligibility.d.ts +12 -0
- package/packages/agent/src/hooks/eligibility.d.ts.map +1 -0
- package/packages/agent/src/hooks/eligibility.js +100 -0
- package/packages/agent/src/hooks/index.d.ts +3 -0
- package/packages/agent/src/hooks/index.d.ts.map +1 -0
- package/packages/agent/src/hooks/index.js +2 -0
- package/packages/agent/src/hooks/loader.d.ts +34 -0
- package/packages/agent/src/hooks/loader.d.ts.map +1 -0
- package/packages/agent/src/hooks/loader.js +176 -0
- package/packages/agent/src/hooks/registry.d.ts +11 -0
- package/packages/agent/src/hooks/registry.d.ts.map +1 -0
- package/packages/agent/src/hooks/registry.js +58 -0
- package/packages/agent/src/hooks/types.d.ts +104 -0
- package/packages/agent/src/hooks/types.d.ts.map +1 -0
- package/packages/agent/src/hooks/types.js +8 -0
- package/packages/agent/src/index.d.ts +20 -0
- package/packages/agent/src/index.d.ts.map +1 -0
- package/packages/agent/src/index.js +19 -0
- package/packages/agent/src/onboarding-presets.d.ts +78 -0
- package/packages/agent/src/onboarding-presets.d.ts.map +1 -0
- package/packages/agent/src/onboarding-presets.js +1352 -0
- package/packages/agent/src/plugins/custom-rtmp/index.d.ts +12 -0
- package/packages/agent/src/plugins/custom-rtmp/index.d.ts.map +1 -0
- package/packages/agent/src/plugins/custom-rtmp/index.js +26 -0
- package/packages/agent/src/providers/admin-trust.d.ts +4 -0
- package/packages/agent/src/providers/admin-trust.d.ts.map +1 -0
- package/packages/agent/src/providers/admin-trust.js +53 -0
- package/packages/agent/src/providers/session-bridge.d.ts +24 -0
- package/packages/agent/src/providers/session-bridge.d.ts.map +1 -0
- package/packages/agent/src/providers/session-bridge.js +85 -0
- package/packages/agent/src/providers/session-utils.d.ts +20 -0
- package/packages/agent/src/providers/session-utils.d.ts.map +1 -0
- package/packages/agent/src/providers/session-utils.js +33 -0
- package/packages/agent/src/providers/simple-mode.d.ts +4 -0
- package/packages/agent/src/providers/simple-mode.d.ts.map +1 -0
- package/packages/agent/src/providers/simple-mode.js +85 -0
- package/packages/agent/src/providers/ui-catalog.d.ts +3 -0
- package/packages/agent/src/providers/ui-catalog.d.ts.map +1 -0
- package/packages/agent/src/providers/ui-catalog.js +123 -0
- package/packages/agent/src/providers/workspace-provider.d.ts +22 -0
- package/packages/agent/src/providers/workspace-provider.d.ts.map +1 -0
- package/packages/agent/src/providers/workspace-provider.js +167 -0
- package/packages/agent/src/providers/workspace.d.ts +54 -0
- package/packages/agent/src/providers/workspace.d.ts.map +1 -0
- package/packages/agent/src/providers/workspace.js +405 -0
- package/packages/agent/src/runtime/agent-event-service.d.ts +35 -0
- package/packages/agent/src/runtime/agent-event-service.d.ts.map +1 -0
- package/packages/agent/src/runtime/agent-event-service.js +16 -0
- package/packages/agent/src/runtime/cloud-onboarding.d.ts +55 -0
- package/packages/agent/src/runtime/cloud-onboarding.d.ts.map +1 -0
- package/packages/agent/src/runtime/cloud-onboarding.js +279 -0
- package/packages/agent/src/runtime/core-plugins.d.ts +14 -0
- package/packages/agent/src/runtime/core-plugins.d.ts.map +1 -0
- package/packages/agent/src/runtime/core-plugins.js +51 -0
- package/packages/agent/src/runtime/custom-actions.d.ts +40 -0
- package/packages/agent/src/runtime/custom-actions.d.ts.map +1 -0
- package/packages/agent/src/runtime/custom-actions.js +454 -0
- package/packages/agent/src/runtime/eliza-plugin.d.ts +16 -0
- package/packages/agent/src/runtime/eliza-plugin.d.ts.map +1 -0
- package/packages/agent/src/runtime/eliza-plugin.js +108 -0
- package/packages/agent/src/runtime/eliza.d.ts +205 -0
- package/packages/agent/src/runtime/eliza.d.ts.map +1 -0
- package/packages/agent/src/runtime/eliza.js +3935 -0
- package/packages/agent/src/runtime/embedding-presets.d.ts +19 -0
- package/packages/agent/src/runtime/embedding-presets.d.ts.map +1 -0
- package/packages/agent/src/runtime/embedding-presets.js +53 -0
- package/packages/agent/src/runtime/index.d.ts +9 -0
- package/packages/agent/src/runtime/index.d.ts.map +1 -0
- package/packages/agent/src/runtime/index.js +8 -0
- package/packages/agent/src/runtime/onboarding-names.d.ts +11 -0
- package/packages/agent/src/runtime/onboarding-names.d.ts.map +1 -0
- package/packages/agent/src/runtime/onboarding-names.js +74 -0
- package/packages/agent/src/runtime/release-plugin-policy.d.ts +20 -0
- package/packages/agent/src/runtime/release-plugin-policy.d.ts.map +1 -0
- package/packages/agent/src/runtime/release-plugin-policy.js +87 -0
- package/packages/agent/src/runtime/restart.d.ts +45 -0
- package/packages/agent/src/runtime/restart.d.ts.map +1 -0
- package/packages/agent/src/runtime/restart.js +45 -0
- package/packages/agent/src/runtime/trajectory-persistence.d.ts +214 -0
- package/packages/agent/src/runtime/trajectory-persistence.d.ts.map +1 -0
- package/packages/agent/src/runtime/trajectory-persistence.js +1957 -0
- package/packages/agent/src/runtime/version.d.ts +2 -0
- package/packages/agent/src/runtime/version.d.ts.map +1 -0
- package/packages/agent/src/runtime/version.js +5 -0
- package/packages/agent/src/security/audit-log.d.ts +49 -0
- package/packages/agent/src/security/audit-log.d.ts.map +1 -0
- package/packages/agent/src/security/audit-log.js +161 -0
- package/packages/agent/src/security/network-policy.d.ts +6 -0
- package/packages/agent/src/security/network-policy.d.ts.map +1 -0
- package/packages/agent/src/security/network-policy.js +85 -0
- package/packages/agent/src/server/index.d.ts +3 -0
- package/packages/agent/src/server/index.d.ts.map +1 -0
- package/packages/agent/src/server/index.js +1 -0
- package/packages/agent/src/services/agent-export.d.ts +100 -0
- package/packages/agent/src/services/agent-export.d.ts.map +1 -0
- package/packages/agent/src/services/agent-export.js +729 -0
- package/packages/agent/src/services/app-manager.d.ts +34 -0
- package/packages/agent/src/services/app-manager.d.ts.map +1 -0
- package/packages/agent/src/services/app-manager.js +425 -0
- package/packages/agent/src/services/browser-capture.d.ts +39 -0
- package/packages/agent/src/services/browser-capture.d.ts.map +1 -0
- package/packages/agent/src/services/browser-capture.js +162 -0
- package/packages/agent/src/services/coding-agent-context.d.ts +310 -0
- package/packages/agent/src/services/coding-agent-context.d.ts.map +1 -0
- package/packages/agent/src/services/coding-agent-context.js +281 -0
- package/packages/agent/src/services/fallback-training-service.d.ts +78 -0
- package/packages/agent/src/services/fallback-training-service.d.ts.map +1 -0
- package/packages/agent/src/services/fallback-training-service.js +126 -0
- package/packages/agent/src/services/index.d.ts +18 -0
- package/packages/agent/src/services/index.d.ts.map +1 -0
- package/packages/agent/src/services/index.js +17 -0
- package/packages/agent/src/services/mcp-marketplace.d.ts +89 -0
- package/packages/agent/src/services/mcp-marketplace.d.ts.map +1 -0
- package/packages/agent/src/services/mcp-marketplace.js +200 -0
- package/packages/agent/src/services/plugin-manager-types.d.ts +139 -0
- package/packages/agent/src/services/plugin-manager-types.d.ts.map +1 -0
- package/packages/agent/src/services/plugin-manager-types.js +18 -0
- package/packages/agent/src/services/privy-wallets.d.ts +18 -0
- package/packages/agent/src/services/privy-wallets.d.ts.map +1 -0
- package/packages/agent/src/services/privy-wallets.js +225 -0
- package/packages/agent/src/services/registry-client-app-meta.d.ts +6 -0
- package/packages/agent/src/services/registry-client-app-meta.d.ts.map +1 -0
- package/packages/agent/src/services/registry-client-app-meta.js +147 -0
- package/packages/agent/src/services/registry-client-endpoints.d.ts +7 -0
- package/packages/agent/src/services/registry-client-endpoints.d.ts.map +1 -0
- package/packages/agent/src/services/registry-client-endpoints.js +183 -0
- package/packages/agent/src/services/registry-client-local.d.ts +4 -0
- package/packages/agent/src/services/registry-client-local.d.ts.map +1 -0
- package/packages/agent/src/services/registry-client-local.js +377 -0
- package/packages/agent/src/services/registry-client-network.d.ts +9 -0
- package/packages/agent/src/services/registry-client-network.d.ts.map +1 -0
- package/packages/agent/src/services/registry-client-network.js +109 -0
- package/packages/agent/src/services/registry-client-queries.d.ts +15 -0
- package/packages/agent/src/services/registry-client-queries.d.ts.map +1 -0
- package/packages/agent/src/services/registry-client-queries.js +150 -0
- package/packages/agent/src/services/registry-client-types.d.ts +115 -0
- package/packages/agent/src/services/registry-client-types.d.ts.map +1 -0
- package/packages/agent/src/services/registry-client-types.js +1 -0
- package/packages/agent/src/services/registry-client.d.ts +39 -0
- package/packages/agent/src/services/registry-client.d.ts.map +1 -0
- package/packages/agent/src/services/registry-client.js +249 -0
- package/packages/agent/src/services/remote-signing-service.d.ts +58 -0
- package/packages/agent/src/services/remote-signing-service.d.ts.map +1 -0
- package/packages/agent/src/services/remote-signing-service.js +185 -0
- package/packages/agent/src/services/sandbox-engine.d.ts +96 -0
- package/packages/agent/src/services/sandbox-engine.d.ts.map +1 -0
- package/packages/agent/src/services/sandbox-engine.js +604 -0
- package/packages/agent/src/services/sandbox-manager.d.ts +104 -0
- package/packages/agent/src/services/sandbox-manager.d.ts.map +1 -0
- package/packages/agent/src/services/sandbox-manager.js +353 -0
- package/packages/agent/src/services/self-updater.d.ts +21 -0
- package/packages/agent/src/services/self-updater.d.ts.map +1 -0
- package/packages/agent/src/services/self-updater.js +162 -0
- package/packages/agent/src/services/signal-pairing.d.ts +37 -0
- package/packages/agent/src/services/signal-pairing.d.ts.map +1 -0
- package/packages/agent/src/services/signal-pairing.js +124 -0
- package/packages/agent/src/services/signing-policy.d.ts +44 -0
- package/packages/agent/src/services/signing-policy.d.ts.map +1 -0
- package/packages/agent/src/services/signing-policy.js +165 -0
- package/packages/agent/src/services/skill-catalog-client.d.ts +47 -0
- package/packages/agent/src/services/skill-catalog-client.d.ts.map +1 -0
- package/packages/agent/src/services/skill-catalog-client.js +130 -0
- package/packages/agent/src/services/skill-marketplace.d.ts +42 -0
- package/packages/agent/src/services/skill-marketplace.d.ts.map +1 -0
- package/packages/agent/src/services/skill-marketplace.js +680 -0
- package/packages/agent/src/services/stream-manager.d.ts +121 -0
- package/packages/agent/src/services/stream-manager.d.ts.map +1 -0
- package/packages/agent/src/services/stream-manager.js +604 -0
- package/packages/agent/src/services/tts-stream-bridge.d.ts +83 -0
- package/packages/agent/src/services/tts-stream-bridge.d.ts.map +1 -0
- package/packages/agent/src/services/tts-stream-bridge.js +349 -0
- package/packages/agent/src/services/update-checker.d.ts +29 -0
- package/packages/agent/src/services/update-checker.d.ts.map +1 -0
- package/packages/agent/src/services/update-checker.js +134 -0
- package/packages/agent/src/services/version-compat.d.ts +99 -0
- package/packages/agent/src/services/version-compat.d.ts.map +1 -0
- package/packages/agent/src/services/version-compat.js +195 -0
- package/packages/agent/src/services/whatsapp-pairing.d.ts +41 -0
- package/packages/agent/src/services/whatsapp-pairing.d.ts.map +1 -0
- package/packages/agent/src/services/whatsapp-pairing.js +209 -0
- package/packages/agent/src/shared/ui-catalog-prompt.d.ts +52 -0
- package/packages/agent/src/shared/ui-catalog-prompt.d.ts.map +1 -0
- package/packages/agent/src/shared/ui-catalog-prompt.js +1028 -0
- package/packages/agent/src/test-support/process-helpers.d.ts +13 -0
- package/packages/agent/src/test-support/process-helpers.d.ts.map +1 -0
- package/packages/agent/src/test-support/process-helpers.js +23 -0
- package/packages/agent/src/test-support/route-test-helpers.d.ts +37 -0
- package/packages/agent/src/test-support/route-test-helpers.d.ts.map +1 -0
- package/packages/agent/src/test-support/route-test-helpers.js +54 -0
- package/packages/agent/src/test-support/test-helpers.d.ts +77 -0
- package/packages/agent/src/test-support/test-helpers.d.ts.map +1 -0
- package/packages/agent/src/test-support/test-helpers.js +210 -0
- package/packages/agent/src/testing/index.d.ts +4 -0
- package/packages/agent/src/testing/index.d.ts.map +1 -0
- package/packages/agent/src/testing/index.js +3 -0
- package/packages/agent/src/triggers/action.d.ts +3 -0
- package/packages/agent/src/triggers/action.d.ts.map +1 -0
- package/packages/agent/src/triggers/action.js +267 -0
- package/packages/agent/src/triggers/runtime.d.ts +24 -0
- package/packages/agent/src/triggers/runtime.d.ts.map +1 -0
- package/packages/agent/src/triggers/runtime.js +322 -0
- package/packages/agent/src/triggers/scheduling.d.ts +70 -0
- package/packages/agent/src/triggers/scheduling.d.ts.map +1 -0
- package/packages/agent/src/triggers/scheduling.js +355 -0
- package/packages/agent/src/triggers/types.d.ts +115 -0
- package/packages/agent/src/triggers/types.d.ts.map +1 -0
- package/packages/agent/src/triggers/types.js +1 -0
- package/packages/agent/src/utils/exec-safety.d.ts +2 -0
- package/packages/agent/src/utils/exec-safety.d.ts.map +1 -0
- package/packages/agent/src/utils/exec-safety.js +21 -0
- package/packages/agent/src/utils/number-parsing.d.ts +26 -0
- package/packages/agent/src/utils/number-parsing.d.ts.map +1 -0
- package/packages/agent/src/utils/number-parsing.js +52 -0
- package/packages/agent/src/utils/spoken-text.d.ts +2 -0
- package/packages/agent/src/utils/spoken-text.d.ts.map +1 -0
- package/packages/agent/src/utils/spoken-text.js +56 -0
- package/packages/agent/src/version-resolver.d.ts +3 -0
- package/packages/agent/src/version-resolver.d.ts.map +1 -0
- package/packages/agent/src/version-resolver.js +51 -0
- package/jest.config.js +0 -17
- package/src/__tests__/client-type-identification.test.ts +0 -59
- package/src/defaultCharacter.ts +0 -530
- package/src/index.ts +0 -865
- package/tsconfig.json +0 -16
|
@@ -0,0 +1,809 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic streaming infrastructure routes.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from retake-routes.ts so any streaming destination (Retake.tv,
|
|
5
|
+
* custom RTMP, etc.) can reuse the same pipeline: capture mode detection,
|
|
6
|
+
* Xvfb management, browser capture, FFmpeg, frame routing, volume/mute.
|
|
7
|
+
*
|
|
8
|
+
* Platform-specific credential fetching lives in destination adapters
|
|
9
|
+
* (e.g. retake-routes.ts exports `createRetakeDestination`).
|
|
10
|
+
*/
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import { logger } from "@elizaos/core";
|
|
13
|
+
import { getTtsProviderStatus, resolveTtsConfig, ttsStreamBridge, } from "../services/tts-stream-bridge";
|
|
14
|
+
import { sanitizeSpeechText } from "../utils/spoken-text";
|
|
15
|
+
import { readRequestBody, readRequestBodyBuffer, sendJson, sendJsonError, } from "./http-helpers";
|
|
16
|
+
import { getHeadlessCaptureConfig, parseDestinationQuery, readOverlayLayout, readStreamSettings, seedOverlayDefaults, validateStreamSettings, writeOverlayLayout, writeStreamSettings, } from "./stream-persistence";
|
|
17
|
+
import { handleStreamVoiceRoute as handleAutonomousStreamVoiceRoute, onAgentMessage as onAutonomousAgentMessage, } from "./stream-voice-routes";
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// MJPEG frame store — shared state for GET /api/stream/screen
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Stores the most-recently received JPEG frame and pushes each new frame
|
|
23
|
+
* to all active MJPEG subscribers (GET /api/stream/screen).
|
|
24
|
+
*
|
|
25
|
+
* Frames arrive via POST /api/stream/frame from:
|
|
26
|
+
* - Electrobun screencapture module (JS canvas → JPEG)
|
|
27
|
+
* - Legacy desktop screencapture bridges
|
|
28
|
+
* - Any client POSTing raw JPEG bytes
|
|
29
|
+
*/
|
|
30
|
+
const MJPEG_BOUNDARY = "elizaframe";
|
|
31
|
+
const mjpegSubscribers = new Set();
|
|
32
|
+
let latestFrame = null;
|
|
33
|
+
function pushFrameToSubscribers(frame) {
|
|
34
|
+
latestFrame = frame;
|
|
35
|
+
if (mjpegSubscribers.size === 0)
|
|
36
|
+
return;
|
|
37
|
+
const header = `--${MJPEG_BOUNDARY}\r\nContent-Type: image/jpeg\r\nContent-Length: ${frame.length}\r\n\r\n`;
|
|
38
|
+
const headerBuf = Buffer.from(header, "ascii");
|
|
39
|
+
const trailer = Buffer.from("\r\n", "ascii");
|
|
40
|
+
const chunk = Buffer.concat([headerBuf, frame, trailer]);
|
|
41
|
+
for (const sub of mjpegSubscribers) {
|
|
42
|
+
try {
|
|
43
|
+
sub.write(chunk);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
mjpegSubscribers.delete(sub);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Resolve the active streaming destination from the registry. */
|
|
51
|
+
export function getActiveDestination(state) {
|
|
52
|
+
if (state.activeDestinationId) {
|
|
53
|
+
return state.destinations.get(state.activeDestinationId);
|
|
54
|
+
}
|
|
55
|
+
// Fallback: first destination in map (backward compat for single-destination configs)
|
|
56
|
+
const first = state.destinations.values().next();
|
|
57
|
+
return first.done ? undefined : first.value;
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Internal helpers
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
function json(res, data, status = 200) {
|
|
63
|
+
sendJson(res, data, status);
|
|
64
|
+
}
|
|
65
|
+
function error(res, message, status) {
|
|
66
|
+
sendJsonError(res, message, status);
|
|
67
|
+
}
|
|
68
|
+
function resolveRouteTtsConfig(config) {
|
|
69
|
+
return resolveTtsConfig(config);
|
|
70
|
+
}
|
|
71
|
+
function getRouteTtsProviderStatus(config) {
|
|
72
|
+
return getTtsProviderStatus(config);
|
|
73
|
+
}
|
|
74
|
+
const ttsBridgeAdapter = {
|
|
75
|
+
isSpeaking() {
|
|
76
|
+
return ttsStreamBridge.isSpeaking();
|
|
77
|
+
},
|
|
78
|
+
isAttached() {
|
|
79
|
+
return ttsStreamBridge.isAttached();
|
|
80
|
+
},
|
|
81
|
+
async speak(text, config) {
|
|
82
|
+
return ttsStreamBridge.speak(text, config);
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
function readRouteStreamSettings() {
|
|
86
|
+
return readStreamSettings();
|
|
87
|
+
}
|
|
88
|
+
function writeRouteStreamSettings(settings) {
|
|
89
|
+
writeStreamSettings(settings);
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Capture mode detection
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
/**
|
|
95
|
+
* Detect the best capture mode for the current environment.
|
|
96
|
+
*
|
|
97
|
+
* Priority:
|
|
98
|
+
* 1. STREAM_MODE / RETAKE_STREAM_MODE env var (explicit override)
|
|
99
|
+
* 2. Desktop screen capture bridge -> "pipe" (POST /api/stream/frame -> FFmpeg stdin)
|
|
100
|
+
* 3. Linux with DISPLAY or Xvfb -> "x11grab" (Hyperscape approach)
|
|
101
|
+
* 4. macOS -> "avfoundation" (native screen capture)
|
|
102
|
+
* 5. Fallback -> "file" (Puppeteer CDP -> temp JPEG -> FFmpeg)
|
|
103
|
+
*/
|
|
104
|
+
/** @internal Exported for testing. */
|
|
105
|
+
export function detectCaptureMode() {
|
|
106
|
+
const explicit = process.env.STREAM_MODE ?? process.env.RETAKE_STREAM_MODE;
|
|
107
|
+
if (explicit === "ui" || explicit === "pipe")
|
|
108
|
+
return "pipe";
|
|
109
|
+
if (explicit === "x11grab")
|
|
110
|
+
return "x11grab";
|
|
111
|
+
if (explicit === "avfoundation" || explicit === "screen")
|
|
112
|
+
return "avfoundation";
|
|
113
|
+
if (explicit === "file")
|
|
114
|
+
return "file";
|
|
115
|
+
// Desktop bridge -> pipe mode
|
|
116
|
+
if ("__elizaScreenCapture" in globalThis) {
|
|
117
|
+
return "pipe";
|
|
118
|
+
}
|
|
119
|
+
// Linux with a display -> x11grab (Xvfb or native X11)
|
|
120
|
+
if (process.platform === "linux" && process.env.DISPLAY)
|
|
121
|
+
return "x11grab";
|
|
122
|
+
// macOS -> avfoundation screen capture
|
|
123
|
+
if (process.platform === "darwin")
|
|
124
|
+
return "avfoundation";
|
|
125
|
+
// Fallback -> headless browser capture -> file mode
|
|
126
|
+
return "file";
|
|
127
|
+
}
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// Xvfb management
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
/**
|
|
132
|
+
* Try to start Xvfb on the specified display if not already running (Linux only).
|
|
133
|
+
* Returns true if display is available, false otherwise.
|
|
134
|
+
*/
|
|
135
|
+
/** @internal Exported for testing. */
|
|
136
|
+
export async function ensureXvfb(display, resolution) {
|
|
137
|
+
if (process.platform !== "linux")
|
|
138
|
+
return false;
|
|
139
|
+
// Validate display format to prevent command injection (must be :<digits>)
|
|
140
|
+
if (!/^:\d+$/.test(display)) {
|
|
141
|
+
logger.warn(`[stream] Invalid display format: ${display} (expected :<number>)`);
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
// Validate resolution early so callers get a clear failure before we
|
|
145
|
+
// touch the display or spawn processes.
|
|
146
|
+
const [w, h] = resolution.split("x");
|
|
147
|
+
if (!w || !h || !/^\d+$/.test(w) || !/^\d+$/.test(h)) {
|
|
148
|
+
logger.warn(`[stream] Invalid resolution for Xvfb: ${resolution}`);
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
// Check if the display is already active
|
|
152
|
+
if (process.env.DISPLAY === display)
|
|
153
|
+
return true;
|
|
154
|
+
try {
|
|
155
|
+
const { execSync } = await import("node:child_process");
|
|
156
|
+
// Check if Xvfb is already running on this display
|
|
157
|
+
try {
|
|
158
|
+
execSync(`xdpyinfo -display ${display}`, {
|
|
159
|
+
stdio: "ignore",
|
|
160
|
+
timeout: 3000,
|
|
161
|
+
});
|
|
162
|
+
logger.info(`[stream] Xvfb already running on display ${display}`);
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// Not running -- start it
|
|
167
|
+
}
|
|
168
|
+
const { spawn: spawnProc } = await import("node:child_process");
|
|
169
|
+
const xvfb = spawnProc("Xvfb", [display, "-screen", "0", `${w}x${h}x24`, "-ac"], {
|
|
170
|
+
stdio: "ignore",
|
|
171
|
+
detached: true,
|
|
172
|
+
});
|
|
173
|
+
xvfb.unref();
|
|
174
|
+
// Wait for Xvfb to be ready
|
|
175
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
176
|
+
logger.info(`[stream] Started Xvfb on display ${display} (${resolution})`);
|
|
177
|
+
process.env.DISPLAY = display;
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
logger.warn(`[stream] Failed to start Xvfb: ${err}`);
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
// Streaming pipeline (destination-driven)
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
/**
|
|
189
|
+
* Start the full streaming pipeline using the configured destination for
|
|
190
|
+
* RTMP credentials. Handles capture mode detection, Xvfb, browser capture,
|
|
191
|
+
* and FFmpeg configuration.
|
|
192
|
+
*/
|
|
193
|
+
async function startStreamPipeline(state, rtmpUrl, rtmpKey) {
|
|
194
|
+
// Defense-in-depth: validate RTMP scheme before passing to FFmpeg
|
|
195
|
+
if (!/^rtmps?:\/\//i.test(rtmpUrl)) {
|
|
196
|
+
throw new Error("RTMP URL must use rtmp:// or rtmps:// scheme");
|
|
197
|
+
}
|
|
198
|
+
// Seed plugin-default overlay layout on first stream start
|
|
199
|
+
const activeDest = getActiveDestination(state);
|
|
200
|
+
if (activeDest) {
|
|
201
|
+
seedOverlayDefaults(activeDest);
|
|
202
|
+
}
|
|
203
|
+
const destId = activeDest?.id ?? null;
|
|
204
|
+
const mode = detectCaptureMode();
|
|
205
|
+
// Check if stream voice (TTS) is enabled in settings
|
|
206
|
+
const streamSettings = readStreamSettings();
|
|
207
|
+
const voiceEnabled = streamSettings.voice?.enabled === true;
|
|
208
|
+
const ttsConfig = state.config?.messages?.tts;
|
|
209
|
+
const resolvedTts = voiceEnabled ? resolveTtsConfig(ttsConfig) : null;
|
|
210
|
+
const audioSource = resolvedTts
|
|
211
|
+
? "tts"
|
|
212
|
+
: (process.env.STREAM_AUDIO_SOURCE ??
|
|
213
|
+
process.env.RETAKE_AUDIO_SOURCE ??
|
|
214
|
+
"silent");
|
|
215
|
+
const audioDevice = process.env.STREAM_AUDIO_DEVICE ?? process.env.RETAKE_AUDIO_DEVICE;
|
|
216
|
+
const volume = parseInt(process.env.STREAM_VOLUME ?? process.env.RETAKE_VOLUME ?? "80", 10);
|
|
217
|
+
const resolution = "1280x720";
|
|
218
|
+
const baseConfig = {
|
|
219
|
+
rtmpUrl,
|
|
220
|
+
rtmpKey,
|
|
221
|
+
resolution,
|
|
222
|
+
bitrate: "1500k",
|
|
223
|
+
audioSource,
|
|
224
|
+
audioDevice,
|
|
225
|
+
volume,
|
|
226
|
+
};
|
|
227
|
+
switch (mode) {
|
|
228
|
+
case "pipe": {
|
|
229
|
+
// Desktop UI mode: FFmpeg reads frames from stdin via writeFrame().
|
|
230
|
+
logger.info("[stream] Capture mode: pipe (desktop UI)");
|
|
231
|
+
await state.streamManager.start({
|
|
232
|
+
...baseConfig,
|
|
233
|
+
inputMode: "pipe",
|
|
234
|
+
framerate: 15,
|
|
235
|
+
});
|
|
236
|
+
// Auto-start desktop frame capture so the UI is streamed without
|
|
237
|
+
// requiring a manual button click in the renderer.
|
|
238
|
+
if (state.screenCapture && !state.screenCapture.isFrameCaptureActive()) {
|
|
239
|
+
try {
|
|
240
|
+
const captureOpts = {
|
|
241
|
+
fps: 15,
|
|
242
|
+
quality: 70,
|
|
243
|
+
endpoint: "/api/stream/frame",
|
|
244
|
+
};
|
|
245
|
+
if (state.activeStreamSource.type !== "stream-tab" &&
|
|
246
|
+
state.activeStreamSource.url) {
|
|
247
|
+
captureOpts.gameUrl = state.activeStreamSource.url;
|
|
248
|
+
}
|
|
249
|
+
await state.screenCapture.startFrameCapture(captureOpts);
|
|
250
|
+
logger.info("[stream] Auto-started desktop frame capture");
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
logger.warn(`[stream] Failed to auto-start frame capture: ${err}`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
else if (!state.screenCapture) {
|
|
257
|
+
logger.warn("[stream] ScreenCaptureManager not available -- frame capture must be started manually");
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
case "x11grab": {
|
|
262
|
+
// Linux Xvfb mode (Hyperscape approach): capture virtual display.
|
|
263
|
+
const display = process.env.STREAM_DISPLAY ?? process.env.RETAKE_DISPLAY ?? ":99";
|
|
264
|
+
logger.info(`[stream] Capture mode: x11grab (display ${display})`);
|
|
265
|
+
// Ensure Xvfb is running
|
|
266
|
+
await ensureXvfb(display, resolution);
|
|
267
|
+
// Launch a browser on the virtual display so there's something to capture
|
|
268
|
+
const captureUrl = state.captureUrl ??
|
|
269
|
+
process.env.STREAM_CAPTURE_URL ??
|
|
270
|
+
process.env.RETAKE_CAPTURE_URL ??
|
|
271
|
+
`http://127.0.0.1:${state.port ?? 2138}`;
|
|
272
|
+
try {
|
|
273
|
+
const { startBrowserCapture } = await import("../services/browser-capture");
|
|
274
|
+
// Browser capture in x11grab mode just opens the browser on the display --
|
|
275
|
+
// we don't need the frame file since FFmpeg captures the display directly.
|
|
276
|
+
await startBrowserCapture({
|
|
277
|
+
url: captureUrl,
|
|
278
|
+
width: 1280,
|
|
279
|
+
height: 720,
|
|
280
|
+
quality: 70,
|
|
281
|
+
...getHeadlessCaptureConfig(destId),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
logger.warn(`[stream] Browser launch on ${display} failed: ${err}`);
|
|
286
|
+
}
|
|
287
|
+
await state.streamManager.start({
|
|
288
|
+
...baseConfig,
|
|
289
|
+
inputMode: "x11grab",
|
|
290
|
+
display,
|
|
291
|
+
framerate: 30,
|
|
292
|
+
});
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
case "avfoundation": {
|
|
296
|
+
// macOS native screen capture.
|
|
297
|
+
const videoDevice = process.env.STREAM_VIDEO_DEVICE ??
|
|
298
|
+
process.env.RETAKE_VIDEO_DEVICE ??
|
|
299
|
+
"3";
|
|
300
|
+
logger.info(`[stream] Capture mode: avfoundation (device ${videoDevice})`);
|
|
301
|
+
await state.streamManager.start({
|
|
302
|
+
...baseConfig,
|
|
303
|
+
inputMode: "avfoundation",
|
|
304
|
+
videoDevice,
|
|
305
|
+
framerate: 30,
|
|
306
|
+
});
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
default: {
|
|
310
|
+
// Headless browser capture -> temp JPEG file -> FFmpeg file mode.
|
|
311
|
+
const captureUrl = state.captureUrl ??
|
|
312
|
+
process.env.STREAM_CAPTURE_URL ??
|
|
313
|
+
process.env.RETAKE_CAPTURE_URL ??
|
|
314
|
+
`http://127.0.0.1:${state.port ?? 2138}`;
|
|
315
|
+
logger.info(`[stream] Capture mode: file (browser capture -> ${captureUrl})`);
|
|
316
|
+
const { startBrowserCapture, FRAME_FILE } = await import("../services/browser-capture");
|
|
317
|
+
try {
|
|
318
|
+
await startBrowserCapture({
|
|
319
|
+
url: captureUrl,
|
|
320
|
+
width: 1280,
|
|
321
|
+
height: 720,
|
|
322
|
+
quality: 70,
|
|
323
|
+
...getHeadlessCaptureConfig(destId),
|
|
324
|
+
});
|
|
325
|
+
// Wait for first frame file to be written
|
|
326
|
+
await new Promise((resolve) => {
|
|
327
|
+
const check = setInterval(() => {
|
|
328
|
+
try {
|
|
329
|
+
if (fs.existsSync(FRAME_FILE) &&
|
|
330
|
+
fs.statSync(FRAME_FILE).size > 0) {
|
|
331
|
+
clearInterval(check);
|
|
332
|
+
resolve(true);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
// Frame file not yet ready -- poll again
|
|
337
|
+
}
|
|
338
|
+
}, 200);
|
|
339
|
+
setTimeout(() => {
|
|
340
|
+
clearInterval(check);
|
|
341
|
+
resolve(false);
|
|
342
|
+
}, 10_000);
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
catch (captureErr) {
|
|
346
|
+
logger.warn(`[stream] Browser capture failed: ${captureErr}`);
|
|
347
|
+
}
|
|
348
|
+
await state.streamManager.start({
|
|
349
|
+
...baseConfig,
|
|
350
|
+
inputMode: "file",
|
|
351
|
+
frameFile: FRAME_FILE,
|
|
352
|
+
framerate: 30,
|
|
353
|
+
});
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return { inputMode: mode || "file", audioSource };
|
|
358
|
+
}
|
|
359
|
+
// ---------------------------------------------------------------------------
|
|
360
|
+
// Route handler
|
|
361
|
+
// ---------------------------------------------------------------------------
|
|
362
|
+
/** Returns `true` if handled, `false` to fall through. */
|
|
363
|
+
export async function handleStreamRoute(req, res, pathname, method, state) {
|
|
364
|
+
// Fast-path: skip if not a stream route
|
|
365
|
+
if (!pathname.startsWith("/api/stream/") &&
|
|
366
|
+
!pathname.startsWith("/api/streaming/")) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
// ── POST /api/stream/frame -- pipe frames to StreamManager + MJPEG ──
|
|
370
|
+
if (method === "POST" && pathname === "/api/stream/frame") {
|
|
371
|
+
try {
|
|
372
|
+
const buf = await readRequestBodyBuffer(req, {
|
|
373
|
+
maxBytes: 2 * 1024 * 1024,
|
|
374
|
+
});
|
|
375
|
+
if (!buf || buf.length === 0) {
|
|
376
|
+
error(res, "Empty frame", 400);
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
// Always store frame for MJPEG monitoring (GET /api/stream/screen)
|
|
380
|
+
pushFrameToSubscribers(buf);
|
|
381
|
+
// Write to FFmpeg only when RTMP streaming is active
|
|
382
|
+
if (state.streamManager.isRunning()) {
|
|
383
|
+
state.streamManager.writeFrame(buf);
|
|
384
|
+
}
|
|
385
|
+
res.writeHead(200);
|
|
386
|
+
res.end();
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
error(res, "Frame write failed", 500);
|
|
390
|
+
}
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
// ── GET /api/stream/screen -- MJPEG live view (local + remote agents) ─
|
|
394
|
+
// Serves a continuous multipart/x-mixed-replace stream of JPEG frames.
|
|
395
|
+
// Works independently of RTMP streaming — frames arrive via POST /api/stream/frame.
|
|
396
|
+
// Usage: <img src="http://agent-host:2138/api/stream/screen" />
|
|
397
|
+
if (method === "GET" && pathname === "/api/stream/screen") {
|
|
398
|
+
res.writeHead(200, {
|
|
399
|
+
"Content-Type": `multipart/x-mixed-replace; boundary=${MJPEG_BOUNDARY}`,
|
|
400
|
+
"Cache-Control": "no-store, no-cache",
|
|
401
|
+
Connection: "close",
|
|
402
|
+
"Access-Control-Allow-Origin": "*",
|
|
403
|
+
});
|
|
404
|
+
mjpegSubscribers.add(res);
|
|
405
|
+
// Send the latest cached frame immediately so there's no blank wait
|
|
406
|
+
if (latestFrame) {
|
|
407
|
+
const header = `--${MJPEG_BOUNDARY}\r\nContent-Type: image/jpeg\r\nContent-Length: ${latestFrame.length}\r\n\r\n`;
|
|
408
|
+
res.write(Buffer.concat([
|
|
409
|
+
Buffer.from(header, "ascii"),
|
|
410
|
+
latestFrame,
|
|
411
|
+
Buffer.from("\r\n", "ascii"),
|
|
412
|
+
]));
|
|
413
|
+
}
|
|
414
|
+
const cleanup = () => {
|
|
415
|
+
mjpegSubscribers.delete(res);
|
|
416
|
+
};
|
|
417
|
+
req.on("close", cleanup);
|
|
418
|
+
req.on("error", cleanup);
|
|
419
|
+
res.on("close", cleanup);
|
|
420
|
+
res.on("error", cleanup);
|
|
421
|
+
// Keep the response open — frames are pushed as they arrive
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
// ── POST /api/stream/live -- start stream via destination ────────────
|
|
425
|
+
if (method === "POST" && pathname === "/api/stream/live") {
|
|
426
|
+
if (state.streamManager.isRunning()) {
|
|
427
|
+
const health = state.streamManager.getHealth();
|
|
428
|
+
json(res, {
|
|
429
|
+
ok: true,
|
|
430
|
+
live: true,
|
|
431
|
+
message: "Already streaming",
|
|
432
|
+
...health,
|
|
433
|
+
});
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
const dest = getActiveDestination(state);
|
|
437
|
+
if (!dest) {
|
|
438
|
+
error(res, "No streaming destination configured", 400);
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
try {
|
|
442
|
+
const { rtmpUrl, rtmpKey } = await dest.getCredentials();
|
|
443
|
+
const { inputMode, audioSource } = await startStreamPipeline(state, rtmpUrl, rtmpKey);
|
|
444
|
+
await dest.onStreamStart?.();
|
|
445
|
+
json(res, {
|
|
446
|
+
ok: true,
|
|
447
|
+
live: true,
|
|
448
|
+
rtmpUrl,
|
|
449
|
+
inputMode,
|
|
450
|
+
audioSource,
|
|
451
|
+
destination: dest.id,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
catch (err) {
|
|
455
|
+
error(res, err instanceof Error ? err.message : "Failed to go live", 500);
|
|
456
|
+
}
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
// ── POST /api/stream/offline -- stop stream + notify destination ─────
|
|
460
|
+
if (method === "POST" && pathname === "/api/stream/offline") {
|
|
461
|
+
try {
|
|
462
|
+
// Stop browser capture
|
|
463
|
+
try {
|
|
464
|
+
const { stopBrowserCapture } = await import("../services/browser-capture");
|
|
465
|
+
await stopBrowserCapture();
|
|
466
|
+
}
|
|
467
|
+
catch {
|
|
468
|
+
// Browser capture may not have been started -- ignore
|
|
469
|
+
}
|
|
470
|
+
// Stop StreamManager
|
|
471
|
+
if (state.streamManager.isRunning()) {
|
|
472
|
+
await state.streamManager.stop();
|
|
473
|
+
}
|
|
474
|
+
// Notify destination
|
|
475
|
+
try {
|
|
476
|
+
await getActiveDestination(state)?.onStreamStop?.();
|
|
477
|
+
}
|
|
478
|
+
catch {
|
|
479
|
+
// Destination notification failure is non-fatal
|
|
480
|
+
}
|
|
481
|
+
json(res, { ok: true, live: false });
|
|
482
|
+
}
|
|
483
|
+
catch (err) {
|
|
484
|
+
error(res, err instanceof Error ? err.message : "Failed to go offline", 500);
|
|
485
|
+
}
|
|
486
|
+
return true;
|
|
487
|
+
}
|
|
488
|
+
// ── POST /api/stream/start -- backward-compat explicit RTMP start ────
|
|
489
|
+
if (method === "POST" && pathname === "/api/stream/start") {
|
|
490
|
+
try {
|
|
491
|
+
const bodyStr = await readRequestBody(req);
|
|
492
|
+
const body = typeof bodyStr === "string" ? JSON.parse(bodyStr) : bodyStr;
|
|
493
|
+
const rtmpUrl = body?.rtmpUrl;
|
|
494
|
+
const rtmpKey = body?.rtmpKey;
|
|
495
|
+
if (!rtmpUrl || !rtmpKey) {
|
|
496
|
+
error(res, "rtmpUrl and rtmpKey are required", 400);
|
|
497
|
+
return true;
|
|
498
|
+
}
|
|
499
|
+
if (!/^rtmps?:\/\//i.test(rtmpUrl)) {
|
|
500
|
+
error(res, "rtmpUrl must use rtmp:// or rtmps:// scheme", 400);
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
// Validate FFmpeg parameters to prevent filter expression injection
|
|
504
|
+
const VALID_INPUT_MODES = ["testsrc", "avfoundation", "pipe"];
|
|
505
|
+
const inputMode = body?.inputMode ?? "testsrc";
|
|
506
|
+
if (!VALID_INPUT_MODES.includes(inputMode)) {
|
|
507
|
+
error(res, `inputMode must be one of: ${VALID_INPUT_MODES.join(", ")}`, 400);
|
|
508
|
+
return true;
|
|
509
|
+
}
|
|
510
|
+
const resolution = body?.resolution || "1280x720";
|
|
511
|
+
if (!/^\d{3,4}x\d{3,4}$/.test(resolution)) {
|
|
512
|
+
error(res, "resolution must match WIDTHxHEIGHT (e.g. 1280x720)", 400);
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
const bitrate = body?.bitrate || "2500k";
|
|
516
|
+
if (!/^\d+k$/.test(bitrate)) {
|
|
517
|
+
error(res, "bitrate must match NUMBERk (e.g. 2500k)", 400);
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
const framerate = body?.framerate ?? 30;
|
|
521
|
+
if (typeof framerate !== "number" ||
|
|
522
|
+
!Number.isInteger(framerate) ||
|
|
523
|
+
framerate < 1 ||
|
|
524
|
+
framerate > 60) {
|
|
525
|
+
error(res, "framerate must be an integer between 1 and 60", 400);
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
await state.streamManager.start({
|
|
529
|
+
rtmpUrl,
|
|
530
|
+
rtmpKey,
|
|
531
|
+
inputMode,
|
|
532
|
+
resolution,
|
|
533
|
+
bitrate,
|
|
534
|
+
framerate,
|
|
535
|
+
});
|
|
536
|
+
json(res, { ok: true, message: "Stream started" });
|
|
537
|
+
}
|
|
538
|
+
catch (err) {
|
|
539
|
+
error(res, err instanceof Error ? err.message : "Stream start failed", 500);
|
|
540
|
+
}
|
|
541
|
+
return true;
|
|
542
|
+
}
|
|
543
|
+
// ── POST /api/stream/stop -- backward-compat explicit stop ───────────
|
|
544
|
+
if (method === "POST" && pathname === "/api/stream/stop") {
|
|
545
|
+
try {
|
|
546
|
+
const result = await state.streamManager.stop();
|
|
547
|
+
json(res, { ok: true, ...result });
|
|
548
|
+
}
|
|
549
|
+
catch (err) {
|
|
550
|
+
error(res, err instanceof Error ? err.message : "Stream stop failed", 500);
|
|
551
|
+
}
|
|
552
|
+
return true;
|
|
553
|
+
}
|
|
554
|
+
// ── GET /api/stream/status -- local stream health ────────────────────
|
|
555
|
+
if (method === "GET" && pathname === "/api/stream/status") {
|
|
556
|
+
const health = state.streamManager.getHealth();
|
|
557
|
+
const activeDest = getActiveDestination(state);
|
|
558
|
+
const destInfo = activeDest
|
|
559
|
+
? { id: activeDest.id, name: activeDest.name }
|
|
560
|
+
: null;
|
|
561
|
+
json(res, { ok: true, ...health, destination: destInfo });
|
|
562
|
+
return true;
|
|
563
|
+
}
|
|
564
|
+
// ── POST /api/stream/volume -- set stream volume (0-100) ─────────────
|
|
565
|
+
if (method === "POST" && pathname === "/api/stream/volume") {
|
|
566
|
+
try {
|
|
567
|
+
const body = await readRequestBody(req);
|
|
568
|
+
const parsed = typeof body === "string" ? JSON.parse(body) : body;
|
|
569
|
+
const level = parsed?.volume;
|
|
570
|
+
if (typeof level !== "number" ||
|
|
571
|
+
!Number.isFinite(level) ||
|
|
572
|
+
level < 0 ||
|
|
573
|
+
level > 100) {
|
|
574
|
+
error(res, "volume must be a number between 0 and 100", 400);
|
|
575
|
+
return true;
|
|
576
|
+
}
|
|
577
|
+
await state.streamManager.setVolume(level);
|
|
578
|
+
json(res, {
|
|
579
|
+
ok: true,
|
|
580
|
+
volume: state.streamManager.getVolume(),
|
|
581
|
+
muted: state.streamManager.isMuted(),
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
catch (err) {
|
|
585
|
+
error(res, err instanceof Error ? err.message : "Failed to set volume", 500);
|
|
586
|
+
}
|
|
587
|
+
return true;
|
|
588
|
+
}
|
|
589
|
+
// ── POST /api/stream/mute -- mute stream audio ──────────────────────
|
|
590
|
+
if (method === "POST" && pathname === "/api/stream/mute") {
|
|
591
|
+
try {
|
|
592
|
+
await state.streamManager.mute();
|
|
593
|
+
json(res, {
|
|
594
|
+
ok: true,
|
|
595
|
+
muted: true,
|
|
596
|
+
volume: state.streamManager.getVolume(),
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
catch (err) {
|
|
600
|
+
error(res, err instanceof Error ? err.message : "Failed to mute", 500);
|
|
601
|
+
}
|
|
602
|
+
return true;
|
|
603
|
+
}
|
|
604
|
+
// ── POST /api/stream/unmute -- unmute stream audio ───────────────────
|
|
605
|
+
if (method === "POST" && pathname === "/api/stream/unmute") {
|
|
606
|
+
try {
|
|
607
|
+
await state.streamManager.unmute();
|
|
608
|
+
json(res, {
|
|
609
|
+
ok: true,
|
|
610
|
+
muted: false,
|
|
611
|
+
volume: state.streamManager.getVolume(),
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
catch (err) {
|
|
615
|
+
error(res, err instanceof Error ? err.message : "Failed to unmute", 500);
|
|
616
|
+
}
|
|
617
|
+
return true;
|
|
618
|
+
}
|
|
619
|
+
// ── GET /api/streaming/destinations -- list configured destination ───
|
|
620
|
+
if (method === "GET" && pathname === "/api/streaming/destinations") {
|
|
621
|
+
const destinations = Array.from(state.destinations.values()).map((d) => ({
|
|
622
|
+
id: d.id,
|
|
623
|
+
name: d.name,
|
|
624
|
+
active: d.id ===
|
|
625
|
+
(state.activeDestinationId ?? state.destinations.keys().next().value),
|
|
626
|
+
}));
|
|
627
|
+
json(res, { ok: true, destinations });
|
|
628
|
+
return true;
|
|
629
|
+
}
|
|
630
|
+
// ── POST /api/streaming/destination -- set active destination ────────
|
|
631
|
+
if (method === "POST" && pathname === "/api/streaming/destination") {
|
|
632
|
+
try {
|
|
633
|
+
const body = await readRequestBody(req);
|
|
634
|
+
const parsed = typeof body === "string" ? JSON.parse(body) : body;
|
|
635
|
+
const destinationId = parsed?.destinationId;
|
|
636
|
+
if (!destinationId) {
|
|
637
|
+
error(res, "destinationId is required", 400);
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
const target = state.destinations.get(destinationId);
|
|
641
|
+
if (target) {
|
|
642
|
+
state.activeDestinationId = destinationId;
|
|
643
|
+
json(res, {
|
|
644
|
+
ok: true,
|
|
645
|
+
destination: { id: target.id, name: target.name },
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
error(res, `Unknown destination: ${destinationId}`, 404);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
catch (err) {
|
|
653
|
+
error(res, err instanceof Error ? err.message : "Failed to set destination", 500);
|
|
654
|
+
}
|
|
655
|
+
return true;
|
|
656
|
+
}
|
|
657
|
+
// ── GET /api/stream/overlay-layout -- read overlay config ─────────────
|
|
658
|
+
// Supports ?destination=<id> for per-destination layouts.
|
|
659
|
+
if (method === "GET" && pathname === "/api/stream/overlay-layout") {
|
|
660
|
+
try {
|
|
661
|
+
const destId = parseDestinationQuery(req.url);
|
|
662
|
+
const layout = readOverlayLayout(destId, getActiveDestination(state));
|
|
663
|
+
json(res, { ok: true, layout, destinationId: destId ?? null });
|
|
664
|
+
}
|
|
665
|
+
catch (err) {
|
|
666
|
+
error(res, err instanceof Error ? err.message : "Failed to read overlay layout", 500);
|
|
667
|
+
}
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
// ── POST /api/stream/overlay-layout -- save overlay config ────────────
|
|
671
|
+
// Supports ?destination=<id> for per-destination layouts.
|
|
672
|
+
if (method === "POST" && pathname === "/api/stream/overlay-layout") {
|
|
673
|
+
try {
|
|
674
|
+
const destId = parseDestinationQuery(req.url);
|
|
675
|
+
const body = await readRequestBody(req);
|
|
676
|
+
const parsed = typeof body === "string" ? JSON.parse(body) : body;
|
|
677
|
+
const layout = parsed?.layout;
|
|
678
|
+
if (!layout || layout.version !== 1 || !Array.isArray(layout.widgets)) {
|
|
679
|
+
error(res, "Invalid layout: must have { version: 1, widgets: [...] }", 400);
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
writeOverlayLayout(layout, destId);
|
|
683
|
+
json(res, { ok: true, layout, destinationId: destId ?? null });
|
|
684
|
+
}
|
|
685
|
+
catch (err) {
|
|
686
|
+
error(res, err instanceof Error ? err.message : "Failed to save overlay layout", 500);
|
|
687
|
+
}
|
|
688
|
+
return true;
|
|
689
|
+
}
|
|
690
|
+
// ── GET /api/stream/settings -- read stream visual settings ───────────
|
|
691
|
+
if (method === "GET" && pathname === "/api/stream/settings") {
|
|
692
|
+
try {
|
|
693
|
+
const settings = readStreamSettings();
|
|
694
|
+
json(res, { ok: true, settings });
|
|
695
|
+
}
|
|
696
|
+
catch (err) {
|
|
697
|
+
error(res, err instanceof Error ? err.message : "Failed to read settings", 500);
|
|
698
|
+
}
|
|
699
|
+
return true;
|
|
700
|
+
}
|
|
701
|
+
// ── POST /api/stream/settings -- save stream visual settings ──────────
|
|
702
|
+
if (method === "POST" && pathname === "/api/stream/settings") {
|
|
703
|
+
try {
|
|
704
|
+
const body = await readRequestBody(req);
|
|
705
|
+
const parsed = typeof body === "string" ? JSON.parse(body) : body;
|
|
706
|
+
const result = validateStreamSettings(parsed?.settings);
|
|
707
|
+
if (result.error || !result.settings) {
|
|
708
|
+
error(res, result.error ?? "Invalid settings", 400);
|
|
709
|
+
return true;
|
|
710
|
+
}
|
|
711
|
+
// Merge with existing settings so partial updates (e.g. just avatarIndex)
|
|
712
|
+
// don't wipe other fields (e.g. voice config).
|
|
713
|
+
const existing = readStreamSettings();
|
|
714
|
+
const merged = { ...existing, ...result.settings };
|
|
715
|
+
writeStreamSettings(merged);
|
|
716
|
+
json(res, { ok: true, settings: merged });
|
|
717
|
+
}
|
|
718
|
+
catch (err) {
|
|
719
|
+
error(res, err instanceof Error ? err.message : "Failed to save settings", 500);
|
|
720
|
+
}
|
|
721
|
+
return true;
|
|
722
|
+
}
|
|
723
|
+
// ── GET /api/stream/source -- get active stream source ───────────────
|
|
724
|
+
if (method === "GET" && pathname === "/api/stream/source") {
|
|
725
|
+
json(res, { source: state.activeStreamSource });
|
|
726
|
+
return true;
|
|
727
|
+
}
|
|
728
|
+
// ── POST /api/stream/source -- set active stream source ──────────────
|
|
729
|
+
if (method === "POST" && pathname === "/api/stream/source") {
|
|
730
|
+
try {
|
|
731
|
+
const body = await readRequestBody(req);
|
|
732
|
+
const { sourceType, customUrl } = JSON.parse(typeof body === "string" ? body : JSON.stringify(body));
|
|
733
|
+
if (!["stream-tab", "game", "custom-url"].includes(sourceType)) {
|
|
734
|
+
error(res, "Invalid sourceType", 400);
|
|
735
|
+
return true;
|
|
736
|
+
}
|
|
737
|
+
if (sourceType === "custom-url" && !customUrl) {
|
|
738
|
+
error(res, "customUrl required for custom-url source", 400);
|
|
739
|
+
return true;
|
|
740
|
+
}
|
|
741
|
+
if (sourceType === "game" && !customUrl) {
|
|
742
|
+
error(res, "customUrl required for game source", 400);
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
745
|
+
// Validate URL scheme to prevent file:// or javascript: URI injection.
|
|
746
|
+
// Only http/https are permitted as capture targets.
|
|
747
|
+
if ((sourceType === "game" || sourceType === "custom-url") &&
|
|
748
|
+
customUrl &&
|
|
749
|
+
!/^https?:\/\//i.test(customUrl)) {
|
|
750
|
+
error(res, "customUrl must use http:// or https:// scheme", 400);
|
|
751
|
+
return true;
|
|
752
|
+
}
|
|
753
|
+
// Stop current frame capture if active
|
|
754
|
+
if (state.screenCapture?.isFrameCaptureActive()) {
|
|
755
|
+
state.screenCapture.stopFrameCapture?.();
|
|
756
|
+
}
|
|
757
|
+
// Build capture options
|
|
758
|
+
const captureOpts = {
|
|
759
|
+
fps: 15,
|
|
760
|
+
quality: 70,
|
|
761
|
+
endpoint: "/api/stream/frame",
|
|
762
|
+
};
|
|
763
|
+
if (sourceType === "game" || sourceType === "custom-url") {
|
|
764
|
+
captureOpts.gameUrl = customUrl;
|
|
765
|
+
}
|
|
766
|
+
// Update state
|
|
767
|
+
state.activeStreamSource = { type: sourceType, url: customUrl };
|
|
768
|
+
// Restart frame capture if stream is running
|
|
769
|
+
if (state.streamManager.isRunning() && state.screenCapture) {
|
|
770
|
+
try {
|
|
771
|
+
await state.screenCapture.startFrameCapture(captureOpts);
|
|
772
|
+
}
|
|
773
|
+
catch (err) {
|
|
774
|
+
logger.warn(`[stream] Failed to restart frame capture after source switch: ${err}`);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
json(res, { ok: true, source: state.activeStreamSource });
|
|
778
|
+
}
|
|
779
|
+
catch (err) {
|
|
780
|
+
error(res, err instanceof Error ? err.message : "Failed to switch source", 500);
|
|
781
|
+
}
|
|
782
|
+
return true;
|
|
783
|
+
}
|
|
784
|
+
// ── Voice routes (GET/POST /api/stream/voice*) — delegated ──────────
|
|
785
|
+
if (pathname.startsWith("/api/stream/voice")) {
|
|
786
|
+
return handleAutonomousStreamVoiceRoute({
|
|
787
|
+
req,
|
|
788
|
+
res,
|
|
789
|
+
pathname,
|
|
790
|
+
method,
|
|
791
|
+
state,
|
|
792
|
+
getTtsProviderStatus: getRouteTtsProviderStatus,
|
|
793
|
+
resolveTtsConfig: resolveRouteTtsConfig,
|
|
794
|
+
ttsStreamBridge: ttsBridgeAdapter,
|
|
795
|
+
sanitizeSpeechText,
|
|
796
|
+
readStreamSettings: readRouteStreamSettings,
|
|
797
|
+
writeStreamSettings: writeRouteStreamSettings,
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
return false;
|
|
801
|
+
}
|
|
802
|
+
export async function onAgentMessage(text, state) {
|
|
803
|
+
return onAutonomousAgentMessage(text, state, {
|
|
804
|
+
sanitizeSpeechText,
|
|
805
|
+
readStreamSettings: readRouteStreamSettings,
|
|
806
|
+
resolveTtsConfig: resolveRouteTtsConfig,
|
|
807
|
+
ttsStreamBridge: ttsBridgeAdapter,
|
|
808
|
+
});
|
|
809
|
+
}
|