@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
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
import { hydrate, save } from "./activation-store.js";
|
|
41
41
|
import { getEdgeIndex } from "./edge-index.js";
|
|
42
42
|
import { readPage, renderPageContent } from "./page-store.js";
|
|
43
|
+
import { runRouter } from "./router.js";
|
|
43
44
|
import { getSkillCapability, isSkillSlug } from "./skill-store.js";
|
|
44
45
|
import type { ActivationState, EverInjectedEntry } from "./types.js";
|
|
45
46
|
|
|
@@ -58,6 +59,16 @@ const log = getLogger("memory-v2-injection");
|
|
|
58
59
|
*/
|
|
59
60
|
export type InjectMemoryV2Mode = "context-load" | "per-turn";
|
|
60
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Internal mode union for `finalizeInjection`. Extends the public
|
|
64
|
+
* `InjectMemoryV2Mode` with `"router"` (router-driven success path) and
|
|
65
|
+
* `"errored"` (caller-supplied failure path or the helper's own
|
|
66
|
+
* try/catch promotion). The public surface intentionally only carries
|
|
67
|
+
* the caller-facing modes — these two are persistence/telemetry concerns
|
|
68
|
+
* that don't belong on `InjectMemoryV2BlockParams`.
|
|
69
|
+
*/
|
|
70
|
+
type FinalizeInjectionMode = InjectMemoryV2Mode | "router" | "errored";
|
|
71
|
+
|
|
61
72
|
export interface InjectMemoryV2BlockParams {
|
|
62
73
|
/** SQLite database handle for activation_state hydrate/save. */
|
|
63
74
|
database: DrizzleDb;
|
|
@@ -94,8 +105,12 @@ export interface InjectMemoryV2BlockResult {
|
|
|
94
105
|
*/
|
|
95
106
|
block: string | null;
|
|
96
107
|
/**
|
|
97
|
-
* Slugs
|
|
98
|
-
*
|
|
108
|
+
* Slugs we attempted to attach this turn (top-K minus everInjected).
|
|
109
|
+
* Always populated even when `block` is `null` — phantom slugs whose
|
|
110
|
+
* backing page is missing on disk land here and are recorded in
|
|
111
|
+
* `everInjected` so we don't infinite-retry next turn. Callers using
|
|
112
|
+
* this for "we injected N slugs" telemetry should cross-reference
|
|
113
|
+
* `block !== null` (or the activation log's `page_missing` status).
|
|
99
114
|
*/
|
|
100
115
|
toInject: string[];
|
|
101
116
|
}
|
|
@@ -135,6 +150,27 @@ export async function injectMemoryV2Block(
|
|
|
135
150
|
throwIfAborted(signal);
|
|
136
151
|
const priorState = await hydrate(database, conversationId);
|
|
137
152
|
|
|
153
|
+
// Flag-gated router dispatch: when the LLM router is enabled, route the
|
|
154
|
+
// per-turn page selection through `runRouter` and reuse `finalizeInjection`
|
|
155
|
+
// for persistence, render, and telemetry. The activation pipeline below
|
|
156
|
+
// remains the default (flag-off) behavior — every code path past this
|
|
157
|
+
// branch only runs when the router is disabled.
|
|
158
|
+
if (config.memory.v2.router.enabled) {
|
|
159
|
+
return injectViaRouter({
|
|
160
|
+
workspaceDir,
|
|
161
|
+
database,
|
|
162
|
+
conversationId,
|
|
163
|
+
currentTurn,
|
|
164
|
+
userMessage,
|
|
165
|
+
assistantMessage,
|
|
166
|
+
nowText,
|
|
167
|
+
messageId,
|
|
168
|
+
config,
|
|
169
|
+
priorState,
|
|
170
|
+
signal,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
138
174
|
// (2) Topology. `getEdgeIndex` walks concept-page frontmatter and caches
|
|
139
175
|
// the result module-locally; an empty workspace yields an empty index.
|
|
140
176
|
throwIfAborted(signal);
|
|
@@ -178,7 +214,7 @@ export async function injectMemoryV2Block(
|
|
|
178
214
|
// prior cached attachments don't exist or have been thrown away. The user
|
|
179
215
|
// message gets a complete top-K dump alongside the static
|
|
180
216
|
// essentials/threads/recent block, then per-turn turns just add deltas.
|
|
181
|
-
const mode = params.mode ?? "per-turn";
|
|
217
|
+
const mode: InjectMemoryV2Mode = params.mode ?? "per-turn";
|
|
182
218
|
const priorEverInjected: readonly EverInjectedEntry[] =
|
|
183
219
|
priorState?.everInjected ?? [];
|
|
184
220
|
const { topNow, toInject } = selectInjections({
|
|
@@ -192,11 +228,108 @@ export async function injectMemoryV2Block(
|
|
|
192
228
|
// even on a "no new injection" turn, prior-state activations decay via the
|
|
193
229
|
// candidate-set carry-forward and need to be rewritten so `epsilon`-trimmed
|
|
194
230
|
// slugs drop out of consideration next turn.
|
|
195
|
-
const
|
|
231
|
+
const nextStateMap: Record<string, number> = {};
|
|
196
232
|
for (const [slug, value] of finalActivation) {
|
|
197
|
-
if (value > epsilon)
|
|
233
|
+
if (value > epsilon) nextStateMap[slug] = value;
|
|
198
234
|
}
|
|
199
235
|
|
|
236
|
+
// Build the rich per-candidate telemetry rows up front (status assigned
|
|
237
|
+
// later by `finalizeInjection` once we know what actually rendered).
|
|
238
|
+
const telemetryRows: MemoryV2ConceptRowRecord[] = [...candidates].map(
|
|
239
|
+
(slug) => {
|
|
240
|
+
const breakdown = ownBreakdown.get(slug);
|
|
241
|
+
const inPrior = fromPrior.has(slug);
|
|
242
|
+
const inAnn = fromAnn.has(slug);
|
|
243
|
+
return {
|
|
244
|
+
slug,
|
|
245
|
+
finalActivation: finalActivation.get(slug) ?? 0,
|
|
246
|
+
ownActivation: ownActivation.get(slug) ?? 0,
|
|
247
|
+
priorActivation: breakdown?.priorContribution ?? 0,
|
|
248
|
+
simUser: breakdown?.simUser ?? 0,
|
|
249
|
+
simAssistant: breakdown?.simAssistant ?? 0,
|
|
250
|
+
simNow: breakdown?.simNow ?? 0,
|
|
251
|
+
simUserRerankBoost: breakdown?.simUserRerankBoost ?? 0,
|
|
252
|
+
simAssistantRerankBoost: breakdown?.simAssistantRerankBoost ?? 0,
|
|
253
|
+
inRerankPool: breakdown?.inRerankPool ?? false,
|
|
254
|
+
spreadContribution: spreadContribution.get(slug) ?? 0,
|
|
255
|
+
source:
|
|
256
|
+
inPrior && inAnn ? "both" : inPrior ? "prior_state" : "ann_top50",
|
|
257
|
+
status: "not_injected",
|
|
258
|
+
};
|
|
259
|
+
},
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
return finalizeInjection({
|
|
263
|
+
workspaceDir,
|
|
264
|
+
database,
|
|
265
|
+
conversationId,
|
|
266
|
+
mode,
|
|
267
|
+
currentTurn,
|
|
268
|
+
messageId,
|
|
269
|
+
priorEverInjected,
|
|
270
|
+
slugsToRender,
|
|
271
|
+
telemetryRows,
|
|
272
|
+
config,
|
|
273
|
+
nextStateMap,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Tail of `injectMemoryV2Block` extracted as a private helper so the
|
|
279
|
+
* router branch (PR 10) can reuse the same persistence + render +
|
|
280
|
+
* telemetry-finalization pipeline. Performs:
|
|
281
|
+
*
|
|
282
|
+
* 1. Build `nextEverInjected` from `slugsToRender`, filtering out skill
|
|
283
|
+
* slugs whose capability cache entry is missing so future turns
|
|
284
|
+
* re-attempt attachment once the cache is populated.
|
|
285
|
+
* 2. Persist the next activation_state row.
|
|
286
|
+
* 3. Render the injection block.
|
|
287
|
+
* 4. Finalize per-row `status` (`injected | in_context | not_injected |
|
|
288
|
+
* page_missing | corrupt`) on the caller-provided telemetry rows
|
|
289
|
+
* using the render result.
|
|
290
|
+
* 5. Sort rows by `finalActivation` descending and flush the activation
|
|
291
|
+
* log — even when an error is thrown partway through, so silent
|
|
292
|
+
* failures remain observable.
|
|
293
|
+
* 6. Return the rendered block plus `toInject = newlyInjected`.
|
|
294
|
+
*
|
|
295
|
+
* The caller pre-builds `telemetryRows` with all per-candidate breakdown
|
|
296
|
+
* fields filled in (router-mode callers can pass zeros where the
|
|
297
|
+
* breakdown doesn't apply) and a placeholder `status: "not_injected"`
|
|
298
|
+
* which this helper overwrites. `nextStateMap` is the activation
|
|
299
|
+
* pipeline's sparse next-state; router-mode callers pass an empty map.
|
|
300
|
+
*/
|
|
301
|
+
async function finalizeInjection(args: {
|
|
302
|
+
workspaceDir: string;
|
|
303
|
+
database: DrizzleDb;
|
|
304
|
+
conversationId: string;
|
|
305
|
+
mode: FinalizeInjectionMode;
|
|
306
|
+
currentTurn: number;
|
|
307
|
+
messageId: string;
|
|
308
|
+
priorEverInjected: readonly EverInjectedEntry[];
|
|
309
|
+
slugsToRender: string[];
|
|
310
|
+
telemetryRows: MemoryV2ConceptRowRecord[];
|
|
311
|
+
config: AssistantConfig;
|
|
312
|
+
nextStateMap: Record<string, number>;
|
|
313
|
+
}): Promise<InjectMemoryV2BlockResult> {
|
|
314
|
+
const {
|
|
315
|
+
workspaceDir,
|
|
316
|
+
database,
|
|
317
|
+
conversationId,
|
|
318
|
+
currentTurn,
|
|
319
|
+
messageId,
|
|
320
|
+
priorEverInjected,
|
|
321
|
+
slugsToRender,
|
|
322
|
+
telemetryRows,
|
|
323
|
+
config,
|
|
324
|
+
nextStateMap,
|
|
325
|
+
} = args;
|
|
326
|
+
|
|
327
|
+
// `mode` is `let` because the trailing try/finally promotes it to "errored"
|
|
328
|
+
// when the render/telemetry path throws — we still want a log row written
|
|
329
|
+
// (with whatever rows we managed to build) so silent failures are
|
|
330
|
+
// observable in the database.
|
|
331
|
+
let mode: FinalizeInjectionMode = args.mode;
|
|
332
|
+
|
|
200
333
|
// Mark every rendered slug as ever-injected so future per-turn deltas don't
|
|
201
334
|
// re-attach the same content. On context-load this is the full top-K (we
|
|
202
335
|
// just rendered all of them); on per-turn it's just the newly added slugs.
|
|
@@ -206,9 +339,21 @@ export async function injectMemoryV2Block(
|
|
|
206
339
|
// like concept slugs — once attached on a turn, the cached attachment lives
|
|
207
340
|
// on that user message and the agent keeps seeing it across subsequent turns
|
|
208
341
|
// until compaction evicts the turn.
|
|
342
|
+
//
|
|
343
|
+
// Skill slugs whose in-process cache entry is missing (e.g. startup race
|
|
344
|
+
// between the skill seed and the first turn, or stale Qdrant index pointing
|
|
345
|
+
// at an uninstalled skill) are excluded from `everInjected` so future
|
|
346
|
+
// per-turn runs re-attempt attachment once the cache is populated. Without
|
|
347
|
+
// this, the slug would be marked injected even though `renderInjectionBlock`
|
|
348
|
+
// silently dropped it.
|
|
349
|
+
const missingSkillSlugs = new Set(
|
|
350
|
+
slugsToRender.filter(
|
|
351
|
+
(slug) => isSkillSlug(slug) && !getSkillCapability(slug),
|
|
352
|
+
),
|
|
353
|
+
);
|
|
209
354
|
const everInjectedSet = new Set(priorEverInjected.map((entry) => entry.slug));
|
|
210
355
|
const newlyInjected = slugsToRender.filter(
|
|
211
|
-
(slug) => !everInjectedSet.has(slug),
|
|
356
|
+
(slug) => !everInjectedSet.has(slug) && !missingSkillSlugs.has(slug),
|
|
212
357
|
);
|
|
213
358
|
const nextEverInjected: EverInjectedEntry[] = [
|
|
214
359
|
...priorEverInjected,
|
|
@@ -217,62 +362,76 @@ export async function injectMemoryV2Block(
|
|
|
217
362
|
|
|
218
363
|
const nextActivationState: ActivationState = {
|
|
219
364
|
messageId,
|
|
220
|
-
state:
|
|
365
|
+
state: nextStateMap,
|
|
221
366
|
everInjected: nextEverInjected,
|
|
222
367
|
currentTurn,
|
|
223
368
|
updatedAt: Date.now(),
|
|
224
369
|
};
|
|
225
370
|
|
|
226
|
-
|
|
371
|
+
// `block` and `conceptRowsForLog` are declared outside the try so the
|
|
372
|
+
// finally block can flush activation telemetry even if rendering, status
|
|
373
|
+
// finalization, or the activation-state save throws partway through.
|
|
374
|
+
// Without this, a Zod failure on a single concept page (e.g. unrecognized
|
|
375
|
+
// frontmatter key) silently dropped the entire turn's activation log row,
|
|
376
|
+
// masking the underlying data-corruption bug.
|
|
377
|
+
//
|
|
378
|
+
// `conceptRowsForLog` only receives the caller-provided `telemetryRows`
|
|
379
|
+
// *after* status finalization succeeds — matching the prior behavior where
|
|
380
|
+
// an early `save()` / `renderInjectionBlock()` throw produced an empty
|
|
381
|
+
// `concepts` array on the log row.
|
|
382
|
+
let block: string | null = null;
|
|
383
|
+
let conceptRowsForLog: MemoryV2ConceptRowRecord[] = [];
|
|
384
|
+
let caughtErr: unknown = undefined;
|
|
227
385
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
386
|
+
try {
|
|
387
|
+
await save(database, conversationId, nextActivationState);
|
|
388
|
+
|
|
389
|
+
// Render before recording telemetry so the activation log can mark slugs
|
|
390
|
+
// whose backing file is gone or failed to load — those are no-op renders
|
|
391
|
+
// that would otherwise be indistinguishable from successful "injected"
|
|
392
|
+
// rows in the log. `renderInjectionBlock` itself short-circuits on empty
|
|
393
|
+
// inputs and emits per-slug `log.warn` for each corrupt page.
|
|
394
|
+
const rendered = await renderInjectionBlock(workspaceDir, slugsToRender);
|
|
395
|
+
block = rendered.block;
|
|
396
|
+
const { missingSlugs, corruptSlugs } = rendered;
|
|
397
|
+
const missingSlugSet = new Set(missingSlugs);
|
|
398
|
+
const corruptSlugSet = new Set(corruptSlugs);
|
|
399
|
+
if (missingSlugs.length > 0) {
|
|
400
|
+
log.warn(
|
|
401
|
+
{
|
|
402
|
+
conversationId,
|
|
403
|
+
turn: currentTurn,
|
|
404
|
+
missingSlugs,
|
|
405
|
+
renderedCount:
|
|
406
|
+
slugsToRender.length - missingSlugs.length - corruptSlugs.length,
|
|
407
|
+
},
|
|
408
|
+
"Memory v2 injection skipped slugs whose page was missing on disk — Qdrant index may be stale; consider reembed",
|
|
409
|
+
);
|
|
410
|
+
}
|
|
248
411
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
// `page_missing` overrides any "would-have-been-injected" status when
|
|
267
|
-
// `readPage` returned null for the slug — telemetry surfaces stale
|
|
268
|
-
// ANN/edge entries instead of silently masquerading as a successful
|
|
269
|
-
// injection.
|
|
412
|
+
// Finalize per-row status onto the caller-provided telemetry rows.
|
|
413
|
+
// - context-load: cache was wiped (turn 1 / post-compaction), so
|
|
414
|
+
// `slugsToRender = topNow` and every rendered slug is freshly
|
|
415
|
+
// injected on this turn. `in_context` is unreachable because there
|
|
416
|
+
// is no prior cached attachment for the inspector to point at.
|
|
417
|
+
// - per-turn: cached attachments from prior turns are still on the
|
|
418
|
+
// user message, so prior-everInjected slugs are `in_context` and
|
|
419
|
+
// the delta (`slugsToRender`, which equals `toInject` in this mode)
|
|
420
|
+
// is `injected`.
|
|
421
|
+
// `page_missing` and `corrupt` override any "would-have-been-injected"
|
|
422
|
+
// status when `readPage` returned null or threw — telemetry surfaces
|
|
423
|
+
// stale ANN/edge entries and malformed pages instead of silently
|
|
424
|
+
// masquerading as successful injections. `corrupt` takes priority over
|
|
425
|
+
// `page_missing` since they're mutually exclusive per slug.
|
|
426
|
+
const renderedSet = new Set(slugsToRender);
|
|
427
|
+
for (const row of telemetryRows) {
|
|
428
|
+
const slug = row.slug;
|
|
270
429
|
let status: MemoryV2ConceptRowRecord["status"];
|
|
271
430
|
if (mode === "context-load") {
|
|
272
431
|
status = renderedSet.has(slug) ? "injected" : "not_injected";
|
|
273
432
|
} else if (everInjectedSet.has(slug)) {
|
|
274
433
|
status = "in_context";
|
|
275
|
-
} else if (
|
|
434
|
+
} else if (renderedSet.has(slug)) {
|
|
276
435
|
status = "injected";
|
|
277
436
|
} else {
|
|
278
437
|
status = "not_injected";
|
|
@@ -280,52 +439,195 @@ export async function injectMemoryV2Block(
|
|
|
280
439
|
if (status === "injected" && missingSlugSet.has(slug)) {
|
|
281
440
|
status = "page_missing";
|
|
282
441
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
simNow: breakdown?.simNow ?? 0,
|
|
291
|
-
simUserRerankBoost: breakdown?.simUserRerankBoost ?? 0,
|
|
292
|
-
simAssistantRerankBoost: breakdown?.simAssistantRerankBoost ?? 0,
|
|
293
|
-
inRerankPool: breakdown?.inRerankPool ?? false,
|
|
294
|
-
spreadContribution: spreadContribution.get(slug) ?? 0,
|
|
295
|
-
source:
|
|
296
|
-
inPrior && inAnn ? "both" : inPrior ? "prior_state" : "ann_top50",
|
|
297
|
-
status,
|
|
298
|
-
};
|
|
299
|
-
},
|
|
300
|
-
);
|
|
301
|
-
conceptRows.sort((a, b) => b.finalActivation - a.finalActivation);
|
|
302
|
-
|
|
303
|
-
const v2Cfg = config.memory.v2;
|
|
304
|
-
try {
|
|
305
|
-
recordMemoryV2ActivationLog({
|
|
306
|
-
conversationId,
|
|
307
|
-
turn: currentTurn,
|
|
308
|
-
mode,
|
|
309
|
-
concepts: conceptRows,
|
|
310
|
-
config: {
|
|
311
|
-
d: v2Cfg.d,
|
|
312
|
-
c_user: v2Cfg.c_user,
|
|
313
|
-
c_assistant: v2Cfg.c_assistant,
|
|
314
|
-
c_now: v2Cfg.c_now,
|
|
315
|
-
k: v2Cfg.k,
|
|
316
|
-
hops: v2Cfg.hops,
|
|
317
|
-
top_k: v2Cfg.top_k,
|
|
318
|
-
epsilon: v2Cfg.epsilon,
|
|
319
|
-
},
|
|
320
|
-
});
|
|
442
|
+
if (corruptSlugSet.has(slug)) {
|
|
443
|
+
status = "corrupt";
|
|
444
|
+
}
|
|
445
|
+
row.status = status;
|
|
446
|
+
}
|
|
447
|
+
telemetryRows.sort((a, b) => b.finalActivation - a.finalActivation);
|
|
448
|
+
conceptRowsForLog = telemetryRows;
|
|
321
449
|
} catch (err) {
|
|
450
|
+
// Stash the error and let `finally` flush a best-effort telemetry row
|
|
451
|
+
// before we re-throw to the caller. `mode = "errored"` flags the row
|
|
452
|
+
// for observability dashboards / inspector queries.
|
|
453
|
+
caughtErr = err;
|
|
454
|
+
mode = "errored";
|
|
455
|
+
} finally {
|
|
456
|
+
try {
|
|
457
|
+
recordMemoryV2ActivationLog({
|
|
458
|
+
conversationId,
|
|
459
|
+
turn: currentTurn,
|
|
460
|
+
mode,
|
|
461
|
+
concepts: conceptRowsForLog,
|
|
462
|
+
config: configSnapshot(config),
|
|
463
|
+
});
|
|
464
|
+
} catch (telemetryErr) {
|
|
465
|
+
log.warn(
|
|
466
|
+
{ err: telemetryErr, conversationId, turn: currentTurn },
|
|
467
|
+
"Failed to record memory v2 activation telemetry — continuing",
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (caughtErr !== undefined) throw caughtErr;
|
|
473
|
+
return { block, toInject: newlyInjected };
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Router-mode dispatch path. Replaces the spreading-activation pipeline with
|
|
478
|
+
* a single LLM call that picks the per-turn concept-page set. On success we
|
|
479
|
+
* reuse `finalizeInjection` so the persistence/render/telemetry contract
|
|
480
|
+
* stays identical to the activation path; on `runRouter` failure we still
|
|
481
|
+
* advance `activation_state` (so `currentTurn` and `messageId` move forward)
|
|
482
|
+
* and emit a `mode: "errored"` telemetry row so the failure is observable.
|
|
483
|
+
*
|
|
484
|
+
* Failure rows are tagged `errored`, not `router`, because router-mode rows
|
|
485
|
+
* are reserved for successful selections — keeping the two visually distinct
|
|
486
|
+
* in inspector queries. `nextStateMap` is always empty in router mode: the
|
|
487
|
+
* router does not compute spreading-activation scores, so there is no sparse
|
|
488
|
+
* activation map to persist.
|
|
489
|
+
*/
|
|
490
|
+
async function injectViaRouter(args: {
|
|
491
|
+
workspaceDir: string;
|
|
492
|
+
database: DrizzleDb;
|
|
493
|
+
conversationId: string;
|
|
494
|
+
currentTurn: number;
|
|
495
|
+
userMessage: string;
|
|
496
|
+
assistantMessage: string;
|
|
497
|
+
nowText: string;
|
|
498
|
+
messageId: string;
|
|
499
|
+
config: AssistantConfig;
|
|
500
|
+
priorState: ActivationState | null;
|
|
501
|
+
signal?: AbortSignal;
|
|
502
|
+
}): Promise<InjectMemoryV2BlockResult> {
|
|
503
|
+
const {
|
|
504
|
+
workspaceDir,
|
|
505
|
+
database,
|
|
506
|
+
conversationId,
|
|
507
|
+
currentTurn,
|
|
508
|
+
userMessage,
|
|
509
|
+
assistantMessage,
|
|
510
|
+
nowText,
|
|
511
|
+
messageId,
|
|
512
|
+
config,
|
|
513
|
+
priorState,
|
|
514
|
+
signal,
|
|
515
|
+
} = args;
|
|
516
|
+
|
|
517
|
+
const priorEverInjected: readonly EverInjectedEntry[] =
|
|
518
|
+
priorState?.everInjected ?? [];
|
|
519
|
+
|
|
520
|
+
const routerResult = await runRouter({
|
|
521
|
+
workspaceDir,
|
|
522
|
+
userMessage,
|
|
523
|
+
assistantMessage,
|
|
524
|
+
nowText,
|
|
525
|
+
priorEverInjected,
|
|
526
|
+
config,
|
|
527
|
+
...(signal ? { signal } : {}),
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
if (routerResult.failureReason !== null) {
|
|
322
531
|
log.warn(
|
|
323
|
-
{
|
|
324
|
-
"
|
|
532
|
+
{ failureReason: routerResult.failureReason },
|
|
533
|
+
"memory v2 router failure; skipping injection",
|
|
325
534
|
);
|
|
535
|
+
// Delegate the failure path to `finalizeInjection` with empty inputs
|
|
536
|
+
// and `mode: "errored"`. The helper persists a stub activation_state
|
|
537
|
+
// (preserving `priorEverInjected` so future turns still subtract
|
|
538
|
+
// previously-attached slugs) and writes the telemetry row through the
|
|
539
|
+
// same code path as the success branch — no inline duplication of
|
|
540
|
+
// `save` + `recordMemoryV2ActivationLog`.
|
|
541
|
+
return finalizeInjection({
|
|
542
|
+
workspaceDir,
|
|
543
|
+
database,
|
|
544
|
+
conversationId,
|
|
545
|
+
mode: "errored",
|
|
546
|
+
currentTurn,
|
|
547
|
+
messageId,
|
|
548
|
+
priorEverInjected,
|
|
549
|
+
slugsToRender: [],
|
|
550
|
+
telemetryRows: [],
|
|
551
|
+
config,
|
|
552
|
+
nextStateMap: {},
|
|
553
|
+
});
|
|
326
554
|
}
|
|
327
555
|
|
|
328
|
-
|
|
556
|
+
// Dedupe router-picked slugs against `priorEverInjected` BEFORE rendering.
|
|
557
|
+
// The router prompt explicitly invites the model to re-pick already-injected
|
|
558
|
+
// pages "to re-anchor"; if we passed those through, `renderInjectionBlock`
|
|
559
|
+
// would re-emit the slug into a fresh `<memory>` block while the prior
|
|
560
|
+
// turn's cached attachment is still on the prior user message — duplicate
|
|
561
|
+
// content. Activation per-turn mode does not have this issue because
|
|
562
|
+
// `selectInjections()` returns `toInject = topNow - everInjected`.
|
|
563
|
+
//
|
|
564
|
+
// Telemetry rows for prior-everInjected slugs are still emitted below,
|
|
565
|
+
// but tagged `source: "carry_over"` (not `"router"`) so inspector queries
|
|
566
|
+
// can attribute selections correctly.
|
|
567
|
+
const everInjectedSet = new Set(priorEverInjected.map((e) => e.slug));
|
|
568
|
+
const slugsToRender = routerResult.selectedSlugs.filter(
|
|
569
|
+
(s) => !everInjectedSet.has(s),
|
|
570
|
+
);
|
|
571
|
+
|
|
572
|
+
// Build minimal telemetry rows for the union of router-selected slugs and
|
|
573
|
+
// prior `everInjected` slugs. Router-mode rows zero out every activation
|
|
574
|
+
// value (no spreading activation runs). Slugs the router picked this turn
|
|
575
|
+
// get `source: "router"`; prior-everInjected slugs the router did NOT
|
|
576
|
+
// re-pick get `source: "carry_over"`. The `status` placeholder is
|
|
577
|
+
// overwritten by `finalizeInjection`.
|
|
578
|
+
const routerPicked = new Set(routerResult.selectedSlugs);
|
|
579
|
+
const telemetrySlugs = new Set<string>(routerPicked);
|
|
580
|
+
for (const entry of priorEverInjected) telemetrySlugs.add(entry.slug);
|
|
581
|
+
const telemetryRows: MemoryV2ConceptRowRecord[] = [...telemetrySlugs].map(
|
|
582
|
+
(slug) => ({
|
|
583
|
+
slug,
|
|
584
|
+
finalActivation: 0,
|
|
585
|
+
ownActivation: 0,
|
|
586
|
+
priorActivation: 0,
|
|
587
|
+
simUser: 0,
|
|
588
|
+
simAssistant: 0,
|
|
589
|
+
simNow: 0,
|
|
590
|
+
simUserRerankBoost: 0,
|
|
591
|
+
simAssistantRerankBoost: 0,
|
|
592
|
+
inRerankPool: false,
|
|
593
|
+
spreadContribution: 0,
|
|
594
|
+
source: routerPicked.has(slug) ? "router" : "carry_over",
|
|
595
|
+
status: "not_injected",
|
|
596
|
+
}),
|
|
597
|
+
);
|
|
598
|
+
|
|
599
|
+
return finalizeInjection({
|
|
600
|
+
workspaceDir,
|
|
601
|
+
database,
|
|
602
|
+
conversationId,
|
|
603
|
+
mode: "router",
|
|
604
|
+
currentTurn,
|
|
605
|
+
messageId,
|
|
606
|
+
priorEverInjected,
|
|
607
|
+
slugsToRender,
|
|
608
|
+
telemetryRows,
|
|
609
|
+
config,
|
|
610
|
+
nextStateMap: {},
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Snapshot the v2 config tunables in the shape `recordMemoryV2ActivationLog`
|
|
616
|
+
* persists. Pulled out so the router-failure path does not duplicate the
|
|
617
|
+
* field list inline.
|
|
618
|
+
*/
|
|
619
|
+
function configSnapshot(config: AssistantConfig) {
|
|
620
|
+
const v2Cfg = config.memory.v2;
|
|
621
|
+
return {
|
|
622
|
+
d: v2Cfg.d,
|
|
623
|
+
c_user: v2Cfg.c_user,
|
|
624
|
+
c_assistant: v2Cfg.c_assistant,
|
|
625
|
+
c_now: v2Cfg.c_now,
|
|
626
|
+
k: v2Cfg.k,
|
|
627
|
+
hops: v2Cfg.hops,
|
|
628
|
+
top_k: v2Cfg.top_k,
|
|
629
|
+
epsilon: v2Cfg.epsilon,
|
|
630
|
+
};
|
|
329
631
|
}
|
|
330
632
|
|
|
331
633
|
function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
@@ -358,8 +660,28 @@ interface RenderInjectionBlockResult {
|
|
|
358
660
|
* edge-index entries that pointed at pages no longer on disk.
|
|
359
661
|
*/
|
|
360
662
|
missingSlugs: string[];
|
|
663
|
+
/**
|
|
664
|
+
* Slugs whose `readPage` call threw (e.g. invalid frontmatter that fails
|
|
665
|
+
* Zod validation, unreadable file). These are reported separately from
|
|
666
|
+
* `missingSlugs` because they're a different failure mode — the file
|
|
667
|
+
* exists but is malformed, not absent — and surfaced so the caller can
|
|
668
|
+
* mark them in the activation log (`status: "corrupt"`). Per-page errors
|
|
669
|
+
* are isolated: one bad page no longer rejects the whole batch.
|
|
670
|
+
*/
|
|
671
|
+
corruptSlugs: string[];
|
|
361
672
|
}
|
|
362
673
|
|
|
674
|
+
/**
|
|
675
|
+
* Leading instruction line emitted at the top of an injection block when at
|
|
676
|
+
* least one section was rendered from a page's `summary` field. Tells the
|
|
677
|
+
* agent the truncated entries are summaries and to read the underlying file
|
|
678
|
+
* if relevant. Suppressed when every section is a full-page fallback —
|
|
679
|
+
* claiming "these are summaries" over already-complete content would mislead
|
|
680
|
+
* the agent into wasted reads.
|
|
681
|
+
*/
|
|
682
|
+
const INJECTION_HEADER =
|
|
683
|
+
"**CRITICAL:** These are page summaries. Read the page file if it looks relevant.";
|
|
684
|
+
|
|
363
685
|
/**
|
|
364
686
|
* Render the inner content of the `<memory>` block for a list of slugs.
|
|
365
687
|
* The caller wraps the result in `<memory>...</memory>` exactly once at
|
|
@@ -370,11 +692,15 @@ interface RenderInjectionBlockResult {
|
|
|
370
692
|
* trailing `### Skills You Can Use` subsection; everything else is read
|
|
371
693
|
* from disk via `readPage` and rendered as a concept-page section.
|
|
372
694
|
*
|
|
373
|
-
* Concept pages are read in parallel via `
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
695
|
+
* Concept pages are read in parallel via `Promise.allSettled`. Per-page
|
|
696
|
+
* errors are isolated: a `readPage` rejection (e.g. invalid frontmatter
|
|
697
|
+
* failing Zod validation) collects the slug into `corruptSlugs` and the
|
|
698
|
+
* remaining pages still render normally. Pages whose file has gone missing
|
|
699
|
+
* between selection and render (e.g. consolidation deleted them, folder
|
|
700
|
+
* reorg renamed the slug) are dropped from the rendered block but reported
|
|
701
|
+
* back via `missingSlugs`. The two buckets are kept separate so callers can
|
|
702
|
+
* distinguish "file vanished" (stale index) from "file is malformed"
|
|
703
|
+
* (data-corruption / programmer error).
|
|
378
704
|
*
|
|
379
705
|
* Skill slugs whose entry the cache no longer knows (e.g. uninstalled
|
|
380
706
|
* mid-run) are silently dropped, mirroring the missing-pages behavior but
|
|
@@ -383,23 +709,24 @@ interface RenderInjectionBlockResult {
|
|
|
383
709
|
* skill is an expected catalog-level outcome rather than a stale-index
|
|
384
710
|
* bug.
|
|
385
711
|
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
712
|
+
* Each concept-page section is rendered as a path header followed by either
|
|
713
|
+
* the page's `summary` (when present in frontmatter) or the full page (the
|
|
714
|
+
* fallback for pages predating the summary field). Skills sit at the end
|
|
715
|
+
* under `### Skills You Can Use`, unchanged. The leading `**CRITICAL:**`
|
|
716
|
+
* line tells the agent how to read the block.
|
|
388
717
|
*
|
|
389
|
-
*
|
|
718
|
+
* **CRITICAL:** These are page summaries. Read the page file if it looks relevant.
|
|
719
|
+
*
|
|
720
|
+
* # memory/concepts/<concept-slug-1>.md
|
|
721
|
+
* <summary-1>
|
|
722
|
+
*
|
|
723
|
+
* # memory/concepts/<concept-slug-2>.md
|
|
390
724
|
* ---
|
|
391
725
|
* edges:
|
|
392
726
|
* - <neighbor-slug>
|
|
393
727
|
* ref_files:
|
|
394
728
|
* - <path/to/asset>
|
|
395
729
|
* ---
|
|
396
|
-
* <body-1>
|
|
397
|
-
*
|
|
398
|
-
* ### <concept-slug-2>
|
|
399
|
-
* ---
|
|
400
|
-
* edges: []
|
|
401
|
-
* ref_files: []
|
|
402
|
-
* ---
|
|
403
730
|
* <body-2>
|
|
404
731
|
*
|
|
405
732
|
* ### Skills You Can Use
|
|
@@ -413,23 +740,43 @@ async function renderInjectionBlock(
|
|
|
413
740
|
const conceptSlugs = slugs.filter((s) => !isSkillSlug(s));
|
|
414
741
|
const skillSlugs = slugs.filter((s) => isSkillSlug(s));
|
|
415
742
|
|
|
416
|
-
const
|
|
417
|
-
conceptSlugs.map(
|
|
418
|
-
const page = await readPage(workspaceDir, slug);
|
|
419
|
-
return { slug, page };
|
|
420
|
-
}),
|
|
743
|
+
const settled = await Promise.allSettled(
|
|
744
|
+
conceptSlugs.map((slug) => readPage(workspaceDir, slug)),
|
|
421
745
|
);
|
|
422
746
|
|
|
423
747
|
const sections: string[] = [];
|
|
424
748
|
const missingSlugs: string[] = [];
|
|
425
|
-
|
|
749
|
+
const corruptSlugs: string[] = [];
|
|
750
|
+
let anySummarySection = false;
|
|
751
|
+
for (let i = 0; i < settled.length; i++) {
|
|
752
|
+
const slug = conceptSlugs[i]!;
|
|
753
|
+
const result = settled[i]!;
|
|
754
|
+
if (result.status === "rejected") {
|
|
755
|
+
corruptSlugs.push(slug);
|
|
756
|
+
log.warn(
|
|
757
|
+
{ slug, err: result.reason },
|
|
758
|
+
"Memory v2 injection skipped slug whose page failed to load — frontmatter may be malformed",
|
|
759
|
+
);
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
const page = result.value;
|
|
426
763
|
if (!page) {
|
|
427
764
|
missingSlugs.push(slug);
|
|
428
765
|
continue;
|
|
429
766
|
}
|
|
767
|
+
const summary = page.frontmatter.summary?.trim();
|
|
768
|
+
const path = `memory/concepts/${slug}.md`;
|
|
769
|
+
if (summary && summary.length > 0) {
|
|
770
|
+
sections.push(`# ${path}\n${summary}`);
|
|
771
|
+
anySummarySection = true;
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
// Fallback: page predates the `summary` field (or the field was set to
|
|
775
|
+
// empty). Render the full page — frontmatter + body — so retrieval
|
|
776
|
+
// still surfaces the same content the agent saw before this change.
|
|
430
777
|
const content = renderPageContent(page).trim();
|
|
431
778
|
if (content.length === 0) continue;
|
|
432
|
-
sections.push(
|
|
779
|
+
sections.push(`# ${path}\n${content}`);
|
|
433
780
|
}
|
|
434
781
|
|
|
435
782
|
const skillLines: string[] = [];
|
|
@@ -442,10 +789,14 @@ async function renderInjectionBlock(
|
|
|
442
789
|
sections.push(`### Skills You Can Use\n${skillLines.join("\n")}`);
|
|
443
790
|
}
|
|
444
791
|
|
|
445
|
-
if (sections.length === 0)
|
|
792
|
+
if (sections.length === 0) {
|
|
793
|
+
return { block: null, missingSlugs, corruptSlugs };
|
|
794
|
+
}
|
|
446
795
|
|
|
796
|
+
const body = sections.join("\n\n");
|
|
447
797
|
return {
|
|
448
|
-
block:
|
|
798
|
+
block: anySummarySection ? `${INJECTION_HEADER}\n\n${body}` : body,
|
|
449
799
|
missingSlugs,
|
|
800
|
+
corruptSlugs,
|
|
450
801
|
};
|
|
451
802
|
}
|