@vellumai/assistant 0.6.2 → 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 +41 -49
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- 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/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +1111 -86
- package/package.json +40 -42
- package/scripts/generate-openapi.ts +0 -2
- package/scripts/test.sh +73 -18
- package/src/__tests__/acp-session.test.ts +43 -0
- 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__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- 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 +240 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- 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 +1000 -0
- package/src/__tests__/channel-approvals.test.ts +53 -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-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +1248 -224
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- 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 +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +99 -3
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +290 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +12 -4
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- 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 +946 -62
- package/src/__tests__/conversation-routes-disk-view.test.ts +275 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +324 -46
- 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-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -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-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +6 -3
- package/src/__tests__/credential-vault-unit.test.ts +383 -7
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +42 -18
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/date-context.test.ts +4 -4
- 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__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +222 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +386 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +2 -0
- package/src/__tests__/gemini-provider.test.ts +66 -2
- 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__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +738 -359
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +528 -49
- package/src/__tests__/headless-browser-read-tools.test.ts +274 -100
- package/src/__tests__/headless-browser-snapshot.test.ts +250 -77
- 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 +145 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +596 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +423 -0
- package/src/__tests__/host-cu-proxy.test.ts +166 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- 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__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- 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-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +67 -8
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +109 -7
- 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__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +18 -12
- package/src/__tests__/oauth-cli.test.ts +709 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +118 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +147 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +52 -14
- package/src/__tests__/oauth-store.test.ts +1465 -176
- package/src/__tests__/oauth2-gateway-transport.test.ts +460 -26
- package/src/__tests__/onboarding-template-contract.test.ts +81 -70
- package/src/__tests__/openai-provider.test.ts +178 -2
- 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-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +32 -3
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +343 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -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__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -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 +8 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- 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 +801 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +738 -0
- 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 +576 -16
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +184 -27
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +25 -5
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- 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__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- 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__/v2-consent-policy.test.ts +103 -0
- 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/acp/client-handler.ts +30 -4
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +55 -9
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- 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/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -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/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +69 -3
- 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 +3 -4
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +273 -16
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +56 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +32 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +330 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +117 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +215 -36
- package/src/cli/commands/oauth/shared.ts +7 -6
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +254 -0
- 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/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -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/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +141 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- 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 +5 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +54 -8
- 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 +9 -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/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -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 +38 -0
- package/src/config/env.ts +49 -4
- package/src/config/feature-flag-registry.json +85 -14
- package/src/config/loader.ts +82 -13
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +81 -15
- 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 +112 -0
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +52 -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 -1
- 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 +177 -0
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +61 -10
- package/src/credential-execution/approval-bridge.ts +49 -15
- 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 +195 -0
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +23 -2
- package/src/daemon/conversation-agent-loop.ts +153 -42
- package/src/daemon/conversation-attachments.ts +40 -0
- 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 +622 -13
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +128 -36
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +131 -40
- package/src/daemon/conversation-tool-setup.ts +99 -8
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +292 -16
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +13 -141
- package/src/daemon/handlers/shared.ts +80 -0
- package/src/daemon/handlers/skills.ts +483 -44
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +192 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +179 -28
- package/src/daemon/message-protocol.ts +13 -0
- package/src/daemon/message-types/conversations.ts +89 -14
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +19 -5
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +26 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +439 -14
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/transport-hints.ts +5 -24
- 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 +30 -20
- 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/mcp/client.ts +59 -24
- 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 +31 -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 +122 -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/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +18 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction-job.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 +67 -40
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- 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 +137 -60
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- 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 +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/oauth.ts +21 -13
- 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/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +25 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +26 -9
- package/src/oauth/byo-connection.ts +10 -8
- package/src/oauth/connect-orchestrator.ts +25 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +22 -18
- package/src/oauth/connection.ts +3 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +223 -100
- package/src/oauth/platform-connection.test.ts +101 -3
- package/src/oauth/platform-connection.ts +56 -35
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +133 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/v2-consent-policy.ts +87 -0
- 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 +76 -38
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- 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 -60
- 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 +10 -1
- package/src/runtime/AGENTS.md +65 -0
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -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/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +48 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +33 -9
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- 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 +368 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +815 -75
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +198 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +7 -0
- package/src/runtime/migrations/migration-wizard.ts +23 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +96 -1
- package/src/runtime/migrations/vbundle-importer.ts +89 -5
- package/src/runtime/pending-interactions.ts +18 -13
- 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/approval-routes.ts +90 -16
- 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 +556 -0
- 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 -141
- package/src/runtime/routes/conversation-management-routes.ts +223 -0
- package/src/runtime/routes/conversation-routes.ts +598 -103
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- 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 +268 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +262 -33
- 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/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +122 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +31 -102
- package/src/runtime/routes/skills-routes.ts +128 -9
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/subagents-routes.ts +14 -10
- 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 +38 -9
- 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/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- 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 +57 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +68 -29
- package/src/security/secure-keys.ts +143 -27
- package/src/security/token-manager.ts +31 -10
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +554 -0
- 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 +169 -40
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- 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/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +1787 -342
- package/src/tools/browser/browser-manager.ts +81 -12
- 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__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1263 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +359 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1993 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +1007 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +744 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +868 -0
- package/src/tools/browser/cdp-client/errors.ts +49 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +148 -0
- package/src/tools/browser/cdp-client/factory.ts +914 -0
- package/src/tools/browser/cdp-client/index.ts +28 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +120 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- 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/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +15 -0
- package/src/tools/terminal/shell.ts +36 -20
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +19 -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 +63 -24
- 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 +31 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/cli/commands/browser-relay.ts +0 -536
- package/src/config/schemas/sandbox.ts +0 -14
- 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/permissions/permission-mode-store.ts +0 -180
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type BrowserBackend,
|
|
5
|
+
BrowserSessionManager,
|
|
6
|
+
type CdpCommand,
|
|
7
|
+
type CdpResult,
|
|
8
|
+
createExtensionBackend,
|
|
9
|
+
createLocalBackend,
|
|
10
|
+
} from "../index.js";
|
|
11
|
+
|
|
12
|
+
interface MockBackendState {
|
|
13
|
+
available: boolean;
|
|
14
|
+
disposed: boolean;
|
|
15
|
+
lastCommand?: CdpCommand;
|
|
16
|
+
lastSignal?: AbortSignal;
|
|
17
|
+
sendImpl?: (command: CdpCommand, signal?: AbortSignal) => Promise<CdpResult>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function createMockExtensionBackend(state: MockBackendState): BrowserBackend {
|
|
21
|
+
return createExtensionBackend({
|
|
22
|
+
isAvailable: () => state.available,
|
|
23
|
+
sendCdp: async (command, signal) => {
|
|
24
|
+
state.lastCommand = command;
|
|
25
|
+
state.lastSignal = signal;
|
|
26
|
+
if (state.sendImpl) return state.sendImpl(command, signal);
|
|
27
|
+
return { result: { ok: true } };
|
|
28
|
+
},
|
|
29
|
+
dispose: () => {
|
|
30
|
+
state.disposed = true;
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function createMockLocalBackend(state: MockBackendState): BrowserBackend {
|
|
36
|
+
return createLocalBackend({
|
|
37
|
+
isAvailable: () => state.available,
|
|
38
|
+
sendCdp: async (command, signal) => {
|
|
39
|
+
state.lastCommand = command;
|
|
40
|
+
state.lastSignal = signal;
|
|
41
|
+
if (state.sendImpl) return state.sendImpl(command, signal);
|
|
42
|
+
return { result: { ok: true, kind: "local" } };
|
|
43
|
+
},
|
|
44
|
+
dispose: () => {
|
|
45
|
+
state.disposed = true;
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
describe("BrowserSessionManager", () => {
|
|
51
|
+
test("selectBackend throws when no backend is available", () => {
|
|
52
|
+
const state: MockBackendState = { available: false, disposed: false };
|
|
53
|
+
const manager = new BrowserSessionManager({
|
|
54
|
+
backends: [createMockExtensionBackend(state)],
|
|
55
|
+
});
|
|
56
|
+
expect(() => manager.selectBackend()).toThrow(
|
|
57
|
+
"No available browser backend",
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("selectBackend returns the extension backend when available", () => {
|
|
62
|
+
const state: MockBackendState = { available: true, disposed: false };
|
|
63
|
+
const backend = createMockExtensionBackend(state);
|
|
64
|
+
const manager = new BrowserSessionManager({ backends: [backend] });
|
|
65
|
+
const selected = manager.selectBackend();
|
|
66
|
+
expect(selected.kind).toBe("extension");
|
|
67
|
+
expect(selected).toBe(backend);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("createSession returns a session with a new uuid stored in the map", () => {
|
|
71
|
+
const state: MockBackendState = { available: true, disposed: false };
|
|
72
|
+
const manager = new BrowserSessionManager({
|
|
73
|
+
backends: [createMockExtensionBackend(state)],
|
|
74
|
+
});
|
|
75
|
+
const session = manager.createSession();
|
|
76
|
+
expect(session.id).toBeTruthy();
|
|
77
|
+
expect(session.backendKind).toBe("extension");
|
|
78
|
+
// Lookup round-trips.
|
|
79
|
+
expect(manager.getSession(session.id)).toEqual(session);
|
|
80
|
+
// Two sessions get unique ids.
|
|
81
|
+
const another = manager.createSession();
|
|
82
|
+
expect(another.id).not.toBe(session.id);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("send delegates to backend.send and returns the CDP result", async () => {
|
|
86
|
+
const expectedResult: CdpResult = { result: { value: 42 } };
|
|
87
|
+
const state: MockBackendState = {
|
|
88
|
+
available: true,
|
|
89
|
+
disposed: false,
|
|
90
|
+
sendImpl: async () => expectedResult,
|
|
91
|
+
};
|
|
92
|
+
const manager = new BrowserSessionManager({
|
|
93
|
+
backends: [createMockExtensionBackend(state)],
|
|
94
|
+
});
|
|
95
|
+
const result = await manager.send(undefined, {
|
|
96
|
+
method: "Browser.getVersion",
|
|
97
|
+
params: { foo: "bar" },
|
|
98
|
+
});
|
|
99
|
+
expect(result).toEqual(expectedResult);
|
|
100
|
+
expect(state.lastCommand).toEqual({
|
|
101
|
+
method: "Browser.getVersion",
|
|
102
|
+
params: { foo: "bar" },
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("send with an aborted signal propagates the abort", async () => {
|
|
107
|
+
const state: MockBackendState = {
|
|
108
|
+
available: true,
|
|
109
|
+
disposed: false,
|
|
110
|
+
sendImpl: async (_command, signal) => {
|
|
111
|
+
if (signal?.aborted) {
|
|
112
|
+
throw new Error("aborted");
|
|
113
|
+
}
|
|
114
|
+
return { result: { ok: true } };
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
const manager = new BrowserSessionManager({
|
|
118
|
+
backends: [createMockExtensionBackend(state)],
|
|
119
|
+
});
|
|
120
|
+
const controller = new AbortController();
|
|
121
|
+
controller.abort();
|
|
122
|
+
await expect(
|
|
123
|
+
manager.send(
|
|
124
|
+
undefined,
|
|
125
|
+
{ method: "Browser.getVersion" },
|
|
126
|
+
controller.signal,
|
|
127
|
+
),
|
|
128
|
+
).rejects.toThrow("aborted");
|
|
129
|
+
expect(state.lastSignal).toBe(controller.signal);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("disposeAll calls backend.dispose and clears the session map", () => {
|
|
133
|
+
const state: MockBackendState = { available: true, disposed: false };
|
|
134
|
+
const manager = new BrowserSessionManager({
|
|
135
|
+
backends: [createMockExtensionBackend(state)],
|
|
136
|
+
});
|
|
137
|
+
const session = manager.createSession();
|
|
138
|
+
expect(manager.getSession(session.id)).toBeDefined();
|
|
139
|
+
manager.disposeAll();
|
|
140
|
+
expect(state.disposed).toBe(true);
|
|
141
|
+
expect(manager.getSession(session.id)).toBeUndefined();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("send with a known sessionId routes through the matching backend", async () => {
|
|
145
|
+
const expectedResult: CdpResult = { result: { routed: true } };
|
|
146
|
+
const state: MockBackendState = {
|
|
147
|
+
available: true,
|
|
148
|
+
disposed: false,
|
|
149
|
+
sendImpl: async () => expectedResult,
|
|
150
|
+
};
|
|
151
|
+
const manager = new BrowserSessionManager({
|
|
152
|
+
backends: [createMockExtensionBackend(state)],
|
|
153
|
+
});
|
|
154
|
+
const session = manager.createSession();
|
|
155
|
+
const result = await manager.send(session.id, {
|
|
156
|
+
method: "Browser.getVersion",
|
|
157
|
+
});
|
|
158
|
+
expect(result).toEqual(expectedResult);
|
|
159
|
+
expect(state.lastCommand).toEqual({ method: "Browser.getVersion" });
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test("send with an unknown sessionId throws", async () => {
|
|
163
|
+
const state: MockBackendState = { available: true, disposed: false };
|
|
164
|
+
const manager = new BrowserSessionManager({
|
|
165
|
+
backends: [createMockExtensionBackend(state)],
|
|
166
|
+
});
|
|
167
|
+
await expect(
|
|
168
|
+
manager.send("does-not-exist", { method: "Browser.getVersion" }),
|
|
169
|
+
).rejects.toThrow("Unknown browser session: does-not-exist");
|
|
170
|
+
// The mock backend should not have received the command.
|
|
171
|
+
expect(state.lastCommand).toBeUndefined();
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("send with a sessionId of a disposed session throws", async () => {
|
|
175
|
+
const state: MockBackendState = { available: true, disposed: false };
|
|
176
|
+
const manager = new BrowserSessionManager({
|
|
177
|
+
backends: [createMockExtensionBackend(state)],
|
|
178
|
+
});
|
|
179
|
+
const session = manager.createSession();
|
|
180
|
+
manager.disposeSession(session.id);
|
|
181
|
+
await expect(
|
|
182
|
+
manager.send(session.id, { method: "Browser.getVersion" }),
|
|
183
|
+
).rejects.toThrow(`Unknown browser session: ${session.id}`);
|
|
184
|
+
expect(state.lastCommand).toBeUndefined();
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("selectBackend returns a local backend when it is the only registration", () => {
|
|
188
|
+
const state: MockBackendState = { available: true, disposed: false };
|
|
189
|
+
const backend = createMockLocalBackend(state);
|
|
190
|
+
const manager = new BrowserSessionManager({ backends: [backend] });
|
|
191
|
+
const selected = manager.selectBackend();
|
|
192
|
+
expect(selected.kind).toBe("local");
|
|
193
|
+
expect(selected).toBe(backend);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("createSession tags sessions with the local backend kind", () => {
|
|
197
|
+
const state: MockBackendState = { available: true, disposed: false };
|
|
198
|
+
const manager = new BrowserSessionManager({
|
|
199
|
+
backends: [createMockLocalBackend(state)],
|
|
200
|
+
});
|
|
201
|
+
const session = manager.createSession();
|
|
202
|
+
expect(session.backendKind).toBe("local");
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("send routes through local backend when its session is used", async () => {
|
|
206
|
+
const state: MockBackendState = { available: true, disposed: false };
|
|
207
|
+
const manager = new BrowserSessionManager({
|
|
208
|
+
backends: [createMockLocalBackend(state)],
|
|
209
|
+
});
|
|
210
|
+
const session = manager.createSession();
|
|
211
|
+
const result = await manager.send(session.id, {
|
|
212
|
+
method: "Runtime.evaluate",
|
|
213
|
+
params: { expression: "1+1" },
|
|
214
|
+
});
|
|
215
|
+
expect(result).toEqual({ result: { ok: true, kind: "local" } });
|
|
216
|
+
expect(state.lastCommand).toEqual({
|
|
217
|
+
method: "Runtime.evaluate",
|
|
218
|
+
params: { expression: "1+1" },
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("selectBackend falls back to the first available backend when earlier ones are unavailable", () => {
|
|
223
|
+
const extState: MockBackendState = { available: false, disposed: false };
|
|
224
|
+
const localState: MockBackendState = { available: true, disposed: false };
|
|
225
|
+
const ext = createMockExtensionBackend(extState);
|
|
226
|
+
const local = createMockLocalBackend(localState);
|
|
227
|
+
const manager = new BrowserSessionManager({ backends: [ext, local] });
|
|
228
|
+
const selected = manager.selectBackend();
|
|
229
|
+
expect(selected.kind).toBe("local");
|
|
230
|
+
expect(selected).toBe(local);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test("selectBackend prefers the first available backend", () => {
|
|
234
|
+
const extState: MockBackendState = { available: true, disposed: false };
|
|
235
|
+
const localState: MockBackendState = { available: true, disposed: false };
|
|
236
|
+
const ext = createMockExtensionBackend(extState);
|
|
237
|
+
const local = createMockLocalBackend(localState);
|
|
238
|
+
const manager = new BrowserSessionManager({ backends: [ext, local] });
|
|
239
|
+
const selected = manager.selectBackend();
|
|
240
|
+
expect(selected.kind).toBe("extension");
|
|
241
|
+
expect(selected).toBe(ext);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test("send routes to the backend matching the session's backendKind when multiple backends are registered", async () => {
|
|
245
|
+
const extState: MockBackendState = {
|
|
246
|
+
available: true,
|
|
247
|
+
disposed: false,
|
|
248
|
+
sendImpl: async () => ({ result: { from: "extension" } }),
|
|
249
|
+
};
|
|
250
|
+
const localState: MockBackendState = {
|
|
251
|
+
available: true,
|
|
252
|
+
disposed: false,
|
|
253
|
+
sendImpl: async () => ({ result: { from: "local" } }),
|
|
254
|
+
};
|
|
255
|
+
const ext = createMockExtensionBackend(extState);
|
|
256
|
+
const local = createMockLocalBackend(localState);
|
|
257
|
+
const manager = new BrowserSessionManager({ backends: [ext, local] });
|
|
258
|
+
|
|
259
|
+
// createSession picks the first available backend (extension), but we
|
|
260
|
+
// can also force the local one by passing a backendKind via direct
|
|
261
|
+
// session construction. To keep this test self-contained we verify the
|
|
262
|
+
// default path and then mark the extension unavailable to force the
|
|
263
|
+
// local backend for a new session.
|
|
264
|
+
const extSession = manager.createSession();
|
|
265
|
+
expect(extSession.backendKind).toBe("extension");
|
|
266
|
+
const extResult = await manager.send(extSession.id, {
|
|
267
|
+
method: "Browser.getVersion",
|
|
268
|
+
});
|
|
269
|
+
expect(extResult).toEqual({ result: { from: "extension" } });
|
|
270
|
+
expect(extState.lastCommand).toEqual({ method: "Browser.getVersion" });
|
|
271
|
+
expect(localState.lastCommand).toBeUndefined();
|
|
272
|
+
|
|
273
|
+
extState.available = false;
|
|
274
|
+
const localSession = manager.createSession();
|
|
275
|
+
expect(localSession.backendKind).toBe("local");
|
|
276
|
+
const localResult = await manager.send(localSession.id, {
|
|
277
|
+
method: "Runtime.evaluate",
|
|
278
|
+
});
|
|
279
|
+
expect(localResult).toEqual({ result: { from: "local" } });
|
|
280
|
+
expect(localState.lastCommand).toEqual({ method: "Runtime.evaluate" });
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test("disposeAll disposes every registered backend", () => {
|
|
284
|
+
const extState: MockBackendState = { available: true, disposed: false };
|
|
285
|
+
const localState: MockBackendState = { available: true, disposed: false };
|
|
286
|
+
const manager = new BrowserSessionManager({
|
|
287
|
+
backends: [
|
|
288
|
+
createMockExtensionBackend(extState),
|
|
289
|
+
createMockLocalBackend(localState),
|
|
290
|
+
],
|
|
291
|
+
});
|
|
292
|
+
manager.createSession();
|
|
293
|
+
manager.disposeAll();
|
|
294
|
+
expect(extState.disposed).toBe(true);
|
|
295
|
+
expect(localState.disposed).toBe(true);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { BrowserBackend, CdpCommand, CdpResult } from "../types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* cdp-inspect backend for BrowserSessionManager. Wraps a
|
|
5
|
+
* caller-provided `sendCdp` transport that talks to an already-running
|
|
6
|
+
* Chrome via DevTools JSON discovery + a raw WebSocket transport
|
|
7
|
+
* (see `assistant/src/tools/browser/cdp-client/cdp-inspect-client.ts`).
|
|
8
|
+
*
|
|
9
|
+
* The factory in
|
|
10
|
+
* `assistant/src/tools/browser/cdp-client/factory.ts` constructs
|
|
11
|
+
* one per tool invocation, paralleling the existing extension
|
|
12
|
+
* and local backend wiring.
|
|
13
|
+
*/
|
|
14
|
+
export interface CdpInspectBackendDeps {
|
|
15
|
+
/** Sends a CDP command to the user's Chrome via cdp-inspect and returns the CDP result. */
|
|
16
|
+
sendCdp(command: CdpCommand, signal?: AbortSignal): Promise<CdpResult>;
|
|
17
|
+
isAvailable(): boolean;
|
|
18
|
+
dispose(): void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createCdpInspectBackend(
|
|
22
|
+
deps: CdpInspectBackendDeps,
|
|
23
|
+
): BrowserBackend {
|
|
24
|
+
return {
|
|
25
|
+
kind: "cdp-inspect",
|
|
26
|
+
isAvailable: deps.isAvailable,
|
|
27
|
+
send: deps.sendCdp,
|
|
28
|
+
dispose: deps.dispose,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BrowserBackend, CdpCommand, CdpResult } from "../types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extension backend for BrowserSessionManager. Wraps a caller-provided
|
|
5
|
+
* `sendCdp` transport that routes CDP commands through the daemon's
|
|
6
|
+
* HostBrowserProxy to an attached chrome extension. The factory in
|
|
7
|
+
* `assistant/src/tools/browser/cdp-client/factory.ts` constructs one
|
|
8
|
+
* per tool invocation using the conversation's `hostBrowserProxy`.
|
|
9
|
+
*/
|
|
10
|
+
export interface ExtensionBackendDeps {
|
|
11
|
+
/** Sends a CDP command to an attached chrome extension and returns the CDP result. */
|
|
12
|
+
sendCdp(command: CdpCommand, signal?: AbortSignal): Promise<CdpResult>;
|
|
13
|
+
isAvailable(): boolean;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createExtensionBackend(
|
|
18
|
+
deps: ExtensionBackendDeps,
|
|
19
|
+
): BrowserBackend {
|
|
20
|
+
return {
|
|
21
|
+
kind: "extension",
|
|
22
|
+
isAvailable: deps.isAvailable,
|
|
23
|
+
send: deps.sendCdp,
|
|
24
|
+
dispose: deps.dispose,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { BrowserBackend, CdpCommand, CdpResult } from "../types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Local backend for BrowserSessionManager. Wraps a caller-provided
|
|
5
|
+
* `sendCdp` transport that drives a Playwright CDPSession against the
|
|
6
|
+
* sacrificial-profile Chromium managed by `browserManager`. The factory
|
|
7
|
+
* in `assistant/src/tools/browser/cdp-client/factory.ts` constructs one
|
|
8
|
+
* per tool invocation using the per-conversation LocalCdpClient.
|
|
9
|
+
*/
|
|
10
|
+
export interface LocalBackendDeps {
|
|
11
|
+
/** Sends a CDP command to a Playwright CDPSession and returns the CDP result. */
|
|
12
|
+
sendCdp(command: CdpCommand, signal?: AbortSignal): Promise<CdpResult>;
|
|
13
|
+
isAvailable(): boolean;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createLocalBackend(deps: LocalBackendDeps): BrowserBackend {
|
|
18
|
+
return {
|
|
19
|
+
kind: "local",
|
|
20
|
+
isAvailable: deps.isAvailable,
|
|
21
|
+
send: deps.sendCdp,
|
|
22
|
+
dispose: deps.dispose,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module-level event bus for out-of-band browser-session signals.
|
|
3
|
+
*
|
|
4
|
+
* The `host_browser_event` and `host_browser_session_invalidated`
|
|
5
|
+
* envelopes (see `assistant/src/daemon/message-types/host-browser.ts`)
|
|
6
|
+
* carry unsolicited CDP events and detach notifications from the
|
|
7
|
+
* chrome extension to the daemon. Unlike `host_browser_result`, these
|
|
8
|
+
* frames are not tied to a specific in-flight request and cannot be
|
|
9
|
+
* routed through `pending-interactions`. Instead they publish into
|
|
10
|
+
* this bus, where tool-side consumers subscribe to react to the signal.
|
|
11
|
+
*
|
|
12
|
+
* Two distinct surfaces:
|
|
13
|
+
*
|
|
14
|
+
* 1. **CDP event listeners** — free-form subscribers that observe
|
|
15
|
+
* every incoming `host_browser_event`. Primarily a seam for
|
|
16
|
+
* future work (event-driven session tracking, lifecycle
|
|
17
|
+
* instrumentation, tool-side reactive hooks) and for tests that
|
|
18
|
+
* need to assert that events were routed.
|
|
19
|
+
*
|
|
20
|
+
* 2. **Invalidated target registry** — a short-lived set of target
|
|
21
|
+
* ids that the extension has reported as detached. The
|
|
22
|
+
* `BrowserSessionManager` checks this set on its next `send()`
|
|
23
|
+
* and evicts any matching session before dispatch so the
|
|
24
|
+
* extension dispatcher can re-attach fresh. Entries are
|
|
25
|
+
* consumed on first lookup to keep the set from growing
|
|
26
|
+
* unbounded across long-running processes.
|
|
27
|
+
*
|
|
28
|
+
* Both surfaces are intentionally transport-agnostic — the WS and
|
|
29
|
+
* HTTP paths both publish through the same module so the routing
|
|
30
|
+
* semantics stay in lockstep.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { getLogger } from "../util/logger.js";
|
|
34
|
+
|
|
35
|
+
const log = getLogger("browser-session-events");
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// CDP event listener surface
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A forwarded CDP event as consumed by runtime-side subscribers. The
|
|
43
|
+
* wire shape comes from `HostBrowserEvent` in
|
|
44
|
+
* `assistant/src/daemon/message-types/host-browser.ts` and is stripped
|
|
45
|
+
* of its `type` discriminator here for ergonomic subscriber code.
|
|
46
|
+
*/
|
|
47
|
+
export interface ForwardedCdpEvent {
|
|
48
|
+
/** CDP event method name, e.g. "Page.frameNavigated". */
|
|
49
|
+
method: string;
|
|
50
|
+
/** CDP event params forwarded verbatim. Opaque to the bus. */
|
|
51
|
+
params?: unknown;
|
|
52
|
+
/**
|
|
53
|
+
* Optional CDP session id — present for flat child sessions routed
|
|
54
|
+
* through `Target.attachToTarget` with `flatten: true`.
|
|
55
|
+
*/
|
|
56
|
+
cdpSessionId?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type CdpEventListener = (event: ForwardedCdpEvent) => void;
|
|
60
|
+
|
|
61
|
+
const cdpEventListeners = new Set<CdpEventListener>();
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Subscribe to forwarded CDP events. Returns an unsubscribe function;
|
|
65
|
+
* callers MUST invoke it at end-of-lifecycle to avoid leaking closures
|
|
66
|
+
* into the module-level set. Listener errors are caught and logged so
|
|
67
|
+
* a broken subscriber cannot take down the WS dispatch path.
|
|
68
|
+
*/
|
|
69
|
+
export function onCdpEvent(listener: CdpEventListener): () => void {
|
|
70
|
+
cdpEventListeners.add(listener);
|
|
71
|
+
return () => {
|
|
72
|
+
cdpEventListeners.delete(listener);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Fan an incoming CDP event out to all registered listeners. Called
|
|
78
|
+
* by the WS frame dispatcher in
|
|
79
|
+
* `assistant/src/runtime/routes/host-browser-routes.ts` after a
|
|
80
|
+
* `host_browser_event` envelope has been validated.
|
|
81
|
+
*/
|
|
82
|
+
export function publishCdpEvent(event: ForwardedCdpEvent): void {
|
|
83
|
+
for (const listener of cdpEventListeners) {
|
|
84
|
+
try {
|
|
85
|
+
listener(event);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
log.warn(
|
|
88
|
+
{ err, method: event.method },
|
|
89
|
+
"CDP event listener threw — suppressing to protect dispatcher",
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Invalidated target registry
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Short-lived set of target ids the chrome extension has reported as
|
|
101
|
+
* detached since the last `consumeInvalidatedTargetId` lookup. The
|
|
102
|
+
* `BrowserSessionManager.invalidateByTargetId` path reads entries
|
|
103
|
+
* out of this set on each `send()` and evicts any matching session
|
|
104
|
+
* before dispatch.
|
|
105
|
+
*
|
|
106
|
+
* Entries are consumed on first read so the set never grows
|
|
107
|
+
* unbounded. If a future consumer needs multiple reads of the same
|
|
108
|
+
* invalidation, a separate long-lived registry should be introduced
|
|
109
|
+
* — this set is scoped to the minimum viable behaviour for
|
|
110
|
+
* "next command forces reattach".
|
|
111
|
+
*/
|
|
112
|
+
const invalidatedTargetIds = new Set<string>();
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Record that the chrome extension has reported a target as
|
|
116
|
+
* detached. Idempotent — re-marking a target is a no-op. Logs at
|
|
117
|
+
* debug because the signal is benign (just a lifecycle notification)
|
|
118
|
+
* and noisy in high-churn workloads.
|
|
119
|
+
*/
|
|
120
|
+
export function markTargetInvalidated(targetId: string, reason?: string): void {
|
|
121
|
+
invalidatedTargetIds.add(targetId);
|
|
122
|
+
log.debug({ targetId, reason }, "browser-session target invalidated");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Peek at whether a given target id is currently marked invalidated
|
|
127
|
+
* without consuming the entry. Primarily used by tests — production
|
|
128
|
+
* consumers should call {@link consumeInvalidatedTargetId} so the
|
|
129
|
+
* set stays bounded.
|
|
130
|
+
*/
|
|
131
|
+
export function isTargetInvalidated(targetId: string): boolean {
|
|
132
|
+
return invalidatedTargetIds.has(targetId);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Test-only helper: snapshot the current invalidated set without
|
|
137
|
+
* draining it. Exported so unit tests can assert exact set contents
|
|
138
|
+
* across multiple frames; production code must not rely on this.
|
|
139
|
+
*/
|
|
140
|
+
export function __peekInvalidatedTargetIdsForTests(): string[] {
|
|
141
|
+
return Array.from(invalidatedTargetIds);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Atomically remove and return a target id from the invalidated set.
|
|
146
|
+
* Returns `true` when the id was present (and has now been removed),
|
|
147
|
+
* `false` otherwise. Designed to be called by
|
|
148
|
+
* `BrowserSessionManager.send()` so the first dispatch after a
|
|
149
|
+
* detach forces a reattach and subsequent dispatches proceed normally.
|
|
150
|
+
*/
|
|
151
|
+
export function consumeInvalidatedTargetId(targetId: string): boolean {
|
|
152
|
+
return invalidatedTargetIds.delete(targetId);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Test-only helper: clear the entire invalidated set. Not exported
|
|
157
|
+
* from any public index — used by unit tests that need a clean slate
|
|
158
|
+
* between cases. Not safe to call from production code because it
|
|
159
|
+
* would race against concurrent invalidations.
|
|
160
|
+
*/
|
|
161
|
+
export function __resetBrowserSessionEventsForTests(): void {
|
|
162
|
+
cdpEventListeners.clear();
|
|
163
|
+
invalidatedTargetIds.clear();
|
|
164
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BrowserSessionManager — multi-backend session router for host_browser.
|
|
3
|
+
*
|
|
4
|
+
* This module is the single CDP backend selector for browser tools. The
|
|
5
|
+
* `cdp-client` factory (`assistant/src/tools/browser/cdp-client/factory.ts`)
|
|
6
|
+
* constructs a BrowserSessionManager per tool invocation, registers the
|
|
7
|
+
* appropriate backend from a three-way selection:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Extension** — selected when `hostBrowserProxy` is present (macOS
|
|
10
|
+
* desktop / cloud-hosted with a chrome-extension bound to the
|
|
11
|
+
* conversation).
|
|
12
|
+
* 2. **cdp-inspect** — selected when the extension is absent and
|
|
13
|
+
* `hostBrowser.cdpInspect.enabled` is `true` in config. Attaches to
|
|
14
|
+
* an already-running Chrome via `--remote-debugging-port`.
|
|
15
|
+
* 3. **Local** — default when neither of the above applies.
|
|
16
|
+
* Drives a Playwright-backed sacrificial-profile Chromium.
|
|
17
|
+
*
|
|
18
|
+
* The factory exposes a `ScopedCdpClient` that routes `send()` through
|
|
19
|
+
* the manager. This gives every call site a single choke point for
|
|
20
|
+
* session invalidation and future multi-tab routing.
|
|
21
|
+
*/
|
|
22
|
+
export * from "./backends/cdp-inspect.js";
|
|
23
|
+
export * from "./backends/extension.js";
|
|
24
|
+
export * from "./backends/local.js";
|
|
25
|
+
export * from "./events.js";
|
|
26
|
+
export * from "./manager.js";
|
|
27
|
+
export * from "./types.js";
|