@vellumai/assistant 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +273 -10
- package/Dockerfile +2 -3
- package/bun.lock +5 -13
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/stt-provider-onboarding.md +120 -0
- package/knip.json +12 -2
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +3 -3
- package/openapi.yaml +982 -72
- package/package.json +4 -6
- package/scripts/generate-openapi.ts +0 -1
- package/scripts/test.sh +73 -18
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop.test.ts +123 -0
- package/src/__tests__/anthropic-provider.test.ts +263 -10
- package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +11 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/browser-skill-endstate.test.ts +31 -7
- package/src/__tests__/btw-routes.test.ts +7 -0
- package/src/__tests__/call-controller.test.ts +581 -20
- package/src/__tests__/catalog-files.test.ts +138 -0
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/checker.test.ts +157 -10
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/config-analysis.test.ts +100 -0
- package/src/__tests__/config-schema.test.ts +1013 -66
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-window-manager.test.ts +88 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +98 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +135 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-history-web-search.test.ts +11 -4
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +901 -60
- package/src/__tests__/conversation-routes-disk-view.test.ts +270 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +55 -0
- package/src/__tests__/conversation-skill-tools.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +89 -18
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +5 -3
- package/src/__tests__/credential-vault-unit.test.ts +379 -3
- package/src/__tests__/credentials-cli.test.ts +40 -16
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +75 -8
- package/src/__tests__/fixtures/mock-chrome-extension.ts +11 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-provider.test.ts +64 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
- package/src/__tests__/gmail-archive-gate.test.ts +246 -0
- package/src/__tests__/gmail-preferences.test.ts +117 -0
- package/src/__tests__/headless-browser-interactions.test.ts +43 -0
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +142 -5
- package/src/__tests__/headless-browser-read-tools.test.ts +11 -0
- package/src/__tests__/headless-browser-snapshot.test.ts +10 -0
- package/src/__tests__/heartbeat-service.test.ts +70 -17
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +0 -5
- package/src/__tests__/host-browser-e2e-cloud.test.ts +138 -4
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +4 -4
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +103 -0
- package/src/__tests__/host-cu-proxy.test.ts +0 -5
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/llm-context-normalization.test.ts +488 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/migration-export-http.test.ts +6 -6
- package/src/__tests__/migration-import-commit-http.test.ts +8 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +2 -2
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +2 -0
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
- package/src/__tests__/oauth-providers-routes.test.ts +2 -0
- package/src/__tests__/oauth-store.test.ts +85 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +249 -6
- package/src/__tests__/onboarding-template-contract.test.ts +6 -13
- package/src/__tests__/openai-provider.test.ts +176 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1105 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +31 -2
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +423 -5
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-scanner-executor.test.ts +4 -0
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +5 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +276 -145
- package/src/__tests__/skills-files-catalog-fallback.test.ts +381 -93
- package/src/__tests__/skills.test.ts +5 -2
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +564 -1
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/system-prompt.test.ts +112 -26
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +18 -7
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +33 -24
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-format.test.ts +59 -0
- package/src/__tests__/update-bulletin.test.ts +206 -5
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-policy.test.ts +2 -0
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +43 -3
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- package/src/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +8 -1
- package/src/channels/types.ts +16 -0
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +22 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +37 -4
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/conversations.ts +77 -0
- package/src/cli/commands/credentials.ts +0 -1
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +255 -3
- package/src/cli/commands/oauth/__tests__/connect.test.ts +12 -0
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -0
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +15 -0
- package/src/cli/commands/oauth/shared.ts +2 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +4 -9
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
- package/src/cli/program.ts +30 -4
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +37 -1
- package/src/config/bundled-skills/browser/SKILL.md +30 -5
- package/src/config/bundled-skills/browser/TOOLS.json +123 -0
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
- package/src/config/bundled-skills/contacts/SKILL.md +2 -2
- package/src/config/bundled-skills/gmail/SKILL.md +53 -7
- package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/outlook/SKILL.md +2 -2
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/slack/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +8 -0
- package/src/config/env-registry.ts +24 -0
- package/src/config/env.ts +34 -10
- package/src/config/feature-flag-registry.json +46 -14
- package/src/config/loader.ts +26 -12
- package/src/config/schema.ts +35 -10
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +51 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -26
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +47 -7
- package/src/config/schemas/heartbeat.ts +27 -5
- package/src/config/schemas/host-browser.ts +47 -1
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/services.ts +44 -0
- package/src/config/schemas/stt.ts +59 -0
- package/src/config/schemas/tts.ts +230 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/skills.ts +4 -0
- package/src/config/types.ts +4 -0
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/post-turn-tool-result-truncation.ts +3 -2
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +45 -12
- package/src/credential-execution/executable-discovery.ts +12 -2
- package/src/credential-execution/process-manager.ts +33 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +17 -8
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/conversation-agent-loop-handlers.ts +6 -0
- package/src/daemon/conversation-agent-loop.ts +101 -24
- package/src/daemon/conversation-error.ts +11 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +59 -9
- package/src/daemon/conversation-messaging.ts +37 -3
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +581 -19
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +11 -1
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +94 -4
- package/src/daemon/conversation-tool-setup.ts +25 -0
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation.ts +86 -28
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +4 -1
- package/src/daemon/handlers/shared.ts +22 -0
- package/src/daemon/handlers/skills.ts +321 -77
- package/src/daemon/host-browser-proxy.ts +2 -1
- package/src/daemon/lifecycle.ts +122 -25
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/conversations.ts +34 -1
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +14 -0
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +16 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +347 -2
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +9 -0
- package/src/email/html-renderer.ts +76 -0
- package/src/heartbeat/heartbeat-service.ts +93 -7
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +194 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +398 -0
- package/src/home/assistant-feed-authoring.ts +124 -0
- package/src/home/emit-feed-event.ts +158 -0
- package/src/home/feed-scheduler.ts +247 -0
- package/src/home/feed-types.ts +181 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +384 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +12 -3
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/cli-client.ts +151 -0
- package/src/ipc/cli-server.ts +234 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/index.ts +5 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/app-store.ts +1 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +73 -0
- package/src/memory/conversation-crud.ts +99 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +34 -2
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/db-init.ts +6 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction.test.ts +23 -0
- package/src/memory/graph/extraction.ts +8 -0
- package/src/memory/graph/retriever.ts +27 -18
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +16 -10
- package/src/memory/jobs-store.ts +64 -4
- package/src/memory/jobs-worker.ts +22 -9
- package/src/memory/llm-usage-store.ts +92 -56
- package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/oauth.ts +3 -0
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/client.ts +57 -6
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +143 -38
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/notifications/decision-engine.ts +3 -3
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +1 -0
- package/src/oauth/byo-connection.test.ts +18 -1
- package/src/oauth/byo-connection.ts +3 -1
- package/src/oauth/connect-orchestrator.ts +2 -0
- package/src/oauth/connection-resolver.ts +6 -2
- package/src/oauth/connection.ts +2 -0
- package/src/oauth/oauth-store.ts +9 -0
- package/src/oauth/platform-connection.test.ts +98 -0
- package/src/oauth/platform-connection.ts +52 -31
- package/src/oauth/seed-providers.ts +7 -0
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/workspace-policy.ts +3 -0
- package/src/platform/client.test.ts +10 -0
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +126 -2
- package/src/prompts/system-prompt.ts +59 -18
- package/src/prompts/templates/BOOTSTRAP.md +5 -5
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-format.ts +26 -9
- package/src/prompts/update-bulletin.ts +34 -23
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/anthropic/client.ts +157 -61
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +9 -1
- package/src/providers/model-catalog.ts +6 -0
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +474 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +502 -0
- package/src/providers/openrouter/client.ts +101 -4
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +14 -3
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +306 -0
- package/src/providers/speech-to-text/resolve.ts +386 -6
- package/src/providers/types.ts +9 -0
- package/src/runtime/AGENTS.md +43 -1
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +512 -0
- package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
- package/src/runtime/auth/route-policy.ts +30 -5
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +10 -10
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/chrome-extension-registry.ts +38 -2
- package/src/runtime/http-server.ts +395 -10
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +36 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +1 -0
- package/src/runtime/migrations/migration-wizard.ts +1 -0
- package/src/runtime/migrations/vbundle-import-analyzer.ts +77 -1
- package/src/runtime/migrations/vbundle-importer.ts +34 -0
- package/src/runtime/pending-interactions.ts +0 -11
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +82 -23
- package/src/runtime/routes/btw-routes.ts +8 -6
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -142
- package/src/runtime/routes/conversation-management-routes.ts +115 -0
- package/src/runtime/routes/conversation-routes.ts +367 -146
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/home-feed-routes.ts +334 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +3 -14
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +3 -17
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +11 -3
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +303 -0
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/migration-routes.ts +40 -5
- package/src/runtime/routes/settings-routes.ts +22 -5
- package/src/runtime/routes/skills-routes.ts +76 -7
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +30 -2
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.ts +8 -1
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +344 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +49 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +50 -0
- package/src/security/oauth2.ts +26 -4
- package/src/security/secure-keys.ts +25 -2
- package/src/security/token-manager.ts +8 -0
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +64 -2
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +195 -0
- package/src/stt/stt-stream-session.ts +499 -0
- package/src/stt/types.ts +330 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +38 -14
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
- package/src/tools/browser/browser-execution.ts +1163 -23
- package/src/tools/browser/browser-manager.ts +45 -0
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +393 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +29 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1648 -32
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +264 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +183 -17
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +254 -21
- package/src/tools/browser/cdp-client/errors.ts +15 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +39 -16
- package/src/tools/browser/cdp-client/factory.ts +797 -87
- package/src/tools/browser/cdp-client/index.ts +16 -2
- package/src/tools/browser/cdp-client/types.ts +68 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +2 -0
- package/src/tools/skills/sandbox-runner.ts +3 -2
- package/src/tools/terminal/safe-env.ts +10 -2
- package/src/tools/terminal/shell.ts +15 -4
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +17 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tts/__tests__/provider-adapters.test.ts +834 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +201 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +42 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +153 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/platform.ts +54 -10
- package/src/util/pricing.ts +66 -3
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +23 -0
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/top-level-renderer.ts +13 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/cli/commands/browser-relay.ts +0 -466
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/runtime/routes/browser-cdp-routes.ts +0 -229
|
@@ -114,6 +114,30 @@ export class MessageQueue {
|
|
|
114
114
|
return item;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Read-only access to a queued message by index without mutating the queue.
|
|
119
|
+
* Returns `undefined` when the index is out of range.
|
|
120
|
+
*/
|
|
121
|
+
peek(index: number = 0): QueuedMessage | undefined {
|
|
122
|
+
return this.items[index];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Pop up to `count` messages FIFO and return them in order.
|
|
127
|
+
* Decrements the byte budget for each popped item using the same
|
|
128
|
+
* accounting as `shift` / `removeByRequestId`, keeping the bookkeeping
|
|
129
|
+
* centralized here rather than at call sites.
|
|
130
|
+
*/
|
|
131
|
+
shiftN(count: number): QueuedMessage[] {
|
|
132
|
+
const n = Math.min(Math.max(0, count), this.items.length);
|
|
133
|
+
if (n === 0) return [];
|
|
134
|
+
const removed = this.items.splice(0, n);
|
|
135
|
+
for (const item of removed) {
|
|
136
|
+
this.currentBytes -= estimateItemBytes(item);
|
|
137
|
+
}
|
|
138
|
+
return removed;
|
|
139
|
+
}
|
|
140
|
+
|
|
117
141
|
clear(): void {
|
|
118
142
|
this.items = [];
|
|
119
143
|
this.currentBytes = 0;
|
|
@@ -611,7 +611,8 @@ const PKB_SYSTEM_REMINDER =
|
|
|
611
611
|
"<system_reminder>" +
|
|
612
612
|
"\n**CRITICAL:** you MUST read any PKB files that might be relevant to this conversation — " +
|
|
613
613
|
"INDEX.md is your table of contents. Don't wait to be asked. " +
|
|
614
|
-
"Use `remember` OFTEN for EVERY new fact you learn IMMEDIATELY, don't wait for the next turn." +
|
|
614
|
+
"Use `remember` OFTEN for EVERY new fact you learn IMMEDIATELY, don't wait for the next turn. " +
|
|
615
|
+
"Corrections to things you had wrong are the highest-priority remembers — never skip them." +
|
|
615
616
|
"\n</system_reminder>";
|
|
616
617
|
|
|
617
618
|
/**
|
|
@@ -876,6 +877,12 @@ export interface UnifiedTurnContextOptions {
|
|
|
876
877
|
interfaceName?: string;
|
|
877
878
|
channelName?: string;
|
|
878
879
|
actorContext?: InboundActorContext | null;
|
|
880
|
+
/**
|
|
881
|
+
* Human-readable duration since the previous user message (e.g. "14h ago",
|
|
882
|
+
* "yesterday", "3d ago"). Only populated when the gap exceeds 12 hours so
|
|
883
|
+
* the model can acknowledge long absences; otherwise omitted.
|
|
884
|
+
*/
|
|
885
|
+
timeSinceLastMessage?: string | null;
|
|
879
886
|
}
|
|
880
887
|
|
|
881
888
|
/**
|
|
@@ -908,6 +915,9 @@ export function buildUnifiedTurnContextBlock(
|
|
|
908
915
|
|
|
909
916
|
const lines: string[] = ["<turn_context>"];
|
|
910
917
|
lines.push(`current_time: ${options.timestamp}`);
|
|
918
|
+
if (options.timeSinceLastMessage) {
|
|
919
|
+
lines.push(`time_since_last_message: ${options.timeSinceLastMessage}`);
|
|
920
|
+
}
|
|
911
921
|
if (options.interfaceName) {
|
|
912
922
|
lines.push(`interface: ${options.interfaceName}`);
|
|
913
923
|
}
|
|
@@ -172,6 +172,42 @@ function resolveCommandsList(context?: SlashContext): string[] {
|
|
|
172
172
|
];
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Pure classifier: returns the kind of slash resolution `resolveSlash` would
|
|
177
|
+
* produce for `content`, without triggering any side effects.
|
|
178
|
+
*
|
|
179
|
+
* Queue-drain lookahead (`buildPassthroughBatch`) uses this to decide whether
|
|
180
|
+
* to include a queued message in a contiguous passthrough batch. `resolveSlash`
|
|
181
|
+
* itself runs side effects (e.g. `/pair` registers a pairing request and
|
|
182
|
+
* writes a QR PNG), so calling it during lookahead and then again in the real
|
|
183
|
+
* drain would execute those side effects twice — the second call sees the
|
|
184
|
+
* first registration and fails with "active pairing already in progress".
|
|
185
|
+
*/
|
|
186
|
+
export function classifySlash(
|
|
187
|
+
content: string,
|
|
188
|
+
): "passthrough" | "compact" | "unknown" {
|
|
189
|
+
const trimmed = content.trim();
|
|
190
|
+
if (
|
|
191
|
+
trimmed === "/model" ||
|
|
192
|
+
(trimmed.startsWith("/model ") && trimmed !== "/models")
|
|
193
|
+
) {
|
|
194
|
+
return "unknown";
|
|
195
|
+
}
|
|
196
|
+
const shortcutMatch = trimmed.match(/^\/([a-z0-9-]+)(\s|$)/i);
|
|
197
|
+
if (
|
|
198
|
+
shortcutMatch &&
|
|
199
|
+
DEPRECATED_MODEL_SHORTCUTS.has(shortcutMatch[1].toLowerCase())
|
|
200
|
+
) {
|
|
201
|
+
return "unknown";
|
|
202
|
+
}
|
|
203
|
+
if (trimmed === "/models") return "unknown";
|
|
204
|
+
if (trimmed === "/pair") return "unknown";
|
|
205
|
+
if (trimmed === "/compact") return "compact";
|
|
206
|
+
if (trimmed === "/status") return "unknown";
|
|
207
|
+
if (trimmed === "/commands") return "unknown";
|
|
208
|
+
return "passthrough";
|
|
209
|
+
}
|
|
210
|
+
|
|
175
211
|
/**
|
|
176
212
|
* Resolve built-in slash commands (/models, /status, /commands, /compact, /pair).
|
|
177
213
|
* Returns `unknown` with a deterministic message, `compact` for forced compaction,
|
|
@@ -17,6 +17,8 @@ import type { ToolExecutionResult } from "../tools/types.js";
|
|
|
17
17
|
import { getLogger } from "../util/logger.js";
|
|
18
18
|
import { isPlainObject } from "../util/object.js";
|
|
19
19
|
import { buildConversationErrorMessage } from "./conversation-error.js";
|
|
20
|
+
import { launchConversation } from "./conversation-launch.js";
|
|
21
|
+
import type { TrustContext } from "./conversation-runtime-assembly.js";
|
|
20
22
|
import type {
|
|
21
23
|
CardSurfaceData,
|
|
22
24
|
DynamicPageSurfaceData,
|
|
@@ -234,6 +236,10 @@ function normalizeTaskProgressCardPatch(
|
|
|
234
236
|
*/
|
|
235
237
|
export interface SurfaceConversationContext {
|
|
236
238
|
readonly conversationId: string;
|
|
239
|
+
/** Assistant id (if known) — used when publishing launch-triggered events. */
|
|
240
|
+
readonly assistantId?: string;
|
|
241
|
+
/** Inherited to spawned conversations in the `launch_conversation` action path. */
|
|
242
|
+
readonly trustContext?: TrustContext;
|
|
237
243
|
readonly channelCapabilities?: {
|
|
238
244
|
channel: string;
|
|
239
245
|
supportsDynamicUi: boolean;
|
|
@@ -278,6 +284,7 @@ export interface SurfaceConversationContext {
|
|
|
278
284
|
data?: Record<string, unknown>;
|
|
279
285
|
}>;
|
|
280
286
|
display?: string;
|
|
287
|
+
persistent?: boolean;
|
|
281
288
|
}>;
|
|
282
289
|
/** Optional proxy for delegating computer-use actions to a connected desktop client. */
|
|
283
290
|
hostCuProxy?: import("./host-cu-proxy.js").HostCuProxy;
|
|
@@ -645,12 +652,75 @@ export function buildDeselectionDescription(
|
|
|
645
652
|
return "";
|
|
646
653
|
}
|
|
647
654
|
|
|
648
|
-
export
|
|
655
|
+
export type SurfaceActionResult =
|
|
656
|
+
| { accepted: true; conversationId: string }
|
|
657
|
+
| { accepted: false; error: string }
|
|
658
|
+
| void;
|
|
659
|
+
|
|
660
|
+
export async function handleSurfaceAction(
|
|
649
661
|
ctx: SurfaceConversationContext,
|
|
650
662
|
surfaceId: string,
|
|
651
663
|
actionId: string,
|
|
652
664
|
data?: Record<string, unknown>,
|
|
653
|
-
):
|
|
665
|
+
): Promise<SurfaceActionResult> {
|
|
666
|
+
// `launch_conversation` actions spawn a fresh conversation inline instead
|
|
667
|
+
// of round-tripping through the LLM with a `[User action on card surface:
|
|
668
|
+
// ...]` chat message. This dispatch must run BEFORE the pending-vs-not
|
|
669
|
+
// branching below: `ui_show` unconditionally calls
|
|
670
|
+
// `pendingSurfaceActions.set(...)` for any interactive card (regardless of
|
|
671
|
+
// the `persistent` flag), so on the very first click of a freshly-rendered
|
|
672
|
+
// launcher card `pending` is already set. Without this hoist the launch
|
|
673
|
+
// branch would fall through into the pending path and the LLM round-trip
|
|
674
|
+
// would happen on every click.
|
|
675
|
+
if (
|
|
676
|
+
data &&
|
|
677
|
+
typeof data === "object" &&
|
|
678
|
+
(data as Record<string, unknown>)._action === "launch_conversation"
|
|
679
|
+
) {
|
|
680
|
+
const payload = data as Record<string, unknown>;
|
|
681
|
+
const title = typeof payload.title === "string" ? payload.title : "";
|
|
682
|
+
const seedPrompt =
|
|
683
|
+
typeof payload.seedPrompt === "string" ? payload.seedPrompt : "";
|
|
684
|
+
const anchorMessageId =
|
|
685
|
+
typeof payload.anchorMessageId === "string"
|
|
686
|
+
? payload.anchorMessageId
|
|
687
|
+
: undefined;
|
|
688
|
+
if (!title || !seedPrompt) {
|
|
689
|
+
return { accepted: false, error: "missing_title_or_seedPrompt" };
|
|
690
|
+
}
|
|
691
|
+
// Launch actions don't consume the surface — persistent launcher cards
|
|
692
|
+
// keep accepting clicks afterward. Drop the pending entry (if any) so
|
|
693
|
+
// sibling button presses on the same card aren't blocked behind a stale
|
|
694
|
+
// expectation that this surface still owes an answer to the LLM.
|
|
695
|
+
ctx.pendingSurfaceActions.delete(surfaceId);
|
|
696
|
+
// `ctx` is the origin Conversation — inherit its trust context so the
|
|
697
|
+
// spawned conversation keeps guardian / trust-class state.
|
|
698
|
+
//
|
|
699
|
+
// `launchConversation` is the sole emitter of `open_conversation` for
|
|
700
|
+
// this path. We pass `focus: false` so the client registers a sidebar
|
|
701
|
+
// entry for the spawned conversation without switching focus away from
|
|
702
|
+
// the origin — critical for fan-out UX where one click launches
|
|
703
|
+
// multiple conversations.
|
|
704
|
+
//
|
|
705
|
+
// The helper also kicks off the seed turn fire-and-forget, so this
|
|
706
|
+
// `await` resolves as soon as the conversation is created + titled +
|
|
707
|
+
// published to the event hub. The HTTP POST /v1/surface-actions
|
|
708
|
+
// response returns promptly — the seed turn runs in the background.
|
|
709
|
+
const originTrustContext = ctx.trustContext;
|
|
710
|
+
const { conversationId } = await launchConversation({
|
|
711
|
+
title,
|
|
712
|
+
seedPrompt,
|
|
713
|
+
focus: false,
|
|
714
|
+
...(anchorMessageId ? { anchorMessageId } : {}),
|
|
715
|
+
...(originTrustContext ? { originTrustContext } : {}),
|
|
716
|
+
});
|
|
717
|
+
log.info(
|
|
718
|
+
{ originConversationId: ctx.conversationId, conversationId, surfaceId },
|
|
719
|
+
"launch_conversation dispatched inline from surface action",
|
|
720
|
+
);
|
|
721
|
+
return { accepted: true, conversationId };
|
|
722
|
+
}
|
|
723
|
+
|
|
654
724
|
const pending = ctx.pendingSurfaceActions.get(surfaceId);
|
|
655
725
|
|
|
656
726
|
// When surfaces are restored from history (e.g. onboarding cards), there is
|
|
@@ -1202,7 +1272,13 @@ export function buildCompletionSummary(
|
|
|
1202
1272
|
: undefined;
|
|
1203
1273
|
return cancelLabel ? `User chose: "${cancelLabel}"` : "Cancelled";
|
|
1204
1274
|
}
|
|
1205
|
-
if (actionId === "confirm")
|
|
1275
|
+
if (actionId === "confirm") {
|
|
1276
|
+
const confirmLabel =
|
|
1277
|
+
typeof surfaceData?.confirmLabel === "string"
|
|
1278
|
+
? surfaceData.confirmLabel
|
|
1279
|
+
: undefined;
|
|
1280
|
+
return confirmLabel ? `User chose: "${confirmLabel}"` : "Confirmed";
|
|
1281
|
+
}
|
|
1206
1282
|
// Preserve the actual action ID so the LLM knows the user's exact choice
|
|
1207
1283
|
// (e.g. "deny", "no", "reject") rather than misreporting it as confirmed.
|
|
1208
1284
|
return `User selected: ${actionId}`;
|
|
@@ -1249,7 +1325,13 @@ export function buildUserFacingLabel(
|
|
|
1249
1325
|
: undefined;
|
|
1250
1326
|
return cancelLabel ?? "Cancelled";
|
|
1251
1327
|
}
|
|
1252
|
-
if (actionId === "confirm")
|
|
1328
|
+
if (actionId === "confirm") {
|
|
1329
|
+
const confirmLabel =
|
|
1330
|
+
typeof surfaceData?.confirmLabel === "string"
|
|
1331
|
+
? surfaceData.confirmLabel
|
|
1332
|
+
: undefined;
|
|
1333
|
+
return confirmLabel ?? "Confirmed";
|
|
1334
|
+
}
|
|
1253
1335
|
return `Selected: ${actionId}`;
|
|
1254
1336
|
}
|
|
1255
1337
|
if (surfaceType === "form") return "Submitted";
|
|
@@ -1378,6 +1460,11 @@ export async function surfaceProxyResolver(
|
|
|
1378
1460
|
}
|
|
1379
1461
|
|
|
1380
1462
|
const display = (input.display as string) === "panel" ? "panel" : "inline";
|
|
1463
|
+
// `persistent: true` keeps the card visible through action clicks (only
|
|
1464
|
+
// marks the clicked action as spent). Forward the flag so
|
|
1465
|
+
// `SurfaceManager.showSurface` on the client sees it — without this the
|
|
1466
|
+
// field is dropped and every card dismisses on first click.
|
|
1467
|
+
const persistent = input.persistent === true ? true : undefined;
|
|
1381
1468
|
|
|
1382
1469
|
const mappedActions = actions?.map((a) => ({
|
|
1383
1470
|
id: a.id,
|
|
@@ -1406,6 +1493,7 @@ export async function surfaceProxyResolver(
|
|
|
1406
1493
|
dataKeys: Object.keys(data),
|
|
1407
1494
|
actionCount: mappedActions?.length ?? 0,
|
|
1408
1495
|
display,
|
|
1496
|
+
persistent: persistent ?? false,
|
|
1409
1497
|
conversationId: ctx.conversationId,
|
|
1410
1498
|
},
|
|
1411
1499
|
"Sending ui_surface_show to client",
|
|
@@ -1420,6 +1508,7 @@ export async function surfaceProxyResolver(
|
|
|
1420
1508
|
data,
|
|
1421
1509
|
actions: mappedActions,
|
|
1422
1510
|
display,
|
|
1511
|
+
...(persistent ? { persistent: true } : {}),
|
|
1423
1512
|
} as unknown as UiSurfaceShow);
|
|
1424
1513
|
|
|
1425
1514
|
// Track surface for persistence with the message
|
|
@@ -1430,6 +1519,7 @@ export async function surfaceProxyResolver(
|
|
|
1430
1519
|
data,
|
|
1431
1520
|
actions: mappedActions,
|
|
1432
1521
|
display,
|
|
1522
|
+
...(persistent ? { persistent: true } : {}),
|
|
1433
1523
|
});
|
|
1434
1524
|
|
|
1435
1525
|
if (awaitAction) {
|
|
@@ -30,6 +30,7 @@ import { isAllowDecision } from "../permissions/types.js";
|
|
|
30
30
|
import { isPermissionControlsV2Enabled } from "../permissions/v2-consent-policy.js";
|
|
31
31
|
import type { Message, ToolDefinition } from "../providers/types.js";
|
|
32
32
|
import type { TrustClass } from "../runtime/actor-trust-resolver.js";
|
|
33
|
+
import { getTaskRunRules } from "../tasks/ephemeral-permissions.js";
|
|
33
34
|
import { coreAppProxyTools } from "../tools/apps/definitions.js";
|
|
34
35
|
import { registerConversationSender } from "../tools/browser/browser-screencast.js";
|
|
35
36
|
import type { ToolExecutor } from "../tools/executor.js";
|
|
@@ -118,6 +119,8 @@ export interface ToolSetupContext extends SurfaceConversationContext {
|
|
|
118
119
|
hostFileProxy?: import("./host-file-proxy.js").HostFileProxy;
|
|
119
120
|
/** CES RPC client for credential execution operations. Injected when CES tools are enabled and the CES process is available. */
|
|
120
121
|
cesClient?: CesClient;
|
|
122
|
+
/** The interface ID of the connected client driving the current turn (e.g. "macos", "chrome-extension"). Propagated into ToolContext for browser backend selection. */
|
|
123
|
+
readonly transportInterface?: InterfaceId;
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
// ── buildToolDefinitions ─────────────────────────────────────────────
|
|
@@ -170,6 +173,15 @@ export function createToolExecutor(
|
|
|
170
173
|
markDoordashStepInProgress(ctx, input);
|
|
171
174
|
}
|
|
172
175
|
|
|
176
|
+
// Unwrap skill_execute dispatch so downstream context (notably
|
|
177
|
+
// batchAuthorizedByTask) is keyed on the tool that will actually run.
|
|
178
|
+
// Task rules in required_tools contain underlying tool names (e.g.
|
|
179
|
+
// "gmail_archive"), never the outer "skill_execute" dispatcher.
|
|
180
|
+
const effectiveToolName =
|
|
181
|
+
name === "skill_execute" && typeof input.tool === "string" && input.tool
|
|
182
|
+
? input.tool
|
|
183
|
+
: name;
|
|
184
|
+
|
|
173
185
|
// Build the context object shared by both the skill_execute interception
|
|
174
186
|
// path and the regular executor path.
|
|
175
187
|
const toolContext: ToolContext = {
|
|
@@ -183,6 +195,17 @@ export function createToolExecutor(
|
|
|
183
195
|
callSessionId: ctx.callSessionId,
|
|
184
196
|
triggeredBySurfaceAction:
|
|
185
197
|
ctx.surfaceActionRequestIds?.has(ctx.currentRequestId ?? "") ?? false,
|
|
198
|
+
// A task without required_tools entries (e.g. ad-hoc tasks created with
|
|
199
|
+
// omitted/empty required_tools, or legacy rows where it was never
|
|
200
|
+
// populated) correctly gets no batch authorization — that's the
|
|
201
|
+
// intended stricter contract this check enforces, not a regression to
|
|
202
|
+
// paper over. Batch tools gate themselves via this flag; callers that
|
|
203
|
+
// never declared the tool shouldn't get blanket authorization.
|
|
204
|
+
batchAuthorizedByTask:
|
|
205
|
+
ctx.taskRunId != null &&
|
|
206
|
+
getTaskRunRules(ctx.taskRunId).some(
|
|
207
|
+
(r) => r.tool === effectiveToolName,
|
|
208
|
+
),
|
|
186
209
|
requesterExternalUserId: ctx.trustContext?.requesterExternalUserId,
|
|
187
210
|
requesterChatId: ctx.trustContext?.requesterChatId,
|
|
188
211
|
requesterIdentifier: ctx.trustContext?.requesterIdentifier,
|
|
@@ -202,6 +225,7 @@ export function createToolExecutor(
|
|
|
202
225
|
hostFileProxy: ctx.hostFileProxy,
|
|
203
226
|
isPlatformHosted: getIsPlatform(),
|
|
204
227
|
cesClient: ctx.cesClient,
|
|
228
|
+
transportInterface: ctx.transportInterface,
|
|
205
229
|
onToolLifecycleEvent: handleToolLifecycleEvent,
|
|
206
230
|
sendToClient: (msg) => {
|
|
207
231
|
// Tool context's sendToClient uses a loose { type: string; [key: string]: unknown }
|
|
@@ -216,6 +240,7 @@ export function createToolExecutor(
|
|
|
216
240
|
data: s.data,
|
|
217
241
|
actions: s.actions,
|
|
218
242
|
display: s.display,
|
|
243
|
+
...(s.persistent ? { persistent: true } : {}),
|
|
219
244
|
});
|
|
220
245
|
}
|
|
221
246
|
},
|
|
@@ -8,7 +8,10 @@ import type {
|
|
|
8
8
|
PricingUsage,
|
|
9
9
|
} from "../usage/types.js";
|
|
10
10
|
import { getLogger } from "../util/logger.js";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
resolvePricingForUsageWithOverrides,
|
|
13
|
+
usesAnthropicPricingRules,
|
|
14
|
+
} from "../util/pricing.js";
|
|
12
15
|
import type { ServerMessage, UsageStats } from "./message-protocol.js";
|
|
13
16
|
|
|
14
17
|
const log = getLogger("conversation-usage");
|
|
@@ -142,16 +145,16 @@ export function recordUsage(
|
|
|
142
145
|
0,
|
|
143
146
|
);
|
|
144
147
|
|
|
145
|
-
const
|
|
148
|
+
const useAnthropicRules = usesAnthropicPricingRules(ctx.providerName, model);
|
|
146
149
|
const pricingUsage: PricingUsage = {
|
|
147
150
|
directInputTokens,
|
|
148
151
|
outputTokens,
|
|
149
152
|
cacheCreationInputTokens: normalizedCacheCreationInputTokens,
|
|
150
153
|
cacheReadInputTokens: normalizedCacheReadInputTokens,
|
|
151
|
-
anthropicCacheCreation:
|
|
154
|
+
anthropicCacheCreation: useAnthropicRules
|
|
152
155
|
? extractAnthropicCacheCreation(rawResponse)
|
|
153
156
|
: null,
|
|
154
|
-
speed:
|
|
157
|
+
speed: useAnthropicRules ? extractAnthropicSpeed(rawResponse) : null,
|
|
155
158
|
};
|
|
156
159
|
const pricing = resolveStructuredPricing(
|
|
157
160
|
ctx.providerName,
|
|
@@ -28,6 +28,7 @@ import type { Speed } from "../config/schemas/inference.js";
|
|
|
28
28
|
import {
|
|
29
29
|
ContextWindowManager,
|
|
30
30
|
type ContextWindowResult,
|
|
31
|
+
getSummaryFromContextMessage,
|
|
31
32
|
} from "../context/window-manager.js";
|
|
32
33
|
import type { CesClient } from "../credential-execution/client.js";
|
|
33
34
|
import { EventBus } from "../events/bus.js";
|
|
@@ -43,6 +44,7 @@ import {
|
|
|
43
44
|
} from "../events/tool-profiling-listener.js";
|
|
44
45
|
import { registerToolTraceListener } from "../events/tool-trace-listener.js";
|
|
45
46
|
import { getHookManager } from "../hooks/manager.js";
|
|
47
|
+
import { enqueueAutoAnalysisOnCompaction } from "../memory/auto-analysis-enqueue.js";
|
|
46
48
|
import { resolveCanonicalGuardianRequest } from "../memory/canonical-guardian-store.js";
|
|
47
49
|
import {
|
|
48
50
|
updateConversationContextWindow,
|
|
@@ -60,13 +62,16 @@ import {
|
|
|
60
62
|
} from "../permissions/v2-consent-policy.js";
|
|
61
63
|
import { resolvePersonaContext } from "../prompts/persona-resolver.js";
|
|
62
64
|
import { buildSystemPrompt } from "../prompts/system-prompt.js";
|
|
63
|
-
import
|
|
65
|
+
import { resolveModelIntent } from "../providers/model-intents.js";
|
|
66
|
+
import type { Message, ModelIntent } from "../providers/types.js";
|
|
64
67
|
import type { Provider } from "../providers/types.js";
|
|
65
68
|
import type { TrustClass } from "../runtime/actor-trust-resolver.js";
|
|
66
69
|
import type { AuthContext } from "../runtime/auth/types.js";
|
|
67
70
|
import * as approvalOverrides from "../runtime/conversation-approval-overrides.js";
|
|
68
71
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
69
72
|
import { ToolExecutor } from "../tools/executor.js";
|
|
73
|
+
import type { OnboardingContext } from "../types/onboarding-context.js";
|
|
74
|
+
import type { AbortReason } from "../util/abort-reasons.js";
|
|
70
75
|
import { getLogger } from "../util/logger.js";
|
|
71
76
|
import type { AssistantAttachmentDraft } from "./assistant-attachments.js";
|
|
72
77
|
import { runAgentLoopImpl } from "./conversation-agent-loop.js";
|
|
@@ -104,6 +109,7 @@ import {
|
|
|
104
109
|
createSurfaceMutex,
|
|
105
110
|
handleSurfaceAction as handleSurfaceActionImpl,
|
|
106
111
|
handleSurfaceUndo as handleSurfaceUndoImpl,
|
|
112
|
+
type SurfaceActionResult,
|
|
107
113
|
} from "./conversation-surfaces.js";
|
|
108
114
|
import type { ToolSetupContext } from "./conversation-tool-setup.js";
|
|
109
115
|
import {
|
|
@@ -196,15 +202,15 @@ export class Conversation {
|
|
|
196
202
|
/** @internal */ hostFileProxy?: HostFileProxy;
|
|
197
203
|
/**
|
|
198
204
|
* Optional override sender used by `restoreBrowserProxyAvailability` so
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* the SSE hub) can preserve their registry-routed sender across drain
|
|
202
|
-
* queue restores. When set, `restoreBrowserProxyAvailability()` uses this
|
|
205
|
+
* registry-routed transports can preserve their sender across drain queue
|
|
206
|
+
* restores. When set, `restoreBrowserProxyAvailability()` uses this
|
|
203
207
|
* function instead of `sendToClient` so the drain-queue path doesn't
|
|
204
|
-
* clobber the
|
|
208
|
+
* clobber the registry-routed sender with the SSE hub emitter.
|
|
205
209
|
*
|
|
206
|
-
* Populated by the POST /messages handler
|
|
207
|
-
*
|
|
210
|
+
* Populated by the POST /messages handler when the guardian has an active
|
|
211
|
+
* extension connection in the `ChromeExtensionRegistry`, regardless of
|
|
212
|
+
* interface (chrome-extension, macOS, etc.). Cleared when a turn without
|
|
213
|
+
* an active extension connection takes over.
|
|
208
214
|
*/
|
|
209
215
|
/** @internal */ hostBrowserSenderOverride?: (msg: ServerMessage) => void;
|
|
210
216
|
/** @internal */ cesClient?: CesClient;
|
|
@@ -268,6 +274,7 @@ export class Conversation {
|
|
|
268
274
|
data: SurfaceData;
|
|
269
275
|
actions?: Array<{ id: string; label: string; style?: string }>;
|
|
270
276
|
display?: string;
|
|
277
|
+
persistent?: boolean;
|
|
271
278
|
}> = [];
|
|
272
279
|
/** @internal */ workspaceTopLevelContext: string | null = null;
|
|
273
280
|
/** @internal */ workspaceTopLevelDirty = true;
|
|
@@ -297,6 +304,14 @@ export class Conversation {
|
|
|
297
304
|
/** @internal */ turnCount = 0;
|
|
298
305
|
public lastAssistantAttachments: AssistantAttachmentDraft[] = [];
|
|
299
306
|
public lastAttachmentWarnings: string[] = [];
|
|
307
|
+
/**
|
|
308
|
+
* Pre-chat onboarding context provided by the native client.
|
|
309
|
+
* In-memory only — not persisted to the DB. Only relevant for the first
|
|
310
|
+
* turn of a brand-new conversation so the system prompt can personalize
|
|
311
|
+
* the opener and skip redundant discovery.
|
|
312
|
+
* @internal
|
|
313
|
+
*/
|
|
314
|
+
private onboardingContext?: OnboardingContext;
|
|
300
315
|
/** @internal */ currentTurnChannelContext: TurnChannelContext | null = null;
|
|
301
316
|
/** @internal */ currentTurnInterfaceContext: TurnInterfaceContext | null =
|
|
302
317
|
null;
|
|
@@ -323,6 +338,8 @@ export class Conversation {
|
|
|
323
338
|
sharedCesClient?: CesClient,
|
|
324
339
|
speedOverride?: Speed,
|
|
325
340
|
cacheTtl?: "5m" | "1h",
|
|
341
|
+
modelIntent?: ModelIntent,
|
|
342
|
+
modelOverride?: string,
|
|
326
343
|
) {
|
|
327
344
|
this.conversationId = conversationId;
|
|
328
345
|
this.systemPrompt = systemPrompt;
|
|
@@ -424,10 +441,18 @@ export class Conversation {
|
|
|
424
441
|
const hasSystemPromptOverride = systemPrompt !== buildSystemPrompt();
|
|
425
442
|
this.hasSystemPromptOverride = hasSystemPromptOverride;
|
|
426
443
|
|
|
444
|
+
// If an explicit modelOverride is supplied, use it verbatim. Otherwise,
|
|
445
|
+
// if modelIntent is set, resolve it against the active provider's
|
|
446
|
+
// intent → model mapping. The AgentLoop passes the resulting string
|
|
447
|
+
// through to `providerConfig.model` on every turn.
|
|
448
|
+
const resolvedModel: string | undefined =
|
|
449
|
+
modelOverride ??
|
|
450
|
+
(modelIntent ? resolveModelIntent(provider.name, modelIntent) : undefined);
|
|
451
|
+
|
|
427
452
|
const resolveSystemPromptCallback = (
|
|
428
453
|
_history: import("../providers/types.js").Message[],
|
|
429
454
|
): ResolvedSystemPrompt => {
|
|
430
|
-
const resolved = {
|
|
455
|
+
const resolved: ResolvedSystemPrompt = {
|
|
431
456
|
systemPrompt: this.hasSystemPromptOverride
|
|
432
457
|
? systemPrompt
|
|
433
458
|
: (() => {
|
|
@@ -440,10 +465,14 @@ export class Conversation {
|
|
|
440
465
|
userPersona: persona.userPersona,
|
|
441
466
|
channelPersona: persona.channelPersona,
|
|
442
467
|
userSlug: persona.userSlug,
|
|
468
|
+
onboardingContext: this.getOnboardingContext(),
|
|
443
469
|
});
|
|
444
470
|
})(),
|
|
445
471
|
maxTokens: configuredMaxTokens,
|
|
446
472
|
};
|
|
473
|
+
if (resolvedModel !== undefined) {
|
|
474
|
+
resolved.model = resolvedModel;
|
|
475
|
+
}
|
|
447
476
|
return resolved;
|
|
448
477
|
};
|
|
449
478
|
|
|
@@ -481,6 +510,16 @@ export class Conversation {
|
|
|
481
510
|
});
|
|
482
511
|
}
|
|
483
512
|
|
|
513
|
+
// ── Onboarding context ───────────────────────────────────────────
|
|
514
|
+
|
|
515
|
+
setOnboardingContext(ctx: OnboardingContext): void {
|
|
516
|
+
this.onboardingContext = ctx;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
getOnboardingContext(): OnboardingContext | undefined {
|
|
520
|
+
return this.onboardingContext;
|
|
521
|
+
}
|
|
522
|
+
|
|
484
523
|
// ── Lifecycle ────────────────────────────────────────────────────
|
|
485
524
|
|
|
486
525
|
async loadFromDb(): Promise<void> {
|
|
@@ -574,21 +613,31 @@ export class Conversation {
|
|
|
574
613
|
this.hostFileProxy?.updateSender(this.sendToClient, false);
|
|
575
614
|
}
|
|
576
615
|
|
|
577
|
-
/**
|
|
578
|
-
|
|
616
|
+
/**
|
|
617
|
+
* Restore host proxy availability based on whether a real client is connected.
|
|
618
|
+
* When `skipBrowser` is true, the browser proxy is left untouched — use this
|
|
619
|
+
* when `restoreBrowserProxyAvailability()` will handle the browser proxy
|
|
620
|
+
* separately with the correct registry-routed sender.
|
|
621
|
+
*/
|
|
622
|
+
restoreProxyAvailability(options?: { skipBrowser?: boolean }): void {
|
|
579
623
|
if (!this.hasNoClient) {
|
|
580
624
|
this.hostBashProxy?.updateSender(this.sendToClient, true);
|
|
581
|
-
|
|
625
|
+
if (!options?.skipBrowser) {
|
|
626
|
+
this.hostBrowserProxy?.updateSender(this.sendToClient, true);
|
|
627
|
+
}
|
|
582
628
|
this.hostCuProxy?.updateSender(this.sendToClient, true);
|
|
583
629
|
this.hostFileProxy?.updateSender(this.sendToClient, true);
|
|
584
630
|
}
|
|
585
631
|
}
|
|
586
632
|
|
|
587
633
|
/**
|
|
588
|
-
* Restore host browser proxy availability only. Used for
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
634
|
+
* Restore host browser proxy availability only. Used for interfaces that
|
|
635
|
+
* support host_browser but not the full desktop proxy set, so calling
|
|
636
|
+
* restoreProxyAvailability() would incorrectly re-enable bash/file/CU
|
|
637
|
+
* proxies that should stay disabled. Applicable to chrome-extension turns
|
|
638
|
+
* (which only support host_browser) and macOS turns with an active
|
|
639
|
+
* extension connection (which route browser tools through the extension
|
|
640
|
+
* registry instead of cdp-inspect/local).
|
|
592
641
|
*
|
|
593
642
|
* Unlike `restoreProxyAvailability()`, this helper does NOT gate on
|
|
594
643
|
* `hasNoClient`. The chrome-extension interface is non-interactive (so
|
|
@@ -599,16 +648,16 @@ export class Conversation {
|
|
|
599
648
|
* incorrectly enable host_bash/host_file/host_cu tool gating downstream.
|
|
600
649
|
*
|
|
601
650
|
* When `hostBrowserSenderOverride` is set, that function is used as the
|
|
602
|
-
* sender instead of `sendToClient`. This is required for
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
* reaching the extension.
|
|
651
|
+
* sender instead of `sendToClient`. This is required for any interface
|
|
652
|
+
* whose host_browser frames route through the ChromeExtensionRegistry
|
|
653
|
+
* WebSocket rather than the SSE hub: if the queue-drain path called this
|
|
654
|
+
* helper with `sendToClient`, the registry-routed sender established at
|
|
655
|
+
* turn-start would be clobbered by the SSE hub emitter and
|
|
656
|
+
* host_browser_request frames would stop reaching the extension.
|
|
609
657
|
*
|
|
610
658
|
* Callers must only invoke this when they know the current interface
|
|
611
|
-
* supports host_browser (see `supportsHostProxy(id, "host_browser")`)
|
|
659
|
+
* supports host_browser (see `supportsHostProxy(id, "host_browser")`)
|
|
660
|
+
* or has an active extension connection with a registry-routed sender.
|
|
612
661
|
*/
|
|
613
662
|
restoreBrowserProxyAvailability(): void {
|
|
614
663
|
const sender = this.hostBrowserSenderOverride ?? this.sendToClient;
|
|
@@ -642,6 +691,8 @@ export class Conversation {
|
|
|
642
691
|
}
|
|
643
692
|
this.messages = [...messages];
|
|
644
693
|
this.contextWindowManager.nonPersistedPrefixCount = messages.length;
|
|
694
|
+
this.contextWindowManager.summaryIsInjected =
|
|
695
|
+
getSummaryFromContextMessage(messages[0]) != null;
|
|
645
696
|
}
|
|
646
697
|
|
|
647
698
|
/**
|
|
@@ -667,8 +718,8 @@ export class Conversation {
|
|
|
667
718
|
return this.stale;
|
|
668
719
|
}
|
|
669
720
|
|
|
670
|
-
abort(): void {
|
|
671
|
-
abortConversation(this);
|
|
721
|
+
abort(reason?: AbortReason): void {
|
|
722
|
+
abortConversation(this, reason);
|
|
672
723
|
}
|
|
673
724
|
|
|
674
725
|
dispose(): void {
|
|
@@ -1130,6 +1181,13 @@ export class Conversation {
|
|
|
1130
1181
|
result.summaryText,
|
|
1131
1182
|
this.contextCompactedMessageCount,
|
|
1132
1183
|
);
|
|
1184
|
+
// Fire auto-analysis on compaction so the reflective agent can
|
|
1185
|
+
// crystallize anything worth remembering before the context window
|
|
1186
|
+
// narrows further.
|
|
1187
|
+
enqueueAutoAnalysisOnCompaction(
|
|
1188
|
+
this.conversationId,
|
|
1189
|
+
this.trustContext?.trustClass,
|
|
1190
|
+
);
|
|
1133
1191
|
}
|
|
1134
1192
|
return result;
|
|
1135
1193
|
}
|
|
@@ -1334,8 +1392,8 @@ export class Conversation {
|
|
|
1334
1392
|
surfaceId: string,
|
|
1335
1393
|
actionId: string,
|
|
1336
1394
|
data?: Record<string, unknown>,
|
|
1337
|
-
):
|
|
1338
|
-
handleSurfaceActionImpl(this, surfaceId, actionId, data);
|
|
1395
|
+
): Promise<SurfaceActionResult> {
|
|
1396
|
+
return handleSurfaceActionImpl(this, surfaceId, actionId, data);
|
|
1339
1397
|
}
|
|
1340
1398
|
|
|
1341
1399
|
handleSurfaceUndo(surfaceId: string): void {
|