@getpaseo/server 0.1.16 → 0.1.18
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/dist/scripts/daemon-runner.js +53 -14
- package/dist/scripts/daemon-runner.js.map +1 -1
- package/dist/scripts/dev-runner.js +9 -16
- package/dist/scripts/dev-runner.js.map +1 -1
- package/dist/scripts/supervisor.js +40 -13
- package/dist/scripts/supervisor.js.map +1 -1
- package/dist/server/client/daemon-client.d.ts +23 -3
- package/dist/server/client/daemon-client.d.ts.map +1 -1
- package/dist/server/client/daemon-client.js +81 -8
- package/dist/server/client/daemon-client.js.map +1 -1
- package/dist/server/server/agent/agent-manager.d.ts +3 -1
- package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
- package/dist/server/server/agent/agent-manager.js +146 -24
- package/dist/server/server/agent/agent-manager.js.map +1 -1
- package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
- package/dist/server/server/agent/agent-metadata-generator.js +13 -4
- package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
- package/dist/server/server/agent/agent-response-loop.js +1 -1
- package/dist/server/server/agent/agent-response-loop.js.map +1 -1
- package/dist/server/server/agent/agent-sdk-types.d.ts +9 -0
- package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
- package/dist/server/server/agent/agent-sdk-types.js +11 -1
- package/dist/server/server/agent/agent-sdk-types.js.map +1 -1
- package/dist/server/server/agent/agent-storage.d.ts +5 -1
- package/dist/server/server/agent/agent-storage.d.ts.map +1 -1
- package/dist/server/server/agent/agent-storage.js +41 -72
- package/dist/server/server/agent/agent-storage.js.map +1 -1
- package/dist/server/server/agent/agent-title-limits.d.ts +3 -0
- package/dist/server/server/agent/agent-title-limits.d.ts.map +1 -0
- package/dist/server/server/agent/agent-title-limits.js +3 -0
- package/dist/server/server/agent/agent-title-limits.js.map +1 -0
- package/dist/server/server/agent/providers/claude/model-catalog.d.ts +29 -0
- package/dist/server/server/agent/providers/claude/model-catalog.d.ts.map +1 -0
- package/dist/server/server/agent/providers/claude/model-catalog.js +70 -0
- package/dist/server/server/agent/providers/claude/model-catalog.js.map +1 -0
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +44 -0
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts.map +1 -0
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +250 -0
- package/dist/server/server/agent/providers/claude/task-notification-tool-call.js.map +1 -0
- package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +15 -0
- package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.d.ts +3 -2
- package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.js +244 -107
- package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
- package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
- package/dist/server/server/agent/providers/codex/tool-call-mapper.js +81 -28
- package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.js +31 -5
- package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
- package/dist/server/server/agent/providers/opencode-agent.d.ts +10 -1
- package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/opencode-agent.js +207 -176
- package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
- package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +15 -0
- package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
- package/dist/server/server/agent/timeline-projection.d.ts +20 -0
- package/dist/server/server/agent/timeline-projection.d.ts.map +1 -1
- package/dist/server/server/agent/timeline-projection.js +73 -0
- package/dist/server/server/agent/timeline-projection.js.map +1 -1
- package/dist/server/server/bootstrap.d.ts +15 -0
- package/dist/server/server/bootstrap.d.ts.map +1 -1
- package/dist/server/server/bootstrap.js +27 -4
- package/dist/server/server/bootstrap.js.map +1 -1
- package/dist/server/server/file-download/token-store.d.ts +0 -1
- package/dist/server/server/file-download/token-store.d.ts.map +1 -1
- package/dist/server/server/file-download/token-store.js.map +1 -1
- package/dist/server/server/file-explorer/service.d.ts.map +1 -1
- package/dist/server/server/file-explorer/service.js +56 -36
- package/dist/server/server/file-explorer/service.js.map +1 -1
- package/dist/server/server/index.js +85 -29
- package/dist/server/server/index.js.map +1 -1
- package/dist/server/server/logger.d.ts +24 -3
- package/dist/server/server/logger.d.ts.map +1 -1
- package/dist/server/server/logger.js +157 -21
- package/dist/server/server/logger.js.map +1 -1
- package/dist/server/server/persisted-config.d.ts +86 -0
- package/dist/server/server/persisted-config.d.ts.map +1 -1
- package/dist/server/server/persisted-config.js +25 -3
- package/dist/server/server/persisted-config.js.map +1 -1
- package/dist/server/server/pid-lock.d.ts +6 -2
- package/dist/server/server/pid-lock.d.ts.map +1 -1
- package/dist/server/server/pid-lock.js +7 -10
- package/dist/server/server/pid-lock.js.map +1 -1
- package/dist/server/server/relay-transport.d.ts.map +1 -1
- package/dist/server/server/relay-transport.js +1 -0
- package/dist/server/server/relay-transport.js.map +1 -1
- package/dist/server/server/session.d.ts +57 -3
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +755 -182
- package/dist/server/server/session.js.map +1 -1
- package/dist/server/server/websocket-server.d.ts +16 -1
- package/dist/server/server/websocket-server.d.ts.map +1 -1
- package/dist/server/server/websocket-server.js +135 -9
- package/dist/server/server/websocket-server.js.map +1 -1
- package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
- package/dist/server/server/worktree-bootstrap.js +45 -2
- package/dist/server/server/worktree-bootstrap.js.map +1 -1
- package/dist/server/shared/messages.d.ts +2841 -541
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +99 -5
- package/dist/server/shared/messages.js.map +1 -1
- package/dist/server/shared/tool-call-display.d.ts.map +1 -1
- package/dist/server/shared/tool-call-display.js +3 -0
- package/dist/server/shared/tool-call-display.js.map +1 -1
- package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
- package/dist/server/terminal/terminal-manager.js +1 -13
- package/dist/server/terminal/terminal-manager.js.map +1 -1
- package/dist/server/terminal/terminal.d.ts.map +1 -1
- package/dist/server/terminal/terminal.js +29 -5
- package/dist/server/terminal/terminal.js.map +1 -1
- package/dist/server/utils/project-icon.d.ts +1 -1
- package/dist/server/utils/project-icon.d.ts.map +1 -1
- package/dist/server/utils/project-icon.js +9 -2
- package/dist/server/utils/project-icon.js.map +1 -1
- package/dist/server/utils/worktree.d.ts +1 -0
- package/dist/server/utils/worktree.d.ts.map +1 -1
- package/dist/server/utils/worktree.js +17 -2
- package/dist/server/utils/worktree.js.map +1 -1
- package/dist/src/server/agent/activity-curator.js +228 -0
- package/dist/src/server/agent/activity-curator.js.map +1 -0
- package/dist/src/server/agent/agent-manager.js +1712 -0
- package/dist/src/server/agent/agent-manager.js.map +1 -0
- package/dist/src/server/agent/agent-metadata-generator.js +163 -0
- package/dist/src/server/agent/agent-metadata-generator.js.map +1 -0
- package/dist/src/server/agent/agent-projections.js +262 -0
- package/dist/src/server/agent/agent-projections.js.map +1 -0
- package/dist/src/server/agent/agent-response-loop.js +304 -0
- package/dist/src/server/agent/agent-response-loop.js.map +1 -0
- package/dist/src/server/agent/agent-sdk-types.js +12 -0
- package/dist/src/server/agent/agent-sdk-types.js.map +1 -0
- package/dist/src/server/agent/agent-storage.js +299 -0
- package/dist/src/server/agent/agent-storage.js.map +1 -0
- package/dist/src/server/agent/agent-title-limits.js +3 -0
- package/dist/src/server/agent/agent-title-limits.js.map +1 -0
- package/dist/src/server/agent/audio-utils.js +19 -0
- package/dist/src/server/agent/audio-utils.js.map +1 -0
- package/dist/src/server/agent/dictation-debug.js +50 -0
- package/dist/src/server/agent/dictation-debug.js.map +1 -0
- package/dist/src/server/agent/mcp-server.js +787 -0
- package/dist/src/server/agent/mcp-server.js.map +1 -0
- package/dist/src/server/agent/orchestrator-instructions.js +51 -0
- package/dist/src/server/agent/orchestrator-instructions.js.map +1 -0
- package/dist/src/server/agent/pcm16-resampler.js +63 -0
- package/dist/src/server/agent/pcm16-resampler.js.map +1 -0
- package/dist/src/server/agent/provider-launch-config.js +83 -0
- package/dist/src/server/agent/provider-launch-config.js.map +1 -0
- package/dist/src/server/agent/provider-manifest.js +97 -0
- package/dist/src/server/agent/provider-manifest.js.map +1 -0
- package/dist/src/server/agent/provider-registry.js +45 -0
- package/dist/src/server/agent/provider-registry.js.map +1 -0
- package/dist/src/server/agent/providers/claude/model-catalog.js +70 -0
- package/dist/src/server/agent/providers/claude/model-catalog.js.map +1 -0
- package/dist/src/server/agent/providers/claude/task-notification-tool-call.js +250 -0
- package/dist/src/server/agent/providers/claude/task-notification-tool-call.js.map +1 -0
- package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js +109 -0
- package/dist/src/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -0
- package/dist/src/server/agent/providers/claude/tool-call-mapper.js +238 -0
- package/dist/src/server/agent/providers/claude/tool-call-mapper.js.map +1 -0
- package/dist/src/server/agent/providers/claude-agent.js +3750 -0
- package/dist/src/server/agent/providers/claude-agent.js.map +1 -0
- package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js +104 -0
- package/dist/src/server/agent/providers/codex/tool-call-detail-parser.js.map +1 -0
- package/dist/src/server/agent/providers/codex/tool-call-mapper.js +720 -0
- package/dist/src/server/agent/providers/codex/tool-call-mapper.js.map +1 -0
- package/dist/src/server/agent/providers/codex-app-server-agent.js +2601 -0
- package/dist/src/server/agent/providers/codex-app-server-agent.js.map +1 -0
- package/dist/src/server/agent/providers/codex-rollout-timeline.js +487 -0
- package/dist/src/server/agent/providers/codex-rollout-timeline.js.map +1 -0
- package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js +39 -0
- package/dist/src/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -0
- package/dist/src/server/agent/providers/opencode/tool-call-mapper.js +151 -0
- package/dist/src/server/agent/providers/opencode/tool-call-mapper.js.map +1 -0
- package/dist/src/server/agent/providers/opencode-agent.js +905 -0
- package/dist/src/server/agent/providers/opencode-agent.js.map +1 -0
- package/dist/src/server/agent/providers/tool-call-detail-primitives.js +552 -0
- package/dist/src/server/agent/providers/tool-call-detail-primitives.js.map +1 -0
- package/dist/src/server/agent/providers/tool-call-mapper-utils.js +109 -0
- package/dist/src/server/agent/providers/tool-call-mapper-utils.js.map +1 -0
- package/dist/src/server/agent/recordings-debug.js +19 -0
- package/dist/src/server/agent/recordings-debug.js.map +1 -0
- package/dist/src/server/agent/stt-debug.js +33 -0
- package/dist/src/server/agent/stt-debug.js.map +1 -0
- package/dist/src/server/agent/stt-manager.js +233 -0
- package/dist/src/server/agent/stt-manager.js.map +1 -0
- package/dist/src/server/agent/timeline-append.js +27 -0
- package/dist/src/server/agent/timeline-append.js.map +1 -0
- package/dist/src/server/agent/timeline-projection.js +215 -0
- package/dist/src/server/agent/timeline-projection.js.map +1 -0
- package/dist/src/server/agent/tool-name-normalization.js +45 -0
- package/dist/src/server/agent/tool-name-normalization.js.map +1 -0
- package/dist/src/server/agent/tts-debug.js +24 -0
- package/dist/src/server/agent/tts-debug.js.map +1 -0
- package/dist/src/server/agent/tts-manager.js +249 -0
- package/dist/src/server/agent/tts-manager.js.map +1 -0
- package/dist/src/server/agent/wait-for-agent-tracker.js +53 -0
- package/dist/src/server/agent/wait-for-agent-tracker.js.map +1 -0
- package/dist/src/server/agent-attention-policy.js +40 -0
- package/dist/src/server/agent-attention-policy.js.map +1 -0
- package/dist/src/server/allowed-hosts.js +94 -0
- package/dist/src/server/allowed-hosts.js.map +1 -0
- package/dist/src/server/bootstrap.js +498 -0
- package/dist/src/server/bootstrap.js.map +1 -0
- package/dist/src/server/client-message-id.js +12 -0
- package/dist/src/server/client-message-id.js.map +1 -0
- package/dist/src/server/config.js +84 -0
- package/dist/src/server/config.js.map +1 -0
- package/dist/src/server/connection-offer.js +60 -0
- package/dist/src/server/connection-offer.js.map +1 -0
- package/dist/src/server/daemon-keypair.js +40 -0
- package/dist/src/server/daemon-keypair.js.map +1 -0
- package/dist/src/server/daemon-version.js +22 -0
- package/dist/src/server/daemon-version.js.map +1 -0
- package/dist/src/server/dictation/dictation-stream-manager.js +568 -0
- package/dist/src/server/dictation/dictation-stream-manager.js.map +1 -0
- package/dist/src/server/file-download/token-store.js +40 -0
- package/dist/src/server/file-download/token-store.js.map +1 -0
- package/dist/src/server/file-explorer/service.js +183 -0
- package/dist/src/server/file-explorer/service.js.map +1 -0
- package/dist/src/server/json-utils.js +45 -0
- package/dist/src/server/json-utils.js.map +1 -0
- package/dist/src/server/messages.js +29 -0
- package/dist/src/server/messages.js.map +1 -0
- package/dist/src/server/package-version.js +47 -0
- package/dist/src/server/package-version.js.map +1 -0
- package/dist/src/server/paseo-home.js +19 -0
- package/dist/src/server/paseo-home.js.map +1 -0
- package/dist/src/server/path-utils.js +20 -0
- package/dist/src/server/path-utils.js.map +1 -0
- package/dist/src/server/persisted-config.js +259 -0
- package/dist/src/server/persisted-config.js.map +1 -0
- package/dist/src/server/persistence-hooks.js +60 -0
- package/dist/src/server/persistence-hooks.js.map +1 -0
- package/dist/src/server/pid-lock.js +126 -0
- package/dist/src/server/pid-lock.js.map +1 -0
- package/dist/src/server/push/push-service.js +68 -0
- package/dist/src/server/push/push-service.js.map +1 -0
- package/dist/src/server/push/token-store.js +70 -0
- package/dist/src/server/push/token-store.js.map +1 -0
- package/dist/src/server/relay-transport.js +457 -0
- package/dist/src/server/relay-transport.js.map +1 -0
- package/dist/src/server/server-id.js +63 -0
- package/dist/src/server/server-id.js.map +1 -0
- package/dist/src/server/session.js +5947 -0
- package/dist/src/server/session.js.map +1 -0
- package/dist/src/server/speech/audio.js +101 -0
- package/dist/src/server/speech/audio.js.map +1 -0
- package/dist/src/server/speech/provider-resolver.js +7 -0
- package/dist/src/server/speech/provider-resolver.js.map +1 -0
- package/dist/src/server/speech/providers/local/config.js +83 -0
- package/dist/src/server/speech/providers/local/config.js.map +1 -0
- package/dist/src/server/speech/providers/local/models.js +17 -0
- package/dist/src/server/speech/providers/local/models.js.map +1 -0
- package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js +422 -0
- package/dist/src/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -0
- package/dist/src/server/speech/providers/local/runtime.js +253 -0
- package/dist/src/server/speech/providers/local/runtime.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/model-catalog.js +166 -0
- package/dist/src/server/speech/providers/local/sherpa/model-catalog.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/model-downloader.js +165 -0
- package/dist/src/server/speech/providers/local/sherpa/model-downloader.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +68 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +79 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.js +11 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-loader.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +102 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +131 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +132 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js +112 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js +140 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js +95 -0
- package/dist/src/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -0
- package/dist/src/server/speech/providers/openai/config.js +99 -0
- package/dist/src/server/speech/providers/openai/config.js.map +1 -0
- package/dist/src/server/speech/providers/openai/realtime-transcription-session.js +165 -0
- package/dist/src/server/speech/providers/openai/realtime-transcription-session.js.map +1 -0
- package/dist/src/server/speech/providers/openai/runtime.js +114 -0
- package/dist/src/server/speech/providers/openai/runtime.js.map +1 -0
- package/dist/src/server/speech/providers/openai/stt.js +208 -0
- package/dist/src/server/speech/providers/openai/stt.js.map +1 -0
- package/dist/src/server/speech/providers/openai/tts.js +46 -0
- package/dist/src/server/speech/providers/openai/tts.js.map +1 -0
- package/dist/src/server/speech/speech-config-resolver.js +85 -0
- package/dist/src/server/speech/speech-config-resolver.js.map +1 -0
- package/dist/src/server/speech/speech-provider.js +2 -0
- package/dist/src/server/speech/speech-provider.js.map +1 -0
- package/dist/src/server/speech/speech-runtime.js +497 -0
- package/dist/src/server/speech/speech-runtime.js.map +1 -0
- package/dist/src/server/speech/speech-types.js +8 -0
- package/dist/src/server/speech/speech-types.js.map +1 -0
- package/dist/src/server/utils/diff-highlighter.js +244 -0
- package/dist/src/server/utils/diff-highlighter.js.map +1 -0
- package/dist/src/server/utils/syntax-highlighter.js +145 -0
- package/dist/src/server/utils/syntax-highlighter.js.map +1 -0
- package/dist/src/server/voice-config.js +51 -0
- package/dist/src/server/voice-config.js.map +1 -0
- package/dist/src/server/voice-mcp-bridge-command.js +31 -0
- package/dist/src/server/voice-mcp-bridge-command.js.map +1 -0
- package/dist/src/server/voice-mcp-bridge.js +109 -0
- package/dist/src/server/voice-mcp-bridge.js.map +1 -0
- package/dist/src/server/voice-permission-policy.js +13 -0
- package/dist/src/server/voice-permission-policy.js.map +1 -0
- package/dist/src/server/voice-types.js +2 -0
- package/dist/src/server/voice-types.js.map +1 -0
- package/dist/src/server/websocket-server.js +967 -0
- package/dist/src/server/websocket-server.js.map +1 -0
- package/dist/src/server/worktree-bootstrap.js +497 -0
- package/dist/src/server/worktree-bootstrap.js.map +1 -0
- package/dist/src/shared/agent-attention-notification.js +130 -0
- package/dist/src/shared/agent-attention-notification.js.map +1 -0
- package/dist/src/shared/agent-lifecycle.js +8 -0
- package/dist/src/shared/agent-lifecycle.js.map +1 -0
- package/dist/src/shared/binary-mux.js +114 -0
- package/dist/src/shared/binary-mux.js.map +1 -0
- package/dist/src/shared/connection-offer.js +17 -0
- package/dist/src/shared/connection-offer.js.map +1 -0
- package/dist/src/shared/daemon-endpoints.js +113 -0
- package/dist/src/shared/daemon-endpoints.js.map +1 -0
- package/dist/src/shared/messages.js +2001 -0
- package/dist/src/shared/messages.js.map +1 -0
- package/dist/src/shared/path-utils.js +16 -0
- package/dist/src/shared/path-utils.js.map +1 -0
- package/dist/src/shared/tool-call-display.js +93 -0
- package/dist/src/shared/tool-call-display.js.map +1 -0
- package/dist/src/terminal/terminal-manager.js +136 -0
- package/dist/src/terminal/terminal-manager.js.map +1 -0
- package/dist/src/terminal/terminal.js +410 -0
- package/dist/src/terminal/terminal.js.map +1 -0
- package/dist/src/utils/checkout-git.js +1397 -0
- package/dist/src/utils/checkout-git.js.map +1 -0
- package/dist/src/utils/directory-suggestions.js +655 -0
- package/dist/src/utils/directory-suggestions.js.map +1 -0
- package/dist/src/utils/path.js +15 -0
- package/dist/src/utils/path.js.map +1 -0
- package/dist/src/utils/project-icon.js +398 -0
- package/dist/src/utils/project-icon.js.map +1 -0
- package/dist/src/utils/worktree-metadata.js +116 -0
- package/dist/src/utils/worktree-metadata.js.map +1 -0
- package/dist/src/utils/worktree.js +741 -0
- package/dist/src/utils/worktree.js.map +1 -0
- package/package.json +14 -6
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function hasActiveClientOnAgent(allClientStates, agentId) {
|
|
2
|
+
return allClientStates.some((state) => state.focusedAgentId === agentId && state.appVisible && !state.isStale);
|
|
3
|
+
}
|
|
4
|
+
function hasActiveWebClient(allClientStates) {
|
|
5
|
+
return allClientStates.some((state) => state.deviceType === "web" && !state.isStale);
|
|
6
|
+
}
|
|
7
|
+
function hasOtherCompetingClient(clientState, allClientStates) {
|
|
8
|
+
return allClientStates.some((state) => state !== clientState && (state.deviceType === "mobile" || state.deviceType === null));
|
|
9
|
+
}
|
|
10
|
+
function hasActiveForegroundMobileClient(allClientStates) {
|
|
11
|
+
return allClientStates.some((state) => state.deviceType === "mobile" && state.appVisible && !state.isStale);
|
|
12
|
+
}
|
|
13
|
+
export function computeShouldNotifyClient({ clientState, allClientStates, agentId, }) {
|
|
14
|
+
if (hasActiveClientOnAgent(allClientStates, agentId)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
if (clientState.deviceType === null) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
if (!clientState.isStale && clientState.appVisible && clientState.focusedAgentId !== null) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (!clientState.isStale) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
if (clientState.deviceType === "mobile") {
|
|
27
|
+
return !hasActiveWebClient(allClientStates);
|
|
28
|
+
}
|
|
29
|
+
if (clientState.deviceType === "web") {
|
|
30
|
+
return !hasOtherCompetingClient(clientState, allClientStates);
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
export function computeShouldSendPush({ reason, allClientStates, }) {
|
|
35
|
+
if (reason === "error") {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return !hasActiveWebClient(allClientStates) && !hasActiveForegroundMobileClient(allClientStates);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=agent-attention-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-attention-policy.js","sourceRoot":"","sources":["../../../src/server/agent-attention-policy.ts"],"names":[],"mappings":"AAoBA,SAAS,sBAAsB,CAC7B,eAAuC,EACvC,OAAe;IAEf,OAAO,eAAe,CAAC,IAAI,CACzB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,KAAK,OAAO,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAClF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,eAAuC;IACjE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACvF,CAAC;AAED,SAAS,uBAAuB,CAC9B,WAAiC,EACjC,eAAuC;IAEvC,OAAO,eAAe,CAAC,IAAI,CACzB,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,KAAK,WAAW,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,CACxF,CAAC;AACJ,CAAC;AAED,SAAS,+BAA+B,CAAC,eAAuC;IAC9E,OAAO,eAAe,CAAC,IAAI,CACzB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAC/E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,EACxC,WAAW,EACX,eAAe,EACf,OAAO,GACwB;IAC/B,IAAI,sBAAsB,CAAC,eAAe,EAAE,OAAO,CAAC,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,WAAW,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,UAAU,IAAI,WAAW,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QAC1F,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,WAAW,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,WAAW,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;QACrC,OAAO,CAAC,uBAAuB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EACpC,MAAM,EACN,eAAe,GACc;IAC7B,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,kBAAkB,CAAC,eAAe,CAAC,IAAI,CAAC,+BAA+B,CAAC,eAAe,CAAC,CAAC;AACnG,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import net from "node:net";
|
|
2
|
+
function normalizeHostname(hostname) {
|
|
3
|
+
return hostname.trim().toLowerCase();
|
|
4
|
+
}
|
|
5
|
+
function parseHostnameFromHostHeader(hostHeader) {
|
|
6
|
+
const trimmed = hostHeader.trim();
|
|
7
|
+
if (!trimmed)
|
|
8
|
+
return null;
|
|
9
|
+
// IPv6 in brackets: [::1]:6767
|
|
10
|
+
if (trimmed.startsWith("[")) {
|
|
11
|
+
const end = trimmed.indexOf("]");
|
|
12
|
+
if (end === -1)
|
|
13
|
+
return null;
|
|
14
|
+
return normalizeHostname(trimmed.slice(1, end));
|
|
15
|
+
}
|
|
16
|
+
// IPv4/hostname with optional port: localhost:6767
|
|
17
|
+
const colonIndex = trimmed.indexOf(":");
|
|
18
|
+
if (colonIndex === -1) {
|
|
19
|
+
return normalizeHostname(trimmed);
|
|
20
|
+
}
|
|
21
|
+
return normalizeHostname(trimmed.slice(0, colonIndex));
|
|
22
|
+
}
|
|
23
|
+
function matchesAllowedHostPattern(hostname, pattern) {
|
|
24
|
+
const normalizedPattern = normalizeHostname(pattern);
|
|
25
|
+
if (!normalizedPattern)
|
|
26
|
+
return false;
|
|
27
|
+
if (normalizedPattern.startsWith(".")) {
|
|
28
|
+
const base = normalizedPattern.slice(1);
|
|
29
|
+
if (!base)
|
|
30
|
+
return false;
|
|
31
|
+
return hostname === base || hostname.endsWith(`.${base}`);
|
|
32
|
+
}
|
|
33
|
+
return hostname === normalizedPattern;
|
|
34
|
+
}
|
|
35
|
+
function isDefaultAllowedHostname(hostname) {
|
|
36
|
+
// Vite-style defaults: localhost, *.localhost, and all IP addresses.
|
|
37
|
+
if (hostname === "localhost")
|
|
38
|
+
return true;
|
|
39
|
+
if (hostname.endsWith(".localhost"))
|
|
40
|
+
return true;
|
|
41
|
+
if (net.isIP(hostname) !== 0)
|
|
42
|
+
return true;
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Vite-style allowed hosts check, adapted to raw Host headers.
|
|
47
|
+
*
|
|
48
|
+
* Semantics:
|
|
49
|
+
* - `allowedHosts === true` => allow any host.
|
|
50
|
+
* - `allowedHosts === []` or `undefined` => allow localhost, *.localhost, and all IPs.
|
|
51
|
+
* - `allowedHosts === ['.example.com', 'myhost']` => allow those *in addition* to defaults.
|
|
52
|
+
*/
|
|
53
|
+
export function isHostAllowed(hostHeader, allowedHosts) {
|
|
54
|
+
const hostname = hostHeader ? parseHostnameFromHostHeader(hostHeader) : null;
|
|
55
|
+
if (!hostname)
|
|
56
|
+
return false;
|
|
57
|
+
if (allowedHosts === true)
|
|
58
|
+
return true;
|
|
59
|
+
// Defaults are always allowed.
|
|
60
|
+
if (isDefaultAllowedHostname(hostname))
|
|
61
|
+
return true;
|
|
62
|
+
const patterns = allowedHosts ?? [];
|
|
63
|
+
for (const pattern of patterns) {
|
|
64
|
+
if (matchesAllowedHostPattern(hostname, pattern))
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
export function mergeAllowedHosts(values) {
|
|
70
|
+
let merged = [];
|
|
71
|
+
for (const value of values) {
|
|
72
|
+
if (value === true)
|
|
73
|
+
return true;
|
|
74
|
+
if (!value)
|
|
75
|
+
continue;
|
|
76
|
+
merged = merged.concat(value);
|
|
77
|
+
}
|
|
78
|
+
const deduped = Array.from(new Set(merged.map((v) => v.trim()).filter((v) => v.length > 0)));
|
|
79
|
+
return deduped;
|
|
80
|
+
}
|
|
81
|
+
export function parseAllowedHostsEnv(raw) {
|
|
82
|
+
if (!raw)
|
|
83
|
+
return undefined;
|
|
84
|
+
const trimmed = raw.trim();
|
|
85
|
+
if (!trimmed)
|
|
86
|
+
return undefined;
|
|
87
|
+
if (trimmed.toLowerCase() === "true")
|
|
88
|
+
return true;
|
|
89
|
+
return trimmed
|
|
90
|
+
.split(",")
|
|
91
|
+
.map((s) => s.trim())
|
|
92
|
+
.filter((s) => s.length > 0);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=allowed-hosts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allowed-hosts.js","sourceRoot":"","sources":["../../../src/server/allowed-hosts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { createServer as createHTTPServer } from "http";
|
|
3
|
+
import { createReadStream, unlinkSync, existsSync } from "fs";
|
|
4
|
+
import { stat } from "fs/promises";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
8
|
+
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
9
|
+
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
function parseListenString(listen) {
|
|
11
|
+
// Unix socket: starts with / or ~ or contains .sock
|
|
12
|
+
if (listen.startsWith("/") || listen.startsWith("~") || listen.includes(".sock")) {
|
|
13
|
+
return { type: "socket", path: listen };
|
|
14
|
+
}
|
|
15
|
+
// Explicit unix:// prefix
|
|
16
|
+
if (listen.startsWith("unix://")) {
|
|
17
|
+
return { type: "socket", path: listen.slice(7) };
|
|
18
|
+
}
|
|
19
|
+
// TCP: host:port or just port
|
|
20
|
+
if (listen.includes(":")) {
|
|
21
|
+
const [host, portStr] = listen.split(":");
|
|
22
|
+
const port = parseInt(portStr, 10);
|
|
23
|
+
if (!Number.isFinite(port)) {
|
|
24
|
+
throw new Error(`Invalid port in listen string: ${listen}`);
|
|
25
|
+
}
|
|
26
|
+
return { type: "tcp", host: host || "127.0.0.1", port };
|
|
27
|
+
}
|
|
28
|
+
// Just a port number
|
|
29
|
+
const port = parseInt(listen, 10);
|
|
30
|
+
if (Number.isFinite(port)) {
|
|
31
|
+
return { type: "tcp", host: "127.0.0.1", port };
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`Invalid listen string: ${listen}`);
|
|
34
|
+
}
|
|
35
|
+
import { VoiceAssistantWebSocketServer } from "./websocket-server.js";
|
|
36
|
+
import { DownloadTokenStore } from "./file-download/token-store.js";
|
|
37
|
+
import { initializeSpeechRuntime } from "./speech/speech-runtime.js";
|
|
38
|
+
import { AgentManager } from "./agent/agent-manager.js";
|
|
39
|
+
import { AgentStorage } from "./agent/agent-storage.js";
|
|
40
|
+
import { attachAgentStoragePersistence } from "./persistence-hooks.js";
|
|
41
|
+
import { createAgentMcpServer } from "./agent/mcp-server.js";
|
|
42
|
+
import { createAllClients, shutdownProviders } from "./agent/provider-registry.js";
|
|
43
|
+
import { createTerminalManager } from "../terminal/terminal-manager.js";
|
|
44
|
+
import { createConnectionOfferV2, encodeOfferToFragmentUrl, } from "./connection-offer.js";
|
|
45
|
+
import { loadOrCreateDaemonKeyPair } from "./daemon-keypair.js";
|
|
46
|
+
import { startRelayTransport } from "./relay-transport.js";
|
|
47
|
+
import { getOrCreateServerId } from "./server-id.js";
|
|
48
|
+
import { resolveDaemonVersion } from "./daemon-version.js";
|
|
49
|
+
import { acquirePidLock, releasePidLock } from "./pid-lock.js";
|
|
50
|
+
import { isHostAllowed } from "./allowed-hosts.js";
|
|
51
|
+
import { createVoiceMcpSocketBridgeManager, } from "./voice-mcp-bridge.js";
|
|
52
|
+
import { resolveVoiceMcpBridgeFromRuntime } from "./voice-mcp-bridge-command.js";
|
|
53
|
+
function resolveVoiceMcpBridgeCommand(logger) {
|
|
54
|
+
const decision = resolveVoiceMcpBridgeFromRuntime({
|
|
55
|
+
bootstrapModuleUrl: import.meta.url,
|
|
56
|
+
execPath: process.execPath,
|
|
57
|
+
explicitScriptPath: process.env.PASEO_MCP_STDIO_SOCKET_BRIDGE_SCRIPT,
|
|
58
|
+
});
|
|
59
|
+
logger.info({
|
|
60
|
+
source: decision.source,
|
|
61
|
+
command: decision.resolved.command,
|
|
62
|
+
baseArgs: decision.resolved.baseArgs,
|
|
63
|
+
}, "Resolved voice MCP bridge command");
|
|
64
|
+
return decision.resolved;
|
|
65
|
+
}
|
|
66
|
+
export async function createPaseoDaemon(config, rootLogger) {
|
|
67
|
+
const logger = rootLogger.child({ module: "bootstrap" });
|
|
68
|
+
const daemonVersion = resolveDaemonVersion(import.meta.url);
|
|
69
|
+
const pidLockMode = config.pidLock?.mode ?? "self";
|
|
70
|
+
const pidLockOwnerPid = config.pidLock?.ownerPid;
|
|
71
|
+
const ownsPidLock = pidLockMode === "self";
|
|
72
|
+
// Acquire PID lock before expensive bootstrap work so duplicate starts fail immediately.
|
|
73
|
+
if (ownsPidLock) {
|
|
74
|
+
await acquirePidLock(config.paseoHome, config.listen, {
|
|
75
|
+
ownerPid: pidLockOwnerPid,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const serverId = getOrCreateServerId(config.paseoHome, { logger });
|
|
80
|
+
const daemonKeyPair = await loadOrCreateDaemonKeyPair(config.paseoHome, logger);
|
|
81
|
+
let relayTransport = null;
|
|
82
|
+
const staticDir = config.staticDir;
|
|
83
|
+
const downloadTokenTtlMs = config.downloadTokenTtlMs ?? 60000;
|
|
84
|
+
const downloadTokenStore = new DownloadTokenStore({ ttlMs: downloadTokenTtlMs });
|
|
85
|
+
const listenTarget = parseListenString(config.listen);
|
|
86
|
+
const app = express();
|
|
87
|
+
// Host allowlist / DNS rebinding protection (vite-like semantics).
|
|
88
|
+
// For non-TCP (unix sockets), skip host validation.
|
|
89
|
+
if (listenTarget.type === "tcp") {
|
|
90
|
+
app.use((req, res, next) => {
|
|
91
|
+
const hostHeader = typeof req.headers.host === "string" ? req.headers.host : undefined;
|
|
92
|
+
if (!isHostAllowed(hostHeader, config.allowedHosts)) {
|
|
93
|
+
res.status(403).json({ error: "Invalid Host header" });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
next();
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// CORS - allow same-origin + configured origins
|
|
100
|
+
const allowedOrigins = new Set([
|
|
101
|
+
...config.corsAllowedOrigins,
|
|
102
|
+
// Tauri desktop app WebView origin (used for fetch/WebSocket in production builds).
|
|
103
|
+
// This origin can't be produced by normal websites, so it's safe to allow by default.
|
|
104
|
+
"tauri://localhost",
|
|
105
|
+
// For TCP, add localhost variants
|
|
106
|
+
...(listenTarget.type === "tcp"
|
|
107
|
+
? [
|
|
108
|
+
`http://${listenTarget.host}:${listenTarget.port}`,
|
|
109
|
+
`http://localhost:${listenTarget.port}`,
|
|
110
|
+
`http://127.0.0.1:${listenTarget.port}`,
|
|
111
|
+
]
|
|
112
|
+
: []),
|
|
113
|
+
]);
|
|
114
|
+
app.use((req, res, next) => {
|
|
115
|
+
const origin = req.headers.origin;
|
|
116
|
+
if (origin && allowedOrigins.has(origin)) {
|
|
117
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
118
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
119
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
120
|
+
res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
121
|
+
}
|
|
122
|
+
if (req.method === "OPTIONS") {
|
|
123
|
+
res.status(204).end();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
next();
|
|
127
|
+
});
|
|
128
|
+
// Serve static files from public directory
|
|
129
|
+
app.use("/public", express.static(staticDir));
|
|
130
|
+
// Middleware
|
|
131
|
+
app.use(express.json());
|
|
132
|
+
// Health check endpoint
|
|
133
|
+
app.get("/api/health", (_req, res) => {
|
|
134
|
+
res.json({ status: "ok", timestamp: new Date().toISOString() });
|
|
135
|
+
});
|
|
136
|
+
app.get("/api/files/download", async (req, res) => {
|
|
137
|
+
const token = typeof req.query.token === "string" && req.query.token.trim().length > 0
|
|
138
|
+
? req.query.token.trim()
|
|
139
|
+
: null;
|
|
140
|
+
if (!token) {
|
|
141
|
+
res.status(400).json({ error: "Missing download token" });
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const entry = downloadTokenStore.consumeToken(token);
|
|
145
|
+
if (!entry) {
|
|
146
|
+
res.status(403).json({ error: "Invalid or expired token" });
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const fileStats = await stat(entry.absolutePath);
|
|
151
|
+
if (!fileStats.isFile()) {
|
|
152
|
+
res.status(404).json({ error: "File not found" });
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const safeFileName = entry.fileName.replace(/["\r\n]/g, "_");
|
|
156
|
+
res.setHeader("Content-Type", entry.mimeType);
|
|
157
|
+
res.setHeader("Content-Disposition", `attachment; filename="${safeFileName}"`);
|
|
158
|
+
res.setHeader("Content-Length", entry.size.toString());
|
|
159
|
+
const stream = createReadStream(entry.absolutePath);
|
|
160
|
+
stream.on("error", (err) => {
|
|
161
|
+
logger.error({ err }, "Failed to stream download");
|
|
162
|
+
if (!res.headersSent) {
|
|
163
|
+
res.status(500).json({ error: "Failed to read file" });
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
res.end();
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
stream.pipe(res);
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
logger.error({ err }, "Failed to download file");
|
|
173
|
+
if (!res.headersSent) {
|
|
174
|
+
res.status(404).json({ error: "File not found" });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
const httpServer = createHTTPServer(app);
|
|
179
|
+
const agentStorage = new AgentStorage(config.agentStoragePath, logger);
|
|
180
|
+
const agentManager = new AgentManager({
|
|
181
|
+
clients: {
|
|
182
|
+
...createAllClients(logger, {
|
|
183
|
+
runtimeSettings: config.agentProviderSettings,
|
|
184
|
+
}),
|
|
185
|
+
...config.agentClients,
|
|
186
|
+
},
|
|
187
|
+
registry: agentStorage,
|
|
188
|
+
logger,
|
|
189
|
+
});
|
|
190
|
+
const terminalManager = createTerminalManager();
|
|
191
|
+
const detachAgentStoragePersistence = attachAgentStoragePersistence(logger, agentManager, agentStorage);
|
|
192
|
+
await agentStorage.initialize();
|
|
193
|
+
const persistedRecords = await agentStorage.list();
|
|
194
|
+
logger.info(`Agent registry loaded (${persistedRecords.length} record${persistedRecords.length === 1 ? "" : "s"}); agents will initialize on demand`);
|
|
195
|
+
logger.info("Voice mode configured for agent-scoped resume flow (no dedicated voice assistant provider)");
|
|
196
|
+
let wsServer = null;
|
|
197
|
+
let voiceMcpBridgeManager = null;
|
|
198
|
+
let unsubscribeSpeechReadiness = null;
|
|
199
|
+
// Create in-memory transport for Session's Agent MCP client (voice assistant tools)
|
|
200
|
+
const createInMemoryAgentMcpTransport = async () => {
|
|
201
|
+
const agentMcpServer = await createAgentMcpServer({
|
|
202
|
+
agentManager,
|
|
203
|
+
agentStorage,
|
|
204
|
+
terminalManager,
|
|
205
|
+
paseoHome: config.paseoHome,
|
|
206
|
+
enableVoiceTools: false,
|
|
207
|
+
resolveSpeakHandler: (callerAgentId) => wsServer?.resolveVoiceSpeakHandler(callerAgentId) ?? null,
|
|
208
|
+
resolveCallerContext: (callerAgentId) => wsServer?.resolveVoiceCallerContext(callerAgentId) ?? null,
|
|
209
|
+
logger,
|
|
210
|
+
});
|
|
211
|
+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
212
|
+
await agentMcpServer.connect(serverTransport);
|
|
213
|
+
return clientTransport;
|
|
214
|
+
};
|
|
215
|
+
const mcpEnabled = config.mcpEnabled ?? true;
|
|
216
|
+
if (mcpEnabled) {
|
|
217
|
+
const agentMcpRoute = "/mcp/agents";
|
|
218
|
+
const agentMcpTransports = new Map();
|
|
219
|
+
const createAgentMcpTransport = async (callerAgentId) => {
|
|
220
|
+
const agentMcpServer = await createAgentMcpServer({
|
|
221
|
+
agentManager,
|
|
222
|
+
agentStorage,
|
|
223
|
+
terminalManager,
|
|
224
|
+
paseoHome: config.paseoHome,
|
|
225
|
+
callerAgentId,
|
|
226
|
+
enableVoiceTools: false,
|
|
227
|
+
resolveSpeakHandler: (agentId) => wsServer?.resolveVoiceSpeakHandler(agentId) ?? null,
|
|
228
|
+
resolveCallerContext: (agentId) => wsServer?.resolveVoiceCallerContext(agentId) ?? null,
|
|
229
|
+
logger,
|
|
230
|
+
});
|
|
231
|
+
const transport = new StreamableHTTPServerTransport({
|
|
232
|
+
sessionIdGenerator: () => randomUUID(),
|
|
233
|
+
onsessioninitialized: (sessionId) => {
|
|
234
|
+
agentMcpTransports.set(sessionId, transport);
|
|
235
|
+
logger.debug({ sessionId }, "Agent MCP session initialized");
|
|
236
|
+
},
|
|
237
|
+
onsessionclosed: (sessionId) => {
|
|
238
|
+
agentMcpTransports.delete(sessionId);
|
|
239
|
+
logger.debug({ sessionId }, "Agent MCP session closed");
|
|
240
|
+
},
|
|
241
|
+
// NOTE: We enforce a Vite-like host allowlist at the app/websocket layer.
|
|
242
|
+
// StreamableHTTPServerTransport's built-in check requires exact Host header matches.
|
|
243
|
+
enableDnsRebindingProtection: false,
|
|
244
|
+
});
|
|
245
|
+
transport.onclose = () => {
|
|
246
|
+
if (transport.sessionId) {
|
|
247
|
+
agentMcpTransports.delete(transport.sessionId);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
transport.onerror = (err) => {
|
|
251
|
+
logger.error({ err }, "Agent MCP transport error");
|
|
252
|
+
};
|
|
253
|
+
await agentMcpServer.connect(transport);
|
|
254
|
+
return transport;
|
|
255
|
+
};
|
|
256
|
+
const handleAgentMcpRequest = async (req, res) => {
|
|
257
|
+
if (config.mcpDebug) {
|
|
258
|
+
logger.debug({
|
|
259
|
+
method: req.method,
|
|
260
|
+
url: req.originalUrl,
|
|
261
|
+
sessionId: req.header("mcp-session-id"),
|
|
262
|
+
authorization: req.header("authorization"),
|
|
263
|
+
body: req.body,
|
|
264
|
+
}, "Agent MCP request");
|
|
265
|
+
}
|
|
266
|
+
try {
|
|
267
|
+
const sessionId = req.header("mcp-session-id");
|
|
268
|
+
let transport = sessionId ? agentMcpTransports.get(sessionId) : undefined;
|
|
269
|
+
if (!transport) {
|
|
270
|
+
if (req.method !== "POST") {
|
|
271
|
+
res.status(400).json({
|
|
272
|
+
jsonrpc: "2.0",
|
|
273
|
+
error: {
|
|
274
|
+
code: -32000,
|
|
275
|
+
message: "Missing or invalid MCP session",
|
|
276
|
+
},
|
|
277
|
+
id: null,
|
|
278
|
+
});
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (!isInitializeRequest(req.body)) {
|
|
282
|
+
res.status(400).json({
|
|
283
|
+
jsonrpc: "2.0",
|
|
284
|
+
error: {
|
|
285
|
+
code: -32000,
|
|
286
|
+
message: "Initialization request expected",
|
|
287
|
+
},
|
|
288
|
+
id: null,
|
|
289
|
+
});
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const callerAgentIdRaw = req.query.callerAgentId;
|
|
293
|
+
const callerAgentId = typeof callerAgentIdRaw === "string"
|
|
294
|
+
? callerAgentIdRaw
|
|
295
|
+
: Array.isArray(callerAgentIdRaw) && typeof callerAgentIdRaw[0] === "string"
|
|
296
|
+
? callerAgentIdRaw[0]
|
|
297
|
+
: undefined;
|
|
298
|
+
transport = await createAgentMcpTransport(callerAgentId);
|
|
299
|
+
}
|
|
300
|
+
await transport.handleRequest(req, res, req.body);
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
logger.error({ err }, "Failed to handle Agent MCP request");
|
|
304
|
+
if (!res.headersSent) {
|
|
305
|
+
res.status(500).json({
|
|
306
|
+
jsonrpc: "2.0",
|
|
307
|
+
error: {
|
|
308
|
+
code: -32603,
|
|
309
|
+
message: "Internal MCP server error",
|
|
310
|
+
},
|
|
311
|
+
id: null,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
app.post(agentMcpRoute, handleAgentMcpRequest);
|
|
317
|
+
app.get(agentMcpRoute, handleAgentMcpRequest);
|
|
318
|
+
app.delete(agentMcpRoute, handleAgentMcpRequest);
|
|
319
|
+
logger.info({ route: agentMcpRoute }, "Agent MCP server mounted on main app");
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
logger.info("Agent MCP HTTP endpoint disabled");
|
|
323
|
+
}
|
|
324
|
+
const voiceMcpSocketDir = path.join(config.paseoHome, "runtime", "voice-mcp");
|
|
325
|
+
const voiceMcpBridgeCommand = resolveVoiceMcpBridgeCommand(logger);
|
|
326
|
+
voiceMcpBridgeManager = createVoiceMcpSocketBridgeManager({
|
|
327
|
+
runtimeDir: voiceMcpSocketDir,
|
|
328
|
+
logger,
|
|
329
|
+
createAgentMcpServerForCaller: async (callerAgentId) => {
|
|
330
|
+
return createAgentMcpServer({
|
|
331
|
+
agentManager,
|
|
332
|
+
agentStorage,
|
|
333
|
+
terminalManager,
|
|
334
|
+
paseoHome: config.paseoHome,
|
|
335
|
+
callerAgentId,
|
|
336
|
+
voiceOnly: true,
|
|
337
|
+
resolveSpeakHandler: (agentId) => wsServer?.resolveVoiceSpeakHandler(agentId) ?? null,
|
|
338
|
+
resolveCallerContext: (agentId) => wsServer?.resolveVoiceCallerContext(agentId) ?? null,
|
|
339
|
+
logger,
|
|
340
|
+
});
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
const { resolveVoiceStt, resolveVoiceTts, resolveDictationStt, getSpeechReadiness, subscribeSpeechReadiness, cleanup: cleanupSpeechRuntime, localModelConfig, } = await initializeSpeechRuntime({
|
|
344
|
+
logger,
|
|
345
|
+
openaiConfig: config.openai,
|
|
346
|
+
speechConfig: config.speech,
|
|
347
|
+
});
|
|
348
|
+
wsServer = new VoiceAssistantWebSocketServer(httpServer, logger, serverId, agentManager, agentStorage, downloadTokenStore, config.paseoHome, createInMemoryAgentMcpTransport, { allowedOrigins, allowedHosts: config.allowedHosts }, { stt: resolveVoiceStt, tts: resolveVoiceTts }, terminalManager, {
|
|
349
|
+
voiceAgentMcpStdio: {
|
|
350
|
+
command: voiceMcpBridgeCommand.command,
|
|
351
|
+
baseArgs: [...voiceMcpBridgeCommand.baseArgs],
|
|
352
|
+
env: {
|
|
353
|
+
PASEO_HOME: config.paseoHome,
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
ensureVoiceMcpSocketForAgent: (agentId) => voiceMcpBridgeManager?.ensureBridgeForCaller(agentId) ??
|
|
357
|
+
Promise.reject(new Error("Voice MCP bridge manager is not initialized")),
|
|
358
|
+
removeVoiceMcpSocketForAgent: (agentId) => voiceMcpBridgeManager?.removeBridgeForCaller(agentId) ?? Promise.resolve(),
|
|
359
|
+
}, {
|
|
360
|
+
finalTimeoutMs: config.dictationFinalTimeoutMs,
|
|
361
|
+
stt: resolveDictationStt,
|
|
362
|
+
localModels: localModelConfig ?? undefined,
|
|
363
|
+
getSpeechReadiness,
|
|
364
|
+
}, config.agentProviderSettings, daemonVersion, (intent) => {
|
|
365
|
+
try {
|
|
366
|
+
config.onLifecycleIntent?.(intent);
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
logger.error({ err: error, intent }, "Failed to handle daemon lifecycle intent");
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
unsubscribeSpeechReadiness = subscribeSpeechReadiness((snapshot) => {
|
|
373
|
+
wsServer?.publishSpeechReadiness(snapshot);
|
|
374
|
+
});
|
|
375
|
+
const start = async () => {
|
|
376
|
+
// Start main HTTP server
|
|
377
|
+
await new Promise((resolve, reject) => {
|
|
378
|
+
const onError = (err) => {
|
|
379
|
+
httpServer.off("listening", onListening);
|
|
380
|
+
reject(err);
|
|
381
|
+
};
|
|
382
|
+
const onListening = () => {
|
|
383
|
+
httpServer.off("error", onError);
|
|
384
|
+
const logAndResolve = async () => {
|
|
385
|
+
if (listenTarget.type === "tcp") {
|
|
386
|
+
logger.info({ host: listenTarget.host, port: listenTarget.port }, `Server listening on http://${listenTarget.host}:${listenTarget.port}`);
|
|
387
|
+
const relayEnabled = config.relayEnabled ?? true;
|
|
388
|
+
const relayEndpoint = config.relayEndpoint ?? "relay.paseo.sh:443";
|
|
389
|
+
const relayPublicEndpoint = config.relayPublicEndpoint ?? relayEndpoint;
|
|
390
|
+
const appBaseUrl = config.appBaseUrl ?? "https://app.paseo.sh";
|
|
391
|
+
if (relayEnabled) {
|
|
392
|
+
const offer = await createConnectionOfferV2({
|
|
393
|
+
serverId,
|
|
394
|
+
daemonPublicKeyB64: daemonKeyPair.publicKeyB64,
|
|
395
|
+
relay: { endpoint: relayPublicEndpoint },
|
|
396
|
+
});
|
|
397
|
+
const url = encodeOfferToFragmentUrl({ offer, appBaseUrl });
|
|
398
|
+
logger.info({ url }, "pairing_offer");
|
|
399
|
+
}
|
|
400
|
+
if (relayEnabled) {
|
|
401
|
+
relayTransport?.stop().catch(() => undefined);
|
|
402
|
+
relayTransport = startRelayTransport({
|
|
403
|
+
logger,
|
|
404
|
+
attachSocket: (ws, metadata) => {
|
|
405
|
+
if (!wsServer) {
|
|
406
|
+
throw new Error("WebSocket server not initialized");
|
|
407
|
+
}
|
|
408
|
+
return wsServer.attachExternalSocket(ws, metadata);
|
|
409
|
+
},
|
|
410
|
+
relayEndpoint,
|
|
411
|
+
serverId,
|
|
412
|
+
daemonKeyPair: daemonKeyPair.keyPair,
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
logger.info({ path: listenTarget.path }, `Server listening on ${listenTarget.path}`);
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
logAndResolve().then(resolve, reject);
|
|
421
|
+
};
|
|
422
|
+
httpServer.once("error", onError);
|
|
423
|
+
httpServer.once("listening", onListening);
|
|
424
|
+
if (listenTarget.type === "tcp") {
|
|
425
|
+
httpServer.listen(listenTarget.port, listenTarget.host);
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
// Remove stale socket file if it exists
|
|
429
|
+
if (existsSync(listenTarget.path)) {
|
|
430
|
+
unlinkSync(listenTarget.path);
|
|
431
|
+
}
|
|
432
|
+
httpServer.listen(listenTarget.path);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
};
|
|
436
|
+
const stop = async () => {
|
|
437
|
+
await closeAllAgents(logger, agentManager);
|
|
438
|
+
await agentManager.flush().catch(() => undefined);
|
|
439
|
+
detachAgentStoragePersistence();
|
|
440
|
+
await agentStorage.flush().catch(() => undefined);
|
|
441
|
+
await shutdownProviders(logger, {
|
|
442
|
+
runtimeSettings: config.agentProviderSettings,
|
|
443
|
+
});
|
|
444
|
+
terminalManager.killAll();
|
|
445
|
+
unsubscribeSpeechReadiness?.();
|
|
446
|
+
unsubscribeSpeechReadiness = null;
|
|
447
|
+
cleanupSpeechRuntime();
|
|
448
|
+
await relayTransport?.stop().catch(() => undefined);
|
|
449
|
+
if (wsServer) {
|
|
450
|
+
await wsServer.close();
|
|
451
|
+
}
|
|
452
|
+
if (voiceMcpBridgeManager) {
|
|
453
|
+
await voiceMcpBridgeManager.stop().catch(() => undefined);
|
|
454
|
+
}
|
|
455
|
+
await new Promise((resolve) => {
|
|
456
|
+
httpServer.close(() => resolve());
|
|
457
|
+
});
|
|
458
|
+
// Clean up socket files
|
|
459
|
+
if (listenTarget.type === "socket" && existsSync(listenTarget.path)) {
|
|
460
|
+
unlinkSync(listenTarget.path);
|
|
461
|
+
}
|
|
462
|
+
// Release PID lock
|
|
463
|
+
if (ownsPidLock) {
|
|
464
|
+
await releasePidLock(config.paseoHome, {
|
|
465
|
+
ownerPid: pidLockOwnerPid,
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
return {
|
|
470
|
+
config,
|
|
471
|
+
agentManager,
|
|
472
|
+
agentStorage,
|
|
473
|
+
terminalManager,
|
|
474
|
+
start,
|
|
475
|
+
stop,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
catch (err) {
|
|
479
|
+
if (ownsPidLock) {
|
|
480
|
+
await releasePidLock(config.paseoHome, {
|
|
481
|
+
ownerPid: pidLockOwnerPid,
|
|
482
|
+
}).catch(() => undefined);
|
|
483
|
+
}
|
|
484
|
+
throw err;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
async function closeAllAgents(logger, agentManager) {
|
|
488
|
+
const agents = agentManager.listAgents();
|
|
489
|
+
for (const agent of agents) {
|
|
490
|
+
try {
|
|
491
|
+
await agentManager.closeAgent(agent.id);
|
|
492
|
+
}
|
|
493
|
+
catch (err) {
|
|
494
|
+
logger.error({ err, agentId: agent.id }, "Failed to close agent");
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
//# sourceMappingURL=bootstrap.js.map
|