@vellumai/assistant 0.7.0 → 0.7.2
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 +38 -56
- package/Dockerfile +2 -0
- package/README.md +3 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +88 -142
- package/bun.lock +29 -26
- package/docs/architecture/security.md +38 -16
- package/docs/plugins.md +7 -9
- package/knip.json +2 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +39 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +9 -5
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
- package/node_modules/@vellumai/slack-text/bun.lock +24 -0
- package/node_modules/@vellumai/slack-text/package.json +18 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
- package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +869 -129
- package/package.json +8 -3
- package/scripts/generate-openapi.ts +16 -111
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
- package/src/__tests__/anthropic-provider.test.ts +56 -13
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +374 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
- package/src/__tests__/app-conversation-ids.test.ts +151 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-cascade.test.ts +0 -15
- package/src/__tests__/approval-routes-http.test.ts +29 -23
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +235 -79
- package/src/__tests__/assistant-event.test.ts +10 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +44 -17
- package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -36
- package/src/__tests__/background-shell-host-bash.test.ts +46 -56
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +50 -2
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/call-site-routing-provider.test.ts +193 -0
- package/src/__tests__/channel-approval-routes.test.ts +10 -296
- package/src/__tests__/channel-approvals.test.ts +25 -17
- package/src/__tests__/channel-guardian.test.ts +100 -146
- package/src/__tests__/channel-readiness-service.test.ts +59 -1
- package/src/__tests__/checker.test.ts +23 -38
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/config-loader-backfill.test.ts +90 -155
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +6 -48
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +14 -2
- package/src/__tests__/connection-policy.test.ts +1 -52
- package/src/__tests__/contacts-write.test.ts +2 -64
- package/src/__tests__/context-image-dimensions.test.ts +1 -1
- package/src/__tests__/context-search-memory-source.test.ts +120 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
- package/src/__tests__/context-search-pkb-source.test.ts +49 -0
- package/src/__tests__/context-search-workspace-source.test.ts +9 -22
- package/src/__tests__/context-window-manager.test.ts +46 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
- package/src/__tests__/conversation-agent-loop.test.ts +980 -13
- package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
- package/src/__tests__/conversation-history-web-search.test.ts +4 -3
- package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +40 -4
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-process-callsite.test.ts +79 -2
- package/src/__tests__/conversation-queue.test.ts +3 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +7 -161
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -104
- package/src/__tests__/conversation-routes-slash-commands.test.ts +76 -66
- package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
- package/src/__tests__/conversation-slash-commands.test.ts +24 -8
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-starter-routes.test.ts +79 -2
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +317 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
- package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
- package/src/__tests__/conversation-usage.test.ts +253 -3
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
- package/src/__tests__/credential-health-service.test.ts +68 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -5
- package/src/__tests__/credential-token-resolver.test.ts +180 -0
- package/src/__tests__/credentials-cli.test.ts +5 -12
- package/src/__tests__/cu-unified-flow.test.ts +206 -27
- package/src/__tests__/daemon-assistant-events.test.ts +34 -21
- package/src/__tests__/daemon-credential-client.test.ts +102 -17
- package/src/__tests__/db-connection-isolation.test.ts +125 -0
- package/src/__tests__/db-migration-rollback.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
- package/src/__tests__/document-conversations.test.ts +332 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
- package/src/__tests__/emit-event-signal.test.ts +4 -6
- package/src/__tests__/events-client-registration.test.ts +193 -49
- package/src/__tests__/filing-service.test.ts +58 -7
- package/src/__tests__/first-greeting.test.ts +156 -150
- package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +7 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
- package/src/__tests__/guardian-routing-state.test.ts +1 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +30 -11
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -84
- package/src/__tests__/headless-browser-mode.test.ts +4 -9
- package/src/__tests__/headless-browser-navigate.test.ts +21 -20
- package/src/__tests__/heartbeat-service.test.ts +1007 -8
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
- package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
- package/src/__tests__/host-app-control-proxy.test.ts +602 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +270 -147
- package/src/__tests__/host-bash-routes.test.ts +294 -0
- package/src/__tests__/host-browser-proxy.test.ts +126 -198
- package/src/__tests__/host-browser-routes.test.ts +50 -54
- package/src/__tests__/host-cu-proxy.test.ts +78 -144
- package/src/__tests__/host-cu-routes-targeted.test.ts +300 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +339 -0
- package/src/__tests__/host-file-proxy.test.ts +62 -122
- package/src/__tests__/host-file-read-tool.test.ts +59 -21
- package/src/__tests__/host-file-routes-targeted.test.ts +262 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +53 -70
- package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +583 -0
- package/src/__tests__/host-transfer-proxy.test.ts +145 -56
- package/src/__tests__/host-transfer-routes-targeted.test.ts +447 -0
- package/src/__tests__/http-user-message-parity.test.ts +1 -6
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/injector-chain.test.ts +10 -5
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -67
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -13
- package/src/__tests__/install-skill-routing.test.ts +1 -13
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
- package/src/__tests__/llm-catalog-parity.test.ts +90 -0
- package/src/__tests__/llm-context-resolution.test.ts +180 -0
- package/src/__tests__/llm-resolver.test.ts +80 -12
- package/src/__tests__/llm-usage-store.test.ts +269 -4
- package/src/__tests__/log-export-routes.test.ts +89 -0
- package/src/__tests__/managed-profile-guard.test.ts +225 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -11
- package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
- package/src/__tests__/migration-export-http.test.ts +33 -26
- package/src/__tests__/migration-export-streaming.test.ts +18 -10
- package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
- package/src/__tests__/migration-import-commit-http.test.ts +172 -21
- package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
- package/src/__tests__/migration-import-from-url.test.ts +20 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
- package/src/__tests__/migration-parity-persistence.test.ts +62 -25
- package/src/__tests__/migration-transport.test.ts +115 -23
- package/src/__tests__/migration-validate-http.test.ts +105 -80
- package/src/__tests__/migration-wizard.test.ts +133 -27
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/non-member-access-request.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth-store.test.ts +19 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +26 -21
- package/src/__tests__/prechat-onboarding-contract.test.ts +34 -8
- package/src/__tests__/pricing.test.ts +68 -4
- package/src/__tests__/process-message-background-slack.test.ts +333 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
- package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
- package/src/__tests__/provider-usage-tracking.test.ts +208 -0
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/reaction-persistence.test.ts +9 -6
- package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
- package/src/__tests__/recording-handler.test.ts +64 -81
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
- package/src/__tests__/relay-server.test.ts +18 -13
- package/src/__tests__/require-fresh-approval.test.ts +13 -23
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +13 -18
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/search-skills-unified.test.ts +9 -15
- package/src/__tests__/secret-ingress-cli.test.ts +2 -5
- package/src/__tests__/secret-ingress-http.test.ts +1 -4
- package/src/__tests__/secret-onetime-send.test.ts +4 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
- package/src/__tests__/secret-response-routing.test.ts +29 -15
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
- package/src/__tests__/secret-scanner.test.ts +2 -545
- package/src/__tests__/send-endpoint-busy.test.ts +12 -24
- package/src/__tests__/settings-routes.test.ts +1 -1
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -57
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -12
- package/src/__tests__/skill-tool-factory.test.ts +97 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
- package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/slack-inbound-verification.test.ts +1 -62
- package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
- package/src/__tests__/subagent-manager-notify.test.ts +70 -70
- package/src/__tests__/subagent-notify-parent.test.ts +80 -83
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +115 -14
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/terminal-tools.test.ts +0 -89
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/thread-backfill.test.ts +945 -31
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -7
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -17
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -8
- package/src/__tests__/tool-executor.test.ts +12 -20
- package/src/__tests__/tool-metrics-listener.test.ts +0 -35
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-trace-listener.test.ts +0 -17
- package/src/__tests__/transfer-progress-screen.test.ts +63 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +16 -5
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/usage-attribution.test.ts +247 -0
- package/src/__tests__/usage-cli.test.ts +143 -0
- package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
- package/src/__tests__/usage-routes.test.ts +150 -0
- package/src/__tests__/validation-results-screen.test.ts +39 -16
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +47 -138
- package/src/__tests__/verification-control-plane-policy.test.ts +6 -11
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/voice-session-bridge.test.ts +5 -5
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
- package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
- package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/acp/index.ts +0 -15
- package/src/acp/session-manager.ts +37 -34
- package/src/agent/loop.ts +16 -1
- package/src/approvals/AGENTS.md +4 -0
- package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
- package/src/approvals/guardian-request-resolvers.ts +10 -2
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +94 -177
- package/src/backup/paths.ts +2 -15
- package/src/backup/restore.ts +107 -231
- package/src/browser-session/events.ts +0 -9
- package/src/bundler/app-bundler.ts +51 -3
- package/src/calls/call-store.ts +1 -34
- package/src/calls/guardian-question-copy.ts +0 -108
- package/src/calls/relay-server.ts +4 -68
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +31 -141
- package/src/calls/twilio-routes.ts +12 -13
- package/src/calls/voice-session-bridge.ts +7 -38
- package/src/channels/types.ts +8 -42
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/cache.test.ts +152 -5
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +18 -28
- package/src/cli/commands/__tests__/trust.test.ts +21 -387
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -1
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/cache-fs.ts +8 -0
- package/src/cli/commands/cache.ts +153 -82
- package/src/cli/commands/clients.ts +64 -7
- package/src/cli/commands/completions.ts +3 -3
- package/src/cli/commands/contacts.ts +304 -76
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +15 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +13 -7
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +320 -53
- package/src/cli/commands/oauth/shared.ts +2 -29
- package/src/cli/commands/pending.ts +102 -0
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -2
- package/src/cli/commands/platform/__tests__/status.test.ts +13 -15
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +0 -18
- package/src/cli/commands/skills.ts +77 -35
- package/src/cli/commands/trust.ts +70 -430
- package/src/cli/commands/usage.ts +25 -16
- package/src/cli/lib/daemon-credential-client.ts +115 -19
- package/src/cli/program.ts +4 -0
- package/src/cli.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/assistant-feature-flags.ts +67 -10
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -44
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +19 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +12 -4
- package/src/config/env.ts +22 -26
- package/src/config/feature-flag-registry.json +40 -152
- package/src/config/llm-callsite-catalog.ts +12 -0
- package/src/config/llm-context-resolution.ts +80 -0
- package/src/config/llm-resolver.ts +58 -22
- package/src/config/loader.ts +76 -102
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schema.ts +2 -158
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +8 -4
- package/src/config/schemas/call-site-catalog.ts +271 -0
- package/src/config/schemas/calls.ts +5 -14
- package/src/config/schemas/heartbeat.ts +63 -0
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/ingress.ts +11 -7
- package/src/config/schemas/llm.ts +34 -11
- package/src/config/schemas/memory-lifecycle.ts +77 -24
- package/src/config/schemas/memory-retrieval.ts +2 -2
- package/src/config/schemas/memory-v2.ts +57 -4
- package/src/config/schemas/platform.ts +6 -0
- package/src/config/schemas/security.ts +1 -42
- package/src/config/schemas/services.ts +7 -21
- package/src/config/schemas/skills.ts +5 -11
- package/src/config/schemas/tts.ts +1 -1
- package/src/config/seed-inference-profiles.ts +117 -0
- package/src/config/skills.ts +0 -90
- package/src/config/types.ts +3 -6
- package/src/contacts/contact-store.ts +0 -47
- package/src/contacts/contacts-write.ts +1 -132
- package/src/context/window-manager.ts +43 -5
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +46 -51
- package/src/credential-health/credential-health-service.ts +21 -16
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +126 -5
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +4 -3
- package/src/daemon/connection-policy.ts +1 -26
- package/src/daemon/conversation-agent-loop-handlers.ts +74 -7
- package/src/daemon/conversation-agent-loop.ts +309 -64
- package/src/daemon/conversation-history.ts +8 -8
- package/src/daemon/conversation-launch.ts +20 -135
- package/src/daemon/conversation-lifecycle.ts +8 -1
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-process.ts +97 -172
- package/src/daemon/conversation-runtime-assembly.ts +219 -76
- package/src/daemon/conversation-slash.ts +47 -5
- package/src/daemon/conversation-store.ts +7 -31
- package/src/daemon/conversation-surfaces.ts +144 -29
- package/src/daemon/conversation-tool-setup.ts +18 -87
- package/src/daemon/conversation-usage.ts +36 -0
- package/src/daemon/conversation.ts +134 -231
- package/src/daemon/daemon-control.ts +3 -71
- package/src/daemon/daemon-skill-host.ts +8 -11
- package/src/daemon/dictation-profile-store.ts +2 -26
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/first-greeting.ts +44 -156
- package/src/daemon/handlers/config-channels.ts +12 -12
- package/src/daemon/handlers/config-ingress.ts +4 -165
- package/src/daemon/handlers/config-model.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +0 -42
- package/src/daemon/handlers/conversations.ts +11 -190
- package/src/daemon/handlers/recording.ts +26 -158
- package/src/daemon/handlers/shared.ts +27 -72
- package/src/daemon/handlers/skills.ts +42 -93
- package/src/daemon/host-app-control-proxy.ts +293 -0
- package/src/daemon/host-bash-proxy.ts +124 -92
- package/src/daemon/host-browser-proxy.ts +111 -88
- package/src/daemon/host-cu-proxy.ts +100 -104
- package/src/daemon/host-file-proxy.ts +136 -91
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +303 -147
- package/src/daemon/lifecycle.ts +164 -132
- package/src/daemon/message-protocol.ts +3 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +18 -8
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +5 -0
- package/src/daemon/message-types/host-cu.ts +3 -0
- package/src/daemon/message-types/host-file.ts +5 -0
- package/src/daemon/message-types/host-transfer.ts +4 -0
- package/src/daemon/message-types/messages.ts +10 -9
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/message-types/workspace.ts +1 -1
- package/src/daemon/process-message.ts +119 -239
- package/src/daemon/server.ts +13 -462
- package/src/daemon/shutdown-handlers.ts +2 -5
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +126 -108
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +4 -9
- package/src/events/domain-events.ts +0 -8
- package/src/events/tool-audit-listener.ts +5 -2
- package/src/events/tool-domain-event-publisher.ts +0 -10
- package/src/events/tool-metrics-listener.ts +0 -17
- package/src/events/tool-trace-listener.ts +0 -14
- package/src/filing/filing-service.ts +13 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +21 -9
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +216 -0
- package/src/heartbeat/heartbeat-run-store.ts +236 -0
- package/src/heartbeat/heartbeat-service.ts +303 -54
- package/src/home/__tests__/feed-writer.test.ts +0 -4
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +41 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/feed-writer.ts +1 -2
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +33 -95
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
- package/src/ipc/assistant-server.ts +17 -11
- package/src/ipc/cli-client.ts +32 -1
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
- package/src/ipc/routes/route-adapter.ts +1 -1
- package/src/ipc/routes/trust-rules.test.ts +0 -95
- package/src/ipc/skill-ipc-types.ts +41 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
- package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
- package/src/ipc/skill-routes/events.ts +12 -23
- package/src/ipc/skill-routes/identity.ts +4 -17
- package/src/ipc/skill-routes/index.ts +1 -1
- package/src/ipc/skill-server.ts +6 -39
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/live-voice/protocol.ts +4 -13
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/manager.ts +0 -5
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/app-git-service.ts +0 -32
- package/src/memory/app-store.ts +154 -0
- package/src/memory/attachments-store.ts +6 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +32 -7
- package/src/memory/context-search/sources/memory-v2.ts +590 -0
- package/src/memory/context-search/sources/memory.ts +5 -0
- package/src/memory/context-search/sources/pkb.ts +10 -1
- package/src/memory/context-search/sources/workspace.ts +3 -2
- package/src/memory/conversation-crud.ts +30 -5
- package/src/memory/conversation-disk-view.ts +1 -5
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/conversation-starter-checkpoints.ts +63 -0
- package/src/memory/db-connection.ts +62 -0
- package/src/memory/db-init.ts +18 -0
- package/src/memory/embedding-backend.ts +12 -42
- package/src/memory/embedding-gemini.ts +0 -2
- package/src/memory/embedding-local.ts +6 -6
- package/src/memory/embedding-ollama.ts +6 -6
- package/src/memory/embedding-openai.ts +6 -6
- package/src/memory/embedding-types.ts +21 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +49 -8
- package/src/memory/graph/conversation-graph-memory.ts +35 -36
- package/src/memory/graph/graph-search.ts +8 -0
- package/src/memory/graph/injection.test.ts +2 -2
- package/src/memory/graph/injection.ts +1 -1
- package/src/memory/graph/retriever.ts +28 -0
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/guardian-action-store.ts +0 -83
- package/src/memory/guardian-approvals.ts +0 -48
- package/src/memory/indexer.ts +1 -15
- package/src/memory/job-handlers/conversation-starters.ts +36 -53
- package/src/memory/job-utils.ts +0 -6
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +66 -23
- package/src/memory/jobs-worker.ts +114 -79
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +129 -43
- package/src/memory/memory-v2-activation-log-store.ts +115 -0
- package/src/memory/migrations/233-document-conversations.ts +54 -0
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
- package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
- package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +32 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +50 -20
- package/src/memory/raw-query.ts +2 -68
- package/src/memory/schema/conversations.ts +7 -0
- package/src/memory/schema/infrastructure.ts +40 -0
- package/src/memory/search/semantic.ts +12 -16
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/tool-usage-store.ts +2 -0
- package/src/memory/usage-buckets.ts +40 -1
- package/src/memory/usage-grouped-buckets.ts +127 -0
- package/src/memory/v2/__tests__/activation.test.ts +361 -180
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
- package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
- package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
- package/src/memory/v2/__tests__/injection.test.ts +424 -33
- package/src/memory/v2/__tests__/migration.test.ts +64 -36
- package/src/memory/v2/__tests__/page-store.test.ts +191 -8
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
- package/src/memory/v2/__tests__/sim.test.ts +166 -6
- package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +152 -0
- package/src/memory/v2/activation.ts +215 -163
- package/src/memory/v2/backfill-jobs.ts +15 -100
- package/src/memory/v2/consolidation-job.ts +17 -17
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/edge-index.ts +191 -0
- package/src/memory/v2/injection.ts +241 -84
- package/src/memory/v2/migration.ts +57 -64
- package/src/memory/v2/now-text.ts +2 -3
- package/src/memory/v2/page-store.ts +168 -31
- package/src/memory/v2/prompts/consolidation.ts +385 -88
- package/src/memory/v2/prompts/sweep.ts +3 -3
- package/src/memory/v2/qdrant.ts +99 -1
- package/src/memory/v2/sim.ts +126 -16
- package/src/memory/v2/skill-qdrant.ts +12 -3
- package/src/memory/v2/skill-store.ts +71 -8
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +63 -0
- package/src/memory/v2/types.ts +10 -20
- package/src/memory/validation.ts +0 -11
- package/src/messaging/draft-store.ts +0 -6
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/client.ts +1 -121
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/outlook/client.ts +0 -73
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
- package/src/messaging/providers/slack/adapter.ts +123 -52
- package/src/messaging/providers/slack/backfill.test.ts +95 -6
- package/src/messaging/providers/slack/backfill.ts +89 -11
- package/src/messaging/providers/slack/client.ts +10 -124
- package/src/messaging/providers/slack/message-metadata.ts +12 -2
- package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
- package/src/messaging/providers/slack/render-transcript.ts +126 -25
- package/src/messaging/providers/slack/types.ts +1 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/oauth/connect-orchestrator.ts +4 -0
- package/src/oauth/connection-resolver.test.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -16
- package/src/oauth/credential-token-resolver.ts +95 -0
- package/src/oauth/manual-token-connection.ts +26 -34
- package/src/oauth/oauth-store.ts +6 -4
- package/src/outbound-proxy/certs.ts +0 -7
- package/src/outbound-proxy/index.ts +1 -59
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/approval-provenance.test.ts +184 -0
- package/src/permissions/approval-provenance.ts +70 -0
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +7 -18
- package/src/permissions/gateway-threshold-reader.ts +6 -1
- package/src/permissions/prompter.ts +43 -3
- package/src/permissions/secret-prompter.ts +25 -48
- package/src/permissions/types.ts +33 -0
- package/src/permissions/workspace-policy.ts +0 -5
- package/src/platform/sync-identity.ts +0 -8
- package/src/plugins/defaults/injectors.ts +69 -2
- package/src/plugins/defaults/overflow-reduce.ts +3 -2
- package/src/plugins/types.ts +8 -0
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/system-prompt.ts +37 -88
- package/src/prompts/templates/BOOTSTRAP.md +52 -6
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/prompts/update-bulletin-job.ts +2 -0
- package/src/providers/__tests__/retry-callsite.test.ts +138 -1
- package/src/providers/anthropic/client.ts +72 -33
- package/src/providers/call-site-routing.ts +42 -3
- package/src/providers/gemini/client.ts +18 -2
- package/src/providers/managed-proxy/context.ts +0 -5
- package/src/providers/model-catalog.ts +105 -19
- package/src/providers/openai/chat-completions-provider.ts +6 -0
- package/src/providers/openai/responses-provider.ts +7 -1
- package/src/providers/provider-send-message.ts +45 -2
- package/src/providers/ratelimit.ts +7 -2
- package/src/providers/registry.ts +14 -9
- package/src/providers/retry.ts +96 -8
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +96 -0
- package/src/runtime/AGENTS.md +10 -6
- package/src/runtime/__tests__/agent-wake.test.ts +89 -0
- package/src/runtime/agent-wake.ts +39 -2
- package/src/runtime/assistant-event-hub.ts +570 -52
- package/src/runtime/assistant-event.ts +2 -6
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/context.ts +0 -9
- package/src/runtime/auth/middleware.ts +1 -97
- package/src/runtime/auth/route-policy.ts +30 -9
- package/src/runtime/auth/token-service.ts +0 -11
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-approvals.ts +6 -2
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/channel-verification-service.ts +3 -5
- package/src/runtime/http-errors.ts +0 -34
- package/src/runtime/http-router.ts +6 -3
- package/src/runtime/http-server.ts +16 -402
- package/src/runtime/http-types.ts +5 -5
- package/src/runtime/interactive-ui.ts +0 -1
- package/src/runtime/middleware/auth.ts +0 -20
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +296 -80
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +421 -0
- package/src/runtime/migrations/migration-transport.ts +49 -16
- package/src/runtime/migrations/migration-wizard.ts +2 -2
- package/src/runtime/migrations/origin-mode.ts +40 -0
- package/src/runtime/migrations/vbundle-builder.ts +457 -136
- package/src/runtime/migrations/vbundle-import-analyzer.ts +13 -11
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +251 -74
- package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +329 -38
- package/src/runtime/migrations/vbundle-streaming-validator.ts +203 -28
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +328 -41
- package/src/runtime/pending-interactions.ts +48 -13
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/backup-routes.test.ts +49 -168
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +333 -0
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
- package/src/runtime/routes/acp-routes.test.ts +0 -3
- package/src/runtime/routes/acp-routes.ts +3 -7
- package/src/runtime/routes/app-management-routes.ts +18 -9
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-routes.ts +55 -14
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/avatar-routes.ts +3 -5
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/browser-routes.ts +1 -15
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/channel-guardian-routes.ts +1 -5
- package/src/runtime/routes/channel-readiness-routes.ts +3 -7
- package/src/runtime/routes/channel-route-shared.ts +2 -28
- package/src/runtime/routes/client-routes.ts +46 -12
- package/src/runtime/routes/consolidation-routes.ts +115 -0
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/conversation-list-routes.ts +12 -29
- package/src/runtime/routes/conversation-management-routes.ts +14 -51
- package/src/runtime/routes/conversation-query-routes.ts +156 -9
- package/src/runtime/routes/conversation-routes.ts +72 -539
- package/src/runtime/routes/conversation-starter-routes.ts +19 -40
- package/src/runtime/routes/document-pdf-renderer.ts +165 -0
- package/src/runtime/routes/documents-routes.ts +83 -18
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +68 -94
- package/src/runtime/routes/filing-routes.ts +18 -1
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-action-routes.ts +4 -9
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +37 -6
- package/src/runtime/routes/host-browser-routes.ts +96 -25
- package/src/runtime/routes/host-cu-routes.ts +48 -13
- package/src/runtime/routes/host-file-routes.ts +35 -11
- package/src/runtime/routes/host-transfer-routes.ts +73 -37
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +93 -49
- package/src/runtime/routes/inbound-message-handler.ts +581 -146
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -95
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +12 -0
- package/src/runtime/routes/integrations/slack/channel.ts +0 -24
- package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +451 -16
- package/src/runtime/routes/migration-routes.ts +284 -31
- package/src/runtime/routes/playground/guard.ts +1 -1
- package/src/runtime/routes/playground/index.ts +0 -2
- package/src/runtime/routes/recording-routes.ts +4 -24
- package/src/runtime/routes/rename-conversation-routes.ts +2 -6
- package/src/runtime/routes/schedule-routes.ts +10 -6
- package/src/runtime/routes/secret-routes.ts +87 -18
- package/src/runtime/routes/settings-routes.ts +29 -28
- package/src/runtime/routes/skills-routes.ts +12 -31
- package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
- package/src/runtime/routes/task-routes.ts +6 -6
- package/src/runtime/routes/trust-rules-routes.ts +3 -94
- package/src/runtime/routes/types.ts +4 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
- package/src/runtime/routes/usage-routes.ts +87 -10
- package/src/runtime/routes/user-routes.ts +17 -31
- package/src/runtime/routes/work-items-routes.ts +1 -4
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
- package/src/runtime/services/analyze-conversation.ts +7 -17
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/runtime/verification-outbound-actions.ts +1 -1
- package/src/runtime/verification-rate-limiter.ts +1 -1
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -18
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +63 -38
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/security/secret-scanner.ts +14 -547
- package/src/security/secure-keys.ts +31 -11
- package/src/security/token-manager.ts +7 -3
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/signals/cancel.ts +16 -25
- package/src/signals/conversation-undo.ts +2 -27
- package/src/signals/emit-event.ts +1 -2
- package/src/signals/user-message.ts +108 -22
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/catalog-install.ts +1 -0
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/inline-command-runner.ts +1 -7
- package/src/skills/remote-skill-policy.ts +5 -5
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/subagent/manager.ts +67 -84
- package/src/tasks/task-store.ts +1 -28
- package/src/telemetry/types.ts +8 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +59 -15
- package/src/telemetry/usage-telemetry-reporter.ts +4 -5
- package/src/tools/acp/spawn.test.ts +1 -2
- package/src/tools/acp/steer.test.ts +1 -2
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/browser/__tests__/browser-status.test.ts +55 -135
- package/src/tools/browser/browser-execution.ts +31 -147
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +145 -70
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +62 -91
- package/src/tools/browser/cdp-client/index.ts +1 -27
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +46 -31
- package/src/tools/host-filesystem/edit.ts +29 -2
- package/src/tools/host-filesystem/read.ts +29 -2
- package/src/tools/host-filesystem/transfer.test.ts +45 -42
- package/src/tools/host-filesystem/transfer.ts +35 -4
- package/src/tools/host-filesystem/write.ts +29 -2
- package/src/tools/host-terminal/host-shell.ts +62 -3
- package/src/tools/network/script-proxy/index.ts +1 -10
- package/src/tools/permission-checker.ts +66 -1
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/skills/sandbox-runner.ts +1 -6
- package/src/tools/skills/skill-tool-factory.ts +32 -0
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/terminal/shell.ts +2 -78
- package/src/tools/tool-approval-handler.ts +1 -5
- package/src/tools/types.ts +16 -39
- package/src/tts/__tests__/provider-catalog.test.ts +2 -2
- package/src/tts/provider-catalog.ts +1 -1
- package/src/usage/actors.ts +2 -1
- package/src/usage/attribution.ts +185 -0
- package/src/usage/pricing.ts +166 -0
- package/src/usage/types.ts +14 -0
- package/src/util/json.ts +13 -0
- package/src/util/logger.ts +3 -3
- package/src/util/pricing.ts +50 -3
- package/src/work-items/work-item-runner.ts +15 -42
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +6 -4
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +54 -0
- package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
- package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
- package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/workspace/provider-commit-message-generator.ts +3 -3
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -904
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -296
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -431
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
- package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
- package/src/__tests__/secret-detection-handler.test.ts +0 -67
- package/src/__tests__/secret-scanner-executor.test.ts +0 -450
- package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
- package/src/__tests__/terminal-sandbox.test.ts +0 -374
- package/src/__tests__/tool-notification-listener.test.ts +0 -65
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -754
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -438
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/context/__tests__/microcompact.test.ts +0 -805
- package/src/context/microcompact.ts +0 -443
- package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/events/tool-notification-listener.ts +0 -17
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
- package/src/memory/v2/__tests__/edges.test.ts +0 -435
- package/src/memory/v2/edges.ts +0 -217
- package/src/outbound-proxy/config.ts +0 -94
- package/src/outbound-proxy/health.ts +0 -62
- package/src/outbound-proxy/types.ts +0 -150
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
- package/src/runtime/__tests__/client-registry.test.ts +0 -271
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/runtime/chrome-extension-registry.ts +0 -368
- package/src/runtime/client-registry.ts +0 -254
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
- package/src/signals/mcp-reload.ts +0 -18
- package/src/tools/secret-detection-handler.ts +0 -269
- package/src/tools/terminal/backends/native.ts +0 -327
- package/src/tools/terminal/backends/types.ts +0 -37
- package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
- package/src/tools/terminal/sandbox.ts +0 -40
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Embedding anisotropy correction (Mu & Viswanath "all-but-the-top")
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// Modern transformer-based embedding models (Gemini's `gemini-embedding-2`
|
|
6
|
+
// being the most pronounced offender) produce vectors that occupy a narrow
|
|
7
|
+
// cone of the embedding space rather than spreading over the unit sphere.
|
|
8
|
+
// The downstream effect is that cosine similarities cluster in a compressed
|
|
9
|
+
// range — typically 0.4–0.7 for Gemini — which (a) makes absolute thresholds
|
|
10
|
+
// meaningless and (b) lets a few dominant directions drown out semantic
|
|
11
|
+
// signal.
|
|
12
|
+
//
|
|
13
|
+
// The fix: compute the corpus mean and its top-k principal components, then
|
|
14
|
+
// post-process every embedding via
|
|
15
|
+
//
|
|
16
|
+
// vec' = vec - mean
|
|
17
|
+
// for each pc_i: vec' = vec' - (vec' · pc_i) pc_i
|
|
18
|
+
// vec' = vec' / ||vec'||
|
|
19
|
+
//
|
|
20
|
+
// k = 1 is the safest starting point and reliably restores spread without
|
|
21
|
+
// risking semantic signal — see Mu & Viswanath 2018.
|
|
22
|
+
//
|
|
23
|
+
// ── Storage ────────────────────────────────────────────────────────────────
|
|
24
|
+
//
|
|
25
|
+
// Calibrations are persisted as JSON under
|
|
26
|
+
// `<workspace>/data/anisotropy/<provider>-<model>-<dim>.json` so each
|
|
27
|
+
// (provider, model, dim) tuple has its own. A loaded calibration is cached
|
|
28
|
+
// in-process; `clearAnisotropyCacheForTests` resets the module cache.
|
|
29
|
+
//
|
|
30
|
+
// ── Sphere-vs-raw inputs ───────────────────────────────────────────────────
|
|
31
|
+
//
|
|
32
|
+
// Qdrant pre-normalises vectors at insert time when the collection uses the
|
|
33
|
+
// Cosine distance, so the data we scroll for fitting lives on the unit
|
|
34
|
+
// sphere. Gemini's API, by contrast, returns raw (un-normalised) vectors at
|
|
35
|
+
// query time. To keep the fit and apply paths consistent we L2-normalise the
|
|
36
|
+
// input before applying the correction, regardless of source.
|
|
37
|
+
|
|
38
|
+
import { existsSync } from "node:fs";
|
|
39
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
40
|
+
import { join } from "node:path";
|
|
41
|
+
|
|
42
|
+
import { getDataDir } from "../util/platform.js";
|
|
43
|
+
import type { EmbeddingProviderName } from "./embedding-types.js";
|
|
44
|
+
|
|
45
|
+
/** Persisted anisotropy fit for a single (provider, model, dim) tuple. */
|
|
46
|
+
export interface AnisotropyCalibration {
|
|
47
|
+
provider: EmbeddingProviderName;
|
|
48
|
+
model: string;
|
|
49
|
+
/** Dimensionality of the embedding vectors this calibration applies to. */
|
|
50
|
+
dim: number;
|
|
51
|
+
/** Per-dimension mean across the fit sample. Length === `dim`. */
|
|
52
|
+
mean: number[];
|
|
53
|
+
/**
|
|
54
|
+
* Top-k principal components to project out. Stored as an array of
|
|
55
|
+
* unit-length d-vectors, one per component, in descending eigenvalue order.
|
|
56
|
+
* `components.length` is the operator-chosen `k` (typically 1, possibly 2-3).
|
|
57
|
+
*/
|
|
58
|
+
components: number[][];
|
|
59
|
+
/**
|
|
60
|
+
* Per-component variance (eigenvalues): `‖X v_i‖² / (N - 1)`. Same length
|
|
61
|
+
* as `components`. Useful to validate the fit (PC1 should explain a clear
|
|
62
|
+
* majority of variance for a truly anisotropic embedder).
|
|
63
|
+
*/
|
|
64
|
+
componentVariance: number[];
|
|
65
|
+
/**
|
|
66
|
+
* Total variance across all directions: `Σ_i ‖x_i - mean‖² / (N - 1)`.
|
|
67
|
+
* Combine with `componentVariance` to compute the explained-variance ratio
|
|
68
|
+
* per PC — i.e. how much of the corpus variance each PC accounts for.
|
|
69
|
+
*/
|
|
70
|
+
totalVariance: number;
|
|
71
|
+
/** Number of vectors used to compute this fit. */
|
|
72
|
+
sampleCount: number;
|
|
73
|
+
/** Wall-clock millis when the fit was computed (Date.now()). */
|
|
74
|
+
fitAt: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ── Public API ───────────────────────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Fit a calibration: corpus mean + top-k principal components via power
|
|
81
|
+
* iteration with Gram-Schmidt deflation.
|
|
82
|
+
*
|
|
83
|
+
* `vectors` is treated as a row-major data matrix (each entry is one sample).
|
|
84
|
+
* `k` is the number of leading principal components to extract (≥ 1).
|
|
85
|
+
*
|
|
86
|
+
* Returns the calibration without persisting it. Use `saveCalibration` to
|
|
87
|
+
* write it under `<workspace>/data/anisotropy/`.
|
|
88
|
+
*
|
|
89
|
+
* Throws when `vectors` is empty, `k` is non-positive, or the row dimensions
|
|
90
|
+
* disagree — these are caller bugs, not transient failures.
|
|
91
|
+
*/
|
|
92
|
+
export function fitAnisotropyCalibration(
|
|
93
|
+
vectors: readonly (readonly number[])[],
|
|
94
|
+
k: number,
|
|
95
|
+
meta: { provider: EmbeddingProviderName; model: string },
|
|
96
|
+
): AnisotropyCalibration {
|
|
97
|
+
if (vectors.length === 0) {
|
|
98
|
+
throw new Error("fitAnisotropyCalibration: no vectors supplied");
|
|
99
|
+
}
|
|
100
|
+
if (k < 1 || !Number.isInteger(k)) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`fitAnisotropyCalibration: k must be a positive integer, got ${k}`,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
const dim = vectors[0].length;
|
|
106
|
+
if (dim === 0) {
|
|
107
|
+
throw new Error("fitAnisotropyCalibration: vectors are zero-dimensional");
|
|
108
|
+
}
|
|
109
|
+
for (let i = 1; i < vectors.length; i++) {
|
|
110
|
+
if (vectors[i].length !== dim) {
|
|
111
|
+
throw new Error(
|
|
112
|
+
`fitAnisotropyCalibration: vector ${i} has dim ${vectors[i].length}, expected ${dim}`,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (k > dim) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`fitAnisotropyCalibration: requested k=${k} exceeds embedding dim=${dim}`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const n = vectors.length;
|
|
123
|
+
// Flatten into a contiguous Float64Array for cache locality during the
|
|
124
|
+
// O(k · iter · n · d) inner loop. Centre each row in place against the
|
|
125
|
+
// running mean once it's computed.
|
|
126
|
+
const data = new Float64Array(n * dim);
|
|
127
|
+
for (let i = 0; i < n; i++) {
|
|
128
|
+
const row = vectors[i];
|
|
129
|
+
for (let j = 0; j < dim; j++) {
|
|
130
|
+
data[i * dim + j] = row[j];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const mean = new Float64Array(dim);
|
|
135
|
+
for (let i = 0; i < n; i++) {
|
|
136
|
+
const base = i * dim;
|
|
137
|
+
for (let j = 0; j < dim; j++) {
|
|
138
|
+
mean[j] += data[base + j];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (let j = 0; j < dim; j++) {
|
|
142
|
+
mean[j] /= n;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Centre rows in place. After this `data` represents X = X_raw - mean.
|
|
146
|
+
for (let i = 0; i < n; i++) {
|
|
147
|
+
const base = i * dim;
|
|
148
|
+
for (let j = 0; j < dim; j++) {
|
|
149
|
+
data[base + j] -= mean[j];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Total variance: tr(X^T X) / (n - 1) = Σ_i ‖x_i‖² / (n - 1).
|
|
154
|
+
// Use n-1 for sample variance; falls back to 1 when n === 1 to avoid div0.
|
|
155
|
+
const denom = Math.max(1, n - 1);
|
|
156
|
+
let totalVariance = 0;
|
|
157
|
+
for (let i = 0; i < n * dim; i++) {
|
|
158
|
+
totalVariance += data[i] * data[i];
|
|
159
|
+
}
|
|
160
|
+
totalVariance /= denom;
|
|
161
|
+
|
|
162
|
+
const components: Float64Array[] = [];
|
|
163
|
+
const componentVariance: number[] = [];
|
|
164
|
+
for (let pcIdx = 0; pcIdx < k; pcIdx++) {
|
|
165
|
+
const v = powerIteration(data, n, dim, components);
|
|
166
|
+
// Eigenvalue λ = ‖X v‖² / (n - 1).
|
|
167
|
+
const Xv = matmulXv(data, n, dim, v);
|
|
168
|
+
let xvSq = 0;
|
|
169
|
+
for (let i = 0; i < n; i++) xvSq += Xv[i] * Xv[i];
|
|
170
|
+
components.push(v);
|
|
171
|
+
componentVariance.push(xvSq / denom);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
provider: meta.provider,
|
|
176
|
+
model: meta.model,
|
|
177
|
+
dim,
|
|
178
|
+
mean: Array.from(mean),
|
|
179
|
+
components: components.map((c) => Array.from(c)),
|
|
180
|
+
componentVariance,
|
|
181
|
+
totalVariance,
|
|
182
|
+
sampleCount: n,
|
|
183
|
+
fitAt: Date.now(),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Apply the all-but-the-top correction to a single embedding vector.
|
|
189
|
+
*
|
|
190
|
+
* The input is L2-normalised first so callers don't have to think about
|
|
191
|
+
* whether the source already lives on the unit sphere (Qdrant pre-normalises
|
|
192
|
+
* stored vectors under cosine distance; Gemini's API does not). The result
|
|
193
|
+
* is L2-normalised again so cosine similarity continues to behave like a
|
|
194
|
+
* dot product.
|
|
195
|
+
*
|
|
196
|
+
* Returns a fresh `number[]`; never mutates `vec` or the calibration.
|
|
197
|
+
*/
|
|
198
|
+
export function applyAnisotropyCorrection(
|
|
199
|
+
vec: readonly number[],
|
|
200
|
+
calib: AnisotropyCalibration,
|
|
201
|
+
): number[] {
|
|
202
|
+
if (vec.length !== calib.dim) {
|
|
203
|
+
throw new Error(
|
|
204
|
+
`applyAnisotropyCorrection: vec dim ${vec.length} != calibration dim ${calib.dim}`,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const out = new Float64Array(calib.dim);
|
|
209
|
+
for (let j = 0; j < calib.dim; j++) out[j] = vec[j];
|
|
210
|
+
l2NormalizeInPlace(out);
|
|
211
|
+
|
|
212
|
+
for (let j = 0; j < calib.dim; j++) {
|
|
213
|
+
out[j] -= calib.mean[j];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
for (const pc of calib.components) {
|
|
217
|
+
let proj = 0;
|
|
218
|
+
for (let j = 0; j < calib.dim; j++) proj += out[j] * pc[j];
|
|
219
|
+
for (let j = 0; j < calib.dim; j++) out[j] -= proj * pc[j];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
l2NormalizeInPlace(out);
|
|
223
|
+
return Array.from(out);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Compute the explained-variance ratio for each component. The list is
|
|
228
|
+
* monotonically non-increasing because power iteration with deflation pulls
|
|
229
|
+
* the largest eigenvalue first.
|
|
230
|
+
*/
|
|
231
|
+
export function explainedVarianceRatio(calib: AnisotropyCalibration): number[] {
|
|
232
|
+
if (calib.totalVariance === 0) {
|
|
233
|
+
return calib.componentVariance.map(() => 0);
|
|
234
|
+
}
|
|
235
|
+
return calib.componentVariance.map((v) => v / calib.totalVariance);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// ── Persistence ──────────────────────────────────────────────────────────────
|
|
239
|
+
|
|
240
|
+
const cache = new Map<string, AnisotropyCalibration | null>();
|
|
241
|
+
|
|
242
|
+
function calibrationKey(
|
|
243
|
+
provider: EmbeddingProviderName,
|
|
244
|
+
model: string,
|
|
245
|
+
dim: number,
|
|
246
|
+
): string {
|
|
247
|
+
return `${provider}:${model}:${dim}`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function calibrationPath(
|
|
251
|
+
provider: EmbeddingProviderName,
|
|
252
|
+
model: string,
|
|
253
|
+
dim: number,
|
|
254
|
+
): string {
|
|
255
|
+
// Models can contain slashes (`gemini-embedding-2`, `text-embedding-3-large`,
|
|
256
|
+
// `BAAI/bge-base-en-v1.5`). Replace anything that's not filename-safe with
|
|
257
|
+
// `_` so the on-disk name is portable across platforms.
|
|
258
|
+
const safeModel = model.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
259
|
+
return join(
|
|
260
|
+
getDataDir(),
|
|
261
|
+
"anisotropy",
|
|
262
|
+
`${provider}-${safeModel}-${dim}.json`,
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Convenience: load the calibration and apply it to a vector in one call.
|
|
268
|
+
* Returns the input untouched when no calibration has been persisted for the
|
|
269
|
+
* (provider, model, dim) tuple. The intended call site is right at the
|
|
270
|
+
* boundary between the embedding backend and consumers that store/query
|
|
271
|
+
* vectors against Qdrant — write paths apply this before upsert, read paths
|
|
272
|
+
* apply it before search.
|
|
273
|
+
*/
|
|
274
|
+
export async function applyCorrectionIfCalibrated(
|
|
275
|
+
vec: number[],
|
|
276
|
+
provider: EmbeddingProviderName,
|
|
277
|
+
model: string,
|
|
278
|
+
): Promise<number[]> {
|
|
279
|
+
const calib = await loadCalibration(provider, model, vec.length);
|
|
280
|
+
if (!calib) return vec;
|
|
281
|
+
return applyAnisotropyCorrection(vec, calib);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Load the calibration for a (provider, model, dim) tuple. Returns `null`
|
|
286
|
+
* when no fit has been persisted yet — callers should treat this as
|
|
287
|
+
* "anisotropy correction is off for this embedder" and pass through raw
|
|
288
|
+
* vectors. Module-level cached so subsequent calls hit memory.
|
|
289
|
+
*/
|
|
290
|
+
export async function loadCalibration(
|
|
291
|
+
provider: EmbeddingProviderName,
|
|
292
|
+
model: string,
|
|
293
|
+
dim: number,
|
|
294
|
+
): Promise<AnisotropyCalibration | null> {
|
|
295
|
+
const key = calibrationKey(provider, model, dim);
|
|
296
|
+
if (cache.has(key)) return cache.get(key) ?? null;
|
|
297
|
+
|
|
298
|
+
const path = calibrationPath(provider, model, dim);
|
|
299
|
+
if (!existsSync(path)) {
|
|
300
|
+
cache.set(key, null);
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
const raw = await readFile(path, "utf8");
|
|
305
|
+
const parsed = JSON.parse(raw) as AnisotropyCalibration;
|
|
306
|
+
cache.set(key, parsed);
|
|
307
|
+
return parsed;
|
|
308
|
+
} catch {
|
|
309
|
+
// A corrupt file is treated the same as a missing one: pass-through.
|
|
310
|
+
// The fit path will overwrite with a valid file on the next run.
|
|
311
|
+
cache.set(key, null);
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Persist a calibration to disk and refresh the in-process cache so the
|
|
318
|
+
* next `loadCalibration` returns the new fit without a file read.
|
|
319
|
+
*/
|
|
320
|
+
export async function saveCalibration(
|
|
321
|
+
calib: AnisotropyCalibration,
|
|
322
|
+
): Promise<string> {
|
|
323
|
+
const path = calibrationPath(calib.provider, calib.model, calib.dim);
|
|
324
|
+
await mkdir(join(getDataDir(), "anisotropy"), { recursive: true });
|
|
325
|
+
await writeFile(path, JSON.stringify(calib), "utf8");
|
|
326
|
+
cache.set(calibrationKey(calib.provider, calib.model, calib.dim), calib);
|
|
327
|
+
return path;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** @internal Test-only: drop the in-process calibration cache. */
|
|
331
|
+
export function clearAnisotropyCacheForTests(): void {
|
|
332
|
+
cache.clear();
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ── Power iteration internals ────────────────────────────────────────────────
|
|
336
|
+
|
|
337
|
+
const POWER_ITERATION_MAX = 200;
|
|
338
|
+
const POWER_ITERATION_TOL = 1e-7;
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Find the dominant eigenvector of X^T X (with previously-found components
|
|
342
|
+
* deflated out) via power iteration. Operates on `X v` and `X^T u` separately
|
|
343
|
+
* so we never materialise the d×d covariance matrix — for d=3072 that would
|
|
344
|
+
* be ~75 MB and cripple memory locality. Returns a unit-length d-vector.
|
|
345
|
+
*/
|
|
346
|
+
function powerIteration(
|
|
347
|
+
data: Float64Array,
|
|
348
|
+
n: number,
|
|
349
|
+
dim: number,
|
|
350
|
+
deflate: readonly Float64Array[],
|
|
351
|
+
): Float64Array {
|
|
352
|
+
// Deterministic init: a fixed unit vector. Power iteration converges from
|
|
353
|
+
// any non-orthogonal start, and a deterministic seed keeps fit results
|
|
354
|
+
// reproducible across runs (helpful for debugging and tests).
|
|
355
|
+
const v = new Float64Array(dim);
|
|
356
|
+
v[0] = 1;
|
|
357
|
+
// Project off any previously-found components from the init too, so we
|
|
358
|
+
// don't waste iterations re-deflating the same direction every step.
|
|
359
|
+
deflateInPlace(v, deflate);
|
|
360
|
+
l2NormalizeInPlace(v);
|
|
361
|
+
|
|
362
|
+
let prevDot = 0;
|
|
363
|
+
for (let iter = 0; iter < POWER_ITERATION_MAX; iter++) {
|
|
364
|
+
const Xv = matmulXv(data, n, dim, v);
|
|
365
|
+
const next = matmulXTu(data, n, dim, Xv);
|
|
366
|
+
deflateInPlace(next, deflate);
|
|
367
|
+
const norm = l2NormalizeInPlace(next);
|
|
368
|
+
if (norm === 0) {
|
|
369
|
+
// The remaining variance lives entirely in the deflated subspace —
|
|
370
|
+
// every direction we can pick is orthogonal to the data. Returning the
|
|
371
|
+
// current best estimate keeps the spectrum monotonic instead of
|
|
372
|
+
// emitting NaN downstream.
|
|
373
|
+
return v;
|
|
374
|
+
}
|
|
375
|
+
let dot = 0;
|
|
376
|
+
for (let j = 0; j < dim; j++) dot += v[j] * next[j];
|
|
377
|
+
// |dot| approaches 1 as power iteration converges (sign can flip across
|
|
378
|
+
// iterations, so absolute value).
|
|
379
|
+
if (Math.abs(Math.abs(dot) - Math.abs(prevDot)) < POWER_ITERATION_TOL) {
|
|
380
|
+
return next;
|
|
381
|
+
}
|
|
382
|
+
prevDot = dot;
|
|
383
|
+
for (let j = 0; j < dim; j++) v[j] = next[j];
|
|
384
|
+
}
|
|
385
|
+
return v;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/** y = X v, where X is n×d row-major. Returns a fresh Float64Array of length n. */
|
|
389
|
+
function matmulXv(
|
|
390
|
+
data: Float64Array,
|
|
391
|
+
n: number,
|
|
392
|
+
dim: number,
|
|
393
|
+
v: Float64Array,
|
|
394
|
+
): Float64Array {
|
|
395
|
+
const out = new Float64Array(n);
|
|
396
|
+
for (let i = 0; i < n; i++) {
|
|
397
|
+
const base = i * dim;
|
|
398
|
+
let acc = 0;
|
|
399
|
+
for (let j = 0; j < dim; j++) acc += data[base + j] * v[j];
|
|
400
|
+
out[i] = acc;
|
|
401
|
+
}
|
|
402
|
+
return out;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** y = X^T u, where X is n×d row-major. Returns a fresh Float64Array of length d. */
|
|
406
|
+
function matmulXTu(
|
|
407
|
+
data: Float64Array,
|
|
408
|
+
n: number,
|
|
409
|
+
dim: number,
|
|
410
|
+
u: Float64Array,
|
|
411
|
+
): Float64Array {
|
|
412
|
+
const out = new Float64Array(dim);
|
|
413
|
+
for (let i = 0; i < n; i++) {
|
|
414
|
+
const base = i * dim;
|
|
415
|
+
const ui = u[i];
|
|
416
|
+
for (let j = 0; j < dim; j++) out[j] += data[base + j] * ui;
|
|
417
|
+
}
|
|
418
|
+
return out;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/** Subtract every previously-found component from `v` (Gram-Schmidt). */
|
|
422
|
+
function deflateInPlace(
|
|
423
|
+
v: Float64Array,
|
|
424
|
+
deflate: readonly Float64Array[],
|
|
425
|
+
): void {
|
|
426
|
+
for (const pc of deflate) {
|
|
427
|
+
let proj = 0;
|
|
428
|
+
const dim = v.length;
|
|
429
|
+
for (let j = 0; j < dim; j++) proj += v[j] * pc[j];
|
|
430
|
+
for (let j = 0; j < dim; j++) v[j] -= proj * pc[j];
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/** L2-normalise `v` in place. Returns the original norm so callers can detect zero vectors. */
|
|
435
|
+
function l2NormalizeInPlace(v: Float64Array): number {
|
|
436
|
+
let norm = 0;
|
|
437
|
+
for (let j = 0; j < v.length; j++) norm += v[j] * v[j];
|
|
438
|
+
norm = Math.sqrt(norm);
|
|
439
|
+
if (norm === 0) return 0;
|
|
440
|
+
const inv = 1 / norm;
|
|
441
|
+
for (let j = 0; j < v.length; j++) v[j] *= inv;
|
|
442
|
+
return norm;
|
|
443
|
+
}
|
|
@@ -132,38 +132,6 @@ function validateRelativePath(path: string): void {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
// ---------------------------------------------------------------------------
|
|
136
|
-
// Initialization & commit
|
|
137
|
-
// ---------------------------------------------------------------------------
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Eagerly initialize the app git repo so that the "Initial commit" is
|
|
141
|
-
* created before any app files are written. Without this, the first
|
|
142
|
-
* mutation's files get absorbed into WorkspaceGitService's bootstrap
|
|
143
|
-
* commit and the "Create app: ..." commit ends up empty.
|
|
144
|
-
*
|
|
145
|
-
* Safe to call multiple times -- ensureInitialized() is idempotent.
|
|
146
|
-
* Commit app changes to the apps git repository.
|
|
147
|
-
*
|
|
148
|
-
* This is fire-and-forget: errors are logged but never thrown.
|
|
149
|
-
* The caller should not await the returned promise unless it needs
|
|
150
|
-
* to guarantee the commit completed (e.g. in tests).
|
|
151
|
-
*/
|
|
152
|
-
export async function commitAppChange(message: string): Promise<void> {
|
|
153
|
-
try {
|
|
154
|
-
const appsDir = getAppsDir();
|
|
155
|
-
|
|
156
|
-
// Re-check .gitignore rules every call in case the apps dir was
|
|
157
|
-
// recreated while the process was running.
|
|
158
|
-
ensureAppGitignoreRules(appsDir);
|
|
159
|
-
|
|
160
|
-
const gitService = getWorkspaceGitService(appsDir);
|
|
161
|
-
await gitService.commitChanges(message);
|
|
162
|
-
} catch (err) {
|
|
163
|
-
log.error({ err, message }, "Failed to commit app change");
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
135
|
/**
|
|
168
136
|
* Commit app changes at turn boundaries.
|
|
169
137
|
*
|
package/src/memory/app-store.ts
CHANGED
|
@@ -36,7 +36,9 @@ import {
|
|
|
36
36
|
|
|
37
37
|
import type { EditEngineResult } from "../tools/shared/filesystem/edit-engine.js";
|
|
38
38
|
import { applyEdit } from "../tools/shared/filesystem/edit-engine.js";
|
|
39
|
+
import { getLogger } from "../util/logger.js";
|
|
39
40
|
import { getDataDir } from "../util/platform.js";
|
|
41
|
+
import { rawAll } from "./raw-query.js";
|
|
40
42
|
|
|
41
43
|
export interface AppDefinition {
|
|
42
44
|
id: string;
|
|
@@ -55,6 +57,8 @@ export interface AppDefinition {
|
|
|
55
57
|
formatVersion?: number;
|
|
56
58
|
/** Filesystem directory/file stem. Frozen at creation -- never changes on rename. */
|
|
57
59
|
dirName?: string;
|
|
60
|
+
/** Conversation IDs that have interacted with this app (create/open/refresh). */
|
|
61
|
+
conversationIds?: string[];
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
/**
|
|
@@ -901,4 +905,154 @@ export function editAppFile(
|
|
|
901
905
|
return result;
|
|
902
906
|
}
|
|
903
907
|
|
|
908
|
+
// ---------------------------------------------------------------------------
|
|
909
|
+
// Conversation association helpers
|
|
910
|
+
// ---------------------------------------------------------------------------
|
|
911
|
+
|
|
912
|
+
/**
|
|
913
|
+
* Associate a conversation with an app. Writes directly to the JSON metadata
|
|
914
|
+
* file without bumping `updatedAt` so the app list ordering is preserved.
|
|
915
|
+
*
|
|
916
|
+
* @returns `true` if the association was added, `false` if the app was not
|
|
917
|
+
* found or the conversationId was already present (dedup).
|
|
918
|
+
*/
|
|
919
|
+
export function addAppConversationId(
|
|
920
|
+
appId: string,
|
|
921
|
+
conversationId: string,
|
|
922
|
+
): boolean {
|
|
923
|
+
const app = getApp(appId);
|
|
924
|
+
if (!app) return false;
|
|
925
|
+
|
|
926
|
+
const { dirName } = resolveAppDir(appId);
|
|
927
|
+
const dir = getAppsDir();
|
|
928
|
+
const jsonPath = join(dir, `${dirName}.json`);
|
|
929
|
+
|
|
930
|
+
// Atomic read-modify-write: re-read the file immediately before writing
|
|
931
|
+
// so concurrent callers (e.g. two tool_result handlers for the same app
|
|
932
|
+
// in different conversations) merge against the latest on-disk state.
|
|
933
|
+
// Because readFileSync → JSON.parse → writeFileSync is a synchronous
|
|
934
|
+
// chain with no async gaps, Node/Bun's single-threaded event loop
|
|
935
|
+
// guarantees no interleaving between the read and the write.
|
|
936
|
+
const raw = readFileSync(jsonPath, "utf-8");
|
|
937
|
+
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
|
938
|
+
const onDiskIds = Array.isArray(parsed.conversationIds)
|
|
939
|
+
? (parsed.conversationIds as string[])
|
|
940
|
+
: [];
|
|
941
|
+
|
|
942
|
+
if (onDiskIds.includes(conversationId)) return false;
|
|
943
|
+
|
|
944
|
+
parsed.conversationIds = [...onDiskIds, conversationId];
|
|
945
|
+
writeFileSync(jsonPath, JSON.stringify(parsed, null, 2));
|
|
946
|
+
|
|
947
|
+
return true;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* Return all apps associated with a given conversation ID.
|
|
952
|
+
*/
|
|
953
|
+
export function listAppsByConversation(
|
|
954
|
+
conversationId: string,
|
|
955
|
+
): AppDefinition[] {
|
|
956
|
+
return listApps().filter((app) =>
|
|
957
|
+
app.conversationIds?.includes(conversationId),
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
// ---------------------------------------------------------------------------
|
|
962
|
+
// Backfill: scan message history for ui_surface blocks referencing apps
|
|
963
|
+
// ---------------------------------------------------------------------------
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Single-pass scan over the messages table to populate `conversationIds` on
|
|
967
|
+
* existing app definitions. Finds messages containing `ui_surface` blocks
|
|
968
|
+
* with a `data.appId`, then calls `addAppConversationId` for each pair.
|
|
969
|
+
*
|
|
970
|
+
* Runs once per workspace: after a successful backfill a sentinel file
|
|
971
|
+
* (`<appsDir>/.conversation-ids-backfilled`) is written. Subsequent daemon
|
|
972
|
+
* startups skip the scan entirely. If the apps directory is wiped the
|
|
973
|
+
* sentinel disappears and the backfill re-runs — which is correct behavior.
|
|
974
|
+
*
|
|
975
|
+
* Wrapped in try/catch so failures never block daemon start.
|
|
976
|
+
*/
|
|
977
|
+
export function backfillAppConversationIds(): void {
|
|
978
|
+
const log = getLogger("app-store");
|
|
979
|
+
|
|
980
|
+
// Check sentinel — skip the potentially expensive scan when already done.
|
|
981
|
+
const sentinelPath = join(getAppsDir(), ".conversation-ids-backfilled");
|
|
982
|
+
if (existsSync(sentinelPath)) {
|
|
983
|
+
log.debug("Skipping backfillAppConversationIds — sentinel exists");
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
try {
|
|
988
|
+
const rows = rawAll<{ conversation_id: string; content: string }>(
|
|
989
|
+
`SELECT conversation_id, content FROM messages WHERE content LIKE '%"type":"ui_surface"%'`,
|
|
990
|
+
);
|
|
991
|
+
|
|
992
|
+
// Build appId → Set<conversationId> map in a single pass
|
|
993
|
+
const appConvMap = new Map<string, Set<string>>();
|
|
994
|
+
|
|
995
|
+
for (const row of rows) {
|
|
996
|
+
let parsed: unknown;
|
|
997
|
+
try {
|
|
998
|
+
parsed = JSON.parse(row.content);
|
|
999
|
+
} catch {
|
|
1000
|
+
// Skip rows that fail to parse
|
|
1001
|
+
continue;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
if (!Array.isArray(parsed)) continue;
|
|
1005
|
+
|
|
1006
|
+
for (const block of parsed) {
|
|
1007
|
+
if (
|
|
1008
|
+
block &&
|
|
1009
|
+
typeof block === "object" &&
|
|
1010
|
+
(block as Record<string, unknown>).type === "ui_surface"
|
|
1011
|
+
) {
|
|
1012
|
+
const data = (block as Record<string, unknown>).data;
|
|
1013
|
+
if (data && typeof data === "object") {
|
|
1014
|
+
const appId = (data as Record<string, unknown>).appId;
|
|
1015
|
+
if (typeof appId === "string" && appId.length > 0) {
|
|
1016
|
+
let convIds = appConvMap.get(appId);
|
|
1017
|
+
if (!convIds) {
|
|
1018
|
+
convIds = new Set<string>();
|
|
1019
|
+
appConvMap.set(appId, convIds);
|
|
1020
|
+
}
|
|
1021
|
+
convIds.add(row.conversation_id);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
// Apply associations
|
|
1029
|
+
let appsUpdated = 0;
|
|
1030
|
+
let associationsAdded = 0;
|
|
1031
|
+
|
|
1032
|
+
for (const [appId, conversationIds] of appConvMap) {
|
|
1033
|
+
let appHadNewAssociation = false;
|
|
1034
|
+
for (const conversationId of conversationIds) {
|
|
1035
|
+
const added = addAppConversationId(appId, conversationId);
|
|
1036
|
+
if (added) {
|
|
1037
|
+
associationsAdded++;
|
|
1038
|
+
appHadNewAssociation = true;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
if (appHadNewAssociation) {
|
|
1042
|
+
appsUpdated++;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
log.info(
|
|
1047
|
+
{ appsUpdated, associationsAdded },
|
|
1048
|
+
`Backfilled app conversationIds: ${appsUpdated} apps, ${associationsAdded} associations`,
|
|
1049
|
+
);
|
|
1050
|
+
|
|
1051
|
+
// Write sentinel so subsequent startups skip this scan.
|
|
1052
|
+
writeFileSync(sentinelPath, new Date().toISOString(), "utf-8");
|
|
1053
|
+
} catch (err) {
|
|
1054
|
+
log.error({ err }, "Failed to backfill app conversationIds");
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
904
1058
|
export type { EditEngineResult };
|
|
@@ -413,8 +413,14 @@ const ALLOWED_MIME_TYPES = new Set([
|
|
|
413
413
|
// Archives
|
|
414
414
|
"application/zip",
|
|
415
415
|
"application/gzip",
|
|
416
|
+
"application/x-gzip",
|
|
417
|
+
"application/x-compressed-tar",
|
|
416
418
|
"application/x-tar",
|
|
417
419
|
"application/x-7z-compressed",
|
|
420
|
+
"application/x-bzip2",
|
|
421
|
+
"application/x-xz",
|
|
422
|
+
"application/vnd.rar",
|
|
423
|
+
"application/x-rar-compressed",
|
|
418
424
|
// Office
|
|
419
425
|
"application/msword",
|
|
420
426
|
"application/vnd.ms-excel",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants extracted from auto-analysis-guard.ts to break the
|
|
3
|
+
* conversation-crud ↔ auto-analysis-guard cycle.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Sentinel value for the `source` column of auto-analysis conversations.
|
|
8
|
+
* Used both when creating them and when querying "all except auto-analysis."
|
|
9
|
+
*/
|
|
10
|
+
export const AUTO_ANALYSIS_SOURCE = "auto-analysis";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Dedicated `group_id` value for auto-analysis rolling conversations.
|
|
14
|
+
* Placed in the `system:background` group alongside heartbeat and filing
|
|
15
|
+
* conversations, rendered as a "Reflections" sub-group in the sidebar.
|
|
16
|
+
*/
|
|
17
|
+
export const AUTO_ANALYSIS_GROUP_ID = "system:background";
|