@vellumai/assistant 0.6.3 → 0.6.5
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/.prettierignore +5 -0
- package/ARCHITECTURE.md +298 -39
- package/Dockerfile +14 -3
- package/README.md +3 -4
- package/bun.lock +13 -16
- package/docs/architecture/integrations.md +1 -20
- package/docs/architecture/security.md +16 -16
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/error-handling.md +111 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +121 -0
- package/knip.json +20 -3
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +5 -4
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
- package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
- package/node_modules/@vellumai/credential-storage/package.json +2 -2
- package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
- package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
- package/node_modules/@vellumai/egress-proxy/package.json +2 -2
- package/openapi.yaml +1094 -72
- package/package.json +9 -8
- package/scripts/generate-openapi.ts +50 -12
- package/scripts/test.sh +73 -18
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
- package/src/__tests__/agent-loop.test.ts +235 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +434 -12
- package/src/__tests__/approval-cascade.test.ts +31 -10
- package/src/__tests__/approval-routes-http.test.ts +134 -10
- package/src/__tests__/assistant-attachments.test.ts +44 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
- 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 +12 -1
- package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
- package/src/__tests__/browser-skill-endstate.test.ts +52 -159
- package/src/__tests__/btw-routes.test.ts +54 -1
- package/src/__tests__/call-controller.test.ts +582 -22
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +27 -4
- package/src/__tests__/catalog-files.test.ts +138 -0
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- 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__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +576 -502
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/compaction-circuit-breaker.test.ts +336 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +83 -0
- package/src/__tests__/config-loader-backfill.test.ts +174 -0
- package/src/__tests__/config-loader-corrupt.test.ts +183 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +1458 -198
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +45 -10
- package/src/__tests__/contact-store-user-file.test.ts +511 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +618 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +32 -16
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +62 -17
- package/src/__tests__/conversation-agent-loop.test.ts +510 -84
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +165 -9
- package/src/__tests__/conversation-error.test.ts +102 -1
- package/src/__tests__/conversation-history-web-search.test.ts +17 -4
- package/src/__tests__/conversation-init.benchmark.test.ts +42 -1
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +32 -16
- package/src/__tests__/conversation-process-callsite.test.ts +306 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +32 -16
- package/src/__tests__/conversation-queue.test.ts +932 -76
- package/src/__tests__/conversation-routes-disk-view.test.ts +299 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2790 -55
- package/src/__tests__/conversation-runtime-workspace.test.ts +12 -12
- package/src/__tests__/conversation-skill-tools.test.ts +12 -143
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +120 -34
- package/src/__tests__/conversation-slash-unknown.test.ts +32 -16
- package/src/__tests__/conversation-speed-override.test.ts +30 -11
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
- package/src/__tests__/conversation-title-service.test.ts +2 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +3 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +31 -10
- package/src/__tests__/conversation-workspace-injection.test.ts +45 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +46 -16
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +8 -3
- package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
- package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
- package/src/__tests__/credential-vault-unit.test.ts +495 -3
- package/src/__tests__/credentials-cli.test.ts +32 -16
- package/src/__tests__/cross-provider-web-search.test.ts +230 -35
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -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__/edit-propagation.test.ts +280 -0
- 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__/ephemeral-permissions.test.ts +93 -3
- package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
- package/src/__tests__/estimator-calibration.test.ts +213 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +101 -15
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- 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 -3
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +44 -1
- 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 +166 -32
- 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__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/intent-routing.test.ts +1 -40
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +609 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- 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__/messaging-skill-split.test.ts +3 -34
- 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-from-url.test.ts +684 -0
- 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 +10 -84
- package/src/__tests__/notification-decision-fallback.test.ts +0 -10
- package/src/__tests__/notification-decision-identity.test.ts +0 -9
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
- 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 +95 -7
- package/src/__tests__/oauth2-gateway-transport.test.ts +257 -9
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/onboarding-template-contract.test.ts +6 -13
- package/src/__tests__/openai-provider.test.ts +183 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1501 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -1
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -1
- 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 +224 -3
- package/src/__tests__/profiler-routes.test.ts +1 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
- package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
- package/src/__tests__/provider-error-scenarios.test.ts +135 -6
- package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
- package/src/__tests__/provider-registry-ollama.test.ts +1 -2
- package/src/__tests__/proxy-approval-callback.test.ts +0 -1
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/reaction-persistence.test.ts +560 -0
- 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 +424 -6
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
- package/src/__tests__/risk-classifier-parity.test.ts +230 -0
- package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-ingress-http.test.ts +28 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
- package/src/__tests__/secret-scanner-executor.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +34 -2
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +80 -0
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -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 +19 -30
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +564 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +160 -3
- package/src/__tests__/system-prompt.test.ts +126 -53
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +26 -7
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -49
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -2
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +10 -6
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +88 -113
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/trust-store.test.ts +442 -103
- 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-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- 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 +5 -22
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/voice-session-bridge.test.ts +39 -0
- package/src/__tests__/volume-security-guard.test.ts +3 -2
- package/src/__tests__/web-search-history.test.ts +337 -0
- 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-039-drop-legacy-llm-keys.test.ts +343 -0
- package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -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-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +1 -11
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +251 -19
- package/src/avatar/resvg-lazy.test.ts +136 -0
- package/src/avatar/resvg-lazy.ts +82 -9
- package/src/avatar/traits-png-sync.ts +21 -1
- 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/__tests__/operations.test.ts +163 -0
- package/src/browser/identifiers.ts +51 -0
- package/src/browser/operations.ts +660 -0
- package/src/browser/types.ts +81 -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/guardian-question-copy.ts +2 -2
- 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 +9 -1
- package/src/channels/types.ts +16 -0
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/browser.test.ts +554 -0
- package/src/cli/commands/__tests__/cache.test.ts +623 -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 +28 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +130 -5
- 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/__tests__/image-generation.test.ts +666 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +451 -0
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
- package/src/cli/commands/__tests__/task.test.ts +913 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +594 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
- package/src/cli/commands/__tests__/ui.test.ts +1215 -0
- package/src/cli/commands/__tests__/watchers.test.ts +716 -0
- package/src/cli/commands/attachment.ts +182 -0
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +90 -0
- package/src/cli/commands/credentials.ts +0 -1
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +308 -16
- package/src/cli/commands/image-generation.ts +300 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- 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 -10
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -2
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -1
- package/src/cli/commands/stt.ts +339 -0
- package/src/cli/commands/task.ts +795 -0
- package/src/cli/commands/trust.ts +50 -19
- package/src/cli/commands/tts.ts +273 -0
- package/src/cli/commands/ui.ts +670 -0
- package/src/cli/commands/watchers.ts +509 -0
- package/src/cli/lib/daemon-credential-client.ts +0 -19
- package/src/cli/program.ts +53 -8
- package/src/cli.ts +0 -37
- 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/contacts/SKILL.md +2 -2
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +23 -1
- 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/services/reduce.ts +1 -1
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -2
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +11 -12
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +28 -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/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 +0 -167
- package/src/config/env-registry.ts +24 -0
- package/src/config/env.ts +39 -10
- package/src/config/feature-flag-registry.json +63 -15
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +220 -22
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +65 -51
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +32 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -30
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +49 -14
- package/src/config/schemas/heartbeat.ts +27 -10
- package/src/config/schemas/host-browser.ts +47 -1
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +318 -0
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/memory-processing.ts +1 -9
- package/src/config/schemas/notifications.ts +4 -11
- package/src/config/schemas/platform.ts +3 -9
- package/src/config/schemas/security.ts +33 -0
- package/src/config/schemas/services.ts +53 -4
- package/src/config/schemas/stt.ts +60 -0
- package/src/config/schemas/tts.ts +283 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skills.ts +6 -2
- 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/__tests__/compact-prompt.test.ts +45 -0
- package/src/context/__tests__/microcompact.test.ts +805 -0
- package/src/context/estimator-calibration.ts +136 -0
- package/src/context/microcompact.ts +443 -0
- package/src/context/post-turn-tool-result-truncation.ts +3 -2
- package/src/context/prompts/compact.md +12 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +272 -35
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +23 -2
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +96 -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/approval-generators.ts +29 -4
- package/src/daemon/assistant-attachments.ts +24 -13
- package/src/daemon/classifier.ts +2 -2
- package/src/daemon/config-watcher.ts +99 -6
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +85 -12
- package/src/daemon/conversation-agent-loop.ts +563 -104
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +46 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +85 -11
- package/src/daemon/conversation-messaging.ts +110 -7
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +591 -23
- package/src/daemon/conversation-queue-manager.ts +27 -0
- package/src/daemon/conversation-runtime-assembly.ts +769 -28
- package/src/daemon/conversation-slash.ts +38 -2
- package/src/daemon/conversation-surfaces.ts +483 -5
- package/src/daemon/conversation-tool-setup.ts +35 -5
- package/src/daemon/conversation-usage.ts +8 -5
- package/src/daemon/conversation.ts +193 -47
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/guardian-action-generators.ts +34 -14
- package/src/daemon/handlers/config-model.test.ts +86 -0
- package/src/daemon/handlers/config-model.ts +54 -12
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +13 -3
- package/src/daemon/handlers/shared.ts +51 -1
- package/src/daemon/handlers/skills.ts +323 -79
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/host-browser-proxy.ts +2 -1
- package/src/daemon/lifecycle.ts +185 -26
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/conversations.ts +48 -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 +23 -1
- 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/message-types/trust.ts +0 -2
- package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
- package/src/daemon/pkb-context-tracker.test.ts +169 -0
- package/src/daemon/pkb-context-tracker.ts +125 -0
- package/src/daemon/pkb-reminder-builder.test.ts +70 -0
- package/src/daemon/pkb-reminder-builder.ts +31 -0
- package/src/daemon/providers-setup.ts +6 -0
- package/src/daemon/server.ts +463 -10
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +9 -9
- package/src/daemon/watch-handler.ts +4 -4
- package/src/daemon/web-search-history.ts +126 -0
- package/src/email/html-renderer.ts +76 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/heartbeat-service.ts +156 -22
- 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 +222 -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 +442 -0
- package/src/home/assistant-feed-authoring.ts +128 -0
- package/src/home/emit-feed-event.ts +162 -0
- package/src/home/feed-scheduler.ts +263 -0
- package/src/home/feed-types.ts +235 -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 +413 -0
- package/src/home/suggested-prompts.ts +101 -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__/attachment-ipc.test.ts +213 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
- package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/__tests__/socket-path.test.ts +73 -0
- package/src/ipc/__tests__/task-ipc.test.ts +577 -0
- package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
- package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
- package/src/ipc/cli-client.ts +152 -0
- package/src/ipc/cli-server.ts +252 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +61 -0
- package/src/ipc/routes/browser.ts +96 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/index.ts +21 -0
- package/src/ipc/routes/task-queue.ts +226 -0
- package/src/ipc/routes/task.ts +173 -0
- package/src/ipc/routes/ui-request.ts +50 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +100 -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 +233 -0
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/admin.ts +18 -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 +74 -0
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +199 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +65 -1
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/conversation-title-service.ts +7 -4
- package/src/memory/db-init.ts +8 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +104 -29
- package/src/memory/graph/extraction.test.ts +295 -2
- package/src/memory/graph/extraction.ts +181 -51
- package/src/memory/graph/graph-search.test.ts +92 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +459 -0
- package/src/memory/graph/retriever.ts +257 -66
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/store.ts +41 -0
- package/src/memory/graph/tool-handlers.ts +27 -0
- package/src/memory/graph/tools.ts +6 -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 +39 -30
- package/src/memory/job-handlers/summarization.ts +2 -2
- package/src/memory/job-utils.ts +7 -1
- package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
- package/src/memory/jobs/embed-pkb-file.ts +54 -0
- package/src/memory/jobs-store.ts +106 -5
- package/src/memory/jobs-worker.ts +26 -9
- package/src/memory/llm-usage-store.ts +92 -56
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- 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/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-index.test.ts +368 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +251 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +438 -0
- package/src/memory/pkb/pkb-search.ts +137 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.ts +122 -1
- 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/slack-thread-store.ts +37 -0
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +79 -6
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +155 -38
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -0
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
- package/src/messaging/providers/slack/message-metadata.ts +123 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1373 -0
- package/src/messaging/providers/slack/render-transcript.ts +443 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/decision-engine.ts +6 -12
- package/src/notifications/preference-extractor.ts +2 -6
- 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 +10 -0
- package/src/oauth/platform-connection.test.ts +145 -0
- package/src/oauth/platform-connection.ts +62 -31
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/approval-policy.test.ts +948 -0
- package/src/permissions/approval-policy.ts +257 -0
- package/src/permissions/bash-risk-classifier.test.ts +1208 -0
- package/src/permissions/bash-risk-classifier.ts +707 -0
- package/src/permissions/checker.ts +218 -699
- package/src/permissions/command-registry.test.ts +535 -0
- package/src/permissions/command-registry.ts +825 -0
- package/src/permissions/defaults.ts +71 -75
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/risk-types.ts +205 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/skill-risk-classifier.test.ts +311 -0
- package/src/permissions/skill-risk-classifier.ts +214 -0
- package/src/permissions/trust-client.ts +52 -25
- package/src/permissions/trust-store-interface.ts +1 -6
- package/src/permissions/trust-store.ts +164 -65
- package/src/permissions/types.ts +23 -14
- package/src/permissions/web-risk-classifier.test.ts +170 -0
- package/src/permissions/web-risk-classifier.ts +89 -0
- package/src/permissions/workspace-policy.ts +1 -13
- package/src/platform/client.test.ts +10 -0
- package/src/platform/client.ts +19 -1
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +127 -3
- package/src/prompts/system-prompt.ts +78 -38
- package/src/prompts/templates/BOOTSTRAP.md +5 -5
- package/src/prompts/templates/SOUL.md +5 -3
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-job.ts +190 -0
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/__tests__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +335 -70
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +74 -3
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +502 -28
- package/src/providers/model-intents.ts +8 -8
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +530 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +579 -0
- package/src/providers/openrouter/client.ts +168 -4
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +21 -10
- package/src/providers/retry.ts +185 -39
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +883 -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 +323 -0
- package/src/providers/speech-to-text/resolve.ts +393 -6
- package/src/providers/speech-to-text/xai-realtime.test.ts +578 -0
- package/src/providers/speech-to-text/xai-realtime.ts +796 -0
- package/src/providers/speech-to-text/xai.test.ts +155 -0
- package/src/providers/speech-to-text/xai.ts +97 -0
- package/src/providers/types.ts +102 -3
- package/src/runtime/AGENTS.md +45 -3
- package/src/runtime/__tests__/agent-wake.test.ts +872 -0
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -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 +553 -0
- package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
- package/src/runtime/auth/route-policy.ts +34 -5
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +15 -3
- 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/channel-reply-delivery.ts +106 -2
- package/src/runtime/chrome-extension-registry.ts +38 -2
- package/src/runtime/decision-token.ts +116 -0
- package/src/runtime/gateway-client.ts +2 -2
- package/src/runtime/http-router.ts +32 -0
- package/src/runtime/http-server.ts +447 -11
- package/src/runtime/http-types.ts +29 -3
- package/src/runtime/interactive-ui.ts +362 -0
- package/src/runtime/invite-instruction-generator.ts +2 -2
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
- 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/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
- package/src/runtime/migrations/gcs-signed-url.ts +162 -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 +187 -8
- package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
- package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
- package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
- package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
- package/src/runtime/migrations/vbundle-validator.ts +15 -6
- 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 +618 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +247 -0
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -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-prompt-ts-tracker.ts +58 -0
- package/src/runtime/routes/approval-routes.ts +12 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/avatar-routes.ts +20 -4
- 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 +9 -10
- 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 +133 -0
- package/src/runtime/routes/conversation-routes.ts +487 -160
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +6 -4
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +452 -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-message-handler.ts +912 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
- 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 +36 -6
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +325 -0
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/migration-routes.ts +722 -91
- package/src/runtime/routes/settings-routes.ts +26 -7
- 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/trust-rules-routes.ts +30 -14
- 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.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +11 -3
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +426 -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 +340 -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 +71 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +58 -0
- package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
- package/src/security/__tests__/untrusted-content.test.ts +109 -0
- package/src/security/oauth2.ts +122 -37
- package/src/security/secure-keys.ts +32 -10
- package/src/security/token-manager.ts +35 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-cache.ts +26 -7
- package/src/skills/catalog-files.ts +64 -2
- package/src/skills/catalog-install.ts +31 -3
- 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-cache-store.ts +97 -0
- 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 +468 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +228 -0
- package/src/stt/stt-stream-session.ts +506 -0
- package/src/stt/types.ts +334 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +79 -27
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +166 -0
- package/src/tools/browser/browser-execution.ts +1208 -41
- 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 +205 -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/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +41 -7
- package/src/tools/executor.ts +4 -0
- package/src/tools/filesystem/write.ts +52 -0
- package/src/tools/host-terminal/host-shell.ts +45 -5
- package/src/tools/memory/register.test.ts +185 -0
- package/src/tools/memory/register.ts +3 -1
- package/src/tools/network/web-fetch.ts +25 -12
- package/src/tools/network/web-search.ts +20 -2
- package/src/tools/permission-checker.ts +36 -15
- package/src/tools/policy-context.ts +25 -8
- package/src/tools/registry.ts +55 -3
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +0 -9
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +6 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +11 -2
- package/src/tools/terminal/shell.ts +16 -4
- package/src/tools/tool-manifest.ts +6 -0
- package/src/tools/types.ts +29 -3
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +1061 -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 +219 -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 +44 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +199 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/types/tar-stream.d.ts +66 -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/json.ts +17 -0
- package/src/util/platform.ts +56 -12
- package/src/util/pricing.ts +78 -5
- 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 +24 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/git-service.ts +23 -4
- 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/038-unify-llm-callsite-configs.ts +516 -0
- package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +57 -0
- package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
- package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
- package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +32 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- 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/__tests__/outlook-attachments.test.ts +0 -301
- package/src/__tests__/outlook-automation-tools.test.ts +0 -425
- package/src/__tests__/outlook-categories.test.ts +0 -212
- package/src/__tests__/outlook-compose-tools.test.ts +0 -325
- package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
- package/src/__tests__/outlook-follow-up.test.ts +0 -196
- package/src/__tests__/outlook-trash.test.ts +0 -77
- package/src/__tests__/outlook-unsubscribe.test.ts +0 -250
- package/src/__tests__/update-bulletin-format.test.ts +0 -122
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -277
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/browser-relay.ts +0 -466
- package/src/cli/commands/doctor.ts +0 -341
- package/src/config/bundled-skills/browser/SKILL.md +0 -63
- package/src/config/bundled-skills/browser/TOOLS.json +0 -393
- package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -32
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
- package/src/config/bundled-skills/gmail/SKILL.md +0 -175
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -558
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -149
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -220
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -251
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
- package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
- package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
- package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/google-calendar/types.ts +0 -97
- package/src/config/bundled-skills/outlook/SKILL.md +0 -196
- package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
- package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
- package/src/config/bundled-skills/slack/SKILL.md +0 -107
- package/src/config/bundled-skills/tasks/SKILL.md +0 -37
- package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
- package/src/config/bundled-skills/tasks/icon.svg +0 -34
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
- package/src/config/bundled-skills/watcher/SKILL.md +0 -31
- package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
- 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/UPDATES.md +0 -38
- package/src/prompts/templates/USER.md +0 -13
- package/src/prompts/update-bulletin-format.ts +0 -68
- package/src/prompts/update-bulletin-state.ts +0 -58
- package/src/prompts/update-bulletin-template-path.ts +0 -13
- package/src/prompts/update-bulletin.ts +0 -128
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/runtime/routes/browser-cdp-routes.ts +0 -229
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/tools/watcher/create.ts +0 -86
- package/src/tools/watcher/delete.ts +0 -36
- package/src/tools/watcher/digest.ts +0 -54
- package/src/tools/watcher/list.ts +0 -83
- package/src/tools/watcher/update.ts +0 -71
|
@@ -11,16 +11,16 @@ import {
|
|
|
11
11
|
createAssistantMessage,
|
|
12
12
|
createUserMessage,
|
|
13
13
|
} from "../agent/message-types.js";
|
|
14
|
-
import type {
|
|
15
|
-
TurnChannelContext,
|
|
16
|
-
TurnInterfaceContext,
|
|
17
|
-
} from "../channels/types.js";
|
|
18
14
|
import {
|
|
15
|
+
canServiceRegistryBrowser,
|
|
19
16
|
parseChannelId,
|
|
20
17
|
parseInterfaceId,
|
|
21
18
|
supportsHostProxy,
|
|
19
|
+
type TurnChannelContext,
|
|
20
|
+
type TurnInterfaceContext,
|
|
22
21
|
} from "../channels/types.js";
|
|
23
22
|
import { getConfig } from "../config/loader.js";
|
|
23
|
+
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
24
24
|
import type { ContextWindowResult } from "../context/window-manager.js";
|
|
25
25
|
import { listPendingRequestsByConversationScope } from "../memory/canonical-guardian-store.js";
|
|
26
26
|
import {
|
|
@@ -34,13 +34,21 @@ import { createPreference } from "../notifications/preferences-store.js";
|
|
|
34
34
|
import type { Message } from "../providers/types.js";
|
|
35
35
|
import { routeGuardianReply } from "../runtime/guardian-reply-router.js";
|
|
36
36
|
import { getLogger } from "../util/logger.js";
|
|
37
|
-
import
|
|
38
|
-
import type {
|
|
37
|
+
import { persistQueuedMessageBody } from "./conversation-messaging.js";
|
|
38
|
+
import type {
|
|
39
|
+
MessageQueue,
|
|
40
|
+
QueuedMessage,
|
|
41
|
+
QueueDrainReason,
|
|
42
|
+
} from "./conversation-queue-manager.js";
|
|
39
43
|
import type {
|
|
40
44
|
ChannelCapabilities,
|
|
41
45
|
TrustContext,
|
|
42
46
|
} from "./conversation-runtime-assembly.js";
|
|
43
|
-
import {
|
|
47
|
+
import {
|
|
48
|
+
classifySlash,
|
|
49
|
+
resolveSlash,
|
|
50
|
+
type SlashContext,
|
|
51
|
+
} from "./conversation-slash.js";
|
|
44
52
|
import { getModelInfo } from "./handlers/config-model.js";
|
|
45
53
|
import type {
|
|
46
54
|
ServerMessage,
|
|
@@ -94,6 +102,12 @@ export interface ProcessConversationContext {
|
|
|
94
102
|
currentRequestId?: string;
|
|
95
103
|
readonly queue: MessageQueue;
|
|
96
104
|
readonly traceEmitter: TraceEmitter;
|
|
105
|
+
/**
|
|
106
|
+
* Set of requestIds created by surface-action responses. Used to
|
|
107
|
+
* distinguish surface-action turns from regular user turns (e.g. for
|
|
108
|
+
* stale-surface auto-dismiss guards and batched-drain exclusion).
|
|
109
|
+
*/
|
|
110
|
+
readonly surfaceActionRequestIds: Set<string>;
|
|
97
111
|
currentActiveSurfaceId?: string;
|
|
98
112
|
currentPage?: string;
|
|
99
113
|
/** Cumulative token usage stats for the conversation. */
|
|
@@ -127,6 +141,7 @@ export interface ProcessConversationContext {
|
|
|
127
141
|
isInteractive?: boolean;
|
|
128
142
|
isUserMessage?: boolean;
|
|
129
143
|
titleText?: string;
|
|
144
|
+
callSite?: LLMCallSite;
|
|
130
145
|
},
|
|
131
146
|
): Promise<void>;
|
|
132
147
|
getTurnChannelContext(): TurnChannelContext | null;
|
|
@@ -135,10 +150,22 @@ export interface ProcessConversationContext {
|
|
|
135
150
|
setTurnInterfaceContext(ctx: TurnInterfaceContext): void;
|
|
136
151
|
/** Mark host proxies as unavailable so tool execution uses local fallback. */
|
|
137
152
|
clearProxyAvailability(): void;
|
|
138
|
-
/**
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Restore host proxy availability based on whether a real client is connected.
|
|
155
|
+
* When `skipBrowser` is true, the browser proxy is left untouched — use this
|
|
156
|
+
* when `restoreBrowserProxyAvailability()` will handle the browser proxy
|
|
157
|
+
* separately with the correct registry-routed sender.
|
|
158
|
+
*/
|
|
159
|
+
restoreProxyAvailability(options?: { skipBrowser?: boolean }): void;
|
|
160
|
+
/** Restore only the host browser proxy (used by chrome-extension and macOS+extension drains). */
|
|
141
161
|
restoreBrowserProxyAvailability(): void;
|
|
162
|
+
/**
|
|
163
|
+
* Registry-routed sender override for the host browser proxy. When set,
|
|
164
|
+
* `restoreBrowserProxyAvailability()` uses this function instead of
|
|
165
|
+
* `sendToClient`. Set by the POST /messages handler when the guardian
|
|
166
|
+
* has an active extension connection (regardless of interface).
|
|
167
|
+
*/
|
|
168
|
+
hostBrowserSenderOverride?: (msg: ServerMessage) => void;
|
|
142
169
|
/** Replace or clear the conversation's host browser proxy. */
|
|
143
170
|
setHostBrowserProxy(
|
|
144
171
|
proxy: import("./host-browser-proxy.js").HostBrowserProxy | undefined,
|
|
@@ -234,14 +261,90 @@ function buildSlashContext(
|
|
|
234
261
|
messageCount: conversation.messages.length,
|
|
235
262
|
inputTokens: conversation.usageStats.inputTokens,
|
|
236
263
|
outputTokens: conversation.usageStats.outputTokens,
|
|
237
|
-
maxInputTokens: config.contextWindow.maxInputTokens,
|
|
238
|
-
model: config.
|
|
239
|
-
provider: config.
|
|
264
|
+
maxInputTokens: config.llm.default.contextWindow.maxInputTokens,
|
|
265
|
+
model: config.llm.default.model,
|
|
266
|
+
provider: config.llm.default.provider,
|
|
240
267
|
estimatedCost: conversation.usageStats.estimatedCost,
|
|
241
268
|
userMessageInterface: turnInterface?.userMessageInterface,
|
|
242
269
|
};
|
|
243
270
|
}
|
|
244
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Walk the head of the queue and return the longest contiguous run of
|
|
274
|
+
* passthrough messages (non-slash, non-verification-intent) that share the
|
|
275
|
+
* same `userMessageInterface`. Returns `[]` when the head is itself a slash
|
|
276
|
+
* command or verification-intent direct-setup — in that case `drainQueue`
|
|
277
|
+
* pops the head via `queue.shift()` and the single-message path handles it.
|
|
278
|
+
*
|
|
279
|
+
* The builder uses `peek` for lookahead and only calls `shiftN(matched)` once
|
|
280
|
+
* a contiguous passthrough run is identified. This keeps byte-budget
|
|
281
|
+
* accounting centralized in `MessageQueue` rather than mutating mid-walk.
|
|
282
|
+
*/
|
|
283
|
+
async function buildPassthroughBatch(
|
|
284
|
+
conversation: ProcessConversationContext,
|
|
285
|
+
): Promise<QueuedMessage[]> {
|
|
286
|
+
const head = conversation.queue.peek(0);
|
|
287
|
+
if (head === undefined) return [];
|
|
288
|
+
|
|
289
|
+
const headInterface = resolveQueuedTurnInterfaceContext(
|
|
290
|
+
head,
|
|
291
|
+
conversation.getTurnInterfaceContext(),
|
|
292
|
+
);
|
|
293
|
+
// Pure classifier — no side effects. `resolveSlash` runs /pair's side
|
|
294
|
+
// effects (pairing registration, QR PNG write); if we called it here the
|
|
295
|
+
// real drain would invoke those again and the second call would fail with
|
|
296
|
+
// "active pairing already in progress".
|
|
297
|
+
if (classifySlash(head.content) !== "passthrough") return [];
|
|
298
|
+
if (resolveVerificationSessionIntent(head.content).kind === "direct_setup") {
|
|
299
|
+
// Verification intents stay on the single-message path so their per-turn
|
|
300
|
+
// skill preactivation isn't leaked into batched tail messages.
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
// Surface-action messages rely on per-message `activeSurfaceId` and
|
|
304
|
+
// `surfaceActionRequestIds` semantics that last-wins batching would
|
|
305
|
+
// corrupt (e.g. erasing the head's surface context when the last tail is
|
|
306
|
+
// a regular text message). Keep them on the single-message path.
|
|
307
|
+
if (
|
|
308
|
+
head.activeSurfaceId !== undefined ||
|
|
309
|
+
conversation.surfaceActionRequestIds.has(head.requestId)
|
|
310
|
+
) {
|
|
311
|
+
return [];
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
let i = 1;
|
|
315
|
+
for (;;) {
|
|
316
|
+
const candidate = conversation.queue.peek(i);
|
|
317
|
+
if (candidate === undefined) break;
|
|
318
|
+
const candIf = resolveQueuedTurnInterfaceContext(
|
|
319
|
+
candidate,
|
|
320
|
+
conversation.getTurnInterfaceContext(),
|
|
321
|
+
);
|
|
322
|
+
// Treat an undefined interface as distinct from a defined one so we don't
|
|
323
|
+
// silently batch cross-interface messages whose env/transport would
|
|
324
|
+
// otherwise diverge.
|
|
325
|
+
if (candIf?.userMessageInterface !== headInterface?.userMessageInterface)
|
|
326
|
+
break;
|
|
327
|
+
if (classifySlash(candidate.content) !== "passthrough") break;
|
|
328
|
+
if (
|
|
329
|
+
resolveVerificationSessionIntent(candidate.content).kind ===
|
|
330
|
+
"direct_setup"
|
|
331
|
+
)
|
|
332
|
+
break;
|
|
333
|
+
// Stop at the first surface-action tail; it will drain via the single-
|
|
334
|
+
// message path so its per-message surface context is preserved.
|
|
335
|
+
if (
|
|
336
|
+
candidate.activeSurfaceId !== undefined ||
|
|
337
|
+
conversation.surfaceActionRequestIds.has(candidate.requestId)
|
|
338
|
+
) {
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
i++;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const matched = i;
|
|
345
|
+
return conversation.queue.shiftN(matched);
|
|
346
|
+
}
|
|
347
|
+
|
|
245
348
|
// ── drainQueue ───────────────────────────────────────────────────────
|
|
246
349
|
|
|
247
350
|
/**
|
|
@@ -258,9 +361,26 @@ export async function drainQueue(
|
|
|
258
361
|
conversation: ProcessConversationContext,
|
|
259
362
|
reason: QueueDrainReason = "loop_complete",
|
|
260
363
|
): Promise<void> {
|
|
261
|
-
const
|
|
262
|
-
if (
|
|
364
|
+
const batch = await buildPassthroughBatch(conversation);
|
|
365
|
+
if (batch.length === 0) {
|
|
366
|
+
// Head is a slash / verification intent / empty queue. If the queue has
|
|
367
|
+
// an item the builder rejected, pop it and hand it to the single-message
|
|
368
|
+
// path — which owns slash / compact / verification-intent behavior.
|
|
369
|
+
const next = conversation.queue.shift();
|
|
370
|
+
if (!next) return;
|
|
371
|
+
return drainSingleMessage(conversation, next, reason);
|
|
372
|
+
}
|
|
373
|
+
if (batch.length === 1) {
|
|
374
|
+
return drainSingleMessage(conversation, batch[0], reason);
|
|
375
|
+
}
|
|
376
|
+
return drainBatch(conversation, batch, reason);
|
|
377
|
+
}
|
|
263
378
|
|
|
379
|
+
async function drainSingleMessage(
|
|
380
|
+
conversation: ProcessConversationContext,
|
|
381
|
+
next: QueuedMessage,
|
|
382
|
+
reason: QueueDrainReason,
|
|
383
|
+
): Promise<void> {
|
|
264
384
|
// Reset per-turn preactivation so a prior iteration (e.g. an unknown-slash
|
|
265
385
|
// from a desktop source that skips runAgentLoop) can't leak CU preactivation
|
|
266
386
|
// into the next queued message.
|
|
@@ -354,21 +474,49 @@ export async function drainQueue(
|
|
|
354
474
|
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
355
475
|
const sourceInterface = interfaceCtx?.userMessageInterface;
|
|
356
476
|
if (sourceInterface && supportsHostProxy(sourceInterface)) {
|
|
357
|
-
|
|
477
|
+
// When hostBrowserSenderOverride is set, skip the browser proxy here
|
|
478
|
+
// — restoreBrowserProxyAvailability() below will handle it with the
|
|
479
|
+
// correct registry-routed sender instead of the SSE hub emitter.
|
|
480
|
+
conversation.restoreProxyAvailability(
|
|
481
|
+
conversation.hostBrowserSenderOverride
|
|
482
|
+
? { skipBrowser: true }
|
|
483
|
+
: undefined,
|
|
484
|
+
);
|
|
358
485
|
conversation.addPreactivatedSkillId("computer-use");
|
|
359
486
|
}
|
|
360
487
|
// Tear down a stale hostBrowserProxy inherited from a prior turn on a
|
|
361
|
-
// different interface (e.g. chrome-extension installed one, then a
|
|
362
|
-
//
|
|
363
|
-
//
|
|
364
|
-
//
|
|
365
|
-
//
|
|
488
|
+
// different interface (e.g. chrome-extension installed one, then a CLI
|
|
489
|
+
// turn drains). Without this, restoreProxyAvailability() above would
|
|
490
|
+
// re-enable the proxy and getCdpClient() would route browser tools
|
|
491
|
+
// through host_browser_request and hang waiting for a client that this
|
|
492
|
+
// turn's interface can't service.
|
|
493
|
+
//
|
|
494
|
+
// Skip teardown only when BOTH conditions hold:
|
|
495
|
+
// 1. `hostBrowserSenderOverride` is set (live registry-routed sender)
|
|
496
|
+
// 2. The current turn's interface can service host_browser frames
|
|
497
|
+
// (chrome-extension or macOS).
|
|
498
|
+
// Without the interface check, queued turns from CLI/iOS/Vellum would
|
|
499
|
+
// inherit a stale override left by a prior extension-connected turn
|
|
500
|
+
// and keep the proxy alive, causing cross-interface misrouting.
|
|
501
|
+
const currentTurnCanServiceBrowser =
|
|
502
|
+
!!sourceInterface && canServiceRegistryBrowser(sourceInterface);
|
|
366
503
|
if (
|
|
367
504
|
sourceInterface &&
|
|
368
|
-
!supportsHostProxy(sourceInterface, "host_browser")
|
|
505
|
+
!supportsHostProxy(sourceInterface, "host_browser") &&
|
|
506
|
+
!(conversation.hostBrowserSenderOverride && currentTurnCanServiceBrowser)
|
|
369
507
|
) {
|
|
370
508
|
conversation.setHostBrowserProxy(undefined);
|
|
371
509
|
}
|
|
510
|
+
// When a macOS turn has a registry-routed sender override (active
|
|
511
|
+
// extension connection), restore the browser proxy so host_browser
|
|
512
|
+
// tools route through the extension rather than cdp-inspect/local.
|
|
513
|
+
if (
|
|
514
|
+
sourceInterface &&
|
|
515
|
+
supportsHostProxy(sourceInterface) &&
|
|
516
|
+
conversation.hostBrowserSenderOverride
|
|
517
|
+
) {
|
|
518
|
+
conversation.restoreBrowserProxyAvailability();
|
|
519
|
+
}
|
|
372
520
|
}
|
|
373
521
|
|
|
374
522
|
// Snapshot persona context at turn start so later tool turns can't pick up
|
|
@@ -644,6 +792,17 @@ export async function drainQueue(
|
|
|
644
792
|
return;
|
|
645
793
|
}
|
|
646
794
|
|
|
795
|
+
// Broadcast the user message to all hub subscribers so passive devices
|
|
796
|
+
// see the user turn before the assistant reply starts streaming.
|
|
797
|
+
next.onEvent({
|
|
798
|
+
type: "user_message_echo",
|
|
799
|
+
text: resolvedContent,
|
|
800
|
+
conversationId: conversation.conversationId,
|
|
801
|
+
messageId: userMessageId,
|
|
802
|
+
requestId: next.requestId,
|
|
803
|
+
clientMessageId: next.clientMessageId,
|
|
804
|
+
});
|
|
805
|
+
|
|
647
806
|
// Set the active surface for the dequeued message so runAgentLoop can inject context
|
|
648
807
|
conversation.currentActiveSurfaceId = next.activeSurfaceId;
|
|
649
808
|
conversation.currentPage = next.currentPage;
|
|
@@ -715,6 +874,413 @@ export async function drainQueue(
|
|
|
715
874
|
});
|
|
716
875
|
}
|
|
717
876
|
|
|
877
|
+
// Drives a batched turn where multiple queued passthrough messages share one
|
|
878
|
+
// runAgentLoop run. Per-message dequeue events and DB persistence are
|
|
879
|
+
// preserved; the agent reply fans out to every batched client.
|
|
880
|
+
async function drainBatch(
|
|
881
|
+
conversation: ProcessConversationContext,
|
|
882
|
+
batch: QueuedMessage[],
|
|
883
|
+
reason: QueueDrainReason,
|
|
884
|
+
): Promise<void> {
|
|
885
|
+
// Head-wins: the batch-builder guarantees identical userMessageInterface
|
|
886
|
+
// across the batch; channel/transport divergence is accepted with the head's
|
|
887
|
+
// environment.
|
|
888
|
+
const head = batch[0];
|
|
889
|
+
|
|
890
|
+
// Reset per-turn preactivation so a prior iteration can't leak CU
|
|
891
|
+
// preactivation into this batched turn.
|
|
892
|
+
conversation.preactivatedSkillIds = undefined;
|
|
893
|
+
|
|
894
|
+
log.info(
|
|
895
|
+
{
|
|
896
|
+
conversationId: conversation.conversationId,
|
|
897
|
+
requestId: head.requestId,
|
|
898
|
+
reason,
|
|
899
|
+
batchSize: batch.length,
|
|
900
|
+
},
|
|
901
|
+
"Dequeuing batched messages",
|
|
902
|
+
);
|
|
903
|
+
|
|
904
|
+
const queuedTurnCtx = resolveQueuedTurnContext(
|
|
905
|
+
head,
|
|
906
|
+
conversation.getTurnChannelContext(),
|
|
907
|
+
);
|
|
908
|
+
if (queuedTurnCtx) {
|
|
909
|
+
conversation.setTurnChannelContext(queuedTurnCtx);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
const queuedInterfaceCtx = resolveQueuedTurnInterfaceContext(
|
|
913
|
+
head,
|
|
914
|
+
conversation.getTurnInterfaceContext(),
|
|
915
|
+
);
|
|
916
|
+
if (queuedInterfaceCtx) {
|
|
917
|
+
conversation.setTurnInterfaceContext(queuedInterfaceCtx);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// Apply transport hints from the head message so this batched turn uses
|
|
921
|
+
// the head's transport metadata. Tail transport divergence is accepted
|
|
922
|
+
// per the head-wins contract.
|
|
923
|
+
if (head.transport) {
|
|
924
|
+
conversation.setTransportHints(buildTransportHints(head.transport));
|
|
925
|
+
conversation.applyHostEnvFromTransport(head.transport);
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// Non-interactive queued messages (channel requests) must not execute tools
|
|
929
|
+
// via the desktop host proxy. Clear proxy availability so isAvailable()
|
|
930
|
+
// returns false and tool execution falls back to local. Mirrors the
|
|
931
|
+
// single-message path exactly — sourced from `head`.
|
|
932
|
+
if (head.isInteractive === false) {
|
|
933
|
+
conversation.clearProxyAvailability();
|
|
934
|
+
const drainInterfaceCtx =
|
|
935
|
+
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
936
|
+
const drainInterface = drainInterfaceCtx?.userMessageInterface;
|
|
937
|
+
if (
|
|
938
|
+
drainInterface &&
|
|
939
|
+
!supportsHostProxy(drainInterface) &&
|
|
940
|
+
supportsHostProxy(drainInterface, "host_browser")
|
|
941
|
+
) {
|
|
942
|
+
conversation.restoreBrowserProxyAvailability();
|
|
943
|
+
}
|
|
944
|
+
} else {
|
|
945
|
+
const interfaceCtx =
|
|
946
|
+
queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
|
|
947
|
+
const sourceInterface = interfaceCtx?.userMessageInterface;
|
|
948
|
+
if (sourceInterface && supportsHostProxy(sourceInterface)) {
|
|
949
|
+
conversation.restoreProxyAvailability(
|
|
950
|
+
conversation.hostBrowserSenderOverride
|
|
951
|
+
? { skipBrowser: true }
|
|
952
|
+
: undefined,
|
|
953
|
+
);
|
|
954
|
+
conversation.addPreactivatedSkillId("computer-use");
|
|
955
|
+
}
|
|
956
|
+
const currentTurnCanServiceBrowser =
|
|
957
|
+
!!sourceInterface && canServiceRegistryBrowser(sourceInterface);
|
|
958
|
+
if (
|
|
959
|
+
sourceInterface &&
|
|
960
|
+
!supportsHostProxy(sourceInterface, "host_browser") &&
|
|
961
|
+
!(conversation.hostBrowserSenderOverride && currentTurnCanServiceBrowser)
|
|
962
|
+
) {
|
|
963
|
+
conversation.setHostBrowserProxy(undefined);
|
|
964
|
+
}
|
|
965
|
+
if (
|
|
966
|
+
sourceInterface &&
|
|
967
|
+
supportsHostProxy(sourceInterface) &&
|
|
968
|
+
conversation.hostBrowserSenderOverride
|
|
969
|
+
) {
|
|
970
|
+
conversation.restoreBrowserProxyAvailability();
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// Snapshot persona context at turn start so later tool turns can't pick up
|
|
975
|
+
// a different actor's context if a concurrent request mutates the live fields.
|
|
976
|
+
conversation.currentTurnTrustContext = conversation.trustContext;
|
|
977
|
+
conversation.currentTurnChannelCapabilities =
|
|
978
|
+
conversation.channelCapabilities;
|
|
979
|
+
|
|
980
|
+
// Single activity-state transition for the batched turn. Per-message
|
|
981
|
+
// emissions would publish N "thinking" phase transitions to every
|
|
982
|
+
// connected SSE client (via activityVersion increments), whipsawing the
|
|
983
|
+
// client-side thinking indicator. The single-message path emits exactly
|
|
984
|
+
// one such event per turn; match it here.
|
|
985
|
+
conversation.emitActivityState(
|
|
986
|
+
"thinking",
|
|
987
|
+
"message_dequeued",
|
|
988
|
+
"assistant_turn",
|
|
989
|
+
head.requestId,
|
|
990
|
+
);
|
|
991
|
+
|
|
992
|
+
// Per-message dequeue events and persistence loop. Track the last
|
|
993
|
+
// SUCCESSFUL persist separately from the batch tail — a failed tail
|
|
994
|
+
// must not corrupt the requestId/surface context that `runAgentLoop`
|
|
995
|
+
// will tag `message_complete` / `generation_cancelled` with.
|
|
996
|
+
let lastSuccessfulRequestId: string | undefined;
|
|
997
|
+
let lastSuccessfulActiveSurfaceId: string | undefined;
|
|
998
|
+
let lastSuccessfulCurrentPage: string | undefined;
|
|
999
|
+
let lastSuccessfulContent: string | undefined;
|
|
1000
|
+
let lastUserMessageId: string | undefined;
|
|
1001
|
+
// Members whose persist succeeded. `fanOutOnEvent` below must only
|
|
1002
|
+
// broadcast agent-loop events to these — clients whose persist failed
|
|
1003
|
+
// already received an error event and must not also receive the
|
|
1004
|
+
// assistant's streaming response for a turn that isn't theirs.
|
|
1005
|
+
const successfulBatch: QueuedMessage[] = [];
|
|
1006
|
+
for (let i = 0; i < batch.length; i++) {
|
|
1007
|
+
const qm = batch[i];
|
|
1008
|
+
qm.onEvent({
|
|
1009
|
+
type: "message_dequeued",
|
|
1010
|
+
conversationId: conversation.conversationId,
|
|
1011
|
+
requestId: qm.requestId,
|
|
1012
|
+
});
|
|
1013
|
+
conversation.traceEmitter.emit(
|
|
1014
|
+
"request_dequeued",
|
|
1015
|
+
"Message dequeued (batched)",
|
|
1016
|
+
{
|
|
1017
|
+
requestId: qm.requestId,
|
|
1018
|
+
status: "info",
|
|
1019
|
+
attributes: { reason, batchIndex: i, batchSize: batch.length },
|
|
1020
|
+
},
|
|
1021
|
+
);
|
|
1022
|
+
|
|
1023
|
+
const qmSlash = await resolveSlash(
|
|
1024
|
+
qm.content,
|
|
1025
|
+
buildSlashContext(conversation),
|
|
1026
|
+
);
|
|
1027
|
+
if (qmSlash.kind !== "passthrough") {
|
|
1028
|
+
// Defensive recovery. `buildPassthroughBatch` should make this
|
|
1029
|
+
// unreachable, but if it ever fires we must avoid stranding
|
|
1030
|
+
// per-turn state and dropping the batch tails that have already
|
|
1031
|
+
// been shifted out of the queue. Log, emit an error to the
|
|
1032
|
+
// affected client, and either recover-and-drain (head case) or
|
|
1033
|
+
// skip the tail (tail case) so the rest of the batch still runs.
|
|
1034
|
+
const invariantMessage =
|
|
1035
|
+
"Internal error: batch drain invariant violated (non-passthrough message in batch)";
|
|
1036
|
+
log.error(
|
|
1037
|
+
{
|
|
1038
|
+
conversationId: conversation.conversationId,
|
|
1039
|
+
requestId: qm.requestId,
|
|
1040
|
+
batchIndex: i,
|
|
1041
|
+
batchSize: batch.length,
|
|
1042
|
+
slashKind: qmSlash.kind,
|
|
1043
|
+
},
|
|
1044
|
+
"drainBatch invariant violated — non-passthrough message found in batch",
|
|
1045
|
+
);
|
|
1046
|
+
conversation.traceEmitter.emit("request_error", invariantMessage, {
|
|
1047
|
+
requestId: qm.requestId,
|
|
1048
|
+
status: "error",
|
|
1049
|
+
attributes: { reason: "batch_invariant_violation" },
|
|
1050
|
+
});
|
|
1051
|
+
qm.onEvent({ type: "error", message: invariantMessage });
|
|
1052
|
+
if (i === 0) {
|
|
1053
|
+
// Head invariant fired — no in-flight turn yet (the check runs
|
|
1054
|
+
// before persistUserMessage, so the head was never persisted).
|
|
1055
|
+
// Clear per-turn state and recursively drain the remaining tails,
|
|
1056
|
+
// which were already shifted out of the queue by
|
|
1057
|
+
// buildPassthroughBatch and would otherwise be stranded. Mirrors
|
|
1058
|
+
// the head persist-failure recovery below.
|
|
1059
|
+
conversation.processing = false;
|
|
1060
|
+
conversation.abortController = null;
|
|
1061
|
+
conversation.currentRequestId = undefined;
|
|
1062
|
+
conversation.preactivatedSkillIds = undefined;
|
|
1063
|
+
const remaining = batch.slice(1);
|
|
1064
|
+
if (remaining.length >= 2) {
|
|
1065
|
+
await drainBatch(conversation, remaining, reason);
|
|
1066
|
+
} else if (remaining.length === 1) {
|
|
1067
|
+
await drainSingleMessage(conversation, remaining[0], reason);
|
|
1068
|
+
} else {
|
|
1069
|
+
await drainQueue(conversation);
|
|
1070
|
+
}
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
// Tail case — processing is live, just skip this message. Loop
|
|
1074
|
+
// continues to drain any remaining tails.
|
|
1075
|
+
continue;
|
|
1076
|
+
}
|
|
1077
|
+
const qmContent = qmSlash.content;
|
|
1078
|
+
|
|
1079
|
+
try {
|
|
1080
|
+
if (i === 0) {
|
|
1081
|
+
lastUserMessageId = await conversation.persistUserMessage(
|
|
1082
|
+
qmContent,
|
|
1083
|
+
qm.attachments,
|
|
1084
|
+
qm.requestId,
|
|
1085
|
+
{ ...qm.metadata, sentAt: qm.sentAt },
|
|
1086
|
+
qm.displayContent,
|
|
1087
|
+
);
|
|
1088
|
+
} else {
|
|
1089
|
+
lastUserMessageId = await persistQueuedMessageBody(
|
|
1090
|
+
conversation,
|
|
1091
|
+
qmContent,
|
|
1092
|
+
qm.attachments,
|
|
1093
|
+
qm.requestId,
|
|
1094
|
+
{ ...qm.metadata, sentAt: qm.sentAt },
|
|
1095
|
+
qm.displayContent,
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
} catch (err) {
|
|
1099
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1100
|
+
log.error(
|
|
1101
|
+
{
|
|
1102
|
+
err,
|
|
1103
|
+
conversationId: conversation.conversationId,
|
|
1104
|
+
requestId: qm.requestId,
|
|
1105
|
+
batchIndex: i,
|
|
1106
|
+
},
|
|
1107
|
+
"Failed to persist batched queued message",
|
|
1108
|
+
);
|
|
1109
|
+
conversation.traceEmitter.emit(
|
|
1110
|
+
"request_error",
|
|
1111
|
+
`Queued message persist failed: ${message}`,
|
|
1112
|
+
{
|
|
1113
|
+
requestId: qm.requestId,
|
|
1114
|
+
status: "error",
|
|
1115
|
+
attributes: { reason: "persist_failure" },
|
|
1116
|
+
},
|
|
1117
|
+
);
|
|
1118
|
+
qm.onEvent({ type: "error", message });
|
|
1119
|
+
|
|
1120
|
+
if (i === 0) {
|
|
1121
|
+
// Head persist failed — processing is not set yet, no in-flight turn
|
|
1122
|
+
// to fan tails into. We've already shifted the tails out of the queue
|
|
1123
|
+
// as part of this batch, so if we simply called drainQueue the tails
|
|
1124
|
+
// would be stranded. Reset per-turn state and recursively drain the
|
|
1125
|
+
// remaining tails (they're still valid by the batch invariant).
|
|
1126
|
+
conversation.preactivatedSkillIds = undefined;
|
|
1127
|
+
const remaining = batch.slice(1);
|
|
1128
|
+
if (remaining.length >= 2) {
|
|
1129
|
+
await drainBatch(conversation, remaining, reason);
|
|
1130
|
+
} else if (remaining.length === 1) {
|
|
1131
|
+
await drainSingleMessage(conversation, remaining[0], reason);
|
|
1132
|
+
} else {
|
|
1133
|
+
await drainQueue(conversation);
|
|
1134
|
+
}
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
// Tail persist failed — we cannot abandon the batch without stranding
|
|
1138
|
+
// the head's in-flight turn. Processing state is already set; skip
|
|
1139
|
+
// this message and continue accumulating siblings. The emitted error
|
|
1140
|
+
// event lets the tail client see the failure. Crucially we do NOT
|
|
1141
|
+
// update lastSuccessful* here, so runAgentLoop tags completion with
|
|
1142
|
+
// the most recent successfully-persisted message's requestId.
|
|
1143
|
+
continue;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// Broadcast the user message to all hub subscribers so passive devices
|
|
1147
|
+
// see each batched user turn before the assistant reply starts streaming.
|
|
1148
|
+
qm.onEvent({
|
|
1149
|
+
type: "user_message_echo",
|
|
1150
|
+
text: qmContent,
|
|
1151
|
+
conversationId: conversation.conversationId,
|
|
1152
|
+
messageId: lastUserMessageId,
|
|
1153
|
+
requestId: qm.requestId,
|
|
1154
|
+
clientMessageId: qm.clientMessageId,
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
// Persist succeeded. Update last-successful markers so a later tail
|
|
1158
|
+
// failure won't overwrite them.
|
|
1159
|
+
lastSuccessfulRequestId = qm.requestId;
|
|
1160
|
+
lastSuccessfulActiveSurfaceId = qm.activeSurfaceId;
|
|
1161
|
+
lastSuccessfulCurrentPage = qm.currentPage;
|
|
1162
|
+
lastSuccessfulContent = qmContent;
|
|
1163
|
+
successfulBatch.push(qm);
|
|
1164
|
+
|
|
1165
|
+
// Fire-and-forget: detect notification preferences in each batched user
|
|
1166
|
+
// message and persist any that are found, mirroring drainSingleMessage.
|
|
1167
|
+
if (conversation.assistantId) {
|
|
1168
|
+
extractPreferences(qmContent)
|
|
1169
|
+
.then((result) => {
|
|
1170
|
+
if (!result.detected) return;
|
|
1171
|
+
for (const pref of result.preferences) {
|
|
1172
|
+
createPreference({
|
|
1173
|
+
preferenceText: pref.preferenceText,
|
|
1174
|
+
appliesWhen: pref.appliesWhen,
|
|
1175
|
+
priority: pref.priority,
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
log.info(
|
|
1179
|
+
{
|
|
1180
|
+
count: result.preferences.length,
|
|
1181
|
+
conversationId: conversation.conversationId,
|
|
1182
|
+
},
|
|
1183
|
+
"Persisted extracted notification preferences (batched)",
|
|
1184
|
+
);
|
|
1185
|
+
})
|
|
1186
|
+
.catch((err) => {
|
|
1187
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1188
|
+
log.warn(
|
|
1189
|
+
{ err: errMsg, conversationId: conversation.conversationId },
|
|
1190
|
+
"Background preference extraction failed (batched)",
|
|
1191
|
+
);
|
|
1192
|
+
});
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
// If the user hit abort mid-batch, stop persisting remaining tails.
|
|
1196
|
+
// runAgentLoop's existing abort handling will emit generation_cancelled
|
|
1197
|
+
// and clear processing state for whatever did persist.
|
|
1198
|
+
if (conversation.abortController?.signal.aborted) {
|
|
1199
|
+
log.info(
|
|
1200
|
+
{
|
|
1201
|
+
conversationId: conversation.conversationId,
|
|
1202
|
+
requestId: qm.requestId,
|
|
1203
|
+
batchIndex: i,
|
|
1204
|
+
batchSize: batch.length,
|
|
1205
|
+
},
|
|
1206
|
+
"drainBatch: abort signaled mid-batch; stopping tail persist",
|
|
1207
|
+
);
|
|
1208
|
+
break;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
if (lastUserMessageId === undefined || lastSuccessfulContent === undefined) {
|
|
1213
|
+
// Nothing persisted — either the head's invariant-violation recovery
|
|
1214
|
+
// already drained and returned, or every message failed. Head failure
|
|
1215
|
+
// has its own recovery path above; if we get here it's because a
|
|
1216
|
+
// defensive code path left us with nothing to run. Log and bail.
|
|
1217
|
+
log.error(
|
|
1218
|
+
{
|
|
1219
|
+
conversationId: conversation.conversationId,
|
|
1220
|
+
batchSize: batch.length,
|
|
1221
|
+
},
|
|
1222
|
+
"drainBatch: no messages persisted successfully; skipping runAgentLoop",
|
|
1223
|
+
);
|
|
1224
|
+
conversation.preactivatedSkillIds = undefined;
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
// Tag turn-completion state with the last SUCCESSFUL persist so client-
|
|
1229
|
+
// side correlation (message_complete / generation_cancelled /
|
|
1230
|
+
// generation_handoff) surfaces a requestId that actually has a DB row.
|
|
1231
|
+
conversation.currentRequestId = lastSuccessfulRequestId;
|
|
1232
|
+
conversation.currentActiveSurfaceId = lastSuccessfulActiveSurfaceId;
|
|
1233
|
+
conversation.currentPage = lastSuccessfulCurrentPage;
|
|
1234
|
+
|
|
1235
|
+
// Broadcast agent-loop events only to members whose persist succeeded.
|
|
1236
|
+
// Members whose persist failed already received an error event in the
|
|
1237
|
+
// catch block above; sending them the assistant's streaming response
|
|
1238
|
+
// would surface a reply for a user message that isn't in their DB.
|
|
1239
|
+
const fanOutOnEvent = (msg: ServerMessage) => {
|
|
1240
|
+
for (const qm of successfulBatch) qm.onEvent(msg);
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1243
|
+
const drainLoopOptions: {
|
|
1244
|
+
isInteractive?: boolean;
|
|
1245
|
+
isUserMessage?: boolean;
|
|
1246
|
+
titleText?: string;
|
|
1247
|
+
} = { isUserMessage: true };
|
|
1248
|
+
// Source interactive flag from the last successfully-persisted sibling so
|
|
1249
|
+
// a trailing failed tail doesn't flip the agent loop's interactivity.
|
|
1250
|
+
const lastSuccessfulBatchEntry =
|
|
1251
|
+
successfulBatch.length > 0
|
|
1252
|
+
? successfulBatch[successfulBatch.length - 1]
|
|
1253
|
+
: undefined;
|
|
1254
|
+
if (lastSuccessfulBatchEntry?.isInteractive !== undefined)
|
|
1255
|
+
drainLoopOptions.isInteractive = lastSuccessfulBatchEntry.isInteractive;
|
|
1256
|
+
|
|
1257
|
+
// Fire-and-forget: runAgentLoop's finally block recursively calls drainQueue
|
|
1258
|
+
// when this run completes. Mirrors drainSingleMessage.
|
|
1259
|
+
conversation
|
|
1260
|
+
.runAgentLoop(
|
|
1261
|
+
lastSuccessfulContent,
|
|
1262
|
+
lastUserMessageId,
|
|
1263
|
+
fanOutOnEvent,
|
|
1264
|
+
drainLoopOptions,
|
|
1265
|
+
)
|
|
1266
|
+
.catch((err) => {
|
|
1267
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1268
|
+
log.error(
|
|
1269
|
+
{
|
|
1270
|
+
err,
|
|
1271
|
+
conversationId: conversation.conversationId,
|
|
1272
|
+
requestId: lastSuccessfulRequestId,
|
|
1273
|
+
batchSize: batch.length,
|
|
1274
|
+
},
|
|
1275
|
+
"Error processing batched queued messages",
|
|
1276
|
+
);
|
|
1277
|
+
fanOutOnEvent({
|
|
1278
|
+
type: "error",
|
|
1279
|
+
message: `Failed to process queued messages: ${message}`,
|
|
1280
|
+
});
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
|
|
718
1284
|
// ── processMessage ───────────────────────────────────────────────────
|
|
719
1285
|
|
|
720
1286
|
/**
|
|
@@ -729,7 +1295,7 @@ export async function processMessage(
|
|
|
729
1295
|
requestId?: string,
|
|
730
1296
|
activeSurfaceId?: string,
|
|
731
1297
|
currentPage?: string,
|
|
732
|
-
options?: { isInteractive?: boolean },
|
|
1298
|
+
options?: { isInteractive?: boolean; callSite?: LLMCallSite },
|
|
733
1299
|
displayContent?: string,
|
|
734
1300
|
): Promise<string> {
|
|
735
1301
|
await conversation.ensureActorScopedHistory();
|
|
@@ -1085,11 +1651,13 @@ export async function processMessage(
|
|
|
1085
1651
|
isInteractive?: boolean;
|
|
1086
1652
|
isUserMessage?: boolean;
|
|
1087
1653
|
titleText?: string;
|
|
1654
|
+
callSite?: LLMCallSite;
|
|
1088
1655
|
} = { isUserMessage: true };
|
|
1089
1656
|
if (options?.isInteractive !== undefined)
|
|
1090
1657
|
loopOptions.isInteractive = options.isInteractive;
|
|
1091
1658
|
if (agentLoopContent !== resolvedContent)
|
|
1092
1659
|
loopOptions.titleText = resolvedContent;
|
|
1660
|
+
if (options?.callSite !== undefined) loopOptions.callSite = options.callSite;
|
|
1093
1661
|
|
|
1094
1662
|
await conversation.runAgentLoop(
|
|
1095
1663
|
agentLoopContent,
|