@vellumai/assistant 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +273 -10
- package/Dockerfile +2 -3
- package/bun.lock +41 -49
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/stt-provider-onboarding.md +120 -0
- package/knip.json +12 -2
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +3 -3
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +1111 -86
- package/package.json +40 -42
- package/scripts/generate-openapi.ts +0 -2
- package/scripts/test.sh +73 -18
- package/src/__tests__/acp-session.test.ts +43 -0
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop.test.ts +123 -0
- package/src/__tests__/anthropic-provider.test.ts +263 -10
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +240 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/browser-skill-endstate.test.ts +31 -7
- package/src/__tests__/btw-routes.test.ts +7 -0
- package/src/__tests__/call-controller.test.ts +581 -20
- package/src/__tests__/catalog-files.test.ts +1000 -0
- package/src/__tests__/channel-approvals.test.ts +53 -0
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/checker.test.ts +157 -10
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/config-analysis.test.ts +100 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +1248 -224
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- package/src/__tests__/context-window-manager.test.ts +88 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +99 -3
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +290 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +12 -4
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +946 -62
- package/src/__tests__/conversation-routes-disk-view.test.ts +275 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +324 -46
- package/src/__tests__/conversation-skill-tools.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +89 -18
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +6 -3
- package/src/__tests__/credential-vault-unit.test.ts +383 -7
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +42 -18
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/date-context.test.ts +4 -4
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +222 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +386 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +2 -0
- package/src/__tests__/gemini-provider.test.ts +66 -2
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
- package/src/__tests__/gmail-archive-gate.test.ts +246 -0
- package/src/__tests__/gmail-preferences.test.ts +117 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +738 -359
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +528 -49
- package/src/__tests__/headless-browser-read-tools.test.ts +274 -100
- package/src/__tests__/headless-browser-snapshot.test.ts +250 -77
- package/src/__tests__/heartbeat-service.test.ts +70 -17
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +145 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +596 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +423 -0
- package/src/__tests__/host-cu-proxy.test.ts +166 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/llm-context-normalization.test.ts +488 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +67 -8
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +109 -7
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +2 -2
- package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +18 -12
- package/src/__tests__/oauth-cli.test.ts +709 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +118 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +147 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +52 -14
- package/src/__tests__/oauth-store.test.ts +1465 -176
- package/src/__tests__/oauth2-gateway-transport.test.ts +460 -26
- package/src/__tests__/onboarding-template-contract.test.ts +81 -70
- package/src/__tests__/openai-provider.test.ts +178 -2
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1105 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outlook-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +32 -3
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +343 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -0
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +423 -5
- package/src/__tests__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/secret-scanner-executor.test.ts +4 -0
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +8 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +801 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +738 -0
- package/src/__tests__/skills.test.ts +5 -2
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +576 -16
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +184 -27
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +25 -5
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +33 -24
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-format.test.ts +59 -0
- package/src/__tests__/update-bulletin.test.ts +206 -5
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-policy.test.ts +2 -0
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +55 -9
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- package/src/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -0
- package/src/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +8 -1
- package/src/channels/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +69 -3
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +22 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +37 -4
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/conversations.ts +77 -0
- package/src/cli/commands/credentials.ts +3 -4
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +273 -16
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +56 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +32 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +330 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +117 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +215 -36
- package/src/cli/commands/oauth/shared.ts +7 -6
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +254 -0
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
- package/src/cli/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -0
- package/src/cli/program.ts +30 -4
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +141 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- package/src/config/bundled-skills/browser/SKILL.md +30 -5
- package/src/config/bundled-skills/browser/TOOLS.json +123 -0
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
- package/src/config/bundled-skills/contacts/SKILL.md +5 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +54 -8
- package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/outlook/SKILL.md +9 -2
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/slack/SKILL.md +1 -0
- package/src/config/bundled-skills/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +8 -0
- package/src/config/env-registry.ts +38 -0
- package/src/config/env.ts +49 -4
- package/src/config/feature-flag-registry.json +85 -14
- package/src/config/loader.ts +82 -13
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +81 -15
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +51 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -26
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +47 -7
- package/src/config/schemas/heartbeat.ts +27 -5
- package/src/config/schemas/host-browser.ts +112 -0
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +52 -0
- package/src/config/schemas/stt.ts +59 -0
- package/src/config/schemas/tts.ts +230 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/skills.ts +4 -0
- package/src/config/types.ts +4 -1
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/post-turn-tool-result-truncation.ts +177 -0
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +61 -10
- package/src/credential-execution/approval-bridge.ts +49 -15
- package/src/credential-execution/executable-discovery.ts +12 -2
- package/src/credential-execution/process-manager.ts +33 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +195 -0
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +23 -2
- package/src/daemon/conversation-agent-loop.ts +153 -42
- package/src/daemon/conversation-attachments.ts +40 -0
- package/src/daemon/conversation-error.ts +11 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +59 -9
- package/src/daemon/conversation-messaging.ts +37 -3
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +622 -13
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +128 -36
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +131 -40
- package/src/daemon/conversation-tool-setup.ts +99 -8
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +292 -16
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +13 -141
- package/src/daemon/handlers/shared.ts +80 -0
- package/src/daemon/handlers/skills.ts +483 -44
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +192 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +179 -28
- package/src/daemon/message-protocol.ts +13 -0
- package/src/daemon/message-types/conversations.ts +89 -14
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +19 -5
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +26 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +439 -14
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/transport-hints.ts +5 -24
- package/src/email/html-renderer.ts +76 -0
- package/src/heartbeat/heartbeat-service.ts +93 -7
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +194 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +398 -0
- package/src/home/assistant-feed-authoring.ts +124 -0
- package/src/home/emit-feed-event.ts +158 -0
- package/src/home/feed-scheduler.ts +247 -0
- package/src/home/feed-types.ts +181 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +384 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +30 -20
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/cli-client.ts +151 -0
- package/src/ipc/cli-server.ts +234 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/index.ts +5 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/mcp/client.ts +59 -24
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/app-store.ts +31 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +73 -0
- package/src/memory/conversation-crud.ts +122 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +34 -2
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +18 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction-job.ts +15 -0
- package/src/memory/graph/extraction.test.ts +23 -0
- package/src/memory/graph/extraction.ts +8 -0
- package/src/memory/graph/retriever.ts +67 -40
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +16 -10
- package/src/memory/jobs-store.ts +64 -4
- package/src/memory/jobs-worker.ts +22 -9
- package/src/memory/llm-usage-store.ts +137 -60
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/index.ts +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/oauth.ts +21 -13
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/client.ts +57 -6
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +143 -38
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/notifications/decision-engine.ts +3 -3
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +25 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +26 -9
- package/src/oauth/byo-connection.ts +10 -8
- package/src/oauth/connect-orchestrator.ts +25 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +22 -18
- package/src/oauth/connection.ts +3 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +223 -100
- package/src/oauth/platform-connection.test.ts +101 -3
- package/src/oauth/platform-connection.ts +56 -35
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +133 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/permissions/workspace-policy.ts +3 -0
- package/src/platform/client.test.ts +10 -0
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +126 -2
- package/src/prompts/system-prompt.ts +76 -38
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-format.ts +26 -9
- package/src/prompts/update-bulletin.ts +34 -23
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/anthropic/client.ts +157 -60
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +9 -1
- package/src/providers/model-catalog.ts +6 -0
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +474 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +502 -0
- package/src/providers/openrouter/client.ts +101 -4
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +14 -3
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +306 -0
- package/src/providers/speech-to-text/resolve.ts +386 -6
- package/src/providers/types.ts +10 -1
- package/src/runtime/AGENTS.md +65 -0
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
- package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +512 -0
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +48 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +33 -9
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/chrome-extension-registry.ts +368 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +815 -75
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +198 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +7 -0
- package/src/runtime/migrations/migration-wizard.ts +23 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +96 -1
- package/src/runtime/migrations/vbundle-importer.ts +89 -5
- package/src/runtime/pending-interactions.ts +18 -13
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/approval-routes.ts +90 -16
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +556 -0
- package/src/runtime/routes/btw-routes.ts +8 -6
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -141
- package/src/runtime/routes/conversation-management-routes.ts +223 -0
- package/src/runtime/routes/conversation-routes.ts +598 -103
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- package/src/runtime/routes/home-feed-routes.ts +334 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +268 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +262 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +11 -3
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +303 -0
- package/src/runtime/routes/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +122 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +31 -102
- package/src/runtime/routes/skills-routes.ts +128 -9
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/subagents-routes.ts +14 -10
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +38 -9
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.ts +8 -1
- package/src/runtime/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +344 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +49 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +57 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +68 -29
- package/src/security/secure-keys.ts +143 -27
- package/src/security/token-manager.ts +31 -10
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +554 -0
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +195 -0
- package/src/stt/stt-stream-session.ts +499 -0
- package/src/stt/types.ts +330 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +169 -40
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
- package/src/tools/browser/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +1787 -342
- package/src/tools/browser/browser-manager.ts +81 -12
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1263 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +359 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1993 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +1007 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +744 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +868 -0
- package/src/tools/browser/cdp-client/errors.ts +49 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +148 -0
- package/src/tools/browser/cdp-client/factory.ts +914 -0
- package/src/tools/browser/cdp-client/index.ts +28 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +120 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +2 -0
- package/src/tools/skills/sandbox-runner.ts +3 -2
- package/src/tools/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +15 -0
- package/src/tools/terminal/shell.ts +36 -20
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +19 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tts/__tests__/provider-adapters.test.ts +834 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +201 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +42 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +153 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/platform.ts +63 -24
- package/src/util/pricing.ts +66 -3
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +23 -0
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/top-level-renderer.ts +31 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/cli/commands/browser-relay.ts +0 -536
- package/src/config/schemas/sandbox.ts +0 -14
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/permissions/permission-mode-store.ts +0 -180
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
2
|
+
import { getConfig } from "../config/loader.js";
|
|
3
|
+
import {
|
|
4
|
+
isUntrustedTrustClass,
|
|
5
|
+
type TrustClass,
|
|
6
|
+
} from "../runtime/actor-trust-resolver.js";
|
|
7
|
+
import { getLogger } from "../util/logger.js";
|
|
8
|
+
import { isAutoAnalysisConversation } from "./auto-analysis-guard.js";
|
|
9
|
+
import { getConversationType } from "./conversation-crud.js";
|
|
10
|
+
import { upsertAutoAnalysisJob } from "./jobs-store.js";
|
|
11
|
+
|
|
12
|
+
const log = getLogger("auto-analysis-enqueue");
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Trigger reason for an auto-analysis enqueue.
|
|
16
|
+
* - `"batch"`: source conversation crossed the batch threshold — enqueue
|
|
17
|
+
* immediately (`runAfter = now`) but still upsert so a pending job
|
|
18
|
+
* coalesces rapid threshold crossings into one.
|
|
19
|
+
* - `"idle"`: source conversation has been idle long enough to warrant a
|
|
20
|
+
* debounced analysis pass.
|
|
21
|
+
* - `"lifecycle"`: a conversation lifecycle transition (e.g. resume,
|
|
22
|
+
* close) should trigger a debounced analysis pass.
|
|
23
|
+
* - `"compaction"`: context was just compacted — some recent turns are
|
|
24
|
+
* now hidden behind a summary, so crystallize anything worth
|
|
25
|
+
* remembering before the window narrows further. Fires immediately
|
|
26
|
+
* (`runAfter = now`) like `"batch"`.
|
|
27
|
+
*/
|
|
28
|
+
export type AutoAnalysisTrigger =
|
|
29
|
+
| "batch"
|
|
30
|
+
| "idle"
|
|
31
|
+
| "lifecycle"
|
|
32
|
+
| "compaction";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Conditionally enqueue a `conversation_analyze` job for the given
|
|
36
|
+
* conversation. Skips silently when:
|
|
37
|
+
* - the `auto-analyze` feature flag is disabled, OR
|
|
38
|
+
* - the source conversation is itself an auto-analysis conversation
|
|
39
|
+
* (recursion guard — we never analyze our own analysis output), OR
|
|
40
|
+
* - the source conversation is private (`analyzeConversation` rejects
|
|
41
|
+
* private conversations, so enqueueing would guarantee a failed job).
|
|
42
|
+
*
|
|
43
|
+
* Immediate triggers (`"batch"`, `"compaction"`) and debounced triggers
|
|
44
|
+
* (`"idle"`, `"lifecycle"`) are written to separate rows keyed by a
|
|
45
|
+
* `triggerGroup` discriminator. This prevents an idle enqueue from
|
|
46
|
+
* pushing an already-scheduled batch row's `runAfter` into the future
|
|
47
|
+
* (and vice versa). Within each group, rapid enqueues still coalesce to
|
|
48
|
+
* a single pending row via `upsertAutoAnalysisJob`.
|
|
49
|
+
*/
|
|
50
|
+
export function enqueueAutoAnalysisIfEnabled(args: {
|
|
51
|
+
conversationId: string;
|
|
52
|
+
trigger: AutoAnalysisTrigger;
|
|
53
|
+
}): void {
|
|
54
|
+
const { conversationId, trigger } = args;
|
|
55
|
+
|
|
56
|
+
let config;
|
|
57
|
+
try {
|
|
58
|
+
config = getConfig();
|
|
59
|
+
} catch (err) {
|
|
60
|
+
log.warn(
|
|
61
|
+
{ err, conversationId },
|
|
62
|
+
"Skipping auto-analysis enqueue: failed to load config",
|
|
63
|
+
);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!isAssistantFeatureFlagEnabled("auto-analyze", config)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (isAutoAnalysisConversation(conversationId)) {
|
|
72
|
+
log.debug(
|
|
73
|
+
{ conversationId, trigger },
|
|
74
|
+
"Skipping auto-analysis enqueue: source is an auto-analysis conversation",
|
|
75
|
+
);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (getConversationType(conversationId) === "private") {
|
|
80
|
+
log.debug(
|
|
81
|
+
{ conversationId, trigger },
|
|
82
|
+
"Skipping auto-analysis enqueue: source is a private conversation",
|
|
83
|
+
);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const idleTimeoutMs = config.analysis?.idleTimeoutMs ?? 600_000;
|
|
88
|
+
const runImmediately = trigger === "batch" || trigger === "compaction";
|
|
89
|
+
const triggerGroup: "immediate" | "debounced" = runImmediately
|
|
90
|
+
? "immediate"
|
|
91
|
+
: "debounced";
|
|
92
|
+
const runAfter = runImmediately ? Date.now() : Date.now() + idleTimeoutMs;
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
upsertAutoAnalysisJob({ conversationId, triggerGroup }, runAfter);
|
|
96
|
+
} catch (err) {
|
|
97
|
+
log.warn(
|
|
98
|
+
{ err, conversationId, trigger },
|
|
99
|
+
"Failed to enqueue auto-analysis job",
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Fire an auto-analysis enqueue from a compaction site. Wraps
|
|
106
|
+
* `enqueueAutoAnalysisIfEnabled` with the trust-class gate and
|
|
107
|
+
* best-effort error handling used at every compaction call site, so
|
|
108
|
+
* the six compaction paths (forceCompact, preflight, overflow reducer,
|
|
109
|
+
* mid-loop, and two emergency paths) stay in sync.
|
|
110
|
+
*
|
|
111
|
+
* Trust gate mirrors the memory-extraction trust boundary applied in
|
|
112
|
+
* `disposeConversation` — we don't trigger analysis (which runs with
|
|
113
|
+
* guardian trust + full tools) for conversations with an untrusted actor.
|
|
114
|
+
*/
|
|
115
|
+
export function enqueueAutoAnalysisOnCompaction(
|
|
116
|
+
conversationId: string,
|
|
117
|
+
trustClass: TrustClass | undefined,
|
|
118
|
+
): void {
|
|
119
|
+
if (isUntrustedTrustClass(trustClass)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
enqueueAutoAnalysisIfEnabled({ conversationId, trigger: "compaction" });
|
|
124
|
+
} catch {
|
|
125
|
+
// Best-effort — never block compaction on enqueue failures.
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getConversationSource } from "./conversation-crud.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The `source` value used for conversations created by the auto-analysis
|
|
5
|
+
* loop. Single source of truth — downstream code (enqueue helper,
|
|
6
|
+
* service auto-branch) imports this constant rather than hardcoding the
|
|
7
|
+
* string.
|
|
8
|
+
*/
|
|
9
|
+
export const AUTO_ANALYSIS_SOURCE = "auto-analysis";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Dedicated `group_id` value for auto-analysis rolling conversations.
|
|
13
|
+
* Placed in the `system:background` group alongside heartbeat and filing
|
|
14
|
+
* conversations, rendered as a "Reflections" sub-group in the sidebar.
|
|
15
|
+
*/
|
|
16
|
+
export const AUTO_ANALYSIS_GROUP_ID = "system:background";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Returns true if the conversation's `source` column is `"auto-analysis"`,
|
|
20
|
+
* meaning it was produced by the auto-analysis loop. Callers use this to
|
|
21
|
+
* skip both `graph_extract` and `conversation_analyze` enqueues so we
|
|
22
|
+
* never (a) analyze our own analysis output or (b) extract memory from
|
|
23
|
+
* reflective musings (the analysis agent writes memory directly via tools).
|
|
24
|
+
*/
|
|
25
|
+
export function isAutoAnalysisConversation(conversationId: string): boolean {
|
|
26
|
+
return getConversationSource(conversationId) === AUTO_ANALYSIS_SOURCE;
|
|
27
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared state for the cleanup-scheduler throttle.
|
|
3
|
+
*
|
|
4
|
+
* `maybeEnqueueScheduledCleanupJobs` in jobs-worker.ts gates cleanup-job
|
|
5
|
+
* enqueueing behind a 6-hour window (configurable via
|
|
6
|
+
* memory.cleanup.enqueueIntervalMs). This module owns the "last enqueue"
|
|
7
|
+
* timestamp so that code paths outside jobs-worker — notably
|
|
8
|
+
* ConfigWatcher.refreshConfigFromSources — can reset the throttle without
|
|
9
|
+
* pulling in jobs-worker's large transitive import graph.
|
|
10
|
+
*
|
|
11
|
+
* The ConfigWatcher uses resetCleanupScheduleThrottle() to ensure that
|
|
12
|
+
* retention changes made via the UI (which flow through config.json →
|
|
13
|
+
* invalidateConfigCache → refreshConfigFromSources) take effect on the
|
|
14
|
+
* very next scheduler tick instead of waiting out the remaining window.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
let lastScheduledCleanupEnqueueMs = 0;
|
|
18
|
+
|
|
19
|
+
/** Read the timestamp of the most recent enqueue (0 if never/reset). */
|
|
20
|
+
export function getLastScheduledCleanupEnqueueMs(): number {
|
|
21
|
+
return lastScheduledCleanupEnqueueMs;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Record that an enqueue just happened at `nowMs`. */
|
|
25
|
+
export function markScheduledCleanupEnqueued(nowMs: number): void {
|
|
26
|
+
lastScheduledCleanupEnqueueMs = nowMs;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Clear the throttle so the next `maybeEnqueueScheduledCleanupJobs` call
|
|
31
|
+
* bypasses the `enqueueIntervalMs` window. Used by ConfigWatcher when
|
|
32
|
+
* retention settings change, and by tests that need deterministic
|
|
33
|
+
* scheduling.
|
|
34
|
+
*/
|
|
35
|
+
export function resetCleanupScheduleThrottle(): void {
|
|
36
|
+
lastScheduledCleanupEnqueueMs = 0;
|
|
37
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Auto-analyze — conversation_analyze job handler
|
|
3
|
+
//
|
|
4
|
+
// Bridges the jobs worker to the shared analyzeConversation() service. The
|
|
5
|
+
// deps bundle is stashed on a module singleton during daemon startup; if it
|
|
6
|
+
// isn't set yet we skip this iteration. The next batch / idle / lifecycle
|
|
7
|
+
// trigger from `enqueueAutoAnalysisIfEnabled()` will produce a fresh job
|
|
8
|
+
// once the daemon has fully started.
|
|
9
|
+
//
|
|
10
|
+
// The service itself distinguishes manual vs. auto triggers: this handler
|
|
11
|
+
// always invokes with `trigger: "auto"`, so the rolling analysis conversation
|
|
12
|
+
// logic and recursion guard apply.
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
import type { AssistantConfig } from "../config/types.js";
|
|
16
|
+
import { analyzeConversation } from "../runtime/services/analyze-conversation.js";
|
|
17
|
+
import { getAnalysisDeps } from "../runtime/services/analyze-deps-singleton.js";
|
|
18
|
+
import { getLogger } from "../util/logger.js";
|
|
19
|
+
import { enqueueAutoAnalysisIfEnabled } from "./auto-analysis-enqueue.js";
|
|
20
|
+
import type { MemoryJob } from "./jobs-store.js";
|
|
21
|
+
|
|
22
|
+
const log = getLogger("conversation-analyze-job");
|
|
23
|
+
|
|
24
|
+
export async function conversationAnalyzeJob(
|
|
25
|
+
job: MemoryJob<{ conversationId?: string }>,
|
|
26
|
+
_config: AssistantConfig,
|
|
27
|
+
): Promise<void> {
|
|
28
|
+
const { conversationId } = job.payload;
|
|
29
|
+
if (!conversationId) {
|
|
30
|
+
log.warn({ jobId: job.id }, "Skipping job: missing conversationId");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const deps = getAnalysisDeps();
|
|
35
|
+
if (!deps) {
|
|
36
|
+
// Daemon hasn't finished startup. Return without throwing — a plain
|
|
37
|
+
// Error here would be classified as fatal by `classifyError()` and the
|
|
38
|
+
// worker would mark the job permanently failed. Throwing
|
|
39
|
+
// `BackendUnavailableError` would defer, but defer counters cap out and
|
|
40
|
+
// would still permanently fail in the worst case. Since
|
|
41
|
+
// `enqueueAutoAnalysisIfEnabled()` re-enqueues on the next batch / idle
|
|
42
|
+
// / lifecycle trigger, dropping this iteration is the safest choice and
|
|
43
|
+
// avoids retry storms during slow daemon startup.
|
|
44
|
+
log.warn(
|
|
45
|
+
{ jobId: job.id, conversationId },
|
|
46
|
+
"Skipping job: analysis deps not yet initialized; will retrigger",
|
|
47
|
+
);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const result = await analyzeConversation(conversationId, deps, {
|
|
52
|
+
trigger: "auto",
|
|
53
|
+
});
|
|
54
|
+
if ("error" in result) {
|
|
55
|
+
log.warn(
|
|
56
|
+
{ jobId: job.id, conversationId, error: result.error },
|
|
57
|
+
"Auto-analysis service rejected source conversation",
|
|
58
|
+
);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (result.skipped) {
|
|
62
|
+
// The rolling analysis conversation was still processing a prior run, so
|
|
63
|
+
// this invocation was a no-op. Schedule a debounced follow-up ourselves
|
|
64
|
+
// — otherwise, if no later batch/idle/lifecycle trigger arrives (e.g.
|
|
65
|
+
// the conversation goes quiet after a long in-flight analysis), new
|
|
66
|
+
// source messages would stay un-analyzed indefinitely.
|
|
67
|
+
enqueueAutoAnalysisIfEnabled({ conversationId, trigger: "idle" });
|
|
68
|
+
log.debug(
|
|
69
|
+
{ jobId: job.id, conversationId },
|
|
70
|
+
"Auto-analysis skipped (rolling conversation busy); requeued follow-up",
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
deleteOrphanAttachments,
|
|
31
31
|
linkAttachmentToMessage,
|
|
32
32
|
} from "./attachments-store.js";
|
|
33
|
+
import { AUTO_ANALYSIS_SOURCE } from "./auto-analysis-guard.js";
|
|
33
34
|
import {
|
|
34
35
|
projectAssistantMessage,
|
|
35
36
|
seedForkedConversationAttention,
|
|
@@ -170,9 +171,11 @@ export interface ConversationRow {
|
|
|
170
171
|
originInterface: string | null;
|
|
171
172
|
forkParentConversationId: string | null;
|
|
172
173
|
forkParentMessageId: string | null;
|
|
174
|
+
hostAccess: number;
|
|
173
175
|
isAutoTitle: number;
|
|
174
176
|
scheduleJobId: string | null;
|
|
175
177
|
lastMessageAt: number | null;
|
|
178
|
+
archivedAt: number | null;
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
export const parseConversation = createRowMapper<
|
|
@@ -196,9 +199,11 @@ export const parseConversation = createRowMapper<
|
|
|
196
199
|
originInterface: "originInterface",
|
|
197
200
|
forkParentConversationId: "forkParentConversationId",
|
|
198
201
|
forkParentMessageId: "forkParentMessageId",
|
|
202
|
+
hostAccess: "hostAccess",
|
|
199
203
|
isAutoTitle: "isAutoTitle",
|
|
200
204
|
scheduleJobId: "scheduleJobId",
|
|
201
205
|
lastMessageAt: "lastMessageAt",
|
|
206
|
+
archivedAt: "archivedAt",
|
|
202
207
|
});
|
|
203
208
|
|
|
204
209
|
export interface MessageRow {
|
|
@@ -245,6 +250,8 @@ export function createConversation(
|
|
|
245
250
|
source?: string;
|
|
246
251
|
scheduleJobId?: string;
|
|
247
252
|
groupId?: string;
|
|
253
|
+
hostAccess?: boolean;
|
|
254
|
+
forkParentConversationId?: string;
|
|
248
255
|
},
|
|
249
256
|
) {
|
|
250
257
|
const db = getDb();
|
|
@@ -276,10 +283,12 @@ export function createConversation(
|
|
|
276
283
|
contextSummary: null as string | null,
|
|
277
284
|
contextCompactedMessageCount: 0,
|
|
278
285
|
contextCompactedAt: null as number | null,
|
|
286
|
+
hostAccess: opts.hostAccess ? 1 : 0,
|
|
279
287
|
conversationType,
|
|
280
288
|
source,
|
|
281
289
|
memoryScopeId,
|
|
282
290
|
scheduleJobId: opts.scheduleJobId ?? null,
|
|
291
|
+
forkParentConversationId: opts.forkParentConversationId ?? null,
|
|
283
292
|
};
|
|
284
293
|
|
|
285
294
|
// Retry on SQLITE_BUSY and SQLITE_IOERR — transient disk I/O errors or WAL
|
|
@@ -375,6 +384,54 @@ export function countConversationsByScheduleJobId(
|
|
|
375
384
|
);
|
|
376
385
|
}
|
|
377
386
|
|
|
387
|
+
/**
|
|
388
|
+
* Find the rolling analysis conversation for a given source conversation,
|
|
389
|
+
* or null if none exists yet. Used by the auto-analyze loop to append
|
|
390
|
+
* to an existing analysis conversation rather than creating a new one
|
|
391
|
+
* each time the analyze job fires.
|
|
392
|
+
*
|
|
393
|
+
* Returns the most recently updated match if multiple exist (defensive —
|
|
394
|
+
* shouldn't happen in normal operation but the contract is well-defined).
|
|
395
|
+
*
|
|
396
|
+
* Hits `idx_conversations_fork_parent_conversation_id` for the
|
|
397
|
+
* `forkParentConversationId` lookup.
|
|
398
|
+
*/
|
|
399
|
+
export function findAnalysisConversationFor(
|
|
400
|
+
parentConversationId: string,
|
|
401
|
+
): { id: string } | null {
|
|
402
|
+
const db = getDb();
|
|
403
|
+
const row = db
|
|
404
|
+
.select({ id: conversations.id })
|
|
405
|
+
.from(conversations)
|
|
406
|
+
.where(
|
|
407
|
+
and(
|
|
408
|
+
eq(conversations.source, AUTO_ANALYSIS_SOURCE),
|
|
409
|
+
eq(conversations.forkParentConversationId, parentConversationId),
|
|
410
|
+
),
|
|
411
|
+
)
|
|
412
|
+
.orderBy(desc(conversations.updatedAt))
|
|
413
|
+
.limit(1)
|
|
414
|
+
.get();
|
|
415
|
+
return row ? { id: row.id } : null;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Returns the `source` column for the given conversation, or null if
|
|
420
|
+
* not found. Tiny convenience used by the recursion guard in the
|
|
421
|
+
* auto-analyze loop.
|
|
422
|
+
*/
|
|
423
|
+
export function getConversationSource(
|
|
424
|
+
conversationId: string,
|
|
425
|
+
): string | null {
|
|
426
|
+
const db = getDb();
|
|
427
|
+
const row = db
|
|
428
|
+
.select({ source: conversations.source })
|
|
429
|
+
.from(conversations)
|
|
430
|
+
.where(eq(conversations.id, conversationId))
|
|
431
|
+
.get();
|
|
432
|
+
return row?.source ?? null;
|
|
433
|
+
}
|
|
434
|
+
|
|
378
435
|
export function getConversationType(
|
|
379
436
|
conversationId: string,
|
|
380
437
|
): "standard" | "private" {
|
|
@@ -388,6 +445,11 @@ export function getConversationMemoryScopeId(conversationId: string): string {
|
|
|
388
445
|
return conv?.memoryScopeId ?? "default";
|
|
389
446
|
}
|
|
390
447
|
|
|
448
|
+
export function getConversationHostAccess(conversationId: string): boolean {
|
|
449
|
+
const conv = getConversation(conversationId);
|
|
450
|
+
return conv?.hostAccess === 1;
|
|
451
|
+
}
|
|
452
|
+
|
|
391
453
|
/**
|
|
392
454
|
* Fetch group_id for a conversation via raw SQL. group_id is NOT in the
|
|
393
455
|
* Drizzle schema (raw-query-only pattern), so ConversationRow doesn't
|
|
@@ -1053,6 +1115,27 @@ export function getLastAssistantTimestampBefore(
|
|
|
1053
1115
|
return row?.createdAt ?? 0;
|
|
1054
1116
|
}
|
|
1055
1117
|
|
|
1118
|
+
export function getLastUserTimestampBefore(
|
|
1119
|
+
conversationId: string,
|
|
1120
|
+
beforeTimestamp: number,
|
|
1121
|
+
): number {
|
|
1122
|
+
const db = getDb();
|
|
1123
|
+
const row = db
|
|
1124
|
+
.select({ createdAt: messages.createdAt })
|
|
1125
|
+
.from(messages)
|
|
1126
|
+
.where(
|
|
1127
|
+
and(
|
|
1128
|
+
eq(messages.conversationId, conversationId),
|
|
1129
|
+
eq(messages.role, "user"),
|
|
1130
|
+
lt(messages.createdAt, beforeTimestamp),
|
|
1131
|
+
),
|
|
1132
|
+
)
|
|
1133
|
+
.orderBy(desc(messages.createdAt))
|
|
1134
|
+
.limit(1)
|
|
1135
|
+
.get();
|
|
1136
|
+
return row?.createdAt ?? 0;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1056
1139
|
/** Fetch a single message by ID, optionally scoped to a specific conversation. */
|
|
1057
1140
|
export function getMessageById(
|
|
1058
1141
|
messageId: string,
|
|
@@ -1123,6 +1206,45 @@ export function updateConversationContextWindow(
|
|
|
1123
1206
|
.run();
|
|
1124
1207
|
}
|
|
1125
1208
|
|
|
1209
|
+
export function updateConversationHostAccess(
|
|
1210
|
+
id: string,
|
|
1211
|
+
hostAccess: boolean,
|
|
1212
|
+
): void {
|
|
1213
|
+
const db = getDb();
|
|
1214
|
+
db.update(conversations)
|
|
1215
|
+
.set({
|
|
1216
|
+
hostAccess: hostAccess ? 1 : 0,
|
|
1217
|
+
updatedAt: Date.now(),
|
|
1218
|
+
})
|
|
1219
|
+
.where(eq(conversations.id, id))
|
|
1220
|
+
.run();
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
export function archiveConversation(id: string): boolean {
|
|
1224
|
+
const conv = getConversation(id);
|
|
1225
|
+
if (!conv) return false;
|
|
1226
|
+
const now = Date.now();
|
|
1227
|
+
rawRun(
|
|
1228
|
+
"UPDATE conversations SET archived_at = ?, updated_at = ? WHERE id = ?",
|
|
1229
|
+
now,
|
|
1230
|
+
now,
|
|
1231
|
+
id,
|
|
1232
|
+
);
|
|
1233
|
+
return true;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
export function unarchiveConversation(id: string): boolean {
|
|
1237
|
+
const conv = getConversation(id);
|
|
1238
|
+
if (!conv) return false;
|
|
1239
|
+
const now = Date.now();
|
|
1240
|
+
rawRun(
|
|
1241
|
+
"UPDATE conversations SET archived_at = NULL, updated_at = ? WHERE id = ?",
|
|
1242
|
+
now,
|
|
1243
|
+
id,
|
|
1244
|
+
);
|
|
1245
|
+
return true;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1126
1248
|
/**
|
|
1127
1249
|
* Delete all conversations, messages, and related data (tool invocations,
|
|
1128
1250
|
* memory segments, etc.) from the daemon database.
|
|
@@ -310,6 +310,13 @@ export function syncMessageToDisk(
|
|
|
310
310
|
if (toolResults.length > 0) record.toolResults = toolResults;
|
|
311
311
|
if (attachmentFilenames.length > 0)
|
|
312
312
|
record.attachments = attachmentFilenames;
|
|
313
|
+
if (message.metadata) {
|
|
314
|
+
try {
|
|
315
|
+
record.metadata = JSON.parse(message.metadata);
|
|
316
|
+
} catch {
|
|
317
|
+
// Invalid JSON — omit metadata from disk record
|
|
318
|
+
}
|
|
319
|
+
}
|
|
313
320
|
|
|
314
321
|
appendFileSync(
|
|
315
322
|
join(dirPath, "messages.jsonl"),
|
|
@@ -57,7 +57,11 @@ export function ensureGroupMigration(): void {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
// 3. Seed system groups
|
|
60
|
+
// 3. Seed system groups.
|
|
61
|
+
//
|
|
62
|
+
// `system:reflections` is a legacy group kept for backward compatibility
|
|
63
|
+
// with existing installations. New auto-analysis conversations are assigned
|
|
64
|
+
// to `system:background`; the migration in step 6 moves existing ones.
|
|
61
65
|
const now = Math.floor(Date.now() / 1000);
|
|
62
66
|
rawExec(`
|
|
63
67
|
INSERT OR IGNORE INTO conversation_groups (id, name, sort_position, is_system_group, created_at, updated_at)
|
|
@@ -65,7 +69,8 @@ export function ensureGroupMigration(): void {
|
|
|
65
69
|
('system:pinned', 'Pinned', 0, TRUE, ${now}, ${now}),
|
|
66
70
|
('system:scheduled', 'Scheduled', 1, TRUE, ${now}, ${now}),
|
|
67
71
|
('system:background', 'Background', 2, TRUE, ${now}, ${now}),
|
|
68
|
-
('system:all', 'Recents', 3, TRUE, ${now}, ${now})
|
|
72
|
+
('system:all', 'Recents', 3, TRUE, ${now}, ${now}),
|
|
73
|
+
('system:reflections', 'Reflections', 100, TRUE, ${now}, ${now})
|
|
69
74
|
`);
|
|
70
75
|
|
|
71
76
|
// One-time migration: move system:all to sortPosition 3 (from 999999).
|
|
@@ -213,5 +218,32 @@ export function ensureGroupMigration(): void {
|
|
|
213
218
|
}
|
|
214
219
|
}
|
|
215
220
|
|
|
221
|
+
// 6. One-time migration: move auto-analysis conversations from system:reflections to system:background
|
|
222
|
+
const reflectionsMigrateDone = rawGet<{ id: string }>(
|
|
223
|
+
"SELECT id FROM conversation_groups WHERE id = '_reflections_to_background_complete'",
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
if (!reflectionsMigrateDone) {
|
|
227
|
+
try {
|
|
228
|
+
rawExec("BEGIN");
|
|
229
|
+
|
|
230
|
+
rawExec(`
|
|
231
|
+
UPDATE conversations SET group_id = 'system:background'
|
|
232
|
+
WHERE group_id = 'system:reflections'
|
|
233
|
+
`);
|
|
234
|
+
|
|
235
|
+
rawExec(`
|
|
236
|
+
INSERT OR IGNORE INTO conversation_groups (id, name, sort_position, is_system_group)
|
|
237
|
+
VALUES ('_reflections_to_background_complete', '_reflections_to_background_complete', -1, TRUE)
|
|
238
|
+
`);
|
|
239
|
+
|
|
240
|
+
rawExec("COMMIT");
|
|
241
|
+
} catch (err) {
|
|
242
|
+
rawExec("ROLLBACK");
|
|
243
|
+
log.error({ err }, "reflections-to-background migration failed, rolled back");
|
|
244
|
+
throw err;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
216
248
|
migrated = true;
|
|
217
249
|
}
|
|
@@ -218,7 +218,7 @@ export function searchConversations(
|
|
|
218
218
|
FROM messages_fts f
|
|
219
219
|
JOIN messages m ON m.id = f.message_id
|
|
220
220
|
JOIN conversations c ON c.id = m.conversation_id
|
|
221
|
-
WHERE messages_fts MATCH ? AND c.conversation_type NOT IN ('background', 'private', 'scheduled')
|
|
221
|
+
WHERE messages_fts MATCH ? AND c.conversation_type NOT IN ('background', 'private', 'scheduled') AND c.archived_at IS NULL
|
|
222
222
|
LIMIT 1000
|
|
223
223
|
`,
|
|
224
224
|
ftsMatch,
|
|
@@ -243,7 +243,7 @@ export function searchConversations(
|
|
|
243
243
|
SELECT DISTINCT m.conversation_id
|
|
244
244
|
FROM messages m
|
|
245
245
|
JOIN conversations c ON c.id = m.conversation_id
|
|
246
|
-
WHERE m.content LIKE ? ESCAPE '\\' AND c.conversation_type NOT IN ('background', 'private', 'scheduled')
|
|
246
|
+
WHERE m.content LIKE ? ESCAPE '\\' AND c.conversation_type NOT IN ('background', 'private', 'scheduled') AND c.archived_at IS NULL
|
|
247
247
|
LIMIT 1000
|
|
248
248
|
`,
|
|
249
249
|
likePattern,
|
|
@@ -257,9 +257,10 @@ export function searchConversations(
|
|
|
257
257
|
.from(conversations)
|
|
258
258
|
.where(
|
|
259
259
|
and(
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
260
|
+
sql`${conversations.conversationType} NOT IN ('background', 'private', 'scheduled')`,
|
|
261
|
+
sql`${conversations.title} LIKE ${titlePattern} ESCAPE '\\'`,
|
|
262
|
+
sql`${conversations.archivedAt} IS NULL`,
|
|
263
|
+
),
|
|
263
264
|
)
|
|
264
265
|
.all();
|
|
265
266
|
for (const row of titleMatchConvs) ftsConvIds.add(row.id);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cadence logic for conversation starters generation.
|
|
3
|
+
*
|
|
4
|
+
* Decides whether a new generation job should be enqueued based on how many
|
|
5
|
+
* active memory items have accumulated since the last generation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { and, eq, inArray, sql } from "drizzle-orm";
|
|
9
|
+
|
|
10
|
+
import { getLogger } from "../util/logger.js";
|
|
11
|
+
import { getDb } from "./db.js";
|
|
12
|
+
import { enqueueMemoryJob } from "./jobs-store.js";
|
|
13
|
+
import { rawGet } from "./raw-query.js";
|
|
14
|
+
import { memoryCheckpoints, memoryJobs } from "./schema.js";
|
|
15
|
+
|
|
16
|
+
const log = getLogger("conversation-starters-cadence");
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Check whether enough new memory items have accumulated to justify
|
|
20
|
+
* generating a fresh batch of conversation starters.
|
|
21
|
+
*/
|
|
22
|
+
export function maybeEnqueueConversationStartersJob(scopeId: string): void {
|
|
23
|
+
const db = getDb();
|
|
24
|
+
|
|
25
|
+
// Count total active memory items
|
|
26
|
+
const countRow = rawGet<{ c: number }>(
|
|
27
|
+
`SELECT COUNT(*) AS c FROM memory_graph_nodes WHERE fidelity != 'gone' AND scope_id = ?`,
|
|
28
|
+
scopeId,
|
|
29
|
+
);
|
|
30
|
+
const totalActive = countRow?.c ?? 0;
|
|
31
|
+
if (totalActive === 0) return;
|
|
32
|
+
|
|
33
|
+
// Read checkpoint: item count at last generation (scoped so each scope tracks independently)
|
|
34
|
+
const checkpointKey = `conversation_starters:item_count_at_last_gen:${scopeId}`;
|
|
35
|
+
const checkpoint = db
|
|
36
|
+
.select({ value: memoryCheckpoints.value })
|
|
37
|
+
.from(memoryCheckpoints)
|
|
38
|
+
.where(eq(memoryCheckpoints.key, checkpointKey))
|
|
39
|
+
.get();
|
|
40
|
+
const parsedLastCount = checkpoint ? parseInt(checkpoint.value, 10) : 0;
|
|
41
|
+
const lastCount = Number.isFinite(parsedLastCount) ? parsedLastCount : 0;
|
|
42
|
+
|
|
43
|
+
// Cadence formula
|
|
44
|
+
let threshold: number;
|
|
45
|
+
if (totalActive <= 10) {
|
|
46
|
+
threshold = 1;
|
|
47
|
+
} else if (totalActive <= 50) {
|
|
48
|
+
threshold = 5;
|
|
49
|
+
} else {
|
|
50
|
+
threshold = 10;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const checkpointAhead = totalActive < lastCount;
|
|
54
|
+
const delta = Math.max(0, totalActive - lastCount);
|
|
55
|
+
if (!checkpointAhead && delta < threshold) return;
|
|
56
|
+
|
|
57
|
+
// Dedup: don't enqueue if a pending/running job for this scope already exists
|
|
58
|
+
const existing = db
|
|
59
|
+
.select({ id: memoryJobs.id })
|
|
60
|
+
.from(memoryJobs)
|
|
61
|
+
.where(
|
|
62
|
+
and(
|
|
63
|
+
eq(memoryJobs.type, "generate_conversation_starters"),
|
|
64
|
+
inArray(memoryJobs.status, ["pending", "running"]),
|
|
65
|
+
sql`json_extract(${memoryJobs.payload}, '$.scopeId') = ${scopeId}`,
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
.get();
|
|
69
|
+
if (existing) return;
|
|
70
|
+
|
|
71
|
+
enqueueMemoryJob("generate_conversation_starters", { scopeId });
|
|
72
|
+
log.info(
|
|
73
|
+
{ totalActive, lastCount, delta, threshold, scopeId, checkpointAhead },
|
|
74
|
+
"Enqueued conversation starters generation job",
|
|
75
|
+
);
|
|
76
|
+
}
|
|
@@ -284,10 +284,13 @@ export function queueRegenerateConversationTitle(
|
|
|
284
284
|
*/
|
|
285
285
|
function buildTitleSystemPrompt(): string {
|
|
286
286
|
return [
|
|
287
|
-
"You generate
|
|
287
|
+
"You generate ultra-concise conversation titles. Output ONLY the title text — no explanation, no quotes, no markdown, no preamble.",
|
|
288
288
|
"",
|
|
289
289
|
"Rules:",
|
|
290
|
-
"-
|
|
290
|
+
"- 2–6 words. Titles longer than 6 words are unacceptable — ruthlessly compress",
|
|
291
|
+
"- Summarize the TOPIC, not the request or instructions",
|
|
292
|
+
"- Noun phrases are ideal (e.g. 'Auth Middleware Rewrite', 'Docker Volume Mounts')",
|
|
293
|
+
"- Do NOT echo back what the user asked you to do",
|
|
291
294
|
"- Do NOT respond to the conversation content",
|
|
292
295
|
"- Do NOT assess feasibility or comment on capabilities",
|
|
293
296
|
].join("\n");
|