@vellumai/assistant 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +273 -10
- package/Dockerfile +2 -3
- package/bun.lock +41 -49
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/stt-provider-onboarding.md +120 -0
- package/knip.json +12 -2
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +3 -3
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +1111 -86
- package/package.json +40 -42
- package/scripts/generate-openapi.ts +0 -2
- package/scripts/test.sh +73 -18
- package/src/__tests__/acp-session.test.ts +43 -0
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop.test.ts +123 -0
- package/src/__tests__/anthropic-provider.test.ts +263 -10
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +240 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/browser-skill-endstate.test.ts +31 -7
- package/src/__tests__/btw-routes.test.ts +7 -0
- package/src/__tests__/call-controller.test.ts +581 -20
- package/src/__tests__/catalog-files.test.ts +1000 -0
- package/src/__tests__/channel-approvals.test.ts +53 -0
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/checker.test.ts +157 -10
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/config-analysis.test.ts +100 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +1248 -224
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- package/src/__tests__/context-window-manager.test.ts +88 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +99 -3
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +290 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +12 -4
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +946 -62
- package/src/__tests__/conversation-routes-disk-view.test.ts +275 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +324 -46
- package/src/__tests__/conversation-skill-tools.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +89 -18
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +6 -3
- package/src/__tests__/credential-vault-unit.test.ts +383 -7
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +42 -18
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/date-context.test.ts +4 -4
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +222 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +386 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +2 -0
- package/src/__tests__/gemini-provider.test.ts +66 -2
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
- package/src/__tests__/gmail-archive-gate.test.ts +246 -0
- package/src/__tests__/gmail-preferences.test.ts +117 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +738 -359
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +528 -49
- package/src/__tests__/headless-browser-read-tools.test.ts +274 -100
- package/src/__tests__/headless-browser-snapshot.test.ts +250 -77
- package/src/__tests__/heartbeat-service.test.ts +70 -17
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +145 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +596 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +423 -0
- package/src/__tests__/host-cu-proxy.test.ts +166 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/llm-context-normalization.test.ts +488 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +67 -8
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +109 -7
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +2 -2
- package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +18 -12
- package/src/__tests__/oauth-cli.test.ts +709 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +118 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +147 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +52 -14
- package/src/__tests__/oauth-store.test.ts +1465 -176
- package/src/__tests__/oauth2-gateway-transport.test.ts +460 -26
- package/src/__tests__/onboarding-template-contract.test.ts +81 -70
- package/src/__tests__/openai-provider.test.ts +178 -2
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1105 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outlook-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +32 -3
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +343 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -0
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +423 -5
- package/src/__tests__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/secret-scanner-executor.test.ts +4 -0
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +8 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +801 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +738 -0
- package/src/__tests__/skills.test.ts +5 -2
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +576 -16
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +184 -27
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +25 -5
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +33 -24
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-format.test.ts +59 -0
- package/src/__tests__/update-bulletin.test.ts +206 -5
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-policy.test.ts +2 -0
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +55 -9
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- package/src/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -0
- package/src/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +8 -1
- package/src/channels/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +69 -3
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +22 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +37 -4
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/conversations.ts +77 -0
- package/src/cli/commands/credentials.ts +3 -4
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +273 -16
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +56 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +32 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +330 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +117 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +215 -36
- package/src/cli/commands/oauth/shared.ts +7 -6
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +254 -0
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
- package/src/cli/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -0
- package/src/cli/program.ts +30 -4
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +141 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- package/src/config/bundled-skills/browser/SKILL.md +30 -5
- package/src/config/bundled-skills/browser/TOOLS.json +123 -0
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
- package/src/config/bundled-skills/contacts/SKILL.md +5 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +54 -8
- package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/outlook/SKILL.md +9 -2
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/slack/SKILL.md +1 -0
- package/src/config/bundled-skills/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +8 -0
- package/src/config/env-registry.ts +38 -0
- package/src/config/env.ts +49 -4
- package/src/config/feature-flag-registry.json +85 -14
- package/src/config/loader.ts +82 -13
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +81 -15
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +51 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -26
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +47 -7
- package/src/config/schemas/heartbeat.ts +27 -5
- package/src/config/schemas/host-browser.ts +112 -0
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +52 -0
- package/src/config/schemas/stt.ts +59 -0
- package/src/config/schemas/tts.ts +230 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/skills.ts +4 -0
- package/src/config/types.ts +4 -1
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/post-turn-tool-result-truncation.ts +177 -0
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +61 -10
- package/src/credential-execution/approval-bridge.ts +49 -15
- package/src/credential-execution/executable-discovery.ts +12 -2
- package/src/credential-execution/process-manager.ts +33 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +195 -0
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +23 -2
- package/src/daemon/conversation-agent-loop.ts +153 -42
- package/src/daemon/conversation-attachments.ts +40 -0
- package/src/daemon/conversation-error.ts +11 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +59 -9
- package/src/daemon/conversation-messaging.ts +37 -3
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +622 -13
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +128 -36
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +131 -40
- package/src/daemon/conversation-tool-setup.ts +99 -8
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +292 -16
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +13 -141
- package/src/daemon/handlers/shared.ts +80 -0
- package/src/daemon/handlers/skills.ts +483 -44
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +192 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +179 -28
- package/src/daemon/message-protocol.ts +13 -0
- package/src/daemon/message-types/conversations.ts +89 -14
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +19 -5
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +26 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +439 -14
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/transport-hints.ts +5 -24
- package/src/email/html-renderer.ts +76 -0
- package/src/heartbeat/heartbeat-service.ts +93 -7
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +194 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +398 -0
- package/src/home/assistant-feed-authoring.ts +124 -0
- package/src/home/emit-feed-event.ts +158 -0
- package/src/home/feed-scheduler.ts +247 -0
- package/src/home/feed-types.ts +181 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +384 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +30 -20
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/cli-client.ts +151 -0
- package/src/ipc/cli-server.ts +234 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/index.ts +5 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/mcp/client.ts +59 -24
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/app-store.ts +31 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +73 -0
- package/src/memory/conversation-crud.ts +122 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +34 -2
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +18 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction-job.ts +15 -0
- package/src/memory/graph/extraction.test.ts +23 -0
- package/src/memory/graph/extraction.ts +8 -0
- package/src/memory/graph/retriever.ts +67 -40
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +16 -10
- package/src/memory/jobs-store.ts +64 -4
- package/src/memory/jobs-worker.ts +22 -9
- package/src/memory/llm-usage-store.ts +137 -60
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/index.ts +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/oauth.ts +21 -13
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/client.ts +57 -6
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +143 -38
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/notifications/decision-engine.ts +3 -3
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +25 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +26 -9
- package/src/oauth/byo-connection.ts +10 -8
- package/src/oauth/connect-orchestrator.ts +25 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +22 -18
- package/src/oauth/connection.ts +3 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +223 -100
- package/src/oauth/platform-connection.test.ts +101 -3
- package/src/oauth/platform-connection.ts +56 -35
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +133 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/permissions/workspace-policy.ts +3 -0
- package/src/platform/client.test.ts +10 -0
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +126 -2
- package/src/prompts/system-prompt.ts +76 -38
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-format.ts +26 -9
- package/src/prompts/update-bulletin.ts +34 -23
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/anthropic/client.ts +157 -60
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +9 -1
- package/src/providers/model-catalog.ts +6 -0
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +474 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +502 -0
- package/src/providers/openrouter/client.ts +101 -4
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +14 -3
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +306 -0
- package/src/providers/speech-to-text/resolve.ts +386 -6
- package/src/providers/types.ts +10 -1
- package/src/runtime/AGENTS.md +65 -0
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
- package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +512 -0
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +48 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +33 -9
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/chrome-extension-registry.ts +368 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +815 -75
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +198 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +7 -0
- package/src/runtime/migrations/migration-wizard.ts +23 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +96 -1
- package/src/runtime/migrations/vbundle-importer.ts +89 -5
- package/src/runtime/pending-interactions.ts +18 -13
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/approval-routes.ts +90 -16
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +556 -0
- package/src/runtime/routes/btw-routes.ts +8 -6
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -141
- package/src/runtime/routes/conversation-management-routes.ts +223 -0
- package/src/runtime/routes/conversation-routes.ts +598 -103
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- package/src/runtime/routes/home-feed-routes.ts +334 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +268 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +262 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +11 -3
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +303 -0
- package/src/runtime/routes/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +122 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +31 -102
- package/src/runtime/routes/skills-routes.ts +128 -9
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/subagents-routes.ts +14 -10
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +38 -9
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.ts +8 -1
- package/src/runtime/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +344 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +49 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +57 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +68 -29
- package/src/security/secure-keys.ts +143 -27
- package/src/security/token-manager.ts +31 -10
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +554 -0
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +195 -0
- package/src/stt/stt-stream-session.ts +499 -0
- package/src/stt/types.ts +330 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +169 -40
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
- package/src/tools/browser/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +1787 -342
- package/src/tools/browser/browser-manager.ts +81 -12
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1263 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +359 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1993 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +1007 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +744 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +868 -0
- package/src/tools/browser/cdp-client/errors.ts +49 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +148 -0
- package/src/tools/browser/cdp-client/factory.ts +914 -0
- package/src/tools/browser/cdp-client/index.ts +28 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +120 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +2 -0
- package/src/tools/skills/sandbox-runner.ts +3 -2
- package/src/tools/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +15 -0
- package/src/tools/terminal/shell.ts +36 -20
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +19 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tts/__tests__/provider-adapters.test.ts +834 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +201 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +42 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +153 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/platform.ts +63 -24
- package/src/util/pricing.ts +66 -3
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +23 -0
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/top-level-renderer.ts +31 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/cli/commands/browser-relay.ts +0 -536
- package/src/config/schemas/sandbox.ts +0 -14
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/permissions/permission-mode-store.ts +0 -180
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
package/src/util/errors.ts
CHANGED
|
@@ -102,16 +102,24 @@ export class AssistantError extends VellumError {
|
|
|
102
102
|
export class ProviderError extends AssistantError {
|
|
103
103
|
/** Delay (in ms) suggested by the server's Retry-After header, if present. */
|
|
104
104
|
public readonly retryAfterMs?: number;
|
|
105
|
+
/**
|
|
106
|
+
* Tagged daemon-owned abort reason carried over from the AbortSignal that
|
|
107
|
+
* triggered this error. Untyped here to avoid a daemon→util import cycle;
|
|
108
|
+
* `AbortReason` from `util/abort-reasons.ts` is the only producer and
|
|
109
|
+
* `isAbortReason` is the canonical type guard for consumers.
|
|
110
|
+
*/
|
|
111
|
+
public readonly abortReason?: unknown;
|
|
105
112
|
|
|
106
113
|
constructor(
|
|
107
114
|
message: string,
|
|
108
115
|
public readonly provider: string,
|
|
109
116
|
public readonly statusCode?: number,
|
|
110
|
-
options?: { cause?: unknown; retryAfterMs?: number },
|
|
117
|
+
options?: { cause?: unknown; retryAfterMs?: number; abortReason?: unknown },
|
|
111
118
|
) {
|
|
112
119
|
super(message, ErrorCode.PROVIDER_ERROR, options);
|
|
113
120
|
this.name = "ProviderError";
|
|
114
121
|
this.retryAfterMs = options?.retryAfterMs;
|
|
122
|
+
this.abortReason = options?.abortReason;
|
|
115
123
|
}
|
|
116
124
|
}
|
|
117
125
|
|
package/src/util/platform.ts
CHANGED
|
@@ -45,13 +45,24 @@ export function normalizeAssistantId(assistantId: string): string {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
* The daemon's per-instance root data directory. Resolution order:
|
|
49
49
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* 1. `BASE_DATA_DIR` env var — set by the CLI when spawning the daemon
|
|
51
|
+
* for a specific assistant (see `cli/src/lib/local.ts`). Points at the
|
|
52
|
+
* per-assistant instanceDir; we append `.vellum` to get the daemon's
|
|
53
|
+
* root so root-level state (PID, credentials, runtime-port, workspace)
|
|
54
|
+
* is isolated per instance.
|
|
55
|
+
* 2. Fallback: `join(homedir(), ".vellum")`. Used when the daemon runs
|
|
56
|
+
* outside the CLI-spawn lifecycle (containerized deployments, manual
|
|
57
|
+
* test invocations).
|
|
58
|
+
*
|
|
59
|
+
* Docker mode relocates the workspace via `VELLUM_WORKSPACE_DIR` rather
|
|
60
|
+
* than `BASE_DATA_DIR`, so honoring `BASE_DATA_DIR` here does not affect
|
|
61
|
+
* containerized deployments.
|
|
53
62
|
*/
|
|
54
63
|
function vellumRoot(): string {
|
|
64
|
+
const baseDataDir = process.env.BASE_DATA_DIR?.trim();
|
|
65
|
+
if (baseDataDir) return join(baseDataDir, ".vellum");
|
|
55
66
|
return join(homedir(), ".vellum");
|
|
56
67
|
}
|
|
57
68
|
|
|
@@ -136,39 +147,54 @@ export function isTCPEnabled(): boolean {
|
|
|
136
147
|
|
|
137
148
|
/**
|
|
138
149
|
* Returns the hostname/address for the TCP listener.
|
|
139
|
-
*
|
|
140
|
-
*
|
|
150
|
+
* Always binds to localhost only. iOS pairing uses the gateway
|
|
151
|
+
* relay.
|
|
141
152
|
*/
|
|
142
153
|
export function getTCPHost(): string {
|
|
143
|
-
if (isIOSPairingEnabled()) return "0.0.0.0";
|
|
144
154
|
return "127.0.0.1";
|
|
145
155
|
}
|
|
146
156
|
|
|
157
|
+
// Kept in sync with `cli/src/lib/environments/seeds.ts` and
|
|
158
|
+
// `clients/chrome-extension/native-host/src/lockfile.ts`. Drift between
|
|
159
|
+
// these three sites is caught at test time by
|
|
160
|
+
// `cli/src/__tests__/env-drift.test.ts`. Fast follow: hoist the shared
|
|
161
|
+
// list into a `packages/environments` package so all three sites import
|
|
162
|
+
// from one place.
|
|
163
|
+
const KNOWN_ENVIRONMENTS: ReadonlySet<string> = new Set([
|
|
164
|
+
"production",
|
|
165
|
+
"staging",
|
|
166
|
+
"test",
|
|
167
|
+
"dev",
|
|
168
|
+
"local",
|
|
169
|
+
]);
|
|
170
|
+
|
|
147
171
|
/**
|
|
148
|
-
* Returns
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* Checks for the presence of the flag file ~/.vellum/ios-pairing-enabled.
|
|
154
|
-
* Default: false.
|
|
172
|
+
* Returns the env-scoped XDG config subdirectory name for Vellum
|
|
173
|
+
* (`vellum` in production, `vellum-<env>` otherwise). Mirrors the Swift
|
|
174
|
+
* side's `VellumPaths.configDir` and the CLI's
|
|
175
|
+
* `environments/paths.ts:getConfigDir` so the daemon resolves to the
|
|
176
|
+
* same on-disk location as every other writer of these files.
|
|
155
177
|
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
178
|
+
* Unknown environment names fall back to production to preserve the
|
|
179
|
+
* legacy path for any unrecognized value.
|
|
158
180
|
*/
|
|
159
|
-
export function
|
|
160
|
-
|
|
181
|
+
export function getXdgVellumConfigDirName(): string {
|
|
182
|
+
const raw = process.env.VELLUM_ENVIRONMENT?.trim();
|
|
183
|
+
if (!raw || raw === "production") return "vellum";
|
|
184
|
+
if (!KNOWN_ENVIRONMENTS.has(raw)) return "vellum";
|
|
185
|
+
return `vellum-${raw}`;
|
|
161
186
|
}
|
|
162
187
|
|
|
163
188
|
/**
|
|
164
|
-
* Returns the XDG-compliant path for the platform API token
|
|
165
|
-
*
|
|
166
|
-
*
|
|
189
|
+
* Returns the XDG-compliant path for the platform API token. Resolves to
|
|
190
|
+
* `$XDG_CONFIG_HOME/vellum/platform-token` in production and
|
|
191
|
+
* `$XDG_CONFIG_HOME/vellum-<env>/platform-token` otherwise, matching the
|
|
192
|
+
* Swift client and CLI.
|
|
167
193
|
*/
|
|
168
|
-
function getXdgPlatformTokenPath(): string {
|
|
194
|
+
export function getXdgPlatformTokenPath(): string {
|
|
169
195
|
const configHome =
|
|
170
196
|
process.env.XDG_CONFIG_HOME?.trim() || join(homedir(), ".config");
|
|
171
|
-
return join(configHome,
|
|
197
|
+
return join(configHome, getXdgVellumConfigDirName(), "platform-token");
|
|
172
198
|
}
|
|
173
199
|
|
|
174
200
|
/**
|
|
@@ -202,6 +228,18 @@ export function getPidPath(): string {
|
|
|
202
228
|
return join(vellumRoot(), "vellum.pid");
|
|
203
229
|
}
|
|
204
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Returns the path to the runtime HTTP port file (~/.vellum/runtime-port).
|
|
233
|
+
* The daemon writes its active HTTP port here on startup so thin helpers
|
|
234
|
+
* that need to reach the runtime (e.g. the chrome-extension native messaging
|
|
235
|
+
* helper) can locate a non-default `RUNTIME_HTTP_PORT` without a manifest
|
|
236
|
+
* change. Root-level path by design — the file is read by helpers that may
|
|
237
|
+
* not know the workspace override path.
|
|
238
|
+
*/
|
|
239
|
+
export function getRuntimePortFilePath(): string {
|
|
240
|
+
return join(vellumRoot(), "runtime-port");
|
|
241
|
+
}
|
|
242
|
+
|
|
205
243
|
export function getDbPath(): string {
|
|
206
244
|
return join(getDataDir(), "db", "assistant.db");
|
|
207
245
|
}
|
|
@@ -328,7 +366,7 @@ export function getConversationsDir(): string {
|
|
|
328
366
|
return join(getWorkspaceDir(), "conversations");
|
|
329
367
|
}
|
|
330
368
|
|
|
331
|
-
/** Returns the workspace path for a prompt file (e.g. IDENTITY.md, SOUL.md
|
|
369
|
+
/** Returns the workspace path for a prompt file (e.g. IDENTITY.md, SOUL.md). */
|
|
332
370
|
export function getWorkspacePromptPath(file: string): string {
|
|
333
371
|
return join(getWorkspaceDir(), file);
|
|
334
372
|
}
|
|
@@ -388,6 +426,7 @@ export function ensureDataDir(): void {
|
|
|
388
426
|
join(wsData, "memory"),
|
|
389
427
|
join(wsData, "memory", "knowledge"),
|
|
390
428
|
join(wsData, "apps"),
|
|
429
|
+
join(wsData, "attachments"),
|
|
391
430
|
join(wsData, "interfaces"),
|
|
392
431
|
join(wsData, "sounds"),
|
|
393
432
|
];
|
package/src/util/pricing.ts
CHANGED
|
@@ -21,6 +21,7 @@ const ANTHROPIC_FAST_MODE_MULTIPLIER = 6;
|
|
|
21
21
|
*/
|
|
22
22
|
const PROVIDER_PRICING: Record<string, Record<string, ModelPricing>> = {
|
|
23
23
|
anthropic: {
|
|
24
|
+
"claude-opus-4-7": { inputPer1M: 5, outputPer1M: 25 },
|
|
24
25
|
"claude-opus-4-6": { inputPer1M: 5, outputPer1M: 25 },
|
|
25
26
|
"claude-opus-4": { inputPer1M: 15, outputPer1M: 75 },
|
|
26
27
|
"claude-sonnet-4": { inputPer1M: 3, outputPer1M: 15 },
|
|
@@ -55,6 +56,44 @@ const PROVIDER_PRICING: Record<string, Record<string, ModelPricing>> = {
|
|
|
55
56
|
},
|
|
56
57
|
};
|
|
57
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Identify a model ID as an Anthropic model — accepts both the OpenRouter
|
|
61
|
+
* prefix form (`anthropic/claude-opus-4.6`) and the bare Anthropic slug
|
|
62
|
+
* (`claude-opus-4-6`) that `response.model` sometimes carries.
|
|
63
|
+
*/
|
|
64
|
+
function isAnthropicModelId(model: string): boolean {
|
|
65
|
+
return model.startsWith("anthropic/") || model.startsWith("claude-");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Normalize an OpenRouter-style Anthropic model ID for lookup against the
|
|
70
|
+
* Anthropic catalog: strip the `anthropic/` prefix and convert OpenRouter's
|
|
71
|
+
* dot-separated version tokens (`claude-opus-4.6`) to the dash form Anthropic
|
|
72
|
+
* uses natively (`claude-opus-4-6`).
|
|
73
|
+
*/
|
|
74
|
+
function normalizeAnthropicModelId(model: string): string {
|
|
75
|
+
const bare = model.startsWith("anthropic/")
|
|
76
|
+
? model.slice("anthropic/".length)
|
|
77
|
+
: model;
|
|
78
|
+
return bare.replace(/\./g, "-");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Whether Anthropic's pricing rules (cache-read/write multipliers, fast-mode
|
|
83
|
+
* surcharge) apply for the given provider/model. True for direct Anthropic
|
|
84
|
+
* calls and for Anthropic models routed through OpenRouter — OpenRouter
|
|
85
|
+
* proxies to Anthropic's Messages API, so the usage response carries the
|
|
86
|
+
* same cache and speed fields and is charged at Anthropic's rates.
|
|
87
|
+
*/
|
|
88
|
+
export function usesAnthropicPricingRules(
|
|
89
|
+
provider: string,
|
|
90
|
+
model: string,
|
|
91
|
+
): boolean {
|
|
92
|
+
if (provider === "anthropic") return true;
|
|
93
|
+
if (provider === "openrouter" && isAnthropicModelId(model)) return true;
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
58
97
|
/**
|
|
59
98
|
* Look up pricing for a model within a provider's catalog.
|
|
60
99
|
* Tries exact match first, then longest prefix match.
|
|
@@ -147,12 +186,14 @@ function getAnthropicCacheWriteTokens(usage: PricingUsage): {
|
|
|
147
186
|
*/
|
|
148
187
|
function calculateUsageCost(
|
|
149
188
|
provider: string,
|
|
189
|
+
model: string,
|
|
150
190
|
pricing: ModelPricing,
|
|
151
191
|
usage: PricingUsage,
|
|
152
192
|
): number {
|
|
193
|
+
const useAnthropicRules = usesAnthropicPricingRules(provider, model);
|
|
153
194
|
// Anthropic fast mode: 6x multiplier on base rates (cache multipliers stack on top)
|
|
154
195
|
const speedMultiplier =
|
|
155
|
-
|
|
196
|
+
useAnthropicRules && usage.speed === "fast"
|
|
156
197
|
? ANTHROPIC_FAST_MODE_MULTIPLIER
|
|
157
198
|
: 1;
|
|
158
199
|
const effectivePricing: ModelPricing = {
|
|
@@ -169,7 +210,7 @@ function calculateUsageCost(
|
|
|
169
210
|
usage.outputTokens,
|
|
170
211
|
);
|
|
171
212
|
|
|
172
|
-
if (
|
|
213
|
+
if (!useAnthropicRules) {
|
|
173
214
|
return (
|
|
174
215
|
directInputCost +
|
|
175
216
|
outputCost +
|
|
@@ -223,6 +264,27 @@ export function resolvePricingForUsage(
|
|
|
223
264
|
model: string,
|
|
224
265
|
usage: PricingUsage,
|
|
225
266
|
): PricingResult {
|
|
267
|
+
// Anthropic models routed through OpenRouter: look up against the Anthropic
|
|
268
|
+
// catalog using the normalized bare slug. OpenRouter bills these calls at
|
|
269
|
+
// Anthropic's rates and the underlying Messages API response includes
|
|
270
|
+
// Anthropic's cache- and speed-metadata fields.
|
|
271
|
+
if (provider === "openrouter" && isAnthropicModelId(model)) {
|
|
272
|
+
const anthropicCatalog = PROVIDER_PRICING.anthropic;
|
|
273
|
+
if (anthropicCatalog) {
|
|
274
|
+
const pricing = findPricing(
|
|
275
|
+
anthropicCatalog,
|
|
276
|
+
normalizeAnthropicModelId(model),
|
|
277
|
+
);
|
|
278
|
+
if (pricing) {
|
|
279
|
+
return {
|
|
280
|
+
estimatedCostUsd: calculateUsageCost(provider, model, pricing, usage),
|
|
281
|
+
pricingStatus: "priced",
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return { estimatedCostUsd: null, pricingStatus: "unpriced" };
|
|
286
|
+
}
|
|
287
|
+
|
|
226
288
|
const providerCatalog = PROVIDER_PRICING[provider];
|
|
227
289
|
if (!providerCatalog) {
|
|
228
290
|
return { estimatedCostUsd: null, pricingStatus: "unpriced" };
|
|
@@ -234,7 +296,7 @@ export function resolvePricingForUsage(
|
|
|
234
296
|
}
|
|
235
297
|
|
|
236
298
|
return {
|
|
237
|
-
estimatedCostUsd: calculateUsageCost(provider, pricing, usage),
|
|
299
|
+
estimatedCostUsd: calculateUsageCost(provider, model, pricing, usage),
|
|
238
300
|
pricingStatus: "priced",
|
|
239
301
|
};
|
|
240
302
|
}
|
|
@@ -253,6 +315,7 @@ export function resolvePricingForUsageWithOverrides(
|
|
|
253
315
|
return {
|
|
254
316
|
estimatedCostUsd: calculateUsageCost(
|
|
255
317
|
provider,
|
|
318
|
+
model,
|
|
256
319
|
{
|
|
257
320
|
inputPer1M: bestOverride.inputPer1M,
|
|
258
321
|
outputPer1M: bestOverride.outputPer1M,
|
package/src/util/spawn.ts
CHANGED
|
@@ -22,7 +22,7 @@ export function spawnWithTimeout(
|
|
|
22
22
|
timeoutMs: number,
|
|
23
23
|
): Promise<{ exitCode: number; stdout: string; stderr: string }> {
|
|
24
24
|
return new Promise((resolve, reject) => {
|
|
25
|
-
// Augment PATH so Homebrew-installed tools (ffmpeg, ffprobe
|
|
25
|
+
// Augment PATH so Homebrew-installed tools (ffmpeg, ffprobe)
|
|
26
26
|
// are found even when the daemon runs as a bundled binary with minimal PATH.
|
|
27
27
|
const proc = Bun.spawn(cmd, {
|
|
28
28
|
stdout: "pipe",
|
package/src/util/truncate.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { safeStringSlice } from "./unicode.js";
|
|
2
|
+
|
|
1
3
|
/** Truncate a string to `maxLen` characters, appending `suffix` if truncated. */
|
|
2
4
|
export function truncate(str: string, maxLen: number, suffix = "..."): string {
|
|
3
5
|
if (str.length <= maxLen) return str;
|
|
4
|
-
if (maxLen < suffix.length) return str
|
|
5
|
-
return str
|
|
6
|
+
if (maxLen < suffix.length) return safeStringSlice(str, 0, maxLen);
|
|
7
|
+
return safeStringSlice(str, 0, maxLen - suffix.length) + suffix;
|
|
6
8
|
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UTF-16 surrogate-pair-safe string utilities.
|
|
3
|
+
*
|
|
4
|
+
* JavaScript strings are UTF-16. Code points above the BMP (emoji, many CJK
|
|
5
|
+
* characters, mathematical symbols, etc.) are stored as surrogate pairs — a
|
|
6
|
+
* high surrogate (U+D800–U+DBFF) followed by a low surrogate (U+DC00–U+DFFF).
|
|
7
|
+
* `String.prototype.slice` operates on code units, not code points, so naive
|
|
8
|
+
* slicing can split a pair and leave an orphaned surrogate. Orphaned
|
|
9
|
+
* surrogates are invalid UTF-16 and cause `JSON.stringify` output to be
|
|
10
|
+
* rejected by strict JSON parsers (including Anthropic's API).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const HIGH_SURROGATE_START = 0xd800;
|
|
14
|
+
const HIGH_SURROGATE_END = 0xdbff;
|
|
15
|
+
const LOW_SURROGATE_START = 0xdc00;
|
|
16
|
+
const LOW_SURROGATE_END = 0xdfff;
|
|
17
|
+
const REPLACEMENT_CHAR = "\ufffd";
|
|
18
|
+
|
|
19
|
+
function isHighSurrogate(code: number): boolean {
|
|
20
|
+
return code >= HIGH_SURROGATE_START && code <= HIGH_SURROGATE_END;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isLowSurrogate(code: number): boolean {
|
|
24
|
+
return code >= LOW_SURROGATE_START && code <= LOW_SURROGATE_END;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Slice a string like `String.prototype.slice`, but never cut a UTF-16
|
|
29
|
+
* surrogate pair in half.
|
|
30
|
+
*
|
|
31
|
+
* If the character at `end - 1` is a high surrogate *and* there is more of
|
|
32
|
+
* the string beyond `end` (so cutting would actually orphan it), `end` is
|
|
33
|
+
* decremented by one.
|
|
34
|
+
*
|
|
35
|
+
* If the character at `start` is a low surrogate *and* `start > 0` (so we
|
|
36
|
+
* would be starting mid-pair), `start` is incremented by one.
|
|
37
|
+
*
|
|
38
|
+
* When `end === str.length` we do not touch a trailing high surrogate: if it
|
|
39
|
+
* was already orphaned upstream, repairing it here would silently mutate
|
|
40
|
+
* content. That is the sanitizer's job, not this function's.
|
|
41
|
+
*/
|
|
42
|
+
export function safeStringSlice(
|
|
43
|
+
str: string,
|
|
44
|
+
start = 0,
|
|
45
|
+
end: number = str.length,
|
|
46
|
+
): string {
|
|
47
|
+
let safeStart = Math.max(0, Math.min(str.length, start));
|
|
48
|
+
let safeEnd = Math.max(safeStart, Math.min(str.length, end));
|
|
49
|
+
|
|
50
|
+
if (safeEnd < str.length && safeEnd > safeStart) {
|
|
51
|
+
const lastCode = str.charCodeAt(safeEnd - 1);
|
|
52
|
+
if (isHighSurrogate(lastCode)) {
|
|
53
|
+
safeEnd--;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (safeStart > 0 && safeStart < str.length) {
|
|
58
|
+
const firstCode = str.charCodeAt(safeStart);
|
|
59
|
+
if (isLowSurrogate(firstCode)) {
|
|
60
|
+
safeStart++;
|
|
61
|
+
if (safeStart > safeEnd) safeEnd = safeStart;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return str.slice(safeStart, safeEnd);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Replace every orphaned UTF-16 surrogate in `str` with U+FFFD
|
|
70
|
+
* (REPLACEMENT CHARACTER).
|
|
71
|
+
*
|
|
72
|
+
* Returns the original reference if no changes were needed, so callers can
|
|
73
|
+
* check `result === input` as a cheap "nothing was stripped" signal.
|
|
74
|
+
*/
|
|
75
|
+
export function stripOrphanedSurrogates(str: string): string {
|
|
76
|
+
let needsFix = false;
|
|
77
|
+
for (let i = 0; i < str.length; i++) {
|
|
78
|
+
const code = str.charCodeAt(i);
|
|
79
|
+
if (isHighSurrogate(code)) {
|
|
80
|
+
const next = i + 1 < str.length ? str.charCodeAt(i + 1) : 0;
|
|
81
|
+
if (!isLowSurrogate(next)) {
|
|
82
|
+
needsFix = true;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
i++;
|
|
86
|
+
} else if (isLowSurrogate(code)) {
|
|
87
|
+
needsFix = true;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (!needsFix) return str;
|
|
92
|
+
|
|
93
|
+
let out = "";
|
|
94
|
+
for (let i = 0; i < str.length; i++) {
|
|
95
|
+
const code = str.charCodeAt(i);
|
|
96
|
+
if (isHighSurrogate(code)) {
|
|
97
|
+
const next = i + 1 < str.length ? str.charCodeAt(i + 1) : 0;
|
|
98
|
+
if (isLowSurrogate(next)) {
|
|
99
|
+
out += str[i] + str[i + 1];
|
|
100
|
+
i++;
|
|
101
|
+
} else {
|
|
102
|
+
out += REPLACEMENT_CHAR;
|
|
103
|
+
}
|
|
104
|
+
} else if (isLowSurrogate(code)) {
|
|
105
|
+
out += REPLACEMENT_CHAR;
|
|
106
|
+
} else {
|
|
107
|
+
out += str[i];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Result of a deep sanitization walk. If `changed` is false the caller should
|
|
115
|
+
* use the original reference it passed in; `value` is only meaningful when
|
|
116
|
+
* `changed` is true.
|
|
117
|
+
*/
|
|
118
|
+
export interface DeepSanitizeResult<T> {
|
|
119
|
+
value: T;
|
|
120
|
+
changed: boolean;
|
|
121
|
+
/** Count of string values that had at least one orphan replaced. */
|
|
122
|
+
fixedStringCount: number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Recursively walk arrays and plain objects, replacing orphaned surrogates in
|
|
127
|
+
* every string value. Non-plain objects (class instances, Date, Buffer, Map,
|
|
128
|
+
* Set, etc.) and non-string primitives are returned unchanged.
|
|
129
|
+
*
|
|
130
|
+
* On the happy path (no orphans found anywhere in the tree) the original
|
|
131
|
+
* reference is returned verbatim — no copies are made.
|
|
132
|
+
*/
|
|
133
|
+
export function stripOrphanedSurrogatesDeep<T>(input: T): DeepSanitizeResult<T> {
|
|
134
|
+
let fixedStringCount = 0;
|
|
135
|
+
|
|
136
|
+
const walk = (value: unknown): { value: unknown; changed: boolean } => {
|
|
137
|
+
if (typeof value === "string") {
|
|
138
|
+
const cleaned = stripOrphanedSurrogates(value);
|
|
139
|
+
if (cleaned !== value) {
|
|
140
|
+
fixedStringCount++;
|
|
141
|
+
return { value: cleaned, changed: true };
|
|
142
|
+
}
|
|
143
|
+
return { value, changed: false };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (Array.isArray(value)) {
|
|
147
|
+
let next: unknown[] | null = null;
|
|
148
|
+
for (let i = 0; i < value.length; i++) {
|
|
149
|
+
const result = walk(value[i]);
|
|
150
|
+
if (result.changed && next === null) {
|
|
151
|
+
next = [];
|
|
152
|
+
for (let j = 0; j < i; j++) {
|
|
153
|
+
next.push(value[j]);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (next !== null) {
|
|
157
|
+
next.push(result.value);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return next !== null
|
|
161
|
+
? { value: next, changed: true }
|
|
162
|
+
: { value, changed: false };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (value != null && typeof value === "object") {
|
|
166
|
+
const proto = Object.getPrototypeOf(value);
|
|
167
|
+
if (proto !== Object.prototype && proto !== null) {
|
|
168
|
+
return { value, changed: false };
|
|
169
|
+
}
|
|
170
|
+
const source = value as Record<string, unknown>;
|
|
171
|
+
const keys = Object.keys(source);
|
|
172
|
+
let next: Record<string, unknown> | null = null;
|
|
173
|
+
for (let i = 0; i < keys.length; i++) {
|
|
174
|
+
const key = keys[i]!;
|
|
175
|
+
const result = walk(source[key]);
|
|
176
|
+
if (result.changed && next === null) {
|
|
177
|
+
next = {};
|
|
178
|
+
for (let j = 0; j < i; j++) {
|
|
179
|
+
const priorKey = keys[j]!;
|
|
180
|
+
next[priorKey] = source[priorKey];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (next !== null) {
|
|
184
|
+
next[key] = result.value;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return next !== null
|
|
188
|
+
? { value: next, changed: true }
|
|
189
|
+
: { value, changed: false };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return { value, changed: false };
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const result = walk(input);
|
|
196
|
+
return {
|
|
197
|
+
value: result.value as T,
|
|
198
|
+
changed: result.changed,
|
|
199
|
+
fixedStringCount,
|
|
200
|
+
};
|
|
201
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -1,36 +1,31 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
|
|
4
|
+
const DEV_VERSION_SENTINEL = "0.0.0-dev";
|
|
5
|
+
|
|
6
|
+
function readPackageVersion(): string | undefined {
|
|
7
|
+
try {
|
|
8
|
+
const pkgPath = join(
|
|
9
|
+
import.meta.dirname ?? __dirname,
|
|
10
|
+
"..",
|
|
11
|
+
"package.json",
|
|
12
|
+
);
|
|
13
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
14
|
+
if (pkg.version && typeof pkg.version === "string") return pkg.version;
|
|
15
|
+
} catch {
|
|
16
|
+
// package.json missing or unreadable
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
4
21
|
function resolveVersion(): string {
|
|
5
22
|
const envVersion = process.env.APP_VERSION;
|
|
6
23
|
|
|
7
|
-
|
|
8
|
-
// sentinel so Sentry (and similar) classify the session as "development".
|
|
9
|
-
if (!envVersion) return "0.0.0-dev";
|
|
10
|
-
|
|
11
|
-
// CI sets APP_VERSION to the dev placeholder during builds; resolve it to
|
|
12
|
-
// the package.json release version so Sentry gets a meaningful release tag.
|
|
13
|
-
if (envVersion === "0.0.0-dev") {
|
|
14
|
-
try {
|
|
15
|
-
const pkgPath = join(
|
|
16
|
-
import.meta.dirname ?? __dirname,
|
|
17
|
-
"..",
|
|
18
|
-
"package.json",
|
|
19
|
-
);
|
|
20
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
21
|
-
if (pkg.version && typeof pkg.version === "string") return pkg.version;
|
|
22
|
-
} catch {
|
|
23
|
-
// package.json missing or unreadable
|
|
24
|
-
}
|
|
25
|
-
return "0.0.0-dev";
|
|
26
|
-
}
|
|
24
|
+
if (envVersion && envVersion !== DEV_VERSION_SENTINEL) return envVersion;
|
|
27
25
|
|
|
28
|
-
return
|
|
26
|
+
return readPackageVersion() ?? DEV_VERSION_SENTINEL;
|
|
29
27
|
}
|
|
30
28
|
|
|
31
|
-
// Version is embedded at compile time via --define in CI.
|
|
32
|
-
// Falls back to "0.0.0-dev" for local development, or resolves the dev
|
|
33
|
-
// placeholder to package.json version when explicitly set in CI.
|
|
34
29
|
export const APP_VERSION: string = resolveVersion();
|
|
35
30
|
|
|
36
31
|
// Commit SHA is embedded at compile time via --define in CI.
|
package/src/watcher/engine.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
insertWatcherEvent,
|
|
20
20
|
resetStuckWatchers,
|
|
21
21
|
setWatcherConversationId,
|
|
22
|
+
skipWatcherPoll,
|
|
22
23
|
updateEventDisposition,
|
|
23
24
|
} from "./watcher-store.js";
|
|
24
25
|
|
|
@@ -76,6 +77,28 @@ export async function runWatchersOnce(
|
|
|
76
77
|
continue;
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
// Pre-poll credential gate: skip if token is irrecoverably broken.
|
|
81
|
+
// Prevents wasting API calls and burning through circuit breaker
|
|
82
|
+
// attempts on credentials that need manual reauthorization.
|
|
83
|
+
try {
|
|
84
|
+
const { checkCredentialForProvider } =
|
|
85
|
+
await import("../credential-health/credential-health-service.js");
|
|
86
|
+
const health = await checkCredentialForProvider(
|
|
87
|
+
watcher.credentialService,
|
|
88
|
+
);
|
|
89
|
+
if (
|
|
90
|
+
health &&
|
|
91
|
+
(health.status === "revoked" ||
|
|
92
|
+
health.status === "missing_token" ||
|
|
93
|
+
(health.status === "expired" && !health.canAutoRecover))
|
|
94
|
+
) {
|
|
95
|
+
skipWatcherPoll(watcher.id, `Credential unhealthy: ${health.details}`);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
// Non-fatal: proceed with normal poll if health check fails
|
|
100
|
+
}
|
|
101
|
+
|
|
79
102
|
try {
|
|
80
103
|
const config = watcher.configJson ? JSON.parse(watcher.configJson) : {};
|
|
81
104
|
|
|
@@ -221,6 +221,37 @@ export function completeWatcherPoll(
|
|
|
221
221
|
db.update(watchers).set(set).where(eq(watchers.id, id)).run();
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Skip a watcher poll: apply backoff to nextPollAt without incrementing
|
|
226
|
+
* consecutiveErrors. Used when a poll is skipped for a recoverable reason
|
|
227
|
+
* (e.g. credential health gate) that should NOT count toward the circuit
|
|
228
|
+
* breaker threshold.
|
|
229
|
+
*/
|
|
230
|
+
export function skipWatcherPoll(id: string, reason: string): void {
|
|
231
|
+
const db = getDb();
|
|
232
|
+
const watcher = db.select().from(watchers).where(eq(watchers.id, id)).get();
|
|
233
|
+
if (!watcher) return;
|
|
234
|
+
|
|
235
|
+
const now = Date.now();
|
|
236
|
+
// Use the same backoff formula but based on existing consecutiveErrors
|
|
237
|
+
// (which stays unchanged). Minimum backoff of 30s.
|
|
238
|
+
const backoff = Math.min(
|
|
239
|
+
30_000 * Math.pow(2, watcher.consecutiveErrors),
|
|
240
|
+
60 * 60 * 1000,
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
db.update(watchers)
|
|
244
|
+
.set({
|
|
245
|
+
status: "idle",
|
|
246
|
+
lastError: truncate(reason, 2000, ""),
|
|
247
|
+
lastPollAt: now,
|
|
248
|
+
nextPollAt: now + backoff,
|
|
249
|
+
updatedAt: now,
|
|
250
|
+
})
|
|
251
|
+
.where(eq(watchers.id, id))
|
|
252
|
+
.run();
|
|
253
|
+
}
|
|
254
|
+
|
|
224
255
|
/**
|
|
225
256
|
* Record a poll error: increment consecutive errors, apply backoff.
|
|
226
257
|
*/
|
|
@@ -8,15 +8,21 @@ import {
|
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
|
|
11
|
-
import { getDeviceIdBaseDir } from "../../util/device-id.js";
|
|
12
11
|
import type { WorkspaceMigration } from "./types.js";
|
|
13
12
|
|
|
13
|
+
function deviceIdBaseDir(): string {
|
|
14
|
+
const containerized =
|
|
15
|
+
process.env.IS_CONTAINERIZED === "true" ||
|
|
16
|
+
process.env.IS_CONTAINERIZED === "1";
|
|
17
|
+
return containerized ? "/home/assistant" : homedir();
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
export const seedDeviceIdMigration: WorkspaceMigration = {
|
|
15
21
|
id: "003-seed-device-id",
|
|
16
22
|
description:
|
|
17
23
|
"Seed device.json deviceId from the most recent lockfile installationId for continuity",
|
|
18
24
|
run(_workspaceDir: string): void {
|
|
19
|
-
const base =
|
|
25
|
+
const base = deviceIdBaseDir();
|
|
20
26
|
const vellumDir = join(base, ".vellum");
|
|
21
27
|
const devicePath = join(vellumDir, "device.json");
|
|
22
28
|
|
|
@@ -109,7 +115,7 @@ export const seedDeviceIdMigration: WorkspaceMigration = {
|
|
|
109
115
|
// The forward migration seeds deviceId in ~/.vellum/device.json from the
|
|
110
116
|
// lockfile. Reverse by removing device.json entirely — getDeviceId() will
|
|
111
117
|
// generate a fresh one on next startup if needed.
|
|
112
|
-
const base =
|
|
118
|
+
const base = deviceIdBaseDir();
|
|
113
119
|
const devicePath = join(base, ".vellum", "device.json");
|
|
114
120
|
if (existsSync(devicePath)) {
|
|
115
121
|
unlinkSync(devicePath);
|