@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
|
@@ -3,6 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import { getIsContainerized } from "../config/env-registry.js";
|
|
4
4
|
import { getConfig } from "../config/loader.js";
|
|
5
5
|
import { getBundledSkillsDir } from "../config/skills.js";
|
|
6
|
+
import { resolveGuardianPersonaPath } from "../prompts/persona-resolver.js";
|
|
6
7
|
import { getWorkspaceDir } from "../util/platform.js";
|
|
7
8
|
|
|
8
9
|
export interface DefaultRuleTemplate {
|
|
@@ -15,6 +16,16 @@ export interface DefaultRuleTemplate {
|
|
|
15
16
|
allowHighRisk?: boolean;
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Escape minimatch metacharacters so a literal path is matched literally when
|
|
21
|
+
* interpolated into a rule pattern. Without this, characters like `*`, `?`,
|
|
22
|
+
* `[`, `]`, `{`, `}` in a filename would be treated as wildcards and broaden
|
|
23
|
+
* the resulting allow rule beyond the intended file.
|
|
24
|
+
*/
|
|
25
|
+
function escapeMinimatchPath(p: string): string {
|
|
26
|
+
return p.replace(/[?*[\]{}()!|\\]/g, "\\$&");
|
|
27
|
+
}
|
|
28
|
+
|
|
18
29
|
const HOST_FILE_TOOLS = [
|
|
19
30
|
"host_file_read",
|
|
20
31
|
"host_file_write",
|
|
@@ -118,7 +129,6 @@ export function getDefaultRuleTemplates(): DefaultRuleTemplate[] {
|
|
|
118
129
|
const workspaceDir = getWorkspaceDir().replaceAll("\\", "/");
|
|
119
130
|
const WORKSPACE_PROMPT_FILES = [
|
|
120
131
|
"IDENTITY.md",
|
|
121
|
-
"USER.md",
|
|
122
132
|
"SOUL.md",
|
|
123
133
|
"BOOTSTRAP.md",
|
|
124
134
|
"UPDATES.md",
|
|
@@ -139,6 +149,40 @@ export function getDefaultRuleTemplates(): DefaultRuleTemplate[] {
|
|
|
139
149
|
})),
|
|
140
150
|
);
|
|
141
151
|
|
|
152
|
+
// Guardian persona file — the contact-store-resolved `users/<slug>.md`
|
|
153
|
+
// for the current guardian. Once the workspace has a guardian contact,
|
|
154
|
+
// their per-user persona file should be readable/editable without a
|
|
155
|
+
// prompt.
|
|
156
|
+
//
|
|
157
|
+
// Resolved dynamically at template-build time (rather than hardcoded
|
|
158
|
+
// like WORKSPACE_PROMPT_FILES) because the slug depends on the
|
|
159
|
+
// installed guardian. The try/catch protects against early-boot paths
|
|
160
|
+
// where the DB may not yet be initialized — in that case no guardian
|
|
161
|
+
// persona rules are emitted and the agent will be prompted on first
|
|
162
|
+
// edit until the guardian contact is created.
|
|
163
|
+
let guardianPersonaRules: DefaultRuleTemplate[] = [];
|
|
164
|
+
try {
|
|
165
|
+
const guardianPath = resolveGuardianPersonaPath();
|
|
166
|
+
if (guardianPath) {
|
|
167
|
+
const posixPath = guardianPath.replaceAll("\\", "/");
|
|
168
|
+
const escapedPath = escapeMinimatchPath(posixPath);
|
|
169
|
+
guardianPersonaRules = WORKSPACE_FILE_TOOLS.map((tool) => ({
|
|
170
|
+
id: `default:allow-${tool}-guardian-persona`,
|
|
171
|
+
tool,
|
|
172
|
+
pattern: `${tool}:${escapedPath}`,
|
|
173
|
+
scope: "everywhere",
|
|
174
|
+
decision: "allow" as const,
|
|
175
|
+
priority: 100,
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
} catch {
|
|
179
|
+
// If guardian resolution fails at default-rule computation, the rule
|
|
180
|
+
// will be missing until the trust cache is invalidated and rebuilt.
|
|
181
|
+
// Runtime guardian-creation paths invalidate the cache via
|
|
182
|
+
// `clearTrustCache()` in `contacts-write.createGuardianBinding` so
|
|
183
|
+
// that the next `getRules()` call picks up the new auto-allow rule.
|
|
184
|
+
}
|
|
185
|
+
|
|
142
186
|
const bootstrapDeleteRule: DefaultRuleTemplate = {
|
|
143
187
|
id: "default:allow-bash-rm-bootstrap",
|
|
144
188
|
tool: "bash",
|
|
@@ -248,6 +292,8 @@ export function getDefaultRuleTemplates(): DefaultRuleTemplate[] {
|
|
|
248
292
|
"browser_snapshot",
|
|
249
293
|
"browser_screenshot",
|
|
250
294
|
"browser_close",
|
|
295
|
+
"browser_attach",
|
|
296
|
+
"browser_detach",
|
|
251
297
|
"browser_click",
|
|
252
298
|
"browser_type",
|
|
253
299
|
"browser_press_key",
|
|
@@ -258,6 +304,7 @@ export function getDefaultRuleTemplates(): DefaultRuleTemplate[] {
|
|
|
258
304
|
"browser_extract",
|
|
259
305
|
"browser_wait_for_download",
|
|
260
306
|
"browser_fill_credential",
|
|
307
|
+
"browser_status",
|
|
261
308
|
] as const;
|
|
262
309
|
|
|
263
310
|
const browserToolRules: DefaultRuleTemplate[] = BROWSER_TOOLS_NO_SLASH.map(
|
|
@@ -303,6 +350,7 @@ export function getDefaultRuleTemplates(): DefaultRuleTemplate[] {
|
|
|
303
350
|
...computerUseRules,
|
|
304
351
|
...managedSkillRules,
|
|
305
352
|
...workspacePromptRules,
|
|
353
|
+
...guardianPersonaRules,
|
|
306
354
|
bootstrapDeleteRule,
|
|
307
355
|
updatesDeleteRule,
|
|
308
356
|
...skillSourceMutationRules,
|
|
@@ -1,27 +1,20 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* commands on the host machine without prompting.
|
|
4
|
+
* Host-access permission state.
|
|
5
|
+
*
|
|
6
|
+
* The only remaining permission-mode axis is whether the assistant can
|
|
7
|
+
* execute commands on the host machine without prompting.
|
|
9
8
|
*/
|
|
10
9
|
export type PermissionMode = {
|
|
11
|
-
askBeforeActing: boolean;
|
|
12
10
|
hostAccess: boolean;
|
|
13
11
|
};
|
|
14
12
|
|
|
15
13
|
export const DEFAULT_PERMISSION_MODE: PermissionMode = {
|
|
16
|
-
askBeforeActing: true,
|
|
17
14
|
hostAccess: false,
|
|
18
15
|
};
|
|
19
16
|
|
|
20
17
|
export const PermissionModeSchema = z.object({
|
|
21
|
-
askBeforeActing: z
|
|
22
|
-
.boolean({ error: "permissionMode.askBeforeActing must be a boolean" })
|
|
23
|
-
.default(true)
|
|
24
|
-
.describe("Whether the assistant should check in before taking actions"),
|
|
25
18
|
hostAccess: z
|
|
26
19
|
.boolean({ error: "permissionMode.hostAccess must be a boolean" })
|
|
27
20
|
.default(false)
|
|
@@ -20,6 +20,7 @@ interface PendingPrompt {
|
|
|
20
20
|
reject: (reason: Error) => void;
|
|
21
21
|
timer: ReturnType<typeof setTimeout>;
|
|
22
22
|
toolUseId?: string;
|
|
23
|
+
hostAccessEnablePrompt?: boolean;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export type ConfirmationStateCallback = (
|
|
@@ -64,6 +65,7 @@ export class PermissionPrompter {
|
|
|
64
65
|
signal?: AbortSignal,
|
|
65
66
|
temporaryOptionsAvailable?: Array<"allow_10m" | "allow_conversation">,
|
|
66
67
|
toolUseId?: string,
|
|
68
|
+
hostAccessEnablePrompt?: boolean,
|
|
67
69
|
): Promise<{
|
|
68
70
|
decision: UserDecision;
|
|
69
71
|
selectedPattern?: string;
|
|
@@ -89,7 +91,13 @@ export class PermissionPrompter {
|
|
|
89
91
|
});
|
|
90
92
|
}, timeoutMs);
|
|
91
93
|
|
|
92
|
-
this.pending.set(requestId, {
|
|
94
|
+
this.pending.set(requestId, {
|
|
95
|
+
resolve,
|
|
96
|
+
reject,
|
|
97
|
+
timer,
|
|
98
|
+
toolUseId,
|
|
99
|
+
hostAccessEnablePrompt,
|
|
100
|
+
});
|
|
93
101
|
|
|
94
102
|
if (signal) {
|
|
95
103
|
const onAbort = () => {
|
|
@@ -143,6 +151,10 @@ export class PermissionPrompter {
|
|
|
143
151
|
return this.pending.get(requestId)?.toolUseId;
|
|
144
152
|
}
|
|
145
153
|
|
|
154
|
+
isHostAccessEnablePrompt(requestId: string): boolean {
|
|
155
|
+
return this.pending.get(requestId)?.hostAccessEnablePrompt === true;
|
|
156
|
+
}
|
|
157
|
+
|
|
146
158
|
resolveConfirmation(
|
|
147
159
|
requestId: string,
|
|
148
160
|
decision: UserDecision,
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
renameSync,
|
|
7
7
|
writeFileSync,
|
|
8
8
|
} from "node:fs";
|
|
9
|
-
import { homedir } from "node:os";
|
|
10
9
|
import { dirname, join } from "node:path";
|
|
11
10
|
|
|
12
11
|
import { Minimatch } from "minimatch";
|
|
@@ -14,6 +13,7 @@ import { v4 as uuid } from "uuid";
|
|
|
14
13
|
|
|
15
14
|
import { getIsContainerized } from "../config/env-registry.js";
|
|
16
15
|
import { getLogger } from "../util/logger.js";
|
|
16
|
+
import { getProtectedDir } from "../util/platform.js";
|
|
17
17
|
import { getDefaultRuleTemplates } from "./defaults.js";
|
|
18
18
|
import * as trustClient from "./trust-client.js";
|
|
19
19
|
import type {
|
|
@@ -135,12 +135,12 @@ function getTrustPath(): string {
|
|
|
135
135
|
* Resolve the gateway security directory.
|
|
136
136
|
*
|
|
137
137
|
* Docker: `GATEWAY_SECURITY_DIR` env var.
|
|
138
|
-
* Local:
|
|
138
|
+
* Local: the per-instance protected directory resolved by `getProtectedDir()`.
|
|
139
139
|
*/
|
|
140
140
|
function getGatewaySecurityDir(): string {
|
|
141
141
|
const securityDir = process.env.GATEWAY_SECURITY_DIR;
|
|
142
142
|
if (securityDir) return securityDir;
|
|
143
|
-
return
|
|
143
|
+
return getProtectedDir();
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
/**
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
2
|
+
import { getConfig } from "../config/loader.js";
|
|
3
|
+
import { getConversationHostAccess as loadConversationHostAccess } from "../memory/conversation-crud.js";
|
|
4
|
+
import { isSideEffectTool } from "../tools/side-effects.js";
|
|
5
|
+
import type { ToolContext } from "../tools/types.js";
|
|
6
|
+
import type { AllowlistOption, ScopeOption, UserDecision } from "./types.js";
|
|
7
|
+
import { isHostTool } from "./workspace-policy.js";
|
|
8
|
+
|
|
9
|
+
export type V2ConsentDisposition =
|
|
10
|
+
| "legacy"
|
|
11
|
+
| "auto_allow"
|
|
12
|
+
| "prompt_host_access";
|
|
13
|
+
|
|
14
|
+
type PromptLike = {
|
|
15
|
+
toolName: string;
|
|
16
|
+
allowlistOptions?: readonly AllowlistOption[];
|
|
17
|
+
scopeOptions?: readonly ScopeOption[];
|
|
18
|
+
persistentDecisionsAllowed?: boolean;
|
|
19
|
+
temporaryOptionsAvailable?: readonly ("allow_10m" | "allow_conversation")[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const CONVERSATION_HOST_ACCESS_PROMPT = Object.freeze({
|
|
23
|
+
allowlistOptions: [] as AllowlistOption[],
|
|
24
|
+
scopeOptions: [] as ScopeOption[],
|
|
25
|
+
persistentDecisionsAllowed: false as const,
|
|
26
|
+
temporaryOptionsAvailable: undefined as
|
|
27
|
+
| Array<"allow_10m" | "allow_conversation">
|
|
28
|
+
| undefined,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export function isPermissionControlsV2Enabled(): boolean {
|
|
32
|
+
return isAssistantFeatureFlagEnabled("permission-controls-v2", getConfig());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function isConversationHostAccessEnabled(
|
|
36
|
+
conversationId: string,
|
|
37
|
+
): boolean {
|
|
38
|
+
return loadConversationHostAccess(conversationId);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function evaluateV2ConsentDisposition(
|
|
42
|
+
toolName: string,
|
|
43
|
+
input: Record<string, unknown>,
|
|
44
|
+
context: ToolContext,
|
|
45
|
+
): V2ConsentDisposition {
|
|
46
|
+
if (!isPermissionControlsV2Enabled()) {
|
|
47
|
+
return "legacy";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (context.requireFreshApproval) {
|
|
51
|
+
return "legacy";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (context.forcePromptSideEffects && isSideEffectTool(toolName, input)) {
|
|
55
|
+
return "legacy";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!isHostTool(toolName)) {
|
|
59
|
+
return "auto_allow";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return loadConversationHostAccess(context.conversationId)
|
|
63
|
+
? "auto_allow"
|
|
64
|
+
: "prompt_host_access";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function isConversationHostAccessEnablePrompt(
|
|
68
|
+
details: PromptLike | undefined,
|
|
69
|
+
): boolean {
|
|
70
|
+
if (!details) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
isHostTool(details.toolName) &&
|
|
76
|
+
(details.allowlistOptions?.length ?? 0) === 0 &&
|
|
77
|
+
(details.scopeOptions?.length ?? 0) === 0 &&
|
|
78
|
+
details.persistentDecisionsAllowed === false &&
|
|
79
|
+
(details.temporaryOptionsAvailable?.length ?? 0) === 0
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function isConversationHostAccessDecision(
|
|
84
|
+
decision: UserDecision,
|
|
85
|
+
): decision is "allow" | "deny" {
|
|
86
|
+
return decision === "allow" || decision === "deny";
|
|
87
|
+
}
|
|
@@ -23,6 +23,16 @@ mock.module("../config/env.js", () => ({
|
|
|
23
23
|
getPlatformAssistantId: () => mockAssistantId,
|
|
24
24
|
}));
|
|
25
25
|
|
|
26
|
+
// Stub the credential-store fallback so tests stay hermetic and do not
|
|
27
|
+
// read real values from the host credential backend.
|
|
28
|
+
mock.module("../security/secure-keys.js", () => ({
|
|
29
|
+
getSecureKeyAsync: async () => null,
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
mock.module("../security/credential-key.js", () => ({
|
|
33
|
+
credentialKey: (namespace: string, key: string) => `${namespace}:${key}`,
|
|
34
|
+
}));
|
|
35
|
+
|
|
26
36
|
// ---------------------------------------------------------------------------
|
|
27
37
|
// Import under test (after mocks)
|
|
28
38
|
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync assistant identity fields to the platform Assistant record.
|
|
3
|
+
*
|
|
4
|
+
* When IDENTITY.md changes on disk the daemon broadcasts an
|
|
5
|
+
* `identity_changed` event to connected clients. This module hooks into
|
|
6
|
+
* that same change signal and PATCHes the platform `Assistant` record so
|
|
7
|
+
* the name (and, in future, other fields) stays in sync.
|
|
8
|
+
*
|
|
9
|
+
* Requests are serialized so that rapid name changes (A → B) never race:
|
|
10
|
+
* only the most recently requested name is sent, and a stale in-flight
|
|
11
|
+
* response cannot overwrite a newer value.
|
|
12
|
+
*
|
|
13
|
+
* The sync is best-effort and fire-and-forget — network failures are
|
|
14
|
+
* logged but never surface to callers.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { getLogger } from "../util/logger.js";
|
|
18
|
+
import { VellumPlatformClient } from "./client.js";
|
|
19
|
+
|
|
20
|
+
const log = getLogger("sync-identity");
|
|
21
|
+
|
|
22
|
+
/** Track the last successfully synced name (used inside doSync to skip redundant PATCHes). */
|
|
23
|
+
let lastSyncedName: string | null = null;
|
|
24
|
+
|
|
25
|
+
/** Track the last requested name (used for dedup at enqueue time). */
|
|
26
|
+
let lastRequestedName: string | null = null;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Monotonically increasing sequence number. Each call to
|
|
30
|
+
* `syncIdentityNameToPlatform` bumps this; after a PATCH completes we
|
|
31
|
+
* only update `lastSyncedName` when `seq` still matches, guaranteeing
|
|
32
|
+
* the newest name always wins.
|
|
33
|
+
*/
|
|
34
|
+
let seq = 0;
|
|
35
|
+
|
|
36
|
+
/** Chain promise that serializes in-flight PATCH requests. */
|
|
37
|
+
let pending: Promise<void> = Promise.resolve();
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Push the current assistant name to the platform `Assistant` record.
|
|
41
|
+
*
|
|
42
|
+
* No-op when:
|
|
43
|
+
* - The platform client cannot be created (not platform-hosted / missing creds).
|
|
44
|
+
* - No assistant ID is configured.
|
|
45
|
+
* - The name is empty or unchanged since the last request.
|
|
46
|
+
*/
|
|
47
|
+
export function syncIdentityNameToPlatform(name: string): void {
|
|
48
|
+
if (!name || name === lastRequestedName) return;
|
|
49
|
+
|
|
50
|
+
lastRequestedName = name;
|
|
51
|
+
|
|
52
|
+
const mySeq = ++seq;
|
|
53
|
+
|
|
54
|
+
pending = pending
|
|
55
|
+
.then(() => doSync(name, mySeq))
|
|
56
|
+
.catch(() => {
|
|
57
|
+
// swallowed — doSync already logs internally
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function doSync(name: string, requestSeq: number): Promise<void> {
|
|
62
|
+
try {
|
|
63
|
+
// A newer call has already been enqueued — skip this stale request.
|
|
64
|
+
if (requestSeq !== seq) return;
|
|
65
|
+
|
|
66
|
+
// Re-check after awaiting the previous request in the chain.
|
|
67
|
+
if (name === lastSyncedName) return;
|
|
68
|
+
|
|
69
|
+
const client = await VellumPlatformClient.create();
|
|
70
|
+
if (!client) {
|
|
71
|
+
clearRequestedIfLatest(requestSeq);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const assistantId = client.platformAssistantId;
|
|
76
|
+
if (!assistantId) {
|
|
77
|
+
clearRequestedIfLatest(requestSeq);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const resp = await client.fetch(
|
|
82
|
+
`/v1/assistants/${encodeURIComponent(assistantId)}/`,
|
|
83
|
+
{
|
|
84
|
+
method: "PATCH",
|
|
85
|
+
headers: { "Content-Type": "application/json" },
|
|
86
|
+
body: JSON.stringify({ name }),
|
|
87
|
+
signal: AbortSignal.timeout(15_000),
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
if (resp.ok) {
|
|
92
|
+
// Only update cache if no newer request has been enqueued since we
|
|
93
|
+
// started this PATCH — prevents a slow response from overwriting a
|
|
94
|
+
// fresher value.
|
|
95
|
+
if (requestSeq === seq) {
|
|
96
|
+
lastSyncedName = name;
|
|
97
|
+
}
|
|
98
|
+
log.info({ name, assistantId }, "Synced assistant name to platform");
|
|
99
|
+
} else {
|
|
100
|
+
clearRequestedIfLatest(requestSeq);
|
|
101
|
+
const text = await resp.text();
|
|
102
|
+
log.warn(
|
|
103
|
+
{ status: resp.status, body: text, assistantId },
|
|
104
|
+
"Failed to sync assistant name to platform",
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
clearRequestedIfLatest(requestSeq);
|
|
109
|
+
log.warn({ err }, "Error syncing assistant name to platform");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Reset `lastRequestedName` when the latest request failed, so that the
|
|
115
|
+
* next call with the same name is allowed through instead of being deduped.
|
|
116
|
+
*/
|
|
117
|
+
function clearRequestedIfLatest(requestSeq: number): void {
|
|
118
|
+
if (requestSeq === seq) {
|
|
119
|
+
lastRequestedName = lastSyncedName;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Reset cached state (for testing). */
|
|
124
|
+
export function _resetSyncState(): void {
|
|
125
|
+
lastSyncedName = null;
|
|
126
|
+
lastRequestedName = null;
|
|
127
|
+
seq = 0;
|
|
128
|
+
pending = Promise.resolve();
|
|
129
|
+
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
mkdirSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
writeFileSync,
|
|
6
|
+
} from "node:fs";
|
|
7
|
+
import { basename, dirname, join } from "node:path";
|
|
3
8
|
|
|
4
9
|
import {
|
|
5
10
|
findContactByChannelExternalId,
|
|
@@ -16,6 +21,28 @@ import { stripCommentLines } from "../util/strip-comment-lines.js";
|
|
|
16
21
|
|
|
17
22
|
const log = getLogger("persona-resolver");
|
|
18
23
|
|
|
24
|
+
// ── Guardian persona template ─────────────────────────────────────
|
|
25
|
+
//
|
|
26
|
+
// Scaffold written to `users/<slug>.md` when a guardian is resolved
|
|
27
|
+
// but no per-user persona file yet exists. Kept in sync with the
|
|
28
|
+
// legacy workspace USER.md template so that upgrading users preserve
|
|
29
|
+
// the same editable shape. Exported so consumers can detect the
|
|
30
|
+
// unmodified scaffold (e.g. heartbeat's `isShallowProfile`).
|
|
31
|
+
export const GUARDIAN_PERSONA_TEMPLATE = `_ Lines starting with _ are comments - they won't appear in the system prompt
|
|
32
|
+
|
|
33
|
+
# User Profile
|
|
34
|
+
|
|
35
|
+
Store details about your user here. Edit freely - build this over time as you learn about them. Don't be pushy about seeking details, but when you learn something, write it down. More context makes you more useful.
|
|
36
|
+
|
|
37
|
+
- Preferred name/reference:
|
|
38
|
+
- Pronouns:
|
|
39
|
+
- Locale:
|
|
40
|
+
- Work role:
|
|
41
|
+
- Goals:
|
|
42
|
+
- Hobbies/fun:
|
|
43
|
+
- Daily tools:
|
|
44
|
+
`;
|
|
45
|
+
|
|
19
46
|
// ── Types ──────────────────────────────────────────────────────────
|
|
20
47
|
|
|
21
48
|
export interface PersonaContext {
|
|
@@ -98,6 +125,22 @@ function resolveUserFilename(
|
|
|
98
125
|
return null;
|
|
99
126
|
}
|
|
100
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Resolve the absolute on-disk path to the guardian's per-user persona
|
|
130
|
+
* file (e.g. `<workspace>/users/sidd.md`). Returns `null` when no
|
|
131
|
+
* guardian is resolvable (no guardian contact, or its `userFile` is
|
|
132
|
+
* unusable / fails basename validation).
|
|
133
|
+
*
|
|
134
|
+
* This does not check whether the file exists — it only resolves the
|
|
135
|
+
* path. Callers use it alongside `ensureGuardianPersonaFile` to open
|
|
136
|
+
* or scaffold the file.
|
|
137
|
+
*/
|
|
138
|
+
export function resolveGuardianPersonaPath(): string | null {
|
|
139
|
+
const filename = resolveUserFilename(undefined);
|
|
140
|
+
if (!filename) return null;
|
|
141
|
+
return join(getWorkspaceDir(), "users", filename);
|
|
142
|
+
}
|
|
143
|
+
|
|
101
144
|
/**
|
|
102
145
|
* Resolve a short slug identifying the current user, derived from
|
|
103
146
|
* their contact's userFile. Used to scope per-user workspace directories
|
|
@@ -192,3 +235,84 @@ export function resolvePersonaContext(
|
|
|
192
235
|
export function resolveGuardianPersona(): string | null {
|
|
193
236
|
return resolveUserPersona(undefined);
|
|
194
237
|
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Resolve the guardian's user persona strictly from their own
|
|
241
|
+
* `users/<slug>.md` file, with NO fallback to `users/default.md`.
|
|
242
|
+
*
|
|
243
|
+
* Returns `null` when no guardian contact is resolvable, the
|
|
244
|
+
* guardian's userFile is unset, or the file is missing / empty.
|
|
245
|
+
*
|
|
246
|
+
* Used by callers that derive guardian-specific attributes (name,
|
|
247
|
+
* pronouns) where `default.md` content would incorrectly override an
|
|
248
|
+
* intentional caller-supplied fallback such as `Contact.displayName`.
|
|
249
|
+
* System-prompt callers that want the default.md fallback should
|
|
250
|
+
* continue to use `resolveGuardianPersona`.
|
|
251
|
+
*/
|
|
252
|
+
export function resolveGuardianPersonaStrict(): string | null {
|
|
253
|
+
const filename = resolveUserFilename(undefined);
|
|
254
|
+
if (!filename) return null;
|
|
255
|
+
const filePath = join(getWorkspaceDir(), "users", filename);
|
|
256
|
+
if (!existsSync(filePath)) return null;
|
|
257
|
+
return readPersonaFile(filePath);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Write the guardian persona template scaffold to `users/<userFile>`
|
|
262
|
+
* when the file does not yet exist. No-op when the file already
|
|
263
|
+
* exists (safe against clobbering user edits).
|
|
264
|
+
*
|
|
265
|
+
* @param userFile - A filename (not a bare slug), matching the shape
|
|
266
|
+
* of `Contact.userFile` — a basename with a `.md` suffix
|
|
267
|
+
* (e.g. `"sidd.md"`). The path traversal guard rejects values that
|
|
268
|
+
* are not a clean basename.
|
|
269
|
+
*
|
|
270
|
+
* Creates the parent `users/` directory if missing.
|
|
271
|
+
*/
|
|
272
|
+
export function ensureGuardianPersonaFile(userFile: string): void {
|
|
273
|
+
if (basename(userFile) !== userFile || userFile === ".." || userFile === ".") {
|
|
274
|
+
log.warn(
|
|
275
|
+
{ userFile },
|
|
276
|
+
"Guardian persona userFile contains path traversal; refusing to write",
|
|
277
|
+
);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const filePath = join(getWorkspaceDir(), "users", userFile);
|
|
282
|
+
if (existsSync(filePath)) return;
|
|
283
|
+
|
|
284
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
285
|
+
writeFileSync(filePath, GUARDIAN_PERSONA_TEMPLATE, "utf-8");
|
|
286
|
+
log.debug({ path: filePath }, "Wrote guardian persona scaffold");
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Return `true` when the persona file at `filePath` has been edited by
|
|
291
|
+
* the user (its stripped content differs from the bare scaffold
|
|
292
|
+
* template). Returns `false` when the file is missing, unreadable,
|
|
293
|
+
* empty after stripping, or byte-identical to the template after
|
|
294
|
+
* stripping comment lines.
|
|
295
|
+
*
|
|
296
|
+
* Used by the vbundle importer to decide whether a legacy
|
|
297
|
+
* `prompts/USER.md` entry may safely overwrite `users/<slug>.md`.
|
|
298
|
+
*/
|
|
299
|
+
export function isGuardianPersonaCustomized(filePath: string): boolean {
|
|
300
|
+
if (!existsSync(filePath)) return false;
|
|
301
|
+
|
|
302
|
+
let content: string;
|
|
303
|
+
try {
|
|
304
|
+
content = readFileSync(filePath, "utf-8");
|
|
305
|
+
} catch (err) {
|
|
306
|
+
log.warn(
|
|
307
|
+
{ err, path: filePath },
|
|
308
|
+
"Failed to read persona file while checking customization",
|
|
309
|
+
);
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const stripped = stripCommentLines(content);
|
|
314
|
+
if (stripped.length === 0) return false;
|
|
315
|
+
|
|
316
|
+
const templateStripped = stripCommentLines(GUARDIAN_PERSONA_TEMPLATE);
|
|
317
|
+
return stripped !== templateStripped;
|
|
318
|
+
}
|