@vellumai/assistant 0.7.3 → 0.8.1
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/AGENTS.md +11 -0
- package/ARCHITECTURE.md +29 -28
- package/Dockerfile +6 -4
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
- package/bun.lock +3 -0
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +3 -1
- package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
- package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
- package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4126 -959
- package/package.json +5 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/annotate-risk-options.test.ts +291 -0
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/approval-cascade.test.ts +8 -16
- package/src/__tests__/approval-routes-http.test.ts +6 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-constants.test.ts +10 -1
- package/src/__tests__/call-controller.test.ts +127 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-source.test.ts +3 -26
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +3 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +22 -7
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
- package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +25 -22
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/injector-chain.test.ts +24 -16
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-decision-fallback.test.ts +91 -0
- package/src/__tests__/notification-decision-strategy.test.ts +22 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -1888
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +164 -2
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
- package/src/__tests__/secret-response-routing.test.ts +7 -5
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/server-history-render.test.ts +82 -0
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-include-graph.test.ts +31 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +42 -16
- package/src/__tests__/skills.test.ts +39 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
- package/src/__tests__/tool-executor.test.ts +155 -0
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/voice-session-bridge.test.ts +3 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
- package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/agent/loop.ts +11 -0
- package/src/approvals/guardian-decision-primitive.ts +0 -13
- package/src/approvals/guardian-request-resolvers.ts +19 -102
- package/src/calls/call-constants.ts +5 -8
- package/src/calls/call-controller.ts +130 -67
- package/src/calls/relay-server.ts +42 -1
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +24 -5
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +163 -517
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +182 -345
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +17 -17
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +148 -33
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +33 -2
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
- package/src/daemon/conversation-agent-loop.ts +140 -107
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +68 -13
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +92 -26
- package/src/daemon/conversation-tool-setup.ts +33 -19
- package/src/daemon/conversation.ts +49 -10
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/shared.ts +26 -0
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +97 -36
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/host-file-proxy.ts +1 -1
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/host-transfer-proxy.ts +2 -2
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +128 -114
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +62 -14
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +28 -2
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/documents/document-store.ts +35 -1
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +42 -56
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +149 -128
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +148 -42
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/ipc/skill-server.ts +99 -42
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +40 -31
- package/src/memory/context-search/sources/memory.ts +9 -2
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +108 -14
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/graph-search.test.ts +6 -5
- package/src/memory/graph/graph-search.ts +3 -4
- package/src/memory/graph/retriever.test.ts +12 -7
- package/src/memory/graph/retriever.ts +4 -5
- package/src/memory/graph/tool-handlers.ts +20 -11
- package/src/memory/graph/tools.ts +48 -9
- package/src/memory/indexer.ts +18 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
- package/src/memory/jobs/embed-concept-page.ts +261 -89
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +60 -7
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -5
- package/src/memory/pkb/pkb-search.ts +4 -5
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/qdrant-client.ts +3 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +5 -9
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +46 -9
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +768 -33
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +163 -8
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +8 -35
- package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +92 -86
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +466 -115
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +42 -0
- package/src/memory/v2/prompts/consolidation.ts +14 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +307 -133
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +88 -34
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +20 -17
- package/src/memory/v2/sweep-job.ts +127 -102
- package/src/memory/v2/types.ts +16 -5
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +61 -12
- package/src/notifications/decision-engine.ts +46 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/gateway-threshold-reader.ts +116 -8
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/permissions/prompter.ts +86 -96
- package/src/permissions/secret-prompter.ts +31 -31
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +20 -5
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +63 -8
- package/src/proactive-artifact/job.ts +20 -2
- package/src/proactive-artifact/message-copy.ts +18 -1
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/templates/SOUL.md +13 -28
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +304 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/channel-approvals.ts +3 -2
- package/src/runtime/guardian-reply-router.ts +0 -10
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pending-interactions.ts +19 -15
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +7 -21
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/consolidation-routes.ts +8 -9
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +373 -82
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-bash-routes.ts +2 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/filing-routes.ts +2 -3
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-item-routes.test.ts +3 -9
- package/src/runtime/routes/memory-item-routes.ts +5 -6
- package/src/runtime/routes/memory-v2-routes.ts +105 -404
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/skills/include-graph.ts +35 -13
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/document/document-tool.ts +20 -0
- package/src/tools/executor.ts +18 -2
- package/src/tools/memory/register.test.ts +10 -8
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +28 -5
- package/src/tools/skills/load.ts +24 -20
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/tools/tool-name-aliases.ts +19 -0
- package/src/tools/types.ts +19 -1
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
- package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -492
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -477
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory v2 — Sonnet router orchestration.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the per-turn spreading-activation page selector with a single LLM
|
|
5
|
+
* call. Given the rendered page index, the most recent user/assistant turn,
|
|
6
|
+
* and the list of pages already injected on prior turns, the router returns a
|
|
7
|
+
* small set of concept-page IDs to inject for the next reply.
|
|
8
|
+
*
|
|
9
|
+
* The design mirrors `sweep-job.ts`:
|
|
10
|
+
* - resolve the configured provider via `getConfiguredProvider`,
|
|
11
|
+
* - call `provider.sendMessage` with a forced `tool_choice`,
|
|
12
|
+
* - validate the tool input via Zod,
|
|
13
|
+
* - map back to slugs and let the caller drive injection.
|
|
14
|
+
*
|
|
15
|
+
* Cache strategy. Two 1h ephemeral breakpoints carry the bulk of the
|
|
16
|
+
* routing cost across turns:
|
|
17
|
+
* 1. The last text block of the system prompt — the page index is the
|
|
18
|
+
* single largest input and changes only when concept pages are edited.
|
|
19
|
+
* Auto-applied by the Anthropic provider at the configured 1h TTL.
|
|
20
|
+
* 2. The first user-message block (`<now>`) — stable across most turns
|
|
21
|
+
* since NOW.md only changes when the model rewrites it. We set the 1h
|
|
22
|
+
* TTL explicitly here to match the provider-side breakpoints; the
|
|
23
|
+
* default 5m would force unnecessary cache re-creation.
|
|
24
|
+
* The Anthropic provider also auto-applies a 1h breakpoint on the last text
|
|
25
|
+
* block of a turn-starting user message, so the trailing uncached block does
|
|
26
|
+
* not need an explicit `cache_control`.
|
|
27
|
+
*
|
|
28
|
+
* This module is pure orchestration — it does not mutate activation state,
|
|
29
|
+
* write any files, or update the conversation. PR 10 wires it into
|
|
30
|
+
* `injectMemoryV2Block`; until then nothing in the daemon calls it.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { z } from "zod";
|
|
34
|
+
|
|
35
|
+
import type { AssistantConfig } from "../../config/types.js";
|
|
36
|
+
import {
|
|
37
|
+
getAssistantName,
|
|
38
|
+
resolveUserName,
|
|
39
|
+
} from "../../daemon/identity-helpers.js";
|
|
40
|
+
import {
|
|
41
|
+
extractToolUse,
|
|
42
|
+
getConfiguredProvider,
|
|
43
|
+
} from "../../providers/provider-send-message.js";
|
|
44
|
+
import type {
|
|
45
|
+
ContentBlock,
|
|
46
|
+
Message,
|
|
47
|
+
ToolDefinition,
|
|
48
|
+
} from "../../providers/types.js";
|
|
49
|
+
import { getLogger } from "../../util/logger.js";
|
|
50
|
+
import { getPageIndex } from "./page-index.js";
|
|
51
|
+
import { resolveRouterPrompt } from "./prompts/router.js";
|
|
52
|
+
import type { EverInjectedEntry } from "./types.js";
|
|
53
|
+
|
|
54
|
+
const log = getLogger("memory-v2-router");
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Reasons the router may fall short of returning a usable selection. The
|
|
58
|
+
* caller (PR 10) maps each reason to a fallback path; the closed string-
|
|
59
|
+
* literal union lets that dispatch stay exhaustive without a brittle
|
|
60
|
+
* free-form string match.
|
|
61
|
+
*/
|
|
62
|
+
export type RouterFailureReason =
|
|
63
|
+
| "no_provider"
|
|
64
|
+
| "tool_use_missing"
|
|
65
|
+
| "schema_mismatch"
|
|
66
|
+
| "api_error"
|
|
67
|
+
| "empty_index";
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Result of a single router call. `selectedSlugs` preserves the order the
|
|
71
|
+
* model returned and is already capped at `config.memory.v2.router.max_page_ids`
|
|
72
|
+
* with out-of-range IDs dropped.
|
|
73
|
+
*/
|
|
74
|
+
export interface RouterResult {
|
|
75
|
+
/** Selected page slugs in the order the model returned them. */
|
|
76
|
+
selectedSlugs: string[];
|
|
77
|
+
/** `null` on success; one of the failure reasons above otherwise. */
|
|
78
|
+
failureReason: RouterFailureReason | null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Tool name forced via `tool_choice`. Single shared constant so tests can match it. */
|
|
82
|
+
const ROUTER_TOOL_NAME = "select_pages_to_inject";
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Build the tool definition handed to the provider. The JSON schema is what
|
|
86
|
+
* the model sees; the Zod schema below validates the response at runtime.
|
|
87
|
+
*
|
|
88
|
+
* `maxItems` mirrors the runtime `config.memory.v2.router.max_page_ids` cap
|
|
89
|
+
* so the model is told the same upper bound the post-call truncation
|
|
90
|
+
* enforces. Built per-call rather than module-scoped because the cap is
|
|
91
|
+
* configurable per workspace.
|
|
92
|
+
*/
|
|
93
|
+
function buildRouterTool(maxPageIds: number): ToolDefinition {
|
|
94
|
+
return {
|
|
95
|
+
name: ROUTER_TOOL_NAME,
|
|
96
|
+
description: `Choose up to ${maxPageIds} concept page IDs to inject for the next reply. Lean toward inclusion when in doubt — missing a relevant page is a worse error than surfacing unused ones. Return [] only when nothing in the index plausibly bears on the turn.`,
|
|
97
|
+
input_schema: {
|
|
98
|
+
type: "object",
|
|
99
|
+
properties: {
|
|
100
|
+
page_ids: {
|
|
101
|
+
type: "array",
|
|
102
|
+
items: { type: "integer" },
|
|
103
|
+
maxItems: maxPageIds,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
required: ["page_ids"],
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const RouterResultSchema = z.object({
|
|
112
|
+
page_ids: z.array(z.number().int()),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
/** Empty-result helper so call sites don't reconstruct the shape inline. */
|
|
116
|
+
function emptyResult(reason: RouterFailureReason | null): RouterResult {
|
|
117
|
+
return { selectedSlugs: [], failureReason: reason };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
interface RunRouterParams {
|
|
121
|
+
workspaceDir: string;
|
|
122
|
+
userMessage: string;
|
|
123
|
+
assistantMessage: string;
|
|
124
|
+
/** Verbatim contents to inject into `<now>...</now>` on this turn. */
|
|
125
|
+
nowText: string;
|
|
126
|
+
/** Slugs already injected on prior turns (used to seed `<already_injected_ids>`). */
|
|
127
|
+
priorEverInjected: readonly EverInjectedEntry[];
|
|
128
|
+
config: AssistantConfig;
|
|
129
|
+
signal?: AbortSignal;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Run the router for one turn. The implementation steps (mirroring
|
|
134
|
+
* `sweep-job.ts` end-to-end):
|
|
135
|
+
*
|
|
136
|
+
* 1. Build the page index. If the workspace has no concept pages and no
|
|
137
|
+
* seeded skill entries, abstain immediately with `empty_index`.
|
|
138
|
+
* 2. Resolve the configured provider for the `memoryRouter` call site.
|
|
139
|
+
* Missing → `no_provider` so the caller can fall back to spreading
|
|
140
|
+
* activation or an empty injection.
|
|
141
|
+
* 3. Build system + user prompts. The system prompt is the rendered
|
|
142
|
+
* router template with the page index inlined and gets one ephemeral
|
|
143
|
+
* breakpoint at the end (the page-index block). The user message is
|
|
144
|
+
* *two* text blocks: the cached `<now>` block and the uncached
|
|
145
|
+
* already-injected/last-turn block.
|
|
146
|
+
* 4. Force `tool_choice` so the model can only emit `select_pages_to_inject`.
|
|
147
|
+
* 5. Parse the tool input via Zod. Anything off-shape collapses to
|
|
148
|
+
* `schema_mismatch`.
|
|
149
|
+
* 6. Map IDs to slugs through the page index, dropping IDs outside
|
|
150
|
+
* `[1, N]` and truncating at `max_page_ids`.
|
|
151
|
+
*
|
|
152
|
+
* Any uncaught throw inside the call (network, provider SDK error, abort)
|
|
153
|
+
* collapses to `api_error` and is logged at warn so callers can keep going
|
|
154
|
+
* without crashing the daemon. `AbortSignal.aborted` errors are *not*
|
|
155
|
+
* special-cased; they propagate as `api_error` because the caller treats
|
|
156
|
+
* "router didn't finish" the same regardless of cause.
|
|
157
|
+
*/
|
|
158
|
+
export async function runRouter(
|
|
159
|
+
params: RunRouterParams,
|
|
160
|
+
): Promise<RouterResult> {
|
|
161
|
+
const {
|
|
162
|
+
workspaceDir,
|
|
163
|
+
userMessage,
|
|
164
|
+
assistantMessage,
|
|
165
|
+
nowText,
|
|
166
|
+
priorEverInjected,
|
|
167
|
+
config,
|
|
168
|
+
signal,
|
|
169
|
+
} = params;
|
|
170
|
+
|
|
171
|
+
const pageIndex = await getPageIndex(workspaceDir);
|
|
172
|
+
if (pageIndex.entries.length === 0) {
|
|
173
|
+
return emptyResult("empty_index");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const provider = await getConfiguredProvider("memoryRouter");
|
|
177
|
+
if (!provider) {
|
|
178
|
+
log.warn("memoryRouter provider unavailable; router skipped");
|
|
179
|
+
return emptyResult("no_provider");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const systemPrompt = resolveRouterPrompt(
|
|
183
|
+
config.memory?.v2?.router?.router_prompt_path ?? null,
|
|
184
|
+
{
|
|
185
|
+
assistantName: getAssistantName(),
|
|
186
|
+
userName: resolveUserName(workspaceDir),
|
|
187
|
+
pageIndexBlock: pageIndex.rendered,
|
|
188
|
+
},
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// Already-injected slugs that map back to a current index ID. Slugs whose
|
|
192
|
+
// page has been deleted since the prior turn drop out silently — the model
|
|
193
|
+
// only sees IDs that still resolve.
|
|
194
|
+
const priorIds: number[] = [];
|
|
195
|
+
for (const entry of priorEverInjected) {
|
|
196
|
+
const idx = pageIndex.bySlug.get(entry.slug);
|
|
197
|
+
if (idx) priorIds.push(idx.id);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Cache breakpoint 2 — `<now>` is stable across most turns (NOW.md only
|
|
201
|
+
// changes when the model rewrites it), so the bulk of the user message
|
|
202
|
+
// rides the cache. We use a 1h TTL to match the system-prompt breakpoint
|
|
203
|
+
// and the provider's auto-applied breakpoints. The trailing block has no
|
|
204
|
+
// `cache_control`; the Anthropic provider auto-applies a 1h breakpoint on
|
|
205
|
+
// the last text block of a turn-starting user message, which covers it.
|
|
206
|
+
const userMsg: Message = {
|
|
207
|
+
role: "user",
|
|
208
|
+
content: [
|
|
209
|
+
cachedTextBlock(`<now>\n${nowText}\n</now>`),
|
|
210
|
+
{
|
|
211
|
+
type: "text",
|
|
212
|
+
text:
|
|
213
|
+
`<already_injected_ids>\n${priorIds.join(", ")}\n</already_injected_ids>\n\n` +
|
|
214
|
+
`<last_turn>\n[user]: ${userMessage}\n[assistant]: ${assistantMessage}\n</last_turn>`,
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const maxPageIds = config.memory?.v2?.router?.max_page_ids ?? 25;
|
|
220
|
+
const routerTool = buildRouterTool(maxPageIds);
|
|
221
|
+
|
|
222
|
+
let response;
|
|
223
|
+
try {
|
|
224
|
+
response = await provider.sendMessage(
|
|
225
|
+
[userMsg],
|
|
226
|
+
[routerTool],
|
|
227
|
+
systemPrompt,
|
|
228
|
+
{
|
|
229
|
+
config: {
|
|
230
|
+
callSite: "memoryRouter" as const,
|
|
231
|
+
tool_choice: { type: "tool" as const, name: ROUTER_TOOL_NAME },
|
|
232
|
+
},
|
|
233
|
+
...(signal ? { signal } : {}),
|
|
234
|
+
},
|
|
235
|
+
);
|
|
236
|
+
} catch (err) {
|
|
237
|
+
log.warn({ err }, "Router provider call threw; treating as api_error");
|
|
238
|
+
return emptyResult("api_error");
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const toolBlock = extractToolUse(response);
|
|
242
|
+
if (!toolBlock || toolBlock.name !== ROUTER_TOOL_NAME) {
|
|
243
|
+
log.warn(
|
|
244
|
+
{ stopReason: response.stopReason },
|
|
245
|
+
"Router model returned no select_pages_to_inject tool_use block",
|
|
246
|
+
);
|
|
247
|
+
return emptyResult("tool_use_missing");
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const parsed = RouterResultSchema.safeParse(toolBlock.input);
|
|
251
|
+
if (!parsed.success) {
|
|
252
|
+
log.warn(
|
|
253
|
+
{ error: parsed.error.message },
|
|
254
|
+
"Router tool input did not match schema",
|
|
255
|
+
);
|
|
256
|
+
return emptyResult("schema_mismatch");
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const N = pageIndex.entries.length;
|
|
260
|
+
|
|
261
|
+
const inRangeIds: number[] = [];
|
|
262
|
+
const droppedIds: number[] = [];
|
|
263
|
+
for (const id of parsed.data.page_ids) {
|
|
264
|
+
if (id >= 1 && id <= N) {
|
|
265
|
+
inRangeIds.push(id);
|
|
266
|
+
} else {
|
|
267
|
+
droppedIds.push(id);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (droppedIds.length > 0) {
|
|
271
|
+
log.warn(
|
|
272
|
+
{ droppedIds, indexSize: N },
|
|
273
|
+
"Router returned page IDs outside the valid range; dropping",
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const truncated = inRangeIds.length > maxPageIds;
|
|
278
|
+
const finalIds = truncated ? inRangeIds.slice(0, maxPageIds) : inRangeIds;
|
|
279
|
+
if (truncated) {
|
|
280
|
+
log.warn(
|
|
281
|
+
{ returned: inRangeIds.length, max: maxPageIds },
|
|
282
|
+
"Router returned more page IDs than max_page_ids; truncating",
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// De-duplicate while preserving order — the index lookup alone wouldn't
|
|
287
|
+
// catch repeats from the model.
|
|
288
|
+
const seen = new Set<number>();
|
|
289
|
+
const selectedSlugs: string[] = [];
|
|
290
|
+
for (const id of finalIds) {
|
|
291
|
+
if (seen.has(id)) continue;
|
|
292
|
+
seen.add(id);
|
|
293
|
+
const entry = pageIndex.byId.get(id);
|
|
294
|
+
if (!entry) continue;
|
|
295
|
+
selectedSlugs.push(entry.slug);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return { selectedSlugs, failureReason: null };
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Build a text content block carrying an ephemeral `cache_control`
|
|
303
|
+
* breakpoint with a 1h TTL. The Anthropic SDK accepts the field as an extra
|
|
304
|
+
* property on text blocks, but our internal `TextContent` type intentionally
|
|
305
|
+
* omits it (only the Anthropic provider transforms it onto the wire), so we
|
|
306
|
+
* reach through a `Record` cast here for the same reason `client.ts` does —
|
|
307
|
+
* it keeps the core types provider-agnostic. The 1h TTL matches the
|
|
308
|
+
* provider's auto-applied breakpoints (see `cacheTtl` in
|
|
309
|
+
* `providers/anthropic/client.ts`); the `<now>` block is stable across most
|
|
310
|
+
* turns, so default 5m would force unnecessary re-creation. The
|
|
311
|
+
* `extended-cache-ttl-2025-04-11` beta header is added unconditionally for
|
|
312
|
+
* non-Haiku models in `client.ts`, so this works without any call-site
|
|
313
|
+
* config.
|
|
314
|
+
*/
|
|
315
|
+
function cachedTextBlock(text: string): ContentBlock {
|
|
316
|
+
const block: ContentBlock = { type: "text", text };
|
|
317
|
+
(block as unknown as Record<string, unknown>).cache_control = {
|
|
318
|
+
type: "ephemeral",
|
|
319
|
+
ttl: "1h",
|
|
320
|
+
};
|
|
321
|
+
return block;
|
|
322
|
+
}
|
package/src/memory/v2/sim.ts
CHANGED
|
@@ -17,13 +17,20 @@
|
|
|
17
17
|
// channel separately and fuses with the configured `dense_weight` /
|
|
18
18
|
// `sparse_weight` (which the schema validates sum to 1.0).
|
|
19
19
|
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
20
|
+
// Score normalization:
|
|
21
|
+
// Qdrant returns cosine similarity in [-1, 1]. We clamp negative cosines
|
|
22
|
+
// to 0 before fusion so anti-correlated documents contribute zero, rather
|
|
23
|
+
// than a negative term that subtracts from the sparse channel and can
|
|
24
|
+
// depress the fused score below the sparse-only floor. Positive cosines
|
|
25
|
+
// pass through unchanged — affine-rescaling them into [0, 1] via
|
|
26
|
+
// `(cos + 1) / 2` would halve every pairwise dense difference and shift
|
|
27
|
+
// ranking toward the sparse channel, the opposite of intent. Qdrant's
|
|
28
|
+
// sparse score is on a different, unbounded scale (it depends on query
|
|
29
|
+
// and document term weights), so we divide by the per-batch maximum
|
|
30
|
+
// sparse score to bring it into [0, 1] before fusing. This is the design
|
|
31
|
+
// doc's choice (§4) — batch-relative normalization is sufficient because
|
|
32
|
+
// the score is consumed only as a per-turn ordering signal, not compared
|
|
33
|
+
// across turns.
|
|
27
34
|
|
|
28
35
|
import type { AssistantConfig } from "../../config/types.js";
|
|
29
36
|
import { applyCorrectionIfCalibrated } from "../anisotropy.js";
|
|
@@ -120,14 +127,18 @@ export function effectiveWeights(
|
|
|
120
127
|
* sparse via the in-process TF-IDF encoder).
|
|
121
128
|
* 2. Run server-side dense + sparse queries against the v2 concept-page
|
|
122
129
|
* Qdrant collection, restricted to `candidateSlugs` so we don't waste
|
|
123
|
-
* query bandwidth on unrelated pages.
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
130
|
+
* query bandwidth on unrelated pages. The query hits four channels per
|
|
131
|
+
* page: body dense + body sparse, and (for pages that have a summary
|
|
132
|
+
* embedded) summary dense + summary sparse.
|
|
133
|
+
* 3. Fuse: per slug, score = `max(fused(body), fused(summary))`. Each
|
|
134
|
+
* half is `clamp01(dense_weight · denseCosine + sparse_weight ·
|
|
135
|
+
* normalizedSparse)` with sparse normalized by the per-batch maximum.
|
|
136
|
+
* Pages without a summary embedding fall back to body-only fusion —
|
|
137
|
+
* the summary half is undefined and the max collapses to the body
|
|
138
|
+
* score.
|
|
128
139
|
*
|
|
129
140
|
* Returns a `Map<slug, score>` containing only the candidate slugs that hit
|
|
130
|
-
* in at least one channel. Slugs in `candidateSlugs` that miss
|
|
141
|
+
* in at least one channel. Slugs in `candidateSlugs` that miss every channel
|
|
131
142
|
* are absent from the map; callers should treat absence as score = 0 (the
|
|
132
143
|
* activation pipeline does this implicitly when reading back A_o).
|
|
133
144
|
*
|
|
@@ -181,20 +192,52 @@ export async function simBatch(
|
|
|
181
192
|
return new Map();
|
|
182
193
|
}
|
|
183
194
|
|
|
184
|
-
|
|
195
|
+
// Compute per-batch sparse maxima independently for the body and summary
|
|
196
|
+
// channels so each side normalizes against its own scale. Mixing the two
|
|
197
|
+
// — e.g. dividing every sparse score by the larger of the two maxima —
|
|
198
|
+
// would punish whichever channel happened to have lower-magnitude scores
|
|
199
|
+
// even when its hits were the best matches available.
|
|
200
|
+
const maxBodySparse = computeMaxSparse(hits, (h) => h.sparseScore);
|
|
201
|
+
const maxSummarySparse = computeMaxSparse(hits, (h) => h.summarySparseScore);
|
|
185
202
|
const { dense_weight: baseDense, sparse_weight: baseSparse } =
|
|
186
203
|
config.memory.v2;
|
|
187
|
-
const { dense:
|
|
188
|
-
hits,
|
|
189
|
-
|
|
204
|
+
const { dense: bodyDenseWeight, sparse: bodySparseWeight } = effectiveWeights(
|
|
205
|
+
hits.map((h) => ({ sparseScore: h.sparseScore })),
|
|
206
|
+
maxBodySparse,
|
|
190
207
|
baseDense,
|
|
191
208
|
baseSparse,
|
|
192
209
|
config,
|
|
193
210
|
);
|
|
211
|
+
const { dense: summaryDenseWeight, sparse: summarySparseWeight } =
|
|
212
|
+
effectiveWeights(
|
|
213
|
+
hits.map((h) => ({ sparseScore: h.summarySparseScore })),
|
|
214
|
+
maxSummarySparse,
|
|
215
|
+
baseDense,
|
|
216
|
+
baseSparse,
|
|
217
|
+
config,
|
|
218
|
+
);
|
|
194
219
|
|
|
195
220
|
const scores = new Map<string, number>();
|
|
196
221
|
for (const hit of hits) {
|
|
197
|
-
|
|
222
|
+
const bodyScore = fuseHalf(
|
|
223
|
+
hit.denseScore,
|
|
224
|
+
hit.sparseScore,
|
|
225
|
+
maxBodySparse,
|
|
226
|
+
bodyDenseWeight,
|
|
227
|
+
bodySparseWeight,
|
|
228
|
+
);
|
|
229
|
+
const summaryScore = fuseHalf(
|
|
230
|
+
hit.summaryDenseScore,
|
|
231
|
+
hit.summarySparseScore,
|
|
232
|
+
maxSummarySparse,
|
|
233
|
+
summaryDenseWeight,
|
|
234
|
+
summarySparseWeight,
|
|
235
|
+
);
|
|
236
|
+
// Pages without a summary embedding return undefined for both summary
|
|
237
|
+
// channels; their `summaryScore` falls back to the body score so the
|
|
238
|
+
// max collapses cleanly to body-only behavior.
|
|
239
|
+
const score = Math.max(bodyScore ?? 0, summaryScore ?? bodyScore ?? 0);
|
|
240
|
+
scores.set(hit.slug, score);
|
|
198
241
|
}
|
|
199
242
|
|
|
200
243
|
return scores;
|
|
@@ -207,36 +250,47 @@ function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
|
207
250
|
}
|
|
208
251
|
|
|
209
252
|
/**
|
|
210
|
-
* Per-batch sparse-score maximum used for normalization.
|
|
211
|
-
*
|
|
253
|
+
* Per-batch sparse-score maximum used for normalization. The accessor picks
|
|
254
|
+
* which sparse channel to scan — `sparseScore` for the body channel,
|
|
255
|
+
* `summarySparseScore` for the summary channel. Hits missing from the
|
|
256
|
+
* channel contribute 0 (handled by the `undefined` guard).
|
|
212
257
|
*/
|
|
213
|
-
function computeMaxSparse(
|
|
214
|
-
hits: ReadonlyArray<
|
|
258
|
+
function computeMaxSparse<T>(
|
|
259
|
+
hits: ReadonlyArray<T>,
|
|
260
|
+
accessor: (hit: T) => number | undefined,
|
|
215
261
|
): number {
|
|
216
262
|
let max = 0;
|
|
217
263
|
for (const hit of hits) {
|
|
218
|
-
|
|
219
|
-
|
|
264
|
+
const value = accessor(hit);
|
|
265
|
+
if (value !== undefined && value > max) {
|
|
266
|
+
max = value;
|
|
220
267
|
}
|
|
221
268
|
}
|
|
222
269
|
return max;
|
|
223
270
|
}
|
|
224
271
|
|
|
225
272
|
/**
|
|
226
|
-
* Fuse a
|
|
227
|
-
* via `clamp01(dense_weight ·
|
|
228
|
-
*
|
|
273
|
+
* Fuse one half of a hit (body or summary) into a normalized [0, 1] score
|
|
274
|
+
* via `clamp01(dense_weight · max(0, cosine) + sparse_weight ·
|
|
275
|
+
* sparse/maxSparse)`. Negative cosines clamp to 0 so they don't subtract
|
|
276
|
+
* from sparse; positive cosines pass through unchanged so the
|
|
277
|
+
* operator-configured dense/sparse balance is preserved. Returns
|
|
278
|
+
* `undefined` when neither channel hit — a signal the half had no match
|
|
279
|
+
* at all, so the caller can fall back to the other half cleanly.
|
|
280
|
+
*
|
|
281
|
+
* Exported so the context-search adapter can reuse the same fusion math
|
|
282
|
+
* for its own activation pipeline.
|
|
229
283
|
*/
|
|
230
|
-
function
|
|
231
|
-
|
|
284
|
+
export function fuseHalf(
|
|
285
|
+
denseScore: number | undefined,
|
|
286
|
+
sparseScore: number | undefined,
|
|
232
287
|
maxSparse: number,
|
|
233
288
|
denseWeight: number,
|
|
234
289
|
sparseWeight: number,
|
|
235
|
-
): number {
|
|
236
|
-
|
|
290
|
+
): number | undefined {
|
|
291
|
+
if (denseScore === undefined && sparseScore === undefined) return undefined;
|
|
292
|
+
const dense = denseScore !== undefined ? Math.max(0, denseScore) : 0;
|
|
237
293
|
const sparseNormalized =
|
|
238
|
-
|
|
239
|
-
? hit.sparseScore / maxSparse
|
|
240
|
-
: 0;
|
|
294
|
+
sparseScore !== undefined && maxSparse > 0 ? sparseScore / maxSparse : 0;
|
|
241
295
|
return clamp01(denseWeight * dense + sparseWeight * sparseNormalized);
|
|
242
296
|
}
|