@vellumai/assistant 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +273 -10
- package/Dockerfile +2 -3
- package/bun.lock +5 -13
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/stt-provider-onboarding.md +120 -0
- package/knip.json +12 -2
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +3 -3
- package/openapi.yaml +982 -72
- package/package.json +4 -6
- package/scripts/generate-openapi.ts +0 -1
- package/scripts/test.sh +73 -18
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop.test.ts +123 -0
- package/src/__tests__/anthropic-provider.test.ts +263 -10
- package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +11 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/browser-skill-endstate.test.ts +31 -7
- package/src/__tests__/btw-routes.test.ts +7 -0
- package/src/__tests__/call-controller.test.ts +581 -20
- package/src/__tests__/catalog-files.test.ts +138 -0
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/checker.test.ts +157 -10
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/config-analysis.test.ts +100 -0
- package/src/__tests__/config-schema.test.ts +1013 -66
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-window-manager.test.ts +88 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +98 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +135 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-history-web-search.test.ts +11 -4
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +901 -60
- package/src/__tests__/conversation-routes-disk-view.test.ts +270 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +55 -0
- package/src/__tests__/conversation-skill-tools.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +89 -18
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +5 -3
- package/src/__tests__/credential-vault-unit.test.ts +379 -3
- package/src/__tests__/credentials-cli.test.ts +40 -16
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +75 -8
- package/src/__tests__/fixtures/mock-chrome-extension.ts +11 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-provider.test.ts +64 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
- package/src/__tests__/gmail-archive-gate.test.ts +246 -0
- package/src/__tests__/gmail-preferences.test.ts +117 -0
- package/src/__tests__/headless-browser-interactions.test.ts +43 -0
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +142 -5
- package/src/__tests__/headless-browser-read-tools.test.ts +11 -0
- package/src/__tests__/headless-browser-snapshot.test.ts +10 -0
- package/src/__tests__/heartbeat-service.test.ts +70 -17
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +0 -5
- package/src/__tests__/host-browser-e2e-cloud.test.ts +138 -4
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +4 -4
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +103 -0
- package/src/__tests__/host-cu-proxy.test.ts +0 -5
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/llm-context-normalization.test.ts +488 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/migration-export-http.test.ts +6 -6
- package/src/__tests__/migration-import-commit-http.test.ts +8 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +2 -2
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +2 -0
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
- package/src/__tests__/oauth-providers-routes.test.ts +2 -0
- package/src/__tests__/oauth-store.test.ts +85 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +249 -6
- package/src/__tests__/onboarding-template-contract.test.ts +6 -13
- package/src/__tests__/openai-provider.test.ts +176 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1105 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +31 -2
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +423 -5
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-scanner-executor.test.ts +4 -0
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +5 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +276 -145
- package/src/__tests__/skills-files-catalog-fallback.test.ts +381 -93
- package/src/__tests__/skills.test.ts +5 -2
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +564 -1
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/system-prompt.test.ts +112 -26
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +18 -7
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +33 -24
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-format.test.ts +59 -0
- package/src/__tests__/update-bulletin.test.ts +206 -5
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-policy.test.ts +2 -0
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +43 -3
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- package/src/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +8 -1
- package/src/channels/types.ts +16 -0
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +22 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +37 -4
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/conversations.ts +77 -0
- package/src/cli/commands/credentials.ts +0 -1
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +255 -3
- package/src/cli/commands/oauth/__tests__/connect.test.ts +12 -0
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -0
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +15 -0
- package/src/cli/commands/oauth/shared.ts +2 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +4 -9
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
- package/src/cli/program.ts +30 -4
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +37 -1
- package/src/config/bundled-skills/browser/SKILL.md +30 -5
- package/src/config/bundled-skills/browser/TOOLS.json +123 -0
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
- package/src/config/bundled-skills/contacts/SKILL.md +2 -2
- package/src/config/bundled-skills/gmail/SKILL.md +53 -7
- package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/outlook/SKILL.md +2 -2
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/slack/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +8 -0
- package/src/config/env-registry.ts +24 -0
- package/src/config/env.ts +34 -10
- package/src/config/feature-flag-registry.json +46 -14
- package/src/config/loader.ts +26 -12
- package/src/config/schema.ts +35 -10
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +51 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -26
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +47 -7
- package/src/config/schemas/heartbeat.ts +27 -5
- package/src/config/schemas/host-browser.ts +47 -1
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/services.ts +44 -0
- package/src/config/schemas/stt.ts +59 -0
- package/src/config/schemas/tts.ts +230 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/skills.ts +4 -0
- package/src/config/types.ts +4 -0
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/post-turn-tool-result-truncation.ts +3 -2
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +45 -12
- package/src/credential-execution/executable-discovery.ts +12 -2
- package/src/credential-execution/process-manager.ts +33 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +17 -8
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/conversation-agent-loop-handlers.ts +6 -0
- package/src/daemon/conversation-agent-loop.ts +101 -24
- package/src/daemon/conversation-error.ts +11 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +59 -9
- package/src/daemon/conversation-messaging.ts +37 -3
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +581 -19
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +11 -1
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +94 -4
- package/src/daemon/conversation-tool-setup.ts +25 -0
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation.ts +86 -28
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +4 -1
- package/src/daemon/handlers/shared.ts +22 -0
- package/src/daemon/handlers/skills.ts +321 -77
- package/src/daemon/host-browser-proxy.ts +2 -1
- package/src/daemon/lifecycle.ts +122 -25
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/conversations.ts +34 -1
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +14 -0
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +16 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +347 -2
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +9 -0
- package/src/email/html-renderer.ts +76 -0
- package/src/heartbeat/heartbeat-service.ts +93 -7
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +194 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +398 -0
- package/src/home/assistant-feed-authoring.ts +124 -0
- package/src/home/emit-feed-event.ts +158 -0
- package/src/home/feed-scheduler.ts +247 -0
- package/src/home/feed-types.ts +181 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +384 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +12 -3
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/cli-client.ts +151 -0
- package/src/ipc/cli-server.ts +234 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/index.ts +5 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/app-store.ts +1 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +73 -0
- package/src/memory/conversation-crud.ts +99 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +34 -2
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/db-init.ts +6 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction.test.ts +23 -0
- package/src/memory/graph/extraction.ts +8 -0
- package/src/memory/graph/retriever.ts +27 -18
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +16 -10
- package/src/memory/jobs-store.ts +64 -4
- package/src/memory/jobs-worker.ts +22 -9
- package/src/memory/llm-usage-store.ts +92 -56
- package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/oauth.ts +3 -0
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/client.ts +57 -6
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +143 -38
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/notifications/decision-engine.ts +3 -3
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +1 -0
- package/src/oauth/byo-connection.test.ts +18 -1
- package/src/oauth/byo-connection.ts +3 -1
- package/src/oauth/connect-orchestrator.ts +2 -0
- package/src/oauth/connection-resolver.ts +6 -2
- package/src/oauth/connection.ts +2 -0
- package/src/oauth/oauth-store.ts +9 -0
- package/src/oauth/platform-connection.test.ts +98 -0
- package/src/oauth/platform-connection.ts +52 -31
- package/src/oauth/seed-providers.ts +7 -0
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/workspace-policy.ts +3 -0
- package/src/platform/client.test.ts +10 -0
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +126 -2
- package/src/prompts/system-prompt.ts +59 -18
- package/src/prompts/templates/BOOTSTRAP.md +5 -5
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-format.ts +26 -9
- package/src/prompts/update-bulletin.ts +34 -23
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/anthropic/client.ts +157 -61
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +9 -1
- package/src/providers/model-catalog.ts +6 -0
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +474 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +502 -0
- package/src/providers/openrouter/client.ts +101 -4
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +14 -3
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +306 -0
- package/src/providers/speech-to-text/resolve.ts +386 -6
- package/src/providers/types.ts +9 -0
- package/src/runtime/AGENTS.md +43 -1
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +512 -0
- package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
- package/src/runtime/auth/route-policy.ts +30 -5
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +10 -10
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/chrome-extension-registry.ts +38 -2
- package/src/runtime/http-server.ts +395 -10
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +36 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +1 -0
- package/src/runtime/migrations/migration-wizard.ts +1 -0
- package/src/runtime/migrations/vbundle-import-analyzer.ts +77 -1
- package/src/runtime/migrations/vbundle-importer.ts +34 -0
- package/src/runtime/pending-interactions.ts +0 -11
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +82 -23
- package/src/runtime/routes/btw-routes.ts +8 -6
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -142
- package/src/runtime/routes/conversation-management-routes.ts +115 -0
- package/src/runtime/routes/conversation-routes.ts +367 -146
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/home-feed-routes.ts +334 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +3 -14
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +3 -17
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +11 -3
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +303 -0
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/migration-routes.ts +40 -5
- package/src/runtime/routes/settings-routes.ts +22 -5
- package/src/runtime/routes/skills-routes.ts +76 -7
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +30 -2
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.ts +8 -1
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +344 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +49 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +50 -0
- package/src/security/oauth2.ts +26 -4
- package/src/security/secure-keys.ts +25 -2
- package/src/security/token-manager.ts +8 -0
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +64 -2
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +195 -0
- package/src/stt/stt-stream-session.ts +499 -0
- package/src/stt/types.ts +330 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +38 -14
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
- package/src/tools/browser/browser-execution.ts +1163 -23
- package/src/tools/browser/browser-manager.ts +45 -0
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +393 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +29 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1648 -32
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +264 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +183 -17
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +254 -21
- package/src/tools/browser/cdp-client/errors.ts +15 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +39 -16
- package/src/tools/browser/cdp-client/factory.ts +797 -87
- package/src/tools/browser/cdp-client/index.ts +16 -2
- package/src/tools/browser/cdp-client/types.ts +68 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +2 -0
- package/src/tools/skills/sandbox-runner.ts +3 -2
- package/src/tools/terminal/safe-env.ts +10 -2
- package/src/tools/terminal/shell.ts +15 -4
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +17 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tts/__tests__/provider-adapters.test.ts +834 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +201 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +42 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +153 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/platform.ts +54 -10
- package/src/util/pricing.ts +66 -3
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +23 -0
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/top-level-renderer.ts +13 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/cli/commands/browser-relay.ts +0 -466
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/runtime/routes/browser-cdp-routes.ts +0 -229
|
@@ -13,10 +13,72 @@ import { desc, eq } from "drizzle-orm";
|
|
|
13
13
|
import { generateUserFileSlug } from "../../contacts/contact-store.js";
|
|
14
14
|
import { getDb } from "../../memory/db.js";
|
|
15
15
|
import { contacts } from "../../memory/schema/contacts.js";
|
|
16
|
-
import { isTemplateContent } from "../../prompts/system-prompt.js";
|
|
17
|
-
import { stripCommentLines } from "../../util/strip-comment-lines.js";
|
|
18
16
|
import type { WorkspaceMigration } from "./types.js";
|
|
19
17
|
|
|
18
|
+
// ── Inlined helpers ───────────────────────────────────────────────
|
|
19
|
+
//
|
|
20
|
+
// Per migrations/AGENTS.md, migrations must be self-contained. The
|
|
21
|
+
// helpers below are duplicated inline (rather than imported from
|
|
22
|
+
// `util/strip-comment-lines.js` or `prompts/system-prompt.js`) so this
|
|
23
|
+
// migration does not regress if those modules change — or, in the case
|
|
24
|
+
// of the legacy `templates/USER.md` template file, disappear entirely.
|
|
25
|
+
// Migration 031-drop-user-md deletes that template file, and previously
|
|
26
|
+
// this migration's unmodified-template check silently started copying
|
|
27
|
+
// bare scaffolds once the template was gone.
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Strip lines starting with `_` (comment convention for prompt .md files)
|
|
31
|
+
* and collapse any resulting consecutive blank lines. Copied from
|
|
32
|
+
* `util/strip-comment-lines.ts` to keep this migration self-contained.
|
|
33
|
+
*/
|
|
34
|
+
function stripCommentLines(content: string): string {
|
|
35
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
36
|
+
let openFenceChar: string | null = null;
|
|
37
|
+
const filtered = normalized.split("\n").filter((line) => {
|
|
38
|
+
const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})/);
|
|
39
|
+
if (fenceMatch) {
|
|
40
|
+
const char = fenceMatch[1][0];
|
|
41
|
+
if (!openFenceChar) {
|
|
42
|
+
openFenceChar = char;
|
|
43
|
+
} else if (char === openFenceChar) {
|
|
44
|
+
openFenceChar = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (openFenceChar) return true;
|
|
48
|
+
return !line.trimStart().startsWith("_");
|
|
49
|
+
});
|
|
50
|
+
return filtered
|
|
51
|
+
.join("\n")
|
|
52
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
53
|
+
.trim();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Frozen snapshot of the legacy `templates/USER.md` contents that
|
|
58
|
+
* shipped at the time this migration was authored. Used to detect
|
|
59
|
+
* unmodified template installs so we don't copy a useless scaffold
|
|
60
|
+
* into `users/<slug>.md`. The template file itself is deleted by
|
|
61
|
+
* migration 031, so we cannot read it from disk here.
|
|
62
|
+
*/
|
|
63
|
+
const LEGACY_USER_MD_TEMPLATE = `_ Lines starting with _ are comments - they won't appear in the system prompt
|
|
64
|
+
|
|
65
|
+
# USER.md
|
|
66
|
+
|
|
67
|
+
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.
|
|
68
|
+
|
|
69
|
+
- Preferred name/reference:
|
|
70
|
+
- Pronouns:
|
|
71
|
+
- Locale:
|
|
72
|
+
- Work role:
|
|
73
|
+
- Goals:
|
|
74
|
+
- Hobbies/fun:
|
|
75
|
+
- Daily tools:
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
const LEGACY_USER_MD_TEMPLATE_STRIPPED = stripCommentLines(
|
|
79
|
+
LEGACY_USER_MD_TEMPLATE,
|
|
80
|
+
);
|
|
81
|
+
|
|
20
82
|
export const seedPersonaDirsMigration: WorkspaceMigration = {
|
|
21
83
|
id: "017-seed-persona-dirs",
|
|
22
84
|
description:
|
|
@@ -55,8 +117,10 @@ export const seedPersonaDirsMigration: WorkspaceMigration = {
|
|
|
55
117
|
const content = stripCommentLines(rawContent);
|
|
56
118
|
if (!content) return;
|
|
57
119
|
|
|
58
|
-
// Skip if the content is the unmodified template
|
|
59
|
-
|
|
120
|
+
// Skip if the content is the unmodified legacy template. We compare
|
|
121
|
+
// against an inlined snapshot rather than reading the bundled
|
|
122
|
+
// template from disk, since migration 031 deletes that template file.
|
|
123
|
+
if (content === LEGACY_USER_MD_TEMPLATE_STRIPPED) return;
|
|
60
124
|
|
|
61
125
|
// Determine destination filename based on guardian contact
|
|
62
126
|
let destFilename = "guardian.md";
|
|
@@ -7,7 +7,7 @@ const INDEX_TEMPLATE = `_ Lines starting with _ are comments - they won't appear
|
|
|
7
7
|
|
|
8
8
|
# Knowledge Base
|
|
9
9
|
|
|
10
|
-
**Remember aggressively.**
|
|
10
|
+
**Remember aggressively.** Capture anything concrete about your user — preferences, names, dates, habits, plans, opinions, health details, commitments. Default to remembering; only skip obvious noise (small talk, hypotheticals). Don't judge importance — filing decides that later. Call \`remember\` immediately, multiple times per conversation. Remembering too much costs nothing. Forgetting something that mattered costs trust.
|
|
11
11
|
|
|
12
12
|
## Always Loaded
|
|
13
13
|
- essentials.md — Core facts, patterns, and biographical info
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import {
|
|
2
|
+
copyFileSync,
|
|
3
|
+
existsSync,
|
|
4
|
+
mkdirSync,
|
|
5
|
+
readFileSync,
|
|
6
|
+
statSync,
|
|
7
|
+
unlinkSync,
|
|
8
|
+
writeFileSync,
|
|
9
|
+
} from "node:fs";
|
|
10
|
+
import { basename, join } from "node:path";
|
|
11
|
+
|
|
12
|
+
import { eq } from "drizzle-orm";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
findGuardianForChannel,
|
|
16
|
+
generateUserFileSlug,
|
|
17
|
+
listGuardianChannels,
|
|
18
|
+
} from "../../contacts/contact-store.js";
|
|
19
|
+
import { getDb } from "../../memory/db.js";
|
|
20
|
+
import { contacts } from "../../memory/schema/contacts.js";
|
|
21
|
+
import { getLogger } from "../../util/logger.js";
|
|
22
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
23
|
+
|
|
24
|
+
const log = getLogger("workspace-migration-031-drop-user-md");
|
|
25
|
+
|
|
26
|
+
// ── Inlined helpers ───────────────────────────────────────────────
|
|
27
|
+
//
|
|
28
|
+
// Per AGENTS.md, migrations should minimize cross-module imports so
|
|
29
|
+
// they remain stable as code around them evolves. The helpers below
|
|
30
|
+
// are duplicated inline (rather than imported from
|
|
31
|
+
// `util/strip-comment-lines.js` and `prompts/system-prompt.js`) so
|
|
32
|
+
// this migration does not regress if those modules change later.
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Strip lines starting with `_` (comment convention for prompt .md files)
|
|
36
|
+
* and collapse any resulting consecutive blank lines. Copied from
|
|
37
|
+
* `util/strip-comment-lines.ts` to keep this migration self-contained.
|
|
38
|
+
*/
|
|
39
|
+
function stripCommentLines(content: string): string {
|
|
40
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
41
|
+
let openFenceChar: string | null = null;
|
|
42
|
+
const filtered = normalized.split("\n").filter((line) => {
|
|
43
|
+
const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})/);
|
|
44
|
+
if (fenceMatch) {
|
|
45
|
+
const char = fenceMatch[1][0];
|
|
46
|
+
if (!openFenceChar) {
|
|
47
|
+
openFenceChar = char;
|
|
48
|
+
} else if (char === openFenceChar) {
|
|
49
|
+
openFenceChar = null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (openFenceChar) return true;
|
|
53
|
+
return !line.trimStart().startsWith("_");
|
|
54
|
+
});
|
|
55
|
+
return filtered
|
|
56
|
+
.join("\n")
|
|
57
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
58
|
+
.trim();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Frozen snapshot of the legacy `templates/USER.md` contents shipped
|
|
63
|
+
* before this migration deletes it. Used to detect unmodified template
|
|
64
|
+
* installs so we don't copy a useless scaffold into `users/<slug>.md`.
|
|
65
|
+
*/
|
|
66
|
+
const LEGACY_USER_MD_TEMPLATE = `_ Lines starting with _ are comments - they won't appear in the system prompt
|
|
67
|
+
|
|
68
|
+
# USER.md
|
|
69
|
+
|
|
70
|
+
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.
|
|
71
|
+
|
|
72
|
+
- Preferred name/reference:
|
|
73
|
+
- Pronouns:
|
|
74
|
+
- Locale:
|
|
75
|
+
- Work role:
|
|
76
|
+
- Goals:
|
|
77
|
+
- Hobbies/fun:
|
|
78
|
+
- Daily tools:
|
|
79
|
+
`;
|
|
80
|
+
|
|
81
|
+
const LEGACY_USER_MD_TEMPLATE_STRIPPED = stripCommentLines(
|
|
82
|
+
LEGACY_USER_MD_TEMPLATE,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Current `GUARDIAN_PERSONA_TEMPLATE` text from `prompts/persona-resolver.ts`,
|
|
87
|
+
* duplicated here for the same self-containment reason. Written when we
|
|
88
|
+
* need to seed an empty `users/<slug>.md` so new installs stay consistent
|
|
89
|
+
* with `ensureGuardianPersonaFile`.
|
|
90
|
+
*/
|
|
91
|
+
const GUARDIAN_PERSONA_TEMPLATE = `_ Lines starting with _ are comments - they won't appear in the system prompt
|
|
92
|
+
|
|
93
|
+
# User Profile
|
|
94
|
+
|
|
95
|
+
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.
|
|
96
|
+
|
|
97
|
+
- Preferred name/reference:
|
|
98
|
+
- Pronouns:
|
|
99
|
+
- Locale:
|
|
100
|
+
- Work role:
|
|
101
|
+
- Goals:
|
|
102
|
+
- Hobbies/fun:
|
|
103
|
+
- Daily tools:
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
function isLegacyTemplateContent(raw: string): boolean {
|
|
107
|
+
const stripped = stripCommentLines(raw);
|
|
108
|
+
if (stripped.length === 0) return true;
|
|
109
|
+
return stripped === LEGACY_USER_MD_TEMPLATE_STRIPPED;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function destFileIsMissingOrEmpty(destPath: string): boolean {
|
|
113
|
+
if (!existsSync(destPath)) return true;
|
|
114
|
+
try {
|
|
115
|
+
const raw = readFileSync(destPath, "utf-8");
|
|
116
|
+
return stripCommentLines(raw).length === 0;
|
|
117
|
+
} catch {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function isValidSlug(slug: string): boolean {
|
|
123
|
+
return basename(slug) === slug && slug !== "." && slug !== "..";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Delete the legacy `USER.md` at the workspace root after migrating
|
|
128
|
+
* any customized content into `users/<slug>.md`.
|
|
129
|
+
*
|
|
130
|
+
* Handles four relevant states:
|
|
131
|
+
* 1. Fresh install, no guardian → no-op (nothing to migrate yet;
|
|
132
|
+
* `USER.md` is no longer seeded post PR 11).
|
|
133
|
+
* 2. Pre-017 customized `USER.md`, guardian has no `userFile` →
|
|
134
|
+
* backfill the slug, copy `USER.md` → `users/<slug>.md`, delete `USER.md`.
|
|
135
|
+
* 3. Post-017 state where `users/<slug>.md` already has content →
|
|
136
|
+
* do NOT overwrite; delete lingering `USER.md` regardless of content.
|
|
137
|
+
* 4. Missing `users/<slug>.md` after guardian is resolved → seed a bare
|
|
138
|
+
* `GUARDIAN_PERSONA_TEMPLATE` scaffold so downstream readers have a file.
|
|
139
|
+
*/
|
|
140
|
+
export const dropUserMdMigration: WorkspaceMigration = {
|
|
141
|
+
id: "031-drop-user-md",
|
|
142
|
+
description:
|
|
143
|
+
"Delete legacy workspace-root USER.md after migrating content to users/<slug>.md",
|
|
144
|
+
|
|
145
|
+
run(workspaceDir: string): void {
|
|
146
|
+
const userMdPath = join(workspaceDir, "USER.md");
|
|
147
|
+
|
|
148
|
+
// Resolve the guardian contact. Prefer the vellum-channel binding
|
|
149
|
+
// (the canonical local/native guardian); fall back to whichever
|
|
150
|
+
// guardian has the most recently verified active channel.
|
|
151
|
+
let guardian: { id: string; displayName: string; userFile: string | null };
|
|
152
|
+
try {
|
|
153
|
+
const vellumGuardian = findGuardianForChannel("vellum");
|
|
154
|
+
if (vellumGuardian) {
|
|
155
|
+
guardian = {
|
|
156
|
+
id: vellumGuardian.contact.id,
|
|
157
|
+
displayName: vellumGuardian.contact.displayName,
|
|
158
|
+
userFile: vellumGuardian.contact.userFile ?? null,
|
|
159
|
+
};
|
|
160
|
+
} else {
|
|
161
|
+
const anyGuardian = listGuardianChannels();
|
|
162
|
+
if (!anyGuardian) {
|
|
163
|
+
// Fresh install or pre-onboarding. If a stale USER.md somehow
|
|
164
|
+
// remains on disk (e.g. leftover from an older build), best-
|
|
165
|
+
// effort remove it so future first runs are clean.
|
|
166
|
+
if (existsSync(userMdPath)) {
|
|
167
|
+
try {
|
|
168
|
+
unlinkSync(userMdPath);
|
|
169
|
+
log.info(
|
|
170
|
+
{ path: userMdPath },
|
|
171
|
+
"Deleted stale pre-onboarding USER.md with no guardian",
|
|
172
|
+
);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
log.warn(
|
|
175
|
+
{ err, path: userMdPath },
|
|
176
|
+
"Failed to delete pre-onboarding USER.md; leaving in place",
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
guardian = {
|
|
183
|
+
id: anyGuardian.contact.id,
|
|
184
|
+
displayName: anyGuardian.contact.displayName,
|
|
185
|
+
userFile: anyGuardian.contact.userFile ?? null,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
} catch (err) {
|
|
189
|
+
// DB not ready or query failed — leave USER.md alone. The next
|
|
190
|
+
// startup after DB init will try again.
|
|
191
|
+
log.warn(
|
|
192
|
+
{ err },
|
|
193
|
+
"Failed to resolve guardian contact; deferring USER.md cleanup",
|
|
194
|
+
);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Backfill a userFile slug on the guardian contact if one isn't set.
|
|
199
|
+
if (!guardian.userFile) {
|
|
200
|
+
try {
|
|
201
|
+
const slug = generateUserFileSlug(guardian.displayName);
|
|
202
|
+
const db = getDb();
|
|
203
|
+
db.update(contacts)
|
|
204
|
+
.set({ userFile: slug })
|
|
205
|
+
.where(eq(contacts.id, guardian.id))
|
|
206
|
+
.run();
|
|
207
|
+
guardian.userFile = slug;
|
|
208
|
+
log.info(
|
|
209
|
+
{ contactId: guardian.id, slug },
|
|
210
|
+
"Backfilled missing guardian.userFile",
|
|
211
|
+
);
|
|
212
|
+
} catch (err) {
|
|
213
|
+
log.warn(
|
|
214
|
+
{ err, contactId: guardian.id },
|
|
215
|
+
"Failed to backfill guardian.userFile; deferring USER.md cleanup",
|
|
216
|
+
);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const userFile = guardian.userFile;
|
|
222
|
+
if (!userFile || !isValidSlug(userFile)) {
|
|
223
|
+
log.warn(
|
|
224
|
+
{ userFile },
|
|
225
|
+
"Guardian userFile is missing or not a safe basename; deferring USER.md cleanup",
|
|
226
|
+
);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const usersDir = join(workspaceDir, "users");
|
|
231
|
+
mkdirSync(usersDir, { recursive: true });
|
|
232
|
+
|
|
233
|
+
const destPath = join(usersDir, userFile);
|
|
234
|
+
|
|
235
|
+
// Read USER.md if it exists and classify its content.
|
|
236
|
+
let userMdRaw: string | null = null;
|
|
237
|
+
let userMdIsCustomized = false;
|
|
238
|
+
if (existsSync(userMdPath)) {
|
|
239
|
+
try {
|
|
240
|
+
// Guard against USER.md being a directory (hostile state).
|
|
241
|
+
if (statSync(userMdPath).isFile()) {
|
|
242
|
+
userMdRaw = readFileSync(userMdPath, "utf-8");
|
|
243
|
+
userMdIsCustomized = !isLegacyTemplateContent(userMdRaw);
|
|
244
|
+
}
|
|
245
|
+
} catch (err) {
|
|
246
|
+
log.warn(
|
|
247
|
+
{ err, path: userMdPath },
|
|
248
|
+
"Failed to read USER.md; treating as unreadable",
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Copy customized USER.md content into users/<slug>.md when the
|
|
254
|
+
// destination is missing or effectively empty. Post-017 installs
|
|
255
|
+
// that already populated users/<slug>.md are left untouched.
|
|
256
|
+
if (
|
|
257
|
+
userMdIsCustomized &&
|
|
258
|
+
userMdRaw !== null &&
|
|
259
|
+
destFileIsMissingOrEmpty(destPath)
|
|
260
|
+
) {
|
|
261
|
+
try {
|
|
262
|
+
copyFileSync(userMdPath, destPath);
|
|
263
|
+
log.info(
|
|
264
|
+
{ src: userMdPath, dest: destPath },
|
|
265
|
+
"Copied customized USER.md content into users/<slug>.md",
|
|
266
|
+
);
|
|
267
|
+
} catch (err) {
|
|
268
|
+
log.warn(
|
|
269
|
+
{ err, src: userMdPath, dest: destPath },
|
|
270
|
+
"Failed to copy USER.md; deferring USER.md cleanup",
|
|
271
|
+
);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Seed the guardian persona scaffold when the destination file
|
|
277
|
+
// still doesn't exist (e.g. no USER.md and no post-017 content).
|
|
278
|
+
// This keeps parity with `ensureGuardianPersonaFile` for new
|
|
279
|
+
// installs so downstream readers always find a file.
|
|
280
|
+
if (!existsSync(destPath)) {
|
|
281
|
+
try {
|
|
282
|
+
writeFileSync(destPath, GUARDIAN_PERSONA_TEMPLATE, "utf-8");
|
|
283
|
+
log.info(
|
|
284
|
+
{ dest: destPath },
|
|
285
|
+
"Seeded guardian persona scaffold at users/<slug>.md",
|
|
286
|
+
);
|
|
287
|
+
} catch (err) {
|
|
288
|
+
log.warn(
|
|
289
|
+
{ err, dest: destPath },
|
|
290
|
+
"Failed to seed guardian persona scaffold; continuing with USER.md deletion",
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Finally, delete the legacy USER.md if it still exists. Template
|
|
296
|
+
// or customized, it has no remaining consumer now that PR 11
|
|
297
|
+
// dropped the seed/fallback read path.
|
|
298
|
+
if (existsSync(userMdPath)) {
|
|
299
|
+
try {
|
|
300
|
+
unlinkSync(userMdPath);
|
|
301
|
+
log.info({ path: userMdPath }, "Deleted legacy workspace USER.md");
|
|
302
|
+
} catch (err) {
|
|
303
|
+
log.warn(
|
|
304
|
+
{ err, path: userMdPath },
|
|
305
|
+
"Failed to delete legacy USER.md",
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
down(_workspaceDir: string): void {
|
|
312
|
+
// No-op: deletion is irreversible. Any content that was present in
|
|
313
|
+
// `USER.md` was copied into `users/<slug>.md` during `run()`, so
|
|
314
|
+
// rolling back this migration cannot restore the original file.
|
|
315
|
+
// Downstream migrations (if any) read from `users/<slug>.md`.
|
|
316
|
+
},
|
|
317
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Convert `memory.cleanup.llmRequestLogRetentionMs: 0` to `null`.
|
|
8
|
+
*
|
|
9
|
+
* Under the old semantics `0` meant "keep forever" (never prune). The new
|
|
10
|
+
* semantics use `null` for "keep forever" and `0` for "prune immediately".
|
|
11
|
+
* Without this migration, users who previously set the retention to "keep
|
|
12
|
+
* forever" would be silently switched to "prune everything on next cleanup
|
|
13
|
+
* run" after upgrading.
|
|
14
|
+
*/
|
|
15
|
+
export const llmLogRetentionZeroToNullMigration: WorkspaceMigration = {
|
|
16
|
+
id: "031-llm-log-retention-zero-to-null",
|
|
17
|
+
description:
|
|
18
|
+
"Convert llmRequestLogRetentionMs: 0 (old 'keep forever') to null (new 'keep forever')",
|
|
19
|
+
run(workspaceDir: string): void {
|
|
20
|
+
const configPath = join(workspaceDir, "config.json");
|
|
21
|
+
if (!existsSync(configPath)) return;
|
|
22
|
+
|
|
23
|
+
let config: Record<string, unknown>;
|
|
24
|
+
try {
|
|
25
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
26
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
27
|
+
config = raw as Record<string, unknown>;
|
|
28
|
+
} catch {
|
|
29
|
+
return; // Malformed config — skip
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const memory = config.memory;
|
|
33
|
+
if (!memory || typeof memory !== "object" || Array.isArray(memory)) return;
|
|
34
|
+
const memoryObj = memory as Record<string, unknown>;
|
|
35
|
+
|
|
36
|
+
const cleanup = memoryObj.cleanup;
|
|
37
|
+
if (!cleanup || typeof cleanup !== "object" || Array.isArray(cleanup))
|
|
38
|
+
return;
|
|
39
|
+
const cleanupObj = cleanup as Record<string, unknown>;
|
|
40
|
+
|
|
41
|
+
if (cleanupObj.llmRequestLogRetentionMs !== 0) return;
|
|
42
|
+
|
|
43
|
+
cleanupObj.llmRequestLogRetentionMs = null;
|
|
44
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
45
|
+
},
|
|
46
|
+
down(workspaceDir: string): void {
|
|
47
|
+
const configPath = join(workspaceDir, "config.json");
|
|
48
|
+
if (!existsSync(configPath)) return;
|
|
49
|
+
|
|
50
|
+
let config: Record<string, unknown>;
|
|
51
|
+
try {
|
|
52
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
53
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
54
|
+
config = raw as Record<string, unknown>;
|
|
55
|
+
} catch {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const memory = config.memory;
|
|
60
|
+
if (!memory || typeof memory !== "object" || Array.isArray(memory)) return;
|
|
61
|
+
const memoryObj = memory as Record<string, unknown>;
|
|
62
|
+
|
|
63
|
+
const cleanup = memoryObj.cleanup;
|
|
64
|
+
if (!cleanup || typeof cleanup !== "object" || Array.isArray(cleanup))
|
|
65
|
+
return;
|
|
66
|
+
const cleanupObj = cleanup as Record<string, unknown>;
|
|
67
|
+
|
|
68
|
+
if (cleanupObj.llmRequestLogRetentionMs !== null) return;
|
|
69
|
+
|
|
70
|
+
cleanupObj.llmRequestLogRetentionMs = 0;
|
|
71
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
72
|
+
},
|
|
73
|
+
};
|