@vellumai/assistant 0.6.3 → 0.6.4
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/ARCHITECTURE.md +273 -10
- package/Dockerfile +2 -3
- package/bun.lock +5 -13
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/stt-provider-onboarding.md +120 -0
- package/knip.json +12 -2
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +3 -3
- package/openapi.yaml +982 -72
- package/package.json +4 -6
- package/scripts/generate-openapi.ts +0 -1
- package/scripts/test.sh +73 -18
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop.test.ts +123 -0
- package/src/__tests__/anthropic-provider.test.ts +263 -10
- package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +11 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/browser-skill-endstate.test.ts +31 -7
- package/src/__tests__/btw-routes.test.ts +7 -0
- package/src/__tests__/call-controller.test.ts +581 -20
- package/src/__tests__/catalog-files.test.ts +138 -0
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/checker.test.ts +157 -10
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/config-analysis.test.ts +100 -0
- package/src/__tests__/config-schema.test.ts +1013 -66
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-window-manager.test.ts +88 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +98 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +135 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-history-web-search.test.ts +11 -4
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +901 -60
- package/src/__tests__/conversation-routes-disk-view.test.ts +270 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +55 -0
- package/src/__tests__/conversation-skill-tools.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +89 -18
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +5 -3
- package/src/__tests__/credential-vault-unit.test.ts +379 -3
- package/src/__tests__/credentials-cli.test.ts +40 -16
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +75 -8
- package/src/__tests__/fixtures/mock-chrome-extension.ts +11 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-provider.test.ts +64 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
- package/src/__tests__/gmail-archive-gate.test.ts +246 -0
- package/src/__tests__/gmail-preferences.test.ts +117 -0
- package/src/__tests__/headless-browser-interactions.test.ts +43 -0
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +142 -5
- package/src/__tests__/headless-browser-read-tools.test.ts +11 -0
- package/src/__tests__/headless-browser-snapshot.test.ts +10 -0
- package/src/__tests__/heartbeat-service.test.ts +70 -17
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +0 -5
- package/src/__tests__/host-browser-e2e-cloud.test.ts +138 -4
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +4 -4
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +103 -0
- package/src/__tests__/host-cu-proxy.test.ts +0 -5
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/llm-context-normalization.test.ts +488 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/migration-export-http.test.ts +6 -6
- package/src/__tests__/migration-import-commit-http.test.ts +8 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +2 -2
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +2 -0
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
- package/src/__tests__/oauth-providers-routes.test.ts +2 -0
- package/src/__tests__/oauth-store.test.ts +85 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +249 -6
- package/src/__tests__/onboarding-template-contract.test.ts +6 -13
- package/src/__tests__/openai-provider.test.ts +176 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1105 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +31 -2
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +423 -5
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-scanner-executor.test.ts +4 -0
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +5 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +276 -145
- package/src/__tests__/skills-files-catalog-fallback.test.ts +381 -93
- package/src/__tests__/skills.test.ts +5 -2
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +564 -1
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/system-prompt.test.ts +112 -26
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +18 -7
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +33 -24
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-format.test.ts +59 -0
- package/src/__tests__/update-bulletin.test.ts +206 -5
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-policy.test.ts +2 -0
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +43 -3
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- package/src/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +8 -1
- package/src/channels/types.ts +16 -0
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +22 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +37 -4
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/conversations.ts +77 -0
- package/src/cli/commands/credentials.ts +0 -1
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +255 -3
- package/src/cli/commands/oauth/__tests__/connect.test.ts +12 -0
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -0
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +15 -0
- package/src/cli/commands/oauth/shared.ts +2 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +4 -9
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
- package/src/cli/program.ts +30 -4
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +37 -1
- package/src/config/bundled-skills/browser/SKILL.md +30 -5
- package/src/config/bundled-skills/browser/TOOLS.json +123 -0
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
- package/src/config/bundled-skills/contacts/SKILL.md +2 -2
- package/src/config/bundled-skills/gmail/SKILL.md +53 -7
- package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/outlook/SKILL.md +2 -2
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/slack/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +8 -0
- package/src/config/env-registry.ts +24 -0
- package/src/config/env.ts +34 -10
- package/src/config/feature-flag-registry.json +46 -14
- package/src/config/loader.ts +26 -12
- package/src/config/schema.ts +35 -10
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +51 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -26
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +47 -7
- package/src/config/schemas/heartbeat.ts +27 -5
- package/src/config/schemas/host-browser.ts +47 -1
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/services.ts +44 -0
- package/src/config/schemas/stt.ts +59 -0
- package/src/config/schemas/tts.ts +230 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/skills.ts +4 -0
- package/src/config/types.ts +4 -0
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/post-turn-tool-result-truncation.ts +3 -2
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +45 -12
- package/src/credential-execution/executable-discovery.ts +12 -2
- package/src/credential-execution/process-manager.ts +33 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +17 -8
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/conversation-agent-loop-handlers.ts +6 -0
- package/src/daemon/conversation-agent-loop.ts +101 -24
- package/src/daemon/conversation-error.ts +11 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +59 -9
- package/src/daemon/conversation-messaging.ts +37 -3
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +581 -19
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +11 -1
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +94 -4
- package/src/daemon/conversation-tool-setup.ts +25 -0
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation.ts +86 -28
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +4 -1
- package/src/daemon/handlers/shared.ts +22 -0
- package/src/daemon/handlers/skills.ts +321 -77
- package/src/daemon/host-browser-proxy.ts +2 -1
- package/src/daemon/lifecycle.ts +122 -25
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/conversations.ts +34 -1
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +14 -0
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +16 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +347 -2
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +9 -0
- package/src/email/html-renderer.ts +76 -0
- package/src/heartbeat/heartbeat-service.ts +93 -7
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +194 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +398 -0
- package/src/home/assistant-feed-authoring.ts +124 -0
- package/src/home/emit-feed-event.ts +158 -0
- package/src/home/feed-scheduler.ts +247 -0
- package/src/home/feed-types.ts +181 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +384 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +12 -3
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/cli-client.ts +151 -0
- package/src/ipc/cli-server.ts +234 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/index.ts +5 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/app-store.ts +1 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +73 -0
- package/src/memory/conversation-crud.ts +99 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +34 -2
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/db-init.ts +6 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction.test.ts +23 -0
- package/src/memory/graph/extraction.ts +8 -0
- package/src/memory/graph/retriever.ts +27 -18
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +16 -10
- package/src/memory/jobs-store.ts +64 -4
- package/src/memory/jobs-worker.ts +22 -9
- package/src/memory/llm-usage-store.ts +92 -56
- package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/oauth.ts +3 -0
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/client.ts +57 -6
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +143 -38
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/notifications/decision-engine.ts +3 -3
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +1 -0
- package/src/oauth/byo-connection.test.ts +18 -1
- package/src/oauth/byo-connection.ts +3 -1
- package/src/oauth/connect-orchestrator.ts +2 -0
- package/src/oauth/connection-resolver.ts +6 -2
- package/src/oauth/connection.ts +2 -0
- package/src/oauth/oauth-store.ts +9 -0
- package/src/oauth/platform-connection.test.ts +98 -0
- package/src/oauth/platform-connection.ts +52 -31
- package/src/oauth/seed-providers.ts +7 -0
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/workspace-policy.ts +3 -0
- package/src/platform/client.test.ts +10 -0
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +126 -2
- package/src/prompts/system-prompt.ts +59 -18
- package/src/prompts/templates/BOOTSTRAP.md +5 -5
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-format.ts +26 -9
- package/src/prompts/update-bulletin.ts +34 -23
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/anthropic/client.ts +157 -61
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +9 -1
- package/src/providers/model-catalog.ts +6 -0
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +474 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +502 -0
- package/src/providers/openrouter/client.ts +101 -4
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +14 -3
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +306 -0
- package/src/providers/speech-to-text/resolve.ts +386 -6
- package/src/providers/types.ts +9 -0
- package/src/runtime/AGENTS.md +43 -1
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +512 -0
- package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
- package/src/runtime/auth/route-policy.ts +30 -5
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +10 -10
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/chrome-extension-registry.ts +38 -2
- package/src/runtime/http-server.ts +395 -10
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +36 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +1 -0
- package/src/runtime/migrations/migration-wizard.ts +1 -0
- package/src/runtime/migrations/vbundle-import-analyzer.ts +77 -1
- package/src/runtime/migrations/vbundle-importer.ts +34 -0
- package/src/runtime/pending-interactions.ts +0 -11
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +82 -23
- package/src/runtime/routes/btw-routes.ts +8 -6
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -142
- package/src/runtime/routes/conversation-management-routes.ts +115 -0
- package/src/runtime/routes/conversation-routes.ts +367 -146
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/home-feed-routes.ts +334 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +3 -14
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +3 -17
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +11 -3
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +303 -0
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/migration-routes.ts +40 -5
- package/src/runtime/routes/settings-routes.ts +22 -5
- package/src/runtime/routes/skills-routes.ts +76 -7
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +30 -2
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.ts +8 -1
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +344 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +49 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +50 -0
- package/src/security/oauth2.ts +26 -4
- package/src/security/secure-keys.ts +25 -2
- package/src/security/token-manager.ts +8 -0
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +64 -2
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +195 -0
- package/src/stt/stt-stream-session.ts +499 -0
- package/src/stt/types.ts +330 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +38 -14
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
- package/src/tools/browser/browser-execution.ts +1163 -23
- package/src/tools/browser/browser-manager.ts +45 -0
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +393 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +29 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1648 -32
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +264 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +183 -17
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +254 -21
- package/src/tools/browser/cdp-client/errors.ts +15 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +39 -16
- package/src/tools/browser/cdp-client/factory.ts +797 -87
- package/src/tools/browser/cdp-client/index.ts +16 -2
- package/src/tools/browser/cdp-client/types.ts +68 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +2 -0
- package/src/tools/skills/sandbox-runner.ts +3 -2
- package/src/tools/terminal/safe-env.ts +10 -2
- package/src/tools/terminal/shell.ts +15 -4
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +17 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tts/__tests__/provider-adapters.test.ts +834 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +201 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +42 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +153 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/platform.ts +54 -10
- package/src/util/pricing.ts +66 -3
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +23 -0
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/top-level-renderer.ts +13 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/cli/commands/browser-relay.ts +0 -466
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/runtime/routes/browser-cdp-routes.ts +0 -229
|
@@ -21,6 +21,10 @@ import {
|
|
|
21
21
|
startGuardianActionSweep,
|
|
22
22
|
stopGuardianActionSweep,
|
|
23
23
|
} from "../calls/guardian-action-sweep.js";
|
|
24
|
+
import {
|
|
25
|
+
activeMediaStreamSessions,
|
|
26
|
+
MediaStreamCallSession,
|
|
27
|
+
} from "../calls/media-stream-server.js";
|
|
24
28
|
import type { RelayWebSocketData } from "../calls/relay-server.js";
|
|
25
29
|
import {
|
|
26
30
|
activeRelayConnections,
|
|
@@ -37,6 +41,7 @@ import {
|
|
|
37
41
|
hasUngatedHttpAuthDisabled,
|
|
38
42
|
isHttpAuthDisabled,
|
|
39
43
|
} from "../config/env.js";
|
|
44
|
+
import { getConfig } from "../config/loader.js";
|
|
40
45
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
41
46
|
import { PairingStore } from "../daemon/pairing-store.js";
|
|
42
47
|
import {
|
|
@@ -62,10 +67,15 @@ import {
|
|
|
62
67
|
import type { ExternalConversationBinding } from "../memory/external-conversation-store.js";
|
|
63
68
|
import * as externalConversationStore from "../memory/external-conversation-store.js";
|
|
64
69
|
import { listGroups } from "../memory/group-crud.js";
|
|
70
|
+
import { resolveStreamingTranscriber } from "../providers/speech-to-text/resolve.js";
|
|
65
71
|
import {
|
|
66
72
|
consumeCallback,
|
|
67
73
|
consumeCallbackError,
|
|
68
74
|
} from "../security/oauth-callback-registry.js";
|
|
75
|
+
import {
|
|
76
|
+
activeSttStreamSessions,
|
|
77
|
+
SttStreamSession,
|
|
78
|
+
} from "../stt/stt-stream-session.js";
|
|
69
79
|
import { UserError } from "../util/errors.js";
|
|
70
80
|
import { getLogger } from "../util/logger.js";
|
|
71
81
|
import { getRuntimePortFilePath } from "../util/platform.js";
|
|
@@ -121,8 +131,8 @@ import { approvalRouteDefinitions } from "./routes/approval-routes.js";
|
|
|
121
131
|
import { attachmentRouteDefinitions } from "./routes/attachment-routes.js";
|
|
122
132
|
import { handleGetAudio } from "./routes/audio-routes.js";
|
|
123
133
|
import { avatarRouteDefinitions } from "./routes/avatar-routes.js";
|
|
134
|
+
import { backupRouteDefinitions } from "./routes/backup-routes.js";
|
|
124
135
|
import { brainGraphRouteDefinitions } from "./routes/brain-graph-routes.js";
|
|
125
|
-
import { browserCdpRouteDefinitions } from "./routes/browser-cdp-routes.js";
|
|
126
136
|
import { handleBrowserExtensionPair } from "./routes/browser-extension-pair-routes.js";
|
|
127
137
|
import { btwRouteDefinitions } from "./routes/btw-routes.js";
|
|
128
138
|
import { callRouteDefinitions } from "./routes/call-routes.js";
|
|
@@ -154,12 +164,15 @@ import { debugRouteDefinitions } from "./routes/debug-routes.js";
|
|
|
154
164
|
import { diagnosticsRouteDefinitions } from "./routes/diagnostics-routes.js";
|
|
155
165
|
import { documentRouteDefinitions } from "./routes/documents-routes.js";
|
|
156
166
|
import { eventsRouteDefinitions } from "./routes/events-routes.js";
|
|
167
|
+
import { filingRouteDefinitions } from "./routes/filing-routes.js";
|
|
157
168
|
import { globalSearchRouteDefinitions } from "./routes/global-search-routes.js";
|
|
158
169
|
import { groupRouteDefinitions } from "./routes/group-routes.js";
|
|
159
170
|
import { guardianActionRouteDefinitions } from "./routes/guardian-action-routes.js";
|
|
160
171
|
import { handleGuardianBootstrap } from "./routes/guardian-bootstrap-routes.js";
|
|
161
172
|
import { handleGuardianRefresh } from "./routes/guardian-refresh-routes.js";
|
|
162
173
|
import { heartbeatRouteDefinitions } from "./routes/heartbeat-routes.js";
|
|
174
|
+
import { homeFeedRouteDefinitions } from "./routes/home-feed-routes.js";
|
|
175
|
+
import { homeStateRouteDefinitions } from "./routes/home-state-routes.js";
|
|
163
176
|
import { hostBashRouteDefinitions } from "./routes/host-bash-routes.js";
|
|
164
177
|
import {
|
|
165
178
|
hostBrowserRouteDefinitions,
|
|
@@ -199,6 +212,7 @@ import { scheduleRouteDefinitions } from "./routes/schedule-routes.js";
|
|
|
199
212
|
import { secretRouteDefinitions } from "./routes/secret-routes.js";
|
|
200
213
|
import { settingsRouteDefinitions } from "./routes/settings-routes.js";
|
|
201
214
|
import { skillRouteDefinitions } from "./routes/skills-routes.js";
|
|
215
|
+
import { sttRouteDefinitions } from "./routes/stt-routes.js";
|
|
202
216
|
import { subagentRouteDefinitions } from "./routes/subagents-routes.js";
|
|
203
217
|
import { surfaceActionRouteDefinitions } from "./routes/surface-action-routes.js";
|
|
204
218
|
import { surfaceContentRouteDefinitions } from "./routes/surface-content-routes.js";
|
|
@@ -213,6 +227,8 @@ import { watchRouteDefinitions } from "./routes/watch-routes.js";
|
|
|
213
227
|
import { workItemRouteDefinitions } from "./routes/work-items-routes.js";
|
|
214
228
|
import { workspaceCommitRouteDefinitions } from "./routes/workspace-commit-routes.js";
|
|
215
229
|
import { workspaceRouteDefinitions } from "./routes/workspace-routes.js";
|
|
230
|
+
import { setAnalysisDeps } from "./services/analyze-deps-singleton.js";
|
|
231
|
+
import { matchSkillRoute } from "./skill-route-registry.js";
|
|
216
232
|
|
|
217
233
|
// Re-export for consumers
|
|
218
234
|
export { isPrivateAddress } from "./middleware/auth.js";
|
|
@@ -282,6 +298,40 @@ interface BrowserRelayWebSocketData {
|
|
|
282
298
|
clientInstanceId?: string;
|
|
283
299
|
}
|
|
284
300
|
|
|
301
|
+
/**
|
|
302
|
+
* WebSocket data attached to `/v1/calls/media-stream` connections.
|
|
303
|
+
* The `wsType` discriminator routes frames to the media-stream call
|
|
304
|
+
* session instead of the ConversationRelay or browser-relay handlers.
|
|
305
|
+
*/
|
|
306
|
+
interface MediaStreamWebSocketData {
|
|
307
|
+
wsType: "media-stream";
|
|
308
|
+
callSessionId: string;
|
|
309
|
+
/** Bound at open time so the close handler tears down the exact session
|
|
310
|
+
* that owns *this* socket, avoiding races with reconnects. */
|
|
311
|
+
session?: MediaStreamCallSession;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* WebSocket data attached to `/v1/stt/stream` connections.
|
|
316
|
+
* The `wsType` discriminator routes frames to the STT streaming
|
|
317
|
+
* session orchestrator instead of the other WebSocket handlers.
|
|
318
|
+
*
|
|
319
|
+
* `provider` is optional compatibility metadata from the client/gateway.
|
|
320
|
+
* The runtime is config-authoritative — it always resolves the streaming
|
|
321
|
+
* transcriber from `services.stt.provider` in the assistant config.
|
|
322
|
+
*/
|
|
323
|
+
interface SttStreamWebSocketData {
|
|
324
|
+
wsType: "stt-stream";
|
|
325
|
+
/** Optional requested provider — metadata only; runtime uses config. */
|
|
326
|
+
provider?: string;
|
|
327
|
+
mimeType: string;
|
|
328
|
+
sampleRate?: number;
|
|
329
|
+
/** The session ID for tracking in the active sessions registry. */
|
|
330
|
+
sessionId: string;
|
|
331
|
+
/** Bound at open time so the close handler tears down the exact session. */
|
|
332
|
+
session?: SttStreamSession;
|
|
333
|
+
}
|
|
334
|
+
|
|
285
335
|
export class RuntimeHttpServer {
|
|
286
336
|
private server: ReturnType<typeof Bun.serve> | null = null;
|
|
287
337
|
private port: number;
|
|
@@ -311,6 +361,7 @@ export class RuntimeHttpServer {
|
|
|
311
361
|
private getCesClient?: RuntimeHttpServerOptions["getCesClient"];
|
|
312
362
|
private onProviderCredentialsChanged?: RuntimeHttpServerOptions["onProviderCredentialsChanged"];
|
|
313
363
|
private getHeartbeatService?: RuntimeHttpServerOptions["getHeartbeatService"];
|
|
364
|
+
private getFilingService?: RuntimeHttpServerOptions["getFilingService"];
|
|
314
365
|
private router: HttpRouter;
|
|
315
366
|
|
|
316
367
|
constructor(options: RuntimeHttpServerOptions = {}) {
|
|
@@ -335,6 +386,7 @@ export class RuntimeHttpServer {
|
|
|
335
386
|
this.getCesClient = options.getCesClient;
|
|
336
387
|
this.onProviderCredentialsChanged = options.onProviderCredentialsChanged;
|
|
337
388
|
this.getHeartbeatService = options.getHeartbeatService;
|
|
389
|
+
this.getFilingService = options.getFilingService;
|
|
338
390
|
this.router = new HttpRouter(this.buildRouteTable());
|
|
339
391
|
}
|
|
340
392
|
|
|
@@ -372,7 +424,11 @@ export class RuntimeHttpServer {
|
|
|
372
424
|
}
|
|
373
425
|
|
|
374
426
|
async start(): Promise<void> {
|
|
375
|
-
type AllWebSocketData =
|
|
427
|
+
type AllWebSocketData =
|
|
428
|
+
| RelayWebSocketData
|
|
429
|
+
| BrowserRelayWebSocketData
|
|
430
|
+
| MediaStreamWebSocketData
|
|
431
|
+
| SttStreamWebSocketData;
|
|
376
432
|
this.server = Bun.serve<AllWebSocketData>({
|
|
377
433
|
port: this.port,
|
|
378
434
|
hostname: this.hostname,
|
|
@@ -399,6 +455,94 @@ export class RuntimeHttpServer {
|
|
|
399
455
|
}
|
|
400
456
|
return;
|
|
401
457
|
}
|
|
458
|
+
if ("wsType" in data && data.wsType === "media-stream") {
|
|
459
|
+
const msData = data as MediaStreamWebSocketData;
|
|
460
|
+
log.info(
|
|
461
|
+
{ callSessionId: msData.callSessionId },
|
|
462
|
+
"Media-stream WebSocket opened",
|
|
463
|
+
);
|
|
464
|
+
const session = new MediaStreamCallSession(
|
|
465
|
+
ws,
|
|
466
|
+
msData.callSessionId,
|
|
467
|
+
);
|
|
468
|
+
activeMediaStreamSessions.set(msData.callSessionId, session);
|
|
469
|
+
// Bind the session instance to the websocket so the close
|
|
470
|
+
// handler tears down *this* session, not a replacement that
|
|
471
|
+
// a reconnect may have inserted under the same callSessionId.
|
|
472
|
+
msData.session = session;
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if ("wsType" in data && data.wsType === "stt-stream") {
|
|
476
|
+
const sttData = data as SttStreamWebSocketData;
|
|
477
|
+
|
|
478
|
+
// The runtime is config-authoritative: always resolve the
|
|
479
|
+
// provider from `services.stt.provider` regardless of what
|
|
480
|
+
// the client/gateway requested.
|
|
481
|
+
//
|
|
482
|
+
// getConfig() can throw (e.g. after invalidateConfigCache()
|
|
483
|
+
// when config.json is temporarily invalid). Wrap in try/catch
|
|
484
|
+
// so the session still starts normally — resolveStreamingTranscriber
|
|
485
|
+
// reads config inside SttStreamSession.start()'s own guarded path.
|
|
486
|
+
let configuredProvider: string | undefined;
|
|
487
|
+
try {
|
|
488
|
+
configuredProvider = getConfig().services.stt.provider;
|
|
489
|
+
|
|
490
|
+
// Mismatch telemetry: when the optional requested provider
|
|
491
|
+
// disagrees with the configured provider, log a warning so
|
|
492
|
+
// operators can detect stale client builds.
|
|
493
|
+
if (sttData.provider && sttData.provider !== configuredProvider) {
|
|
494
|
+
log.warn(
|
|
495
|
+
{
|
|
496
|
+
requestedProvider: sttData.provider,
|
|
497
|
+
configuredProvider,
|
|
498
|
+
sessionId: sttData.sessionId,
|
|
499
|
+
},
|
|
500
|
+
"STT stream provider mismatch — requested provider differs from configured provider; using configured provider",
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
} catch (err) {
|
|
504
|
+
log.warn(
|
|
505
|
+
{
|
|
506
|
+
error: err instanceof Error ? err.message : String(err),
|
|
507
|
+
sessionId: sttData.sessionId,
|
|
508
|
+
},
|
|
509
|
+
"Failed to read config for STT provider mismatch telemetry — proceeding without mismatch check",
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Fall back to the requested provider (or "unknown") when
|
|
514
|
+
// config reading failed, so the session constructor still
|
|
515
|
+
// gets a usable label for logging/error messages.
|
|
516
|
+
const effectiveProvider =
|
|
517
|
+
configuredProvider ?? sttData.provider ?? "unknown";
|
|
518
|
+
|
|
519
|
+
log.info(
|
|
520
|
+
{
|
|
521
|
+
requestedProvider: sttData.provider ?? "(none)",
|
|
522
|
+
configuredProvider: effectiveProvider,
|
|
523
|
+
mimeType: sttData.mimeType,
|
|
524
|
+
sessionId: sttData.sessionId,
|
|
525
|
+
},
|
|
526
|
+
"STT stream WebSocket opened",
|
|
527
|
+
);
|
|
528
|
+
const session = new SttStreamSession(
|
|
529
|
+
ws,
|
|
530
|
+
effectiveProvider,
|
|
531
|
+
sttData.mimeType,
|
|
532
|
+
{ sampleRate: sttData.sampleRate },
|
|
533
|
+
);
|
|
534
|
+
sttData.session = session;
|
|
535
|
+
activeSttStreamSessions.set(sttData.sessionId, session);
|
|
536
|
+
|
|
537
|
+
// Start the session asynchronously — resolves the streaming
|
|
538
|
+
// transcriber and sends a `ready` event on success.
|
|
539
|
+
void session.start(() =>
|
|
540
|
+
resolveStreamingTranscriber({
|
|
541
|
+
sampleRate: sttData.sampleRate,
|
|
542
|
+
}),
|
|
543
|
+
);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
402
546
|
const callSessionId = (data as RelayWebSocketData).callSessionId;
|
|
403
547
|
log.info({ callSessionId }, "ConversationRelay WebSocket opened");
|
|
404
548
|
if (callSessionId) {
|
|
@@ -521,6 +665,14 @@ export class RuntimeHttpServer {
|
|
|
521
665
|
}
|
|
522
666
|
return;
|
|
523
667
|
}
|
|
668
|
+
case "keepalive": {
|
|
669
|
+
// Extension keepalive frames refresh the connection's
|
|
670
|
+
// activity timestamp without producing log noise or
|
|
671
|
+
// altering routing semantics. Unknown extra keys on
|
|
672
|
+
// the frame are silently ignored (lenient validation).
|
|
673
|
+
getChromeExtensionRegistry().touch(data.connectionId);
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
524
676
|
default: {
|
|
525
677
|
log.debug(
|
|
526
678
|
{ connectionId: data.connectionId, type: frame.type },
|
|
@@ -530,6 +682,28 @@ export class RuntimeHttpServer {
|
|
|
530
682
|
}
|
|
531
683
|
}
|
|
532
684
|
}
|
|
685
|
+
if ("wsType" in data && data.wsType === "media-stream") {
|
|
686
|
+
const msData = data as MediaStreamWebSocketData;
|
|
687
|
+
msData.session?.handleMessage(raw);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
if ("wsType" in data && data.wsType === "stt-stream") {
|
|
691
|
+
const sttData = data as SttStreamWebSocketData;
|
|
692
|
+
const session = sttData.session;
|
|
693
|
+
if (!session) return;
|
|
694
|
+
|
|
695
|
+
if (typeof message === "string") {
|
|
696
|
+
session.handleMessage(message);
|
|
697
|
+
} else {
|
|
698
|
+
// Binary frame — raw audio bytes.
|
|
699
|
+
const buffer =
|
|
700
|
+
message instanceof ArrayBuffer
|
|
701
|
+
? Buffer.from(new Uint8Array(message))
|
|
702
|
+
: Buffer.from(message);
|
|
703
|
+
session.handleBinaryAudio(buffer);
|
|
704
|
+
}
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
533
707
|
const callSessionId = (data as RelayWebSocketData).callSessionId;
|
|
534
708
|
if (callSessionId) {
|
|
535
709
|
const connection = activeRelayConnections.get(callSessionId);
|
|
@@ -547,6 +721,56 @@ export class RuntimeHttpServer {
|
|
|
547
721
|
getChromeExtensionRegistry().unregister(data.connectionId);
|
|
548
722
|
return;
|
|
549
723
|
}
|
|
724
|
+
if ("wsType" in data && data.wsType === "media-stream") {
|
|
725
|
+
const msData = data as MediaStreamWebSocketData;
|
|
726
|
+
log.info(
|
|
727
|
+
{
|
|
728
|
+
callSessionId: msData.callSessionId,
|
|
729
|
+
code,
|
|
730
|
+
reason: reason?.toString(),
|
|
731
|
+
},
|
|
732
|
+
"Media-stream WebSocket closed",
|
|
733
|
+
);
|
|
734
|
+
// Use the session bound at open time so we tear down the
|
|
735
|
+
// exact session that owns *this* socket, not a replacement
|
|
736
|
+
// that a reconnect may have inserted under the same key.
|
|
737
|
+
const msSession = msData.session;
|
|
738
|
+
if (msSession) {
|
|
739
|
+
msSession.handleTransportClosed(code, reason?.toString());
|
|
740
|
+
msSession.destroy();
|
|
741
|
+
// Only delete from the map if *our* session is still the
|
|
742
|
+
// registered one — a reconnect may have already replaced it.
|
|
743
|
+
if (
|
|
744
|
+
activeMediaStreamSessions.get(msData.callSessionId) ===
|
|
745
|
+
msSession
|
|
746
|
+
) {
|
|
747
|
+
activeMediaStreamSessions.delete(msData.callSessionId);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
if ("wsType" in data && data.wsType === "stt-stream") {
|
|
753
|
+
const sttData = data as SttStreamWebSocketData;
|
|
754
|
+
log.info(
|
|
755
|
+
{
|
|
756
|
+
provider: sttData.provider,
|
|
757
|
+
sessionId: sttData.sessionId,
|
|
758
|
+
code,
|
|
759
|
+
reason: reason?.toString(),
|
|
760
|
+
},
|
|
761
|
+
"STT stream WebSocket closed",
|
|
762
|
+
);
|
|
763
|
+
const session = sttData.session;
|
|
764
|
+
if (session) {
|
|
765
|
+
session.handleClose(code, reason?.toString());
|
|
766
|
+
// Only delete from the map if our session is still the
|
|
767
|
+
// registered one — avoids races with reconnects.
|
|
768
|
+
if (activeSttStreamSessions.get(sttData.sessionId) === session) {
|
|
769
|
+
activeSttStreamSessions.delete(sttData.sessionId);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
550
774
|
const callSessionId = (data as RelayWebSocketData).callSessionId;
|
|
551
775
|
log.info(
|
|
552
776
|
{ callSessionId, code, reason: reason?.toString() },
|
|
@@ -715,6 +939,15 @@ export class RuntimeHttpServer {
|
|
|
715
939
|
clearInterval(this.retrySweepTimer);
|
|
716
940
|
this.retrySweepTimer = null;
|
|
717
941
|
}
|
|
942
|
+
|
|
943
|
+
// Deterministic teardown of active STT streaming sessions before
|
|
944
|
+
// stopping the HTTP server so provider sessions are cleaned up
|
|
945
|
+
// and clients receive proper close frames.
|
|
946
|
+
for (const [sessionId, session] of activeSttStreamSessions) {
|
|
947
|
+
session.destroy();
|
|
948
|
+
activeSttStreamSessions.delete(sessionId);
|
|
949
|
+
}
|
|
950
|
+
|
|
718
951
|
if (this.server) {
|
|
719
952
|
this.server.stop(true);
|
|
720
953
|
this.server = null;
|
|
@@ -771,6 +1004,24 @@ export class RuntimeHttpServer {
|
|
|
771
1004
|
return this.handleRelayUpgrade(req, server);
|
|
772
1005
|
}
|
|
773
1006
|
|
|
1007
|
+
// WebSocket upgrade for Twilio Media Streams — same private-network
|
|
1008
|
+
// restrictions as relay upgrades.
|
|
1009
|
+
if (
|
|
1010
|
+
path.startsWith("/v1/calls/media-stream") &&
|
|
1011
|
+
req.headers.get("upgrade")?.toLowerCase() === "websocket"
|
|
1012
|
+
) {
|
|
1013
|
+
return this.handleMediaStreamUpgrade(req, server);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// WebSocket upgrade for STT streaming — private-network restrictions
|
|
1017
|
+
// and explicit gateway-service token verification before upgrade.
|
|
1018
|
+
if (
|
|
1019
|
+
path === "/v1/stt/stream" &&
|
|
1020
|
+
req.headers.get("upgrade")?.toLowerCase() === "websocket"
|
|
1021
|
+
) {
|
|
1022
|
+
return this.handleSttStreamUpgrade(req, server);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
774
1025
|
// Twilio webhook endpoints — before auth check because Twilio
|
|
775
1026
|
// webhook POSTs don't include bearer tokens.
|
|
776
1027
|
const twilioResponse = await this.handleTwilioWebhook(req, path);
|
|
@@ -810,6 +1061,14 @@ export class RuntimeHttpServer {
|
|
|
810
1061
|
return await handleGuardianRefresh(req);
|
|
811
1062
|
}
|
|
812
1063
|
|
|
1064
|
+
// Skill-registered routes (e.g. meet-bot event ingress). Handled before
|
|
1065
|
+
// JWT auth because skills may use their own auth (e.g. per-meeting bearer
|
|
1066
|
+
// tokens minted by a session manager).
|
|
1067
|
+
const skillMatch = matchSkillRoute(path, req.method);
|
|
1068
|
+
if (skillMatch) {
|
|
1069
|
+
return await skillMatch.route.handler(req, skillMatch.match);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
813
1072
|
// JWT bearer authentication — replaces the old shared-secret comparison.
|
|
814
1073
|
// authenticateRequest handles dev bypass (DISABLE_HTTP_AUTH) internally.
|
|
815
1074
|
//
|
|
@@ -1060,6 +1319,108 @@ export class RuntimeHttpServer {
|
|
|
1060
1319
|
return undefined!;
|
|
1061
1320
|
}
|
|
1062
1321
|
|
|
1322
|
+
private handleMediaStreamUpgrade(
|
|
1323
|
+
req: Request,
|
|
1324
|
+
server: ReturnType<typeof Bun.serve>,
|
|
1325
|
+
): Response {
|
|
1326
|
+
if (!isPrivateNetworkPeer(server, req) || !isPrivateNetworkOrigin(req)) {
|
|
1327
|
+
return httpError(
|
|
1328
|
+
"FORBIDDEN",
|
|
1329
|
+
"Direct media-stream access disabled — only private network peers allowed",
|
|
1330
|
+
403,
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
const wsUrl = new URL(req.url);
|
|
1335
|
+
const callSessionId = wsUrl.searchParams.get("callSessionId");
|
|
1336
|
+
if (!callSessionId) {
|
|
1337
|
+
return new Response("Missing callSessionId", { status: 400 });
|
|
1338
|
+
}
|
|
1339
|
+
// Media-stream connections use a distinct wsType so the open/message/close
|
|
1340
|
+
// handlers route them to MediaStreamCallSession instead of RelayConnection.
|
|
1341
|
+
const upgraded = server.upgrade(req, {
|
|
1342
|
+
data: {
|
|
1343
|
+
wsType: "media-stream",
|
|
1344
|
+
callSessionId,
|
|
1345
|
+
} satisfies MediaStreamWebSocketData,
|
|
1346
|
+
});
|
|
1347
|
+
if (!upgraded) {
|
|
1348
|
+
return new Response("WebSocket upgrade failed", { status: 500 });
|
|
1349
|
+
}
|
|
1350
|
+
// Bun's WebSocket upgrade consumes the request — no Response is sent.
|
|
1351
|
+
return undefined!;
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
/**
|
|
1355
|
+
* Handle WebSocket upgrade for `/v1/stt/stream`.
|
|
1356
|
+
*
|
|
1357
|
+
* Private-network restrictions apply (same as relay/media-stream) so the
|
|
1358
|
+
* runtime remains unreachable from the public internet. The gateway
|
|
1359
|
+
* authenticates the downstream client and proxies the upgrade with a
|
|
1360
|
+
* short-lived gateway service token.
|
|
1361
|
+
*/
|
|
1362
|
+
private handleSttStreamUpgrade(
|
|
1363
|
+
req: Request,
|
|
1364
|
+
server: ReturnType<typeof Bun.serve>,
|
|
1365
|
+
): Response {
|
|
1366
|
+
if (!isPrivateNetworkPeer(server, req) || !isPrivateNetworkOrigin(req)) {
|
|
1367
|
+
return httpError(
|
|
1368
|
+
"FORBIDDEN",
|
|
1369
|
+
"Direct STT stream access disabled — only private network peers allowed",
|
|
1370
|
+
403,
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
// Verify the gateway service token before accepting the upgrade.
|
|
1375
|
+
if (!isHttpAuthDisabled()) {
|
|
1376
|
+
const wsUrl = new URL(req.url);
|
|
1377
|
+
const token = wsUrl.searchParams.get("token");
|
|
1378
|
+
if (!token) {
|
|
1379
|
+
return httpError("UNAUTHORIZED", "Unauthorized", 401);
|
|
1380
|
+
}
|
|
1381
|
+
const jwtResult = verifyToken(token, "vellum-daemon");
|
|
1382
|
+
if (!jwtResult.ok) {
|
|
1383
|
+
return httpError("UNAUTHORIZED", "Unauthorized", 401);
|
|
1384
|
+
}
|
|
1385
|
+
// Accept gateway service tokens (svc:gateway:*) — these are the
|
|
1386
|
+
// only tokens the gateway mints for upstream connections.
|
|
1387
|
+
const subResult = parseSub(jwtResult.claims.sub);
|
|
1388
|
+
if (!subResult.ok || subResult.principalType !== "svc_gateway") {
|
|
1389
|
+
return httpError("UNAUTHORIZED", "Unauthorized", 401);
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
const wsUrl = new URL(req.url);
|
|
1394
|
+
// provider is optional compatibility metadata — the runtime resolves
|
|
1395
|
+
// the streaming transcriber from config (`services.stt.provider`).
|
|
1396
|
+
const provider = wsUrl.searchParams.get("provider") ?? undefined;
|
|
1397
|
+
const mimeType = wsUrl.searchParams.get("mimeType");
|
|
1398
|
+
if (!mimeType) {
|
|
1399
|
+
return new Response("Missing required query parameter: mimeType", {
|
|
1400
|
+
status: 400,
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
const sampleRateRaw = wsUrl.searchParams.get("sampleRate");
|
|
1405
|
+
const sampleRate = sampleRateRaw ? parseInt(sampleRateRaw, 10) : undefined;
|
|
1406
|
+
|
|
1407
|
+
const sessionId = crypto.randomUUID();
|
|
1408
|
+
const upgraded = server.upgrade(req, {
|
|
1409
|
+
data: {
|
|
1410
|
+
wsType: "stt-stream",
|
|
1411
|
+
provider,
|
|
1412
|
+
mimeType,
|
|
1413
|
+
sampleRate,
|
|
1414
|
+
sessionId,
|
|
1415
|
+
} satisfies SttStreamWebSocketData,
|
|
1416
|
+
});
|
|
1417
|
+
if (!upgraded) {
|
|
1418
|
+
return new Response("WebSocket upgrade failed", { status: 500 });
|
|
1419
|
+
}
|
|
1420
|
+
// Bun's WebSocket upgrade consumes the request — no Response is sent.
|
|
1421
|
+
return undefined!;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1063
1424
|
private async handleTwilioWebhook(
|
|
1064
1425
|
req: Request,
|
|
1065
1426
|
path: string,
|
|
@@ -1237,6 +1598,9 @@ export class RuntimeHttpServer {
|
|
|
1237
1598
|
: {}),
|
|
1238
1599
|
groupId: displayMeta?.groupId ?? null,
|
|
1239
1600
|
...(forkParent ? { forkParent } : {}),
|
|
1601
|
+
...(conversation.archivedAt != null
|
|
1602
|
+
? { archivedAt: conversation.archivedAt }
|
|
1603
|
+
: {}),
|
|
1240
1604
|
};
|
|
1241
1605
|
}
|
|
1242
1606
|
|
|
@@ -1339,6 +1703,11 @@ export class RuntimeHttpServer {
|
|
|
1339
1703
|
...heartbeatRouteDefinitions({
|
|
1340
1704
|
getHeartbeatService: this.getHeartbeatService,
|
|
1341
1705
|
}),
|
|
1706
|
+
...filingRouteDefinitions({
|
|
1707
|
+
getFilingService: this.getFilingService,
|
|
1708
|
+
}),
|
|
1709
|
+
...homeStateRouteDefinitions(),
|
|
1710
|
+
...homeFeedRouteDefinitions(),
|
|
1342
1711
|
...notificationRouteDefinitions(),
|
|
1343
1712
|
...diagnosticsRouteDefinitions(),
|
|
1344
1713
|
...logExportRouteDefinitions(),
|
|
@@ -1372,6 +1741,7 @@ export class RuntimeHttpServer {
|
|
|
1372
1741
|
: undefined,
|
|
1373
1742
|
}),
|
|
1374
1743
|
...ttsRouteDefinitions(),
|
|
1744
|
+
...sttRouteDefinitions(),
|
|
1375
1745
|
|
|
1376
1746
|
// Conversation list and seen signal — kept inline because they
|
|
1377
1747
|
// depend on multiple cross-cutting stores that aren't grouped
|
|
@@ -1438,13 +1808,28 @@ export class RuntimeHttpServer {
|
|
|
1438
1808
|
? conversationManagementRouteDefinitions(conversationManagementDeps)
|
|
1439
1809
|
: []),
|
|
1440
1810
|
|
|
1441
|
-
...(
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1811
|
+
...((): RouteDefinition[] => {
|
|
1812
|
+
const sendMessageDeps = this.sendMessageDeps;
|
|
1813
|
+
if (!sendMessageDeps) return [];
|
|
1814
|
+
const analysisDeps = {
|
|
1815
|
+
sendMessageDeps,
|
|
1816
|
+
buildConversationDetailResponse: (id: string) =>
|
|
1817
|
+
this.buildConversationDetailResponse(id),
|
|
1818
|
+
};
|
|
1819
|
+
// Also expose via the module singleton so background callers
|
|
1820
|
+
// (e.g. job handlers) can invoke analyzeConversation() without
|
|
1821
|
+
// HTTP-layer wiring. Daemon startup must never block, so failures
|
|
1822
|
+
// to register the singleton are logged and swallowed.
|
|
1823
|
+
try {
|
|
1824
|
+
setAnalysisDeps(analysisDeps);
|
|
1825
|
+
} catch (err) {
|
|
1826
|
+
log.warn(
|
|
1827
|
+
{ err },
|
|
1828
|
+
"Failed to register analysis deps singleton; background analysis jobs will be skipped",
|
|
1829
|
+
);
|
|
1830
|
+
}
|
|
1831
|
+
return conversationAnalysisRouteDefinitions(analysisDeps);
|
|
1832
|
+
})(),
|
|
1448
1833
|
|
|
1449
1834
|
...groupRouteDefinitions(),
|
|
1450
1835
|
|
|
@@ -1563,7 +1948,6 @@ export class RuntimeHttpServer {
|
|
|
1563
1948
|
...approvalRouteDefinitions(),
|
|
1564
1949
|
...hostBashRouteDefinitions(),
|
|
1565
1950
|
...hostBrowserRouteDefinitions(),
|
|
1566
|
-
...browserCdpRouteDefinitions(),
|
|
1567
1951
|
...hostCuRouteDefinitions(),
|
|
1568
1952
|
...hostFileRouteDefinitions(),
|
|
1569
1953
|
...(this.getSkillContext
|
|
@@ -1685,6 +2069,7 @@ export class RuntimeHttpServer {
|
|
|
1685
2069
|
...eventsRouteDefinitions(),
|
|
1686
2070
|
...traceEventRouteDefinitions(),
|
|
1687
2071
|
...migrationRouteDefinitions(),
|
|
2072
|
+
...backupRouteDefinitions(),
|
|
1688
2073
|
|
|
1689
2074
|
// User-defined routes under /x/* — must be LAST so built-in routes
|
|
1690
2075
|
// always take priority.
|
|
@@ -193,7 +193,7 @@ export interface RuntimeHttpServerOptions {
|
|
|
193
193
|
surfaceId: string,
|
|
194
194
|
actionId: string,
|
|
195
195
|
data?: Record<string, unknown>,
|
|
196
|
-
): void
|
|
196
|
+
): void | Promise<unknown>;
|
|
197
197
|
surfaceState: Map<
|
|
198
198
|
string,
|
|
199
199
|
{ surfaceType: SurfaceType; data: SurfaceData; title?: string }
|
|
@@ -215,7 +215,7 @@ export interface RuntimeHttpServerOptions {
|
|
|
215
215
|
surfaceId: string,
|
|
216
216
|
actionId: string,
|
|
217
217
|
data?: Record<string, unknown>,
|
|
218
|
-
): void
|
|
218
|
+
): void | Promise<unknown>;
|
|
219
219
|
surfaceState: Map<
|
|
220
220
|
string,
|
|
221
221
|
{ surfaceType: SurfaceType; data: SurfaceData; title?: string }
|
|
@@ -241,6 +241,10 @@ export interface RuntimeHttpServerOptions {
|
|
|
241
241
|
getHeartbeatService?: () =>
|
|
242
242
|
| import("../heartbeat/heartbeat-service.js").HeartbeatService
|
|
243
243
|
| undefined;
|
|
244
|
+
/** Accessor for the filing service (for run-now and config routes). */
|
|
245
|
+
getFilingService?: () =>
|
|
246
|
+
| import("../filing/filing-service.js").FilingService
|
|
247
|
+
| undefined;
|
|
244
248
|
}
|
|
245
249
|
|
|
246
250
|
export interface RuntimeAttachmentMetadata {
|
|
@@ -135,6 +135,42 @@ describe("extractCredentialsFromBundle", () => {
|
|
|
135
135
|
value: "value with spaces & special=chars!",
|
|
136
136
|
});
|
|
137
137
|
});
|
|
138
|
+
|
|
139
|
+
test("extracts vellum:-prefixed credentials (filtering happens in migration-routes)", () => {
|
|
140
|
+
const entries = new Map<string, VBundleTarEntry>();
|
|
141
|
+
entries.set(
|
|
142
|
+
"credentials/vellum:assistant_api_key",
|
|
143
|
+
makeTarEntry("key-123"),
|
|
144
|
+
);
|
|
145
|
+
entries.set(
|
|
146
|
+
"credentials/vellum:platform_assistant_id",
|
|
147
|
+
makeTarEntry("asst-456"),
|
|
148
|
+
);
|
|
149
|
+
entries.set("credentials/openai-key", makeTarEntry("sk-user-789"));
|
|
150
|
+
|
|
151
|
+
const manifest = makeManifest([
|
|
152
|
+
"credentials/vellum:assistant_api_key",
|
|
153
|
+
"credentials/vellum:platform_assistant_id",
|
|
154
|
+
"credentials/openai-key",
|
|
155
|
+
]);
|
|
156
|
+
const credentials = extractCredentialsFromBundle(entries, manifest);
|
|
157
|
+
|
|
158
|
+
// extractCredentialsFromBundle does NOT filter — it returns all credentials.
|
|
159
|
+
// Filtering of vellum:* platform credentials is done in migration-routes.ts.
|
|
160
|
+
expect(credentials).toHaveLength(3);
|
|
161
|
+
expect(credentials).toContainEqual({
|
|
162
|
+
account: "vellum:assistant_api_key",
|
|
163
|
+
value: "key-123",
|
|
164
|
+
});
|
|
165
|
+
expect(credentials).toContainEqual({
|
|
166
|
+
account: "vellum:platform_assistant_id",
|
|
167
|
+
value: "asst-456",
|
|
168
|
+
});
|
|
169
|
+
expect(credentials).toContainEqual({
|
|
170
|
+
account: "openai-key",
|
|
171
|
+
value: "sk-user-789",
|
|
172
|
+
});
|
|
173
|
+
});
|
|
138
174
|
});
|
|
139
175
|
|
|
140
176
|
// ---------------------------------------------------------------------------
|