@vellumai/assistant 0.7.0 → 0.7.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/ARCHITECTURE.md +6 -7
- package/Dockerfile +1 -0
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
- package/bun.lock +3 -0
- package/docs/architecture/security.md +18 -16
- package/knip.json +1 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
- package/node_modules/@vellumai/slack-text/bun.lock +24 -0
- package/node_modules/@vellumai/slack-text/package.json +18 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
- package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
- package/openapi.yaml +294 -107
- package/package.json +4 -2
- package/scripts/generate-openapi.ts +16 -111
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
- package/src/__tests__/anthropic-provider.test.ts +56 -13
- package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
- package/src/__tests__/app-conversation-ids.test.ts +151 -0
- package/src/__tests__/approval-cascade.test.ts +0 -15
- package/src/__tests__/approval-routes-http.test.ts +6 -17
- package/src/__tests__/assistant-event-hub.test.ts +126 -77
- package/src/__tests__/assistant-event.test.ts +0 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
- package/src/__tests__/background-shell-host-bash.test.ts +34 -43
- package/src/__tests__/call-controller.test.ts +1 -1
- package/src/__tests__/call-site-routing-provider.test.ts +193 -0
- package/src/__tests__/channel-approval-routes.test.ts +10 -296
- package/src/__tests__/channel-approvals.test.ts +25 -17
- package/src/__tests__/channel-guardian.test.ts +100 -146
- package/src/__tests__/checker.test.ts +20 -34
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/config-schema.test.ts +6 -48
- package/src/__tests__/config-watcher.test.ts +12 -0
- package/src/__tests__/connection-policy.test.ts +1 -52
- package/src/__tests__/contacts-write.test.ts +2 -64
- package/src/__tests__/context-image-dimensions.test.ts +1 -1
- package/src/__tests__/context-search-memory-source.test.ts +120 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
- package/src/__tests__/context-search-pkb-source.test.ts +49 -0
- package/src/__tests__/context-search-workspace-source.test.ts +9 -22
- package/src/__tests__/context-window-manager.test.ts +46 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
- package/src/__tests__/conversation-agent-loop.test.ts +980 -13
- package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
- package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
- package/src/__tests__/conversation-history-web-search.test.ts +4 -3
- package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
- package/src/__tests__/conversation-lifecycle.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +79 -2
- package/src/__tests__/conversation-queue.test.ts +3 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
- package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
- package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
- package/src/__tests__/conversation-slash-commands.test.ts +24 -4
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-starter-routes.test.ts +79 -2
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
- package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
- package/src/__tests__/conversation-usage.test.ts +253 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
- package/src/__tests__/credential-health-service.test.ts +68 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -5
- package/src/__tests__/credential-token-resolver.test.ts +180 -0
- package/src/__tests__/cu-unified-flow.test.ts +33 -16
- package/src/__tests__/daemon-assistant-events.test.ts +34 -21
- package/src/__tests__/daemon-credential-client.test.ts +4 -1
- package/src/__tests__/db-connection-isolation.test.ts +125 -0
- package/src/__tests__/db-migration-rollback.test.ts +101 -0
- package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
- package/src/__tests__/document-conversations.test.ts +332 -0
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
- package/src/__tests__/emit-event-signal.test.ts +4 -6
- package/src/__tests__/events-client-registration.test.ts +193 -49
- package/src/__tests__/filing-service.test.ts +58 -7
- package/src/__tests__/first-greeting.test.ts +156 -150
- package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
- package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +7 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
- package/src/__tests__/guardian-routing-state.test.ts +1 -1
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
- package/src/__tests__/headless-browser-mode.test.ts +4 -9
- package/src/__tests__/headless-browser-navigate.test.ts +21 -20
- package/src/__tests__/heartbeat-service.test.ts +289 -7
- package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
- package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
- package/src/__tests__/host-bash-proxy.test.ts +46 -122
- package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
- package/src/__tests__/host-browser-proxy.test.ts +111 -185
- package/src/__tests__/host-browser-routes.test.ts +45 -75
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
- package/src/__tests__/host-cu-proxy.test.ts +56 -111
- package/src/__tests__/host-file-proxy.test.ts +44 -98
- package/src/__tests__/host-file-read-tool.test.ts +42 -21
- package/src/__tests__/host-shell-tool.test.ts +33 -68
- package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
- package/src/__tests__/host-transfer-proxy.test.ts +43 -53
- package/src/__tests__/http-user-message-parity.test.ts +0 -6
- package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
- package/src/__tests__/injector-chain.test.ts +10 -5
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -66
- package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
- package/src/__tests__/install-skill-routing.test.ts +1 -13
- package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
- package/src/__tests__/llm-catalog-parity.test.ts +90 -0
- package/src/__tests__/llm-context-resolution.test.ts +180 -0
- package/src/__tests__/llm-resolver.test.ts +80 -12
- package/src/__tests__/llm-usage-store.test.ts +269 -4
- package/src/__tests__/log-export-routes.test.ts +89 -0
- package/src/__tests__/managed-profile-guard.test.ts +225 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
- package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
- package/src/__tests__/migration-export-http.test.ts +33 -26
- package/src/__tests__/migration-export-streaming.test.ts +18 -10
- package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
- package/src/__tests__/migration-import-commit-http.test.ts +66 -21
- package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
- package/src/__tests__/migration-import-from-url.test.ts +20 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
- package/src/__tests__/migration-parity-persistence.test.ts +62 -25
- package/src/__tests__/migration-transport.test.ts +115 -23
- package/src/__tests__/migration-validate-http.test.ts +105 -80
- package/src/__tests__/migration-wizard.test.ts +133 -27
- package/src/__tests__/non-member-access-request.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +19 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
- package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
- package/src/__tests__/pricing.test.ts +68 -4
- package/src/__tests__/process-message-background-slack.test.ts +331 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
- package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
- package/src/__tests__/provider-usage-tracking.test.ts +208 -0
- package/src/__tests__/reaction-persistence.test.ts +9 -6
- package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
- package/src/__tests__/recording-handler.test.ts +64 -81
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
- package/src/__tests__/relay-server.test.ts +18 -13
- package/src/__tests__/require-fresh-approval.test.ts +13 -22
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +3 -12
- package/src/__tests__/search-skills-unified.test.ts +9 -15
- package/src/__tests__/secret-ingress-cli.test.ts +2 -5
- package/src/__tests__/secret-ingress-http.test.ts +0 -4
- package/src/__tests__/secret-onetime-send.test.ts +4 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
- package/src/__tests__/secret-response-routing.test.ts +29 -15
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
- package/src/__tests__/secret-scanner.test.ts +2 -545
- package/src/__tests__/send-endpoint-busy.test.ts +9 -24
- package/src/__tests__/settings-routes.test.ts +1 -1
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
- package/src/__tests__/skill-tool-factory.test.ts +97 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
- package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
- package/src/__tests__/slack-inbound-verification.test.ts +1 -62
- package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
- package/src/__tests__/subagent-manager-notify.test.ts +70 -70
- package/src/__tests__/subagent-notify-parent.test.ts +80 -83
- package/src/__tests__/system-prompt.test.ts +115 -13
- package/src/__tests__/terminal-tools.test.ts +0 -89
- package/src/__tests__/thread-backfill.test.ts +945 -31
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
- package/src/__tests__/tool-executor.test.ts +12 -19
- package/src/__tests__/tool-metrics-listener.test.ts +0 -35
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-trace-listener.test.ts +0 -17
- package/src/__tests__/transfer-progress-screen.test.ts +63 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +16 -5
- package/src/__tests__/usage-attribution.test.ts +247 -0
- package/src/__tests__/usage-cli.test.ts +143 -0
- package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
- package/src/__tests__/usage-routes.test.ts +150 -0
- package/src/__tests__/validation-results-screen.test.ts +39 -16
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
- package/src/__tests__/voice-session-bridge.test.ts +5 -5
- package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
- package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
- package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
- package/src/acp/index.ts +0 -15
- package/src/acp/session-manager.ts +37 -34
- package/src/agent/loop.ts +16 -1
- package/src/approvals/AGENTS.md +4 -0
- package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
- package/src/approvals/guardian-request-resolvers.ts +10 -2
- package/src/backup/__tests__/backup-worker.test.ts +36 -8
- package/src/backup/__tests__/paths.test.ts +2 -2
- package/src/backup/__tests__/restore.test.ts +45 -28
- package/src/backup/backup-worker.ts +36 -2
- package/src/backup/paths.ts +9 -6
- package/src/browser-session/events.ts +0 -9
- package/src/calls/call-store.ts +1 -34
- package/src/calls/guardian-question-copy.ts +0 -108
- package/src/calls/relay-server.ts +0 -24
- package/src/calls/twilio-rest.ts +0 -38
- package/src/calls/twilio-routes.ts +1 -1
- package/src/calls/voice-session-bridge.ts +7 -38
- package/src/channels/types.ts +1 -36
- package/src/cli/commands/__tests__/cache.test.ts +152 -5
- package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
- package/src/cli/commands/__tests__/trust.test.ts +21 -387
- package/src/cli/commands/backup.ts +4 -4
- package/src/cli/commands/cache-fs.ts +8 -0
- package/src/cli/commands/cache.ts +153 -82
- package/src/cli/commands/clients.ts +63 -5
- package/src/cli/commands/completions.ts +3 -3
- package/src/cli/commands/contacts.ts +231 -76
- package/src/cli/commands/keys.ts +4 -1
- package/src/cli/commands/memory-v2.ts +24 -52
- package/src/cli/commands/oauth/shared.ts +2 -29
- package/src/cli/commands/pending.ts +102 -0
- package/src/cli/commands/skills.ts +77 -35
- package/src/cli/commands/trust.ts +70 -430
- package/src/cli/commands/usage.ts +25 -16
- package/src/cli/lib/daemon-credential-client.ts +14 -0
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
- package/src/config/env-registry.ts +12 -2
- package/src/config/env.ts +3 -14
- package/src/config/feature-flag-registry.json +30 -30
- package/src/config/llm-callsite-catalog.ts +12 -0
- package/src/config/llm-context-resolution.ts +80 -0
- package/src/config/llm-resolver.ts +58 -22
- package/src/config/loader.ts +3 -3
- package/src/config/schema.ts +2 -158
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +271 -0
- package/src/config/schemas/calls.ts +5 -5
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/ingress.ts +1 -1
- package/src/config/schemas/llm.ts +31 -3
- package/src/config/schemas/memory-retrieval.ts +2 -2
- package/src/config/schemas/memory-v2.ts +9 -0
- package/src/config/schemas/security.ts +1 -42
- package/src/config/schemas/services.ts +6 -6
- package/src/config/schemas/skills.ts +5 -5
- package/src/config/schemas/tts.ts +1 -1
- package/src/config/seed-inference-profiles.ts +117 -0
- package/src/config/skills.ts +0 -90
- package/src/config/types.ts +3 -6
- package/src/contacts/contact-store.ts +0 -17
- package/src/contacts/contacts-write.ts +1 -105
- package/src/context/window-manager.ts +44 -5
- package/src/credential-execution/process-manager.ts +34 -10
- package/src/credential-health/credential-health-service.ts +21 -16
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
- package/src/daemon/connection-policy.ts +1 -26
- package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
- package/src/daemon/conversation-agent-loop.ts +277 -36
- package/src/daemon/conversation-history.ts +8 -8
- package/src/daemon/conversation-launch.ts +20 -135
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-process.ts +83 -163
- package/src/daemon/conversation-runtime-assembly.ts +219 -76
- package/src/daemon/conversation-slash.ts +47 -5
- package/src/daemon/conversation-store.ts +7 -31
- package/src/daemon/conversation-surfaces.ts +22 -28
- package/src/daemon/conversation-tool-setup.ts +3 -33
- package/src/daemon/conversation-usage.ts +36 -0
- package/src/daemon/conversation.ts +117 -233
- package/src/daemon/daemon-control.ts +3 -71
- package/src/daemon/daemon-skill-host.ts +8 -11
- package/src/daemon/dictation-profile-store.ts +2 -26
- package/src/daemon/first-greeting.ts +44 -156
- package/src/daemon/handlers/config-channels.ts +12 -12
- package/src/daemon/handlers/config-ingress.ts +4 -165
- package/src/daemon/handlers/config-model.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +0 -42
- package/src/daemon/handlers/conversations.ts +11 -190
- package/src/daemon/handlers/recording.ts +26 -158
- package/src/daemon/handlers/shared.ts +23 -71
- package/src/daemon/handlers/skills.ts +42 -93
- package/src/daemon/host-bash-proxy.ts +67 -45
- package/src/daemon/host-browser-proxy.ts +65 -27
- package/src/daemon/host-cu-proxy.ts +40 -39
- package/src/daemon/host-file-proxy.ts +58 -37
- package/src/daemon/host-transfer-proxy.ts +84 -46
- package/src/daemon/lifecycle.ts +49 -15
- package/src/daemon/message-types/conversations.ts +7 -0
- package/src/daemon/message-types/host-bash.ts +1 -0
- package/src/daemon/message-types/host-cu.ts +1 -0
- package/src/daemon/message-types/host-file.ts +1 -0
- package/src/daemon/message-types/host-transfer.ts +1 -0
- package/src/daemon/message-types/messages.ts +10 -9
- package/src/daemon/message-types/workspace.ts +1 -1
- package/src/daemon/process-message.ts +102 -239
- package/src/daemon/server.ts +13 -462
- package/src/daemon/shutdown-handlers.ts +2 -2
- package/src/daemon/tool-side-effects.ts +125 -107
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +4 -9
- package/src/events/domain-events.ts +0 -8
- package/src/events/tool-audit-listener.ts +3 -1
- package/src/events/tool-domain-event-publisher.ts +0 -10
- package/src/events/tool-metrics-listener.ts +0 -17
- package/src/events/tool-trace-listener.ts +0 -14
- package/src/filing/filing-service.ts +13 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
- package/src/heartbeat/heartbeat-service.ts +23 -5
- package/src/home/__tests__/feed-writer.test.ts +0 -4
- package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
- package/src/home/feed-writer.ts +1 -2
- package/src/home/relationship-state-writer.ts +16 -3
- package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
- package/src/ipc/assistant-server.ts +3 -10
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
- package/src/ipc/routes/route-adapter.ts +1 -1
- package/src/ipc/routes/trust-rules.test.ts +0 -95
- package/src/ipc/skill-ipc-types.ts +41 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
- package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
- package/src/ipc/skill-routes/events.ts +12 -23
- package/src/ipc/skill-routes/identity.ts +4 -17
- package/src/ipc/skill-routes/index.ts +1 -1
- package/src/ipc/skill-server.ts +6 -39
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
- package/src/live-voice/protocol.ts +4 -13
- package/src/mcp/manager.ts +0 -5
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
- package/src/memory/app-git-service.ts +0 -32
- package/src/memory/app-store.ts +154 -0
- package/src/memory/attachments-store.ts +6 -0
- package/src/memory/context-search/sources/memory-v2.ts +578 -0
- package/src/memory/context-search/sources/memory.ts +5 -0
- package/src/memory/context-search/sources/pkb.ts +10 -1
- package/src/memory/context-search/sources/workspace.ts +3 -2
- package/src/memory/conversation-crud.ts +29 -4
- package/src/memory/conversation-disk-view.ts +1 -5
- package/src/memory/conversation-starter-checkpoints.ts +63 -0
- package/src/memory/db-connection.ts +62 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +3 -21
- package/src/memory/embedding-gemini.ts +0 -2
- package/src/memory/embedding-local.ts +6 -6
- package/src/memory/embedding-ollama.ts +6 -6
- package/src/memory/embedding-openai.ts +6 -6
- package/src/memory/embedding-types.ts +21 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
- package/src/memory/graph/conversation-graph-memory.ts +35 -13
- package/src/memory/graph/injection.test.ts +2 -2
- package/src/memory/graph/injection.ts +1 -1
- package/src/memory/guardian-action-store.ts +0 -83
- package/src/memory/guardian-approvals.ts +0 -48
- package/src/memory/indexer.ts +1 -15
- package/src/memory/job-handlers/conversation-starters.ts +36 -53
- package/src/memory/job-utils.ts +0 -6
- package/src/memory/jobs-store.ts +0 -1
- package/src/memory/jobs-worker.ts +2 -16
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +129 -43
- package/src/memory/memory-v2-activation-log-store.ts +115 -0
- package/src/memory/migrations/233-document-conversations.ts +54 -0
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
- package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
- package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
- package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
- package/src/memory/migrations/index.ts +14 -0
- package/src/memory/migrations/registry.ts +24 -0
- package/src/memory/raw-query.ts +2 -68
- package/src/memory/schema/conversations.ts +7 -0
- package/src/memory/schema/infrastructure.ts +25 -0
- package/src/memory/search/semantic.ts +5 -16
- package/src/memory/tool-usage-store.ts +2 -0
- package/src/memory/usage-buckets.ts +40 -1
- package/src/memory/usage-grouped-buckets.ts +127 -0
- package/src/memory/v2/__tests__/activation.test.ts +289 -90
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
- package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
- package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
- package/src/memory/v2/__tests__/injection.test.ts +384 -15
- package/src/memory/v2/__tests__/migration.test.ts +64 -36
- package/src/memory/v2/__tests__/page-store.test.ts +191 -8
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
- package/src/memory/v2/__tests__/static-context.test.ts +153 -0
- package/src/memory/v2/activation.ts +168 -97
- package/src/memory/v2/backfill-jobs.ts +15 -100
- package/src/memory/v2/consolidation-job.ts +14 -12
- package/src/memory/v2/edge-index.ts +191 -0
- package/src/memory/v2/injection.ts +182 -58
- package/src/memory/v2/migration.ts +57 -64
- package/src/memory/v2/now-text.ts +2 -3
- package/src/memory/v2/page-store.ts +168 -31
- package/src/memory/v2/prompts/consolidation.ts +118 -42
- package/src/memory/v2/prompts/sweep.ts +3 -3
- package/src/memory/v2/skill-store.ts +55 -7
- package/src/memory/v2/static-context.ts +62 -0
- package/src/memory/v2/types.ts +10 -20
- package/src/memory/validation.ts +0 -11
- package/src/messaging/draft-store.ts +0 -6
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/client.ts +1 -121
- package/src/messaging/providers/outlook/client.ts +0 -73
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
- package/src/messaging/providers/slack/adapter.ts +122 -21
- package/src/messaging/providers/slack/backfill.test.ts +95 -6
- package/src/messaging/providers/slack/backfill.ts +89 -11
- package/src/messaging/providers/slack/client.ts +10 -124
- package/src/messaging/providers/slack/message-metadata.ts +12 -2
- package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
- package/src/messaging/providers/slack/render-transcript.ts +126 -25
- package/src/messaging/providers/slack/types.ts +1 -0
- package/src/oauth/connection-resolver.test.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -16
- package/src/oauth/credential-token-resolver.ts +97 -0
- package/src/oauth/manual-token-connection.ts +30 -34
- package/src/oauth/oauth-store.ts +6 -4
- package/src/outbound-proxy/certs.ts +0 -7
- package/src/outbound-proxy/config.ts +0 -74
- package/src/outbound-proxy/health.ts +0 -44
- package/src/outbound-proxy/index.ts +0 -22
- package/src/permissions/approval-provenance.test.ts +184 -0
- package/src/permissions/approval-provenance.ts +70 -0
- package/src/permissions/checker.ts +4 -1
- package/src/permissions/gateway-threshold-reader.ts +4 -1
- package/src/permissions/prompter.ts +9 -2
- package/src/permissions/secret-prompter.ts +21 -48
- package/src/permissions/types.ts +33 -0
- package/src/permissions/workspace-policy.ts +0 -5
- package/src/platform/sync-identity.ts +0 -8
- package/src/plugins/defaults/injectors.ts +69 -2
- package/src/plugins/defaults/overflow-reduce.ts +3 -2
- package/src/plugins/types.ts +8 -0
- package/src/prompts/system-prompt.ts +34 -70
- package/src/prompts/templates/BOOTSTRAP.md +52 -6
- package/src/prompts/update-bulletin-job.ts +2 -0
- package/src/providers/__tests__/retry-callsite.test.ts +138 -1
- package/src/providers/anthropic/client.ts +72 -33
- package/src/providers/call-site-routing.ts +42 -3
- package/src/providers/gemini/client.ts +18 -2
- package/src/providers/managed-proxy/context.ts +0 -5
- package/src/providers/model-catalog.ts +105 -19
- package/src/providers/openai/chat-completions-provider.ts +6 -0
- package/src/providers/openai/responses-provider.ts +7 -1
- package/src/providers/provider-send-message.ts +45 -2
- package/src/providers/ratelimit.ts +7 -2
- package/src/providers/registry.ts +14 -9
- package/src/providers/retry.ts +96 -8
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +96 -0
- package/src/runtime/AGENTS.md +10 -6
- package/src/runtime/__tests__/agent-wake.test.ts +89 -0
- package/src/runtime/agent-wake.ts +39 -2
- package/src/runtime/assistant-event-hub.ts +541 -45
- package/src/runtime/assistant-event.ts +1 -6
- package/src/runtime/auth/context.ts +0 -9
- package/src/runtime/auth/middleware.ts +1 -1
- package/src/runtime/auth/route-policy.ts +11 -9
- package/src/runtime/auth/token-service.ts +0 -11
- package/src/runtime/channel-approvals.ts +6 -2
- package/src/runtime/channel-verification-service.ts +3 -5
- package/src/runtime/http-errors.ts +0 -34
- package/src/runtime/http-router.ts +6 -3
- package/src/runtime/http-server.ts +22 -82
- package/src/runtime/http-types.ts +5 -0
- package/src/runtime/interactive-ui.ts +0 -1
- package/src/runtime/middleware/auth.ts +0 -20
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
- package/src/runtime/migrations/migration-transport.ts +46 -13
- package/src/runtime/migrations/migration-wizard.ts +2 -2
- package/src/runtime/migrations/origin-mode.ts +40 -0
- package/src/runtime/migrations/vbundle-builder.ts +133 -79
- package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
- package/src/runtime/migrations/vbundle-importer.ts +7 -7
- package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
- package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
- package/src/runtime/migrations/vbundle-validator.ts +214 -41
- package/src/runtime/pending-interactions.ts +13 -4
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
- package/src/runtime/routes/acp-routes.test.ts +0 -3
- package/src/runtime/routes/acp-routes.ts +3 -7
- package/src/runtime/routes/app-management-routes.ts +18 -9
- package/src/runtime/routes/approval-routes.ts +55 -14
- package/src/runtime/routes/avatar-routes.ts +3 -5
- package/src/runtime/routes/browser-routes.ts +1 -15
- package/src/runtime/routes/channel-guardian-routes.ts +1 -5
- package/src/runtime/routes/channel-readiness-routes.ts +3 -7
- package/src/runtime/routes/channel-route-shared.ts +2 -28
- package/src/runtime/routes/client-routes.ts +45 -12
- package/src/runtime/routes/consolidation-routes.ts +115 -0
- package/src/runtime/routes/conversation-list-routes.ts +12 -29
- package/src/runtime/routes/conversation-management-routes.ts +14 -51
- package/src/runtime/routes/conversation-query-routes.ts +120 -8
- package/src/runtime/routes/conversation-routes.ts +44 -528
- package/src/runtime/routes/conversation-starter-routes.ts +19 -40
- package/src/runtime/routes/documents-routes.ts +53 -18
- package/src/runtime/routes/events-routes.ts +59 -91
- package/src/runtime/routes/filing-routes.ts +18 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -9
- package/src/runtime/routes/host-bash-routes.ts +3 -2
- package/src/runtime/routes/host-browser-routes.ts +9 -33
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +3 -2
- package/src/runtime/routes/host-transfer-routes.ts +11 -15
- package/src/runtime/routes/identity-routes.ts +78 -6
- package/src/runtime/routes/inbound-message-handler.ts +580 -137
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
- package/src/runtime/routes/index.ts +4 -0
- package/src/runtime/routes/integrations/slack/channel.ts +0 -24
- package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
- package/src/runtime/routes/memory-v2-routes.ts +10 -15
- package/src/runtime/routes/migration-routes.ts +188 -31
- package/src/runtime/routes/playground/guard.ts +1 -1
- package/src/runtime/routes/playground/index.ts +0 -2
- package/src/runtime/routes/recording-routes.ts +4 -24
- package/src/runtime/routes/rename-conversation-routes.ts +2 -6
- package/src/runtime/routes/schedule-routes.ts +3 -6
- package/src/runtime/routes/secret-routes.ts +87 -18
- package/src/runtime/routes/settings-routes.ts +29 -28
- package/src/runtime/routes/skills-routes.ts +12 -31
- package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
- package/src/runtime/routes/task-routes.ts +6 -6
- package/src/runtime/routes/trust-rules-routes.ts +3 -94
- package/src/runtime/routes/types.ts +4 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
- package/src/runtime/routes/usage-routes.ts +87 -10
- package/src/runtime/routes/user-routes.ts +17 -31
- package/src/runtime/routes/work-items-routes.ts +1 -4
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
- package/src/runtime/services/analyze-conversation.ts +7 -17
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/runtime/verification-outbound-actions.ts +1 -1
- package/src/runtime/verification-rate-limiter.ts +1 -1
- package/src/schedule/schedule-store.ts +0 -16
- package/src/security/secret-scanner.ts +14 -547
- package/src/security/secure-keys.ts +31 -11
- package/src/security/token-manager.ts +7 -3
- package/src/signals/cancel.ts +16 -25
- package/src/signals/conversation-undo.ts +2 -27
- package/src/signals/emit-event.ts +1 -2
- package/src/signals/user-message.ts +108 -22
- package/src/skills/catalog-install.ts +1 -0
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/inline-command-runner.ts +1 -7
- package/src/subagent/manager.ts +67 -84
- package/src/tasks/task-store.ts +1 -28
- package/src/telemetry/types.ts +6 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
- package/src/telemetry/usage-telemetry-reporter.ts +3 -5
- package/src/tools/acp/spawn.test.ts +1 -2
- package/src/tools/acp/steer.test.ts +1 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
- package/src/tools/browser/browser-execution.ts +31 -147
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
- package/src/tools/browser/cdp-client/factory.ts +48 -76
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/executor.ts +44 -31
- package/src/tools/host-filesystem/edit.ts +3 -2
- package/src/tools/host-filesystem/read.ts +3 -2
- package/src/tools/host-filesystem/transfer.test.ts +45 -42
- package/src/tools/host-filesystem/transfer.ts +4 -3
- package/src/tools/host-filesystem/write.ts +3 -2
- package/src/tools/host-terminal/host-shell.ts +4 -3
- package/src/tools/network/script-proxy/index.ts +1 -10
- package/src/tools/permission-checker.ts +66 -1
- package/src/tools/skills/sandbox-runner.ts +1 -6
- package/src/tools/skills/skill-tool-factory.ts +32 -0
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/terminal/shell.ts +2 -78
- package/src/tools/types.ts +12 -39
- package/src/tts/__tests__/provider-catalog.test.ts +2 -2
- package/src/tts/provider-catalog.ts +1 -1
- package/src/usage/actors.ts +2 -1
- package/src/usage/attribution.ts +185 -0
- package/src/usage/pricing.ts +166 -0
- package/src/usage/types.ts +14 -0
- package/src/util/json.ts +13 -0
- package/src/util/logger.ts +3 -3
- package/src/util/pricing.ts +50 -3
- package/src/work-items/work-item-runner.ts +15 -42
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
- package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
- package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
- package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
- package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/provider-commit-message-generator.ts +3 -3
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
- package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
- package/src/__tests__/secret-detection-handler.test.ts +0 -67
- package/src/__tests__/secret-scanner-executor.test.ts +0 -450
- package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
- package/src/__tests__/terminal-sandbox.test.ts +0 -374
- package/src/__tests__/tool-notification-listener.test.ts +0 -65
- package/src/context/__tests__/microcompact.test.ts +0 -805
- package/src/context/microcompact.ts +0 -443
- package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
- package/src/events/tool-notification-listener.ts +0 -17
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
- package/src/memory/v2/__tests__/edges.test.ts +0 -435
- package/src/memory/v2/edges.ts +0 -217
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
- package/src/runtime/__tests__/client-registry.test.ts +0 -271
- package/src/runtime/chrome-extension-registry.ts +0 -368
- package/src/runtime/client-registry.ts +0 -254
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
- package/src/tools/secret-detection-handler.ts +0 -269
- package/src/tools/terminal/backends/native.ts +0 -327
- package/src/tools/terminal/backends/types.ts +0 -37
- package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
- package/src/tools/terminal/sandbox.ts +0 -40
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
// Implements §5 of the design doc:
|
|
7
7
|
//
|
|
8
8
|
// 1. Hydrate prior activation state for the conversation.
|
|
9
|
-
// 2.
|
|
9
|
+
// 2. Build the in-memory edge index from concept-page frontmatter.
|
|
10
10
|
// 3. Select the per-turn candidate set (prior-state survivors ∪ ANN top-K).
|
|
11
11
|
// 4. Compute own activation A_o over the candidates.
|
|
12
|
-
// 5. Apply 2-hop spreading activation
|
|
12
|
+
// 5. Apply 2-hop spreading activation along directed edges (incoming) → A.
|
|
13
13
|
// 6. Pick top-K by activation; subtract everInjected to get the injection delta.
|
|
14
14
|
// 7. If no new slugs, render nothing — caller leaves the prior cached
|
|
15
15
|
// attachments on prior user messages exactly as Anthropic prompt caching
|
|
16
16
|
// requires.
|
|
17
|
-
// 8. Otherwise render a `<memory
|
|
17
|
+
// 8. Otherwise render a `<memory>` block scoped to the *new* slugs
|
|
18
18
|
// ordered by activation (descending) and persist the updated state +
|
|
19
19
|
// everInjected list (with `currentTurn` annotated) so future turns can
|
|
20
20
|
// append-inject cache-stably.
|
|
@@ -24,8 +24,14 @@
|
|
|
24
24
|
// cached prefix bytes-identical across turns.
|
|
25
25
|
|
|
26
26
|
import type { AssistantConfig } from "../../config/types.js";
|
|
27
|
+
import { getLogger } from "../../util/logger.js";
|
|
27
28
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
28
29
|
import type { DrizzleDb } from "../db-connection.js";
|
|
30
|
+
import {
|
|
31
|
+
type MemoryV2ConceptRowRecord,
|
|
32
|
+
type MemoryV2SkillRowRecord,
|
|
33
|
+
recordMemoryV2ActivationLog,
|
|
34
|
+
} from "../memory-v2-activation-log-store.js";
|
|
29
35
|
import {
|
|
30
36
|
computeOwnActivation,
|
|
31
37
|
computeSkillActivation,
|
|
@@ -36,11 +42,13 @@ import {
|
|
|
36
42
|
spreadActivation,
|
|
37
43
|
} from "./activation.js";
|
|
38
44
|
import { hydrate, save } from "./activation-store.js";
|
|
39
|
-
import {
|
|
40
|
-
import { readPage } from "./page-store.js";
|
|
45
|
+
import { getEdgeIndex } from "./edge-index.js";
|
|
46
|
+
import { readPage, renderPageContent } from "./page-store.js";
|
|
41
47
|
import { getSkillCapability } from "./skill-store.js";
|
|
42
48
|
import type { ActivationState, EverInjectedEntry } from "./types.js";
|
|
43
49
|
|
|
50
|
+
const log = getLogger("memory-v2-injection");
|
|
51
|
+
|
|
44
52
|
// ---------------------------------------------------------------------------
|
|
45
53
|
// Public types
|
|
46
54
|
// ---------------------------------------------------------------------------
|
|
@@ -49,7 +57,7 @@ import type { ActivationState, EverInjectedEntry } from "./types.js";
|
|
|
49
57
|
* Discriminator the wiring layer (`conversation-graph-memory.ts`) sets to
|
|
50
58
|
* tell the v2 injector which call site is asking. Both modes currently share
|
|
51
59
|
* the same block layout (mirroring v1 which also wraps both flows in
|
|
52
|
-
* `<memory
|
|
60
|
+
* `<memory>...</memory>`); the parameter exists so future tuning
|
|
53
61
|
* can shape the conversation-start block without touching the call site.
|
|
54
62
|
*/
|
|
55
63
|
export type InjectMemoryV2Mode = "context-load" | "per-turn";
|
|
@@ -81,7 +89,7 @@ export interface InjectMemoryV2BlockParams {
|
|
|
81
89
|
|
|
82
90
|
export interface InjectMemoryV2BlockResult {
|
|
83
91
|
/**
|
|
84
|
-
* Rendered `<memory
|
|
92
|
+
* Rendered `<memory>` block, ready to prepend to the current
|
|
85
93
|
* user message — or `null` when nothing new is eligible for injection.
|
|
86
94
|
* `null` is the cache-stable default: the caller adds nothing to the new
|
|
87
95
|
* user message and prior attachments stay byte-identical.
|
|
@@ -127,12 +135,14 @@ export async function injectMemoryV2Block(
|
|
|
127
135
|
// with an effective empty prior state so the first turn can still inject.
|
|
128
136
|
const priorState = await hydrate(database, conversationId);
|
|
129
137
|
|
|
130
|
-
// (2) Topology. `
|
|
131
|
-
//
|
|
132
|
-
const
|
|
138
|
+
// (2) Topology. `getEdgeIndex` walks concept-page frontmatter and caches
|
|
139
|
+
// the result module-locally; an empty workspace yields an empty index.
|
|
140
|
+
const edgeIndex = await getEdgeIndex(workspaceDir);
|
|
133
141
|
|
|
134
142
|
// (3) Candidate set: prior-state survivors above epsilon ∪ ANN top-50.
|
|
135
|
-
|
|
143
|
+
// `selectCandidates` also returns `fromPrior` / `fromAnn` provenance sets so
|
|
144
|
+
// telemetry can attribute each candidate back to its source.
|
|
145
|
+
const { candidates, fromPrior, fromAnn } = await selectCandidates({
|
|
136
146
|
priorState,
|
|
137
147
|
userText: userMessage,
|
|
138
148
|
assistantText: assistantMessage,
|
|
@@ -141,27 +151,36 @@ export async function injectMemoryV2Block(
|
|
|
141
151
|
});
|
|
142
152
|
|
|
143
153
|
// (4) Own activation: A_o = d·prev + c_user·sim_u + c_a·sim_a + c_now·sim_n.
|
|
144
|
-
const ownActivation
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
const { activation: ownActivation, breakdown: ownBreakdown } =
|
|
155
|
+
await computeOwnActivation({
|
|
156
|
+
candidates,
|
|
157
|
+
priorState,
|
|
158
|
+
userText: userMessage,
|
|
159
|
+
assistantText: assistantMessage,
|
|
160
|
+
nowText,
|
|
161
|
+
config,
|
|
162
|
+
});
|
|
152
163
|
|
|
153
164
|
// (5) Spreading activation across the edge graph (k, hops from config).
|
|
154
165
|
const { k, hops, top_k, epsilon } = config.memory.v2;
|
|
155
|
-
const
|
|
166
|
+
const { final: finalActivation, contribution: spreadContribution } =
|
|
167
|
+
spreadActivation(ownActivation, edgeIndex, k, hops);
|
|
156
168
|
|
|
157
|
-
// (6) Pick top-K by activation
|
|
169
|
+
// (6) Pick top-K by activation. Per-turn turns subtract everInjected for the
|
|
170
|
+
// injection delta (cache-stable append-only); context-load renders the
|
|
171
|
+
// entire top-K because it's a fresh load (turn 1 / post-compaction) where
|
|
172
|
+
// prior cached attachments don't exist or have been thrown away. The user
|
|
173
|
+
// message gets a complete top-K dump alongside the static
|
|
174
|
+
// essentials/threads/recent block, then per-turn turns just add deltas.
|
|
175
|
+
const mode = params.mode ?? "per-turn";
|
|
158
176
|
const priorEverInjected: readonly EverInjectedEntry[] =
|
|
159
177
|
priorState?.everInjected ?? [];
|
|
160
|
-
const { toInject } = selectInjections({
|
|
178
|
+
const { topNow, toInject } = selectInjections({
|
|
161
179
|
A: finalActivation,
|
|
162
180
|
priorEverInjected,
|
|
163
181
|
topK: top_k,
|
|
164
182
|
});
|
|
183
|
+
const slugsToRender = mode === "context-load" ? topNow : toInject;
|
|
165
184
|
|
|
166
185
|
// (6b) Skill pipeline — a sibling pipeline to the concept-page one above.
|
|
167
186
|
// Skills are stateless: no decay carry-over, no spread, no `everInjected`
|
|
@@ -174,13 +193,14 @@ export async function injectMemoryV2Block(
|
|
|
174
193
|
config,
|
|
175
194
|
topK: config.memory.v2.top_k_skills,
|
|
176
195
|
});
|
|
177
|
-
const skillActivation
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
196
|
+
const { activation: skillActivation, breakdown: skillBreakdown } =
|
|
197
|
+
await computeSkillActivation({
|
|
198
|
+
candidates: skillCandidates,
|
|
199
|
+
userText: userMessage,
|
|
200
|
+
assistantText: assistantMessage,
|
|
201
|
+
nowText,
|
|
202
|
+
config,
|
|
203
|
+
});
|
|
184
204
|
const { topNow: topSkillIds } = selectSkillInjections({
|
|
185
205
|
A: skillActivation,
|
|
186
206
|
topK: config.memory.v2.top_k_skills,
|
|
@@ -195,14 +215,20 @@ export async function injectMemoryV2Block(
|
|
|
195
215
|
if (value > epsilon) nextState[slug] = value;
|
|
196
216
|
}
|
|
197
217
|
|
|
198
|
-
//
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
// `
|
|
218
|
+
// Mark every rendered slug as ever-injected so future per-turn deltas don't
|
|
219
|
+
// re-attach the same content. On context-load this is the full top-K (we
|
|
220
|
+
// just rendered all of them); on per-turn it's just the newly added slugs.
|
|
221
|
+
// We append rather than reset so that compaction-driven eviction
|
|
222
|
+
// (`evictCompactedTurns`) is the only path that can re-enable a previously-
|
|
223
|
+
// injected slug. Skills do NOT enter `everInjected` — they are stateless
|
|
224
|
+
// and re-presented every turn.
|
|
225
|
+
const everInjectedSet = new Set(priorEverInjected.map((entry) => entry.slug));
|
|
226
|
+
const newlyInjected = slugsToRender.filter(
|
|
227
|
+
(slug) => !everInjectedSet.has(slug),
|
|
228
|
+
);
|
|
203
229
|
const nextEverInjected: EverInjectedEntry[] = [
|
|
204
230
|
...priorEverInjected,
|
|
205
|
-
...
|
|
231
|
+
...newlyInjected.map((slug) => ({ slug, turn: currentTurn })),
|
|
206
232
|
];
|
|
207
233
|
|
|
208
234
|
const nextActivationState: ActivationState = {
|
|
@@ -215,19 +241,110 @@ export async function injectMemoryV2Block(
|
|
|
215
241
|
|
|
216
242
|
await save(database, conversationId, nextActivationState);
|
|
217
243
|
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
|
|
244
|
+
// Record per-turn activation telemetry. This runs *before* the cache-stable
|
|
245
|
+
// empty-block return so we capture diagnostics even on no-op turns. Failures
|
|
246
|
+
// are warn-logged and never block memory injection.
|
|
247
|
+
const toInjectSet = new Set(toInject);
|
|
248
|
+
const renderedSet = new Set(slugsToRender);
|
|
249
|
+
const topSkillIdSet = new Set(topSkillIds);
|
|
250
|
+
const conceptRows: MemoryV2ConceptRowRecord[] = [...candidates].map(
|
|
251
|
+
(slug) => {
|
|
252
|
+
const breakdown = ownBreakdown.get(slug);
|
|
253
|
+
const inPrior = fromPrior.has(slug);
|
|
254
|
+
const inAnn = fromAnn.has(slug);
|
|
255
|
+
// Status reflects what was rendered for *this* turn:
|
|
256
|
+
// - context-load: cache was wiped (turn 1 / post-compaction), so
|
|
257
|
+
// `slugsToRender = topNow` and every rendered slug is freshly
|
|
258
|
+
// injected on this turn. `in_context` is unreachable because there
|
|
259
|
+
// is no prior cached attachment for the inspector to point at.
|
|
260
|
+
// - per-turn: cached attachments from prior turns are still on the
|
|
261
|
+
// user message, so prior-everInjected slugs are `in_context` and
|
|
262
|
+
// the delta (`toInject`) is `injected`.
|
|
263
|
+
let status: MemoryV2ConceptRowRecord["status"];
|
|
264
|
+
if (mode === "context-load") {
|
|
265
|
+
status = renderedSet.has(slug) ? "injected" : "not_injected";
|
|
266
|
+
} else if (everInjectedSet.has(slug)) {
|
|
267
|
+
status = "in_context";
|
|
268
|
+
} else if (toInjectSet.has(slug)) {
|
|
269
|
+
status = "injected";
|
|
270
|
+
} else {
|
|
271
|
+
status = "not_injected";
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
slug,
|
|
275
|
+
finalActivation: finalActivation.get(slug) ?? 0,
|
|
276
|
+
ownActivation: ownActivation.get(slug) ?? 0,
|
|
277
|
+
priorActivation: breakdown?.priorContribution ?? 0,
|
|
278
|
+
simUser: breakdown?.simUser ?? 0,
|
|
279
|
+
simAssistant: breakdown?.simAssistant ?? 0,
|
|
280
|
+
simNow: breakdown?.simNow ?? 0,
|
|
281
|
+
spreadContribution: spreadContribution.get(slug) ?? 0,
|
|
282
|
+
source:
|
|
283
|
+
inPrior && inAnn ? "both" : inPrior ? "prior_state" : "ann_top50",
|
|
284
|
+
status,
|
|
285
|
+
};
|
|
286
|
+
},
|
|
287
|
+
);
|
|
288
|
+
conceptRows.sort((a, b) => b.finalActivation - a.finalActivation);
|
|
289
|
+
|
|
290
|
+
const skillRows: MemoryV2SkillRowRecord[] = [...skillCandidates].map((id) => {
|
|
291
|
+
const breakdown = skillBreakdown.get(id);
|
|
292
|
+
return {
|
|
293
|
+
id,
|
|
294
|
+
activation: skillActivation.get(id) ?? 0,
|
|
295
|
+
simUser: breakdown?.simUser ?? 0,
|
|
296
|
+
simAssistant: breakdown?.simAssistant ?? 0,
|
|
297
|
+
simNow: breakdown?.simNow ?? 0,
|
|
298
|
+
status: topSkillIdSet.has(id) ? "injected" : "not_injected",
|
|
299
|
+
};
|
|
300
|
+
});
|
|
301
|
+
skillRows.sort((a, b) => b.activation - a.activation);
|
|
302
|
+
|
|
303
|
+
const v2Cfg = config.memory.v2;
|
|
304
|
+
try {
|
|
305
|
+
recordMemoryV2ActivationLog({
|
|
306
|
+
conversationId,
|
|
307
|
+
turn: currentTurn,
|
|
308
|
+
mode,
|
|
309
|
+
concepts: conceptRows,
|
|
310
|
+
skills: skillRows,
|
|
311
|
+
config: {
|
|
312
|
+
d: v2Cfg.d,
|
|
313
|
+
c_user: v2Cfg.c_user,
|
|
314
|
+
c_assistant: v2Cfg.c_assistant,
|
|
315
|
+
c_now: v2Cfg.c_now,
|
|
316
|
+
k: v2Cfg.k,
|
|
317
|
+
hops: v2Cfg.hops,
|
|
318
|
+
top_k: v2Cfg.top_k,
|
|
319
|
+
top_k_skills: v2Cfg.top_k_skills,
|
|
320
|
+
epsilon: v2Cfg.epsilon,
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
} catch (err) {
|
|
324
|
+
log.warn(
|
|
325
|
+
{ err, conversationId, turn: currentTurn },
|
|
326
|
+
"Failed to record memory v2 activation telemetry — continuing",
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// (7) Cache-stable empty path: nothing to render AND no ranked skills.
|
|
331
|
+
if (slugsToRender.length === 0 && topSkillIds.length === 0) {
|
|
221
332
|
return { block: null, toInject: [] };
|
|
222
333
|
}
|
|
223
334
|
|
|
224
|
-
// (8) Render. `toInject`
|
|
225
|
-
//
|
|
226
|
-
// render order.
|
|
227
|
-
//
|
|
228
|
-
|
|
335
|
+
// (8) Render. Both `topNow` and `toInject` are activation-descending
|
|
336
|
+
// (selectInjections sorts before slicing), so `slugsToRender` doubles as
|
|
337
|
+
// the render order. Per-turn: only the new slugs render (prior turns'
|
|
338
|
+
// attachments stay cached on prior user messages). Context-load: full
|
|
339
|
+
// top-K renders so the fresh user message gets a complete activation dump.
|
|
340
|
+
// Skills are appended after concept-page sections.
|
|
341
|
+
const block = await renderInjectionBlock(
|
|
342
|
+
workspaceDir,
|
|
343
|
+
slugsToRender,
|
|
344
|
+
topSkillIds,
|
|
345
|
+
);
|
|
229
346
|
|
|
230
|
-
return { block, toInject };
|
|
347
|
+
return { block, toInject: newlyInjected };
|
|
231
348
|
}
|
|
232
349
|
|
|
233
350
|
// ---------------------------------------------------------------------------
|
|
@@ -235,7 +352,7 @@ export async function injectMemoryV2Block(
|
|
|
235
352
|
// ---------------------------------------------------------------------------
|
|
236
353
|
|
|
237
354
|
/**
|
|
238
|
-
* Render the `<memory
|
|
355
|
+
* Render the `<memory>` block for a list of slugs and a list of
|
|
239
356
|
* ranked skill ids.
|
|
240
357
|
*
|
|
241
358
|
* Concept pages are read in parallel via `readPage`. Pages whose file has
|
|
@@ -248,14 +365,26 @@ export async function injectMemoryV2Block(
|
|
|
248
365
|
* the missing-pages behavior.
|
|
249
366
|
*
|
|
250
367
|
* The block shape is the §5 layout from the design doc, with an optional
|
|
251
|
-
* trailing skills subsection
|
|
368
|
+
* trailing skills subsection. Each concept-page section reproduces the page
|
|
369
|
+
* as it lives on disk — frontmatter (`edges`, `ref_files`) plus body — so
|
|
370
|
+
* the agent sees the page's edges and any referenced media paths alongside
|
|
371
|
+
* the prose:
|
|
252
372
|
*
|
|
253
|
-
* <memory
|
|
254
|
-
* ## What I Remember Right Now
|
|
373
|
+
* <memory>
|
|
255
374
|
* ### <slug-1>
|
|
375
|
+
* ---
|
|
376
|
+
* edges:
|
|
377
|
+
* - <neighbor-slug>
|
|
378
|
+
* ref_files:
|
|
379
|
+
* - <path/to/asset>
|
|
380
|
+
* ---
|
|
256
381
|
* <body-1>
|
|
257
382
|
*
|
|
258
383
|
* ### <slug-2>
|
|
384
|
+
* ---
|
|
385
|
+
* edges: []
|
|
386
|
+
* ref_files: []
|
|
387
|
+
* ---
|
|
259
388
|
* <body-2>
|
|
260
389
|
*
|
|
261
390
|
* ### Skills You Can Use
|
|
@@ -263,13 +392,9 @@ export async function injectMemoryV2Block(
|
|
|
263
392
|
* - <skill-2 content>
|
|
264
393
|
* </memory>
|
|
265
394
|
*
|
|
266
|
-
* The same `## What I Remember Right Now` header wraps the block whether
|
|
267
|
-
* the skills section is alone, the concept-page sections are alone, or
|
|
268
|
-
* both are present — keeping the renderer one shape.
|
|
269
|
-
*
|
|
270
395
|
* Returns `null` when both lists collapse to empty after cache misses so
|
|
271
396
|
* the caller can fall through to its empty-block path instead of attaching
|
|
272
|
-
*
|
|
397
|
+
* an empty `<memory>` wrapper.
|
|
273
398
|
*/
|
|
274
399
|
async function renderInjectionBlock(
|
|
275
400
|
workspaceDir: string,
|
|
@@ -279,14 +404,14 @@ async function renderInjectionBlock(
|
|
|
279
404
|
const pages = await Promise.all(
|
|
280
405
|
slugs.map(async (slug) => {
|
|
281
406
|
const page = await readPage(workspaceDir, slug);
|
|
282
|
-
return page ? { slug,
|
|
407
|
+
return page ? { slug, content: renderPageContent(page).trim() } : null;
|
|
283
408
|
}),
|
|
284
409
|
);
|
|
285
410
|
|
|
286
411
|
const sections: string[] = [];
|
|
287
412
|
for (const entry of pages) {
|
|
288
|
-
if (!entry || entry.
|
|
289
|
-
sections.push(`### ${entry.slug}\n${entry.
|
|
413
|
+
if (!entry || entry.content.length === 0) continue;
|
|
414
|
+
sections.push(`### ${entry.slug}\n${entry.content}`);
|
|
290
415
|
}
|
|
291
416
|
|
|
292
417
|
// v2's skills collection is skills-only, so the activation suffix always applies.
|
|
@@ -302,6 +427,5 @@ async function renderInjectionBlock(
|
|
|
302
427
|
|
|
303
428
|
if (sections.length === 0) return null;
|
|
304
429
|
|
|
305
|
-
|
|
306
|
-
return `<memory __injected>\n${inner}\n</memory>`;
|
|
430
|
+
return `<memory>\n${sections.join("\n\n")}\n</memory>`;
|
|
307
431
|
}
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* synthesizes a concept page per cluster via the configured LLM, promotes
|
|
6
6
|
* high-significance nodes to `essentials.md` / active follow-ups to
|
|
7
7
|
* `threads.md` / low-significance episodes to `archive/migrated-<date>.md`,
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* page. A sentinel file at `memory/.v2-state/.migration-complete-v1-to-v2`
|
|
8
|
+
* preserves v1 weighted directional edges as outgoing-edge entries on each
|
|
9
|
+
* source page's frontmatter, and enqueues `embed_concept_page` jobs for each
|
|
10
|
+
* new page. A sentinel file at `memory/.v2-state/.migration-complete-v1-to-v2`
|
|
11
11
|
* gates re-runs — `force: true` is required to overwrite.
|
|
12
12
|
*
|
|
13
13
|
* The migration is structured as a sequence of small helpers — `gatherV1State`,
|
|
@@ -31,9 +31,8 @@ import type { Provider } from "../../providers/types.js";
|
|
|
31
31
|
import { getLogger } from "../../util/logger.js";
|
|
32
32
|
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
33
33
|
import { enqueueMemoryJob } from "../jobs-store.js";
|
|
34
|
-
import { writeEdges } from "./edges.js";
|
|
35
34
|
import { slugify, writePage } from "./page-store.js";
|
|
36
|
-
import type { ConceptPage
|
|
35
|
+
import type { ConceptPage } from "./types.js";
|
|
37
36
|
|
|
38
37
|
const log = getLogger("memory-v2-migration");
|
|
39
38
|
|
|
@@ -56,7 +55,6 @@ export interface MigrationResult {
|
|
|
56
55
|
threadsLines: number;
|
|
57
56
|
archiveLines: number;
|
|
58
57
|
embedsEnqueued: number;
|
|
59
|
-
rebuildEdgesJobId: string;
|
|
60
58
|
sentinelWritten: boolean;
|
|
61
59
|
}
|
|
62
60
|
|
|
@@ -86,8 +84,9 @@ export interface V1Item {
|
|
|
86
84
|
}
|
|
87
85
|
|
|
88
86
|
/**
|
|
89
|
-
* v1 weighted directional edge
|
|
90
|
-
*
|
|
87
|
+
* v1 weighted directional edge. v2 preserves direction (an edge A→B in v1
|
|
88
|
+
* becomes an outgoing-edge entry on A's page in v2), so the migration just
|
|
89
|
+
* has to map node ids to slugs and group by source.
|
|
91
90
|
*/
|
|
92
91
|
export interface V1Edge {
|
|
93
92
|
sourceNodeId: string;
|
|
@@ -409,31 +408,38 @@ function formatPromotionLine(item: V1Item): string {
|
|
|
409
408
|
}
|
|
410
409
|
|
|
411
410
|
// ---------------------------------------------------------------------------
|
|
412
|
-
// Stage 5 —
|
|
411
|
+
// Stage 5 — Map v1 edges to per-page outgoing edges
|
|
413
412
|
// ---------------------------------------------------------------------------
|
|
414
413
|
|
|
415
414
|
/**
|
|
416
|
-
* Map every v1 graph-node id to a v2 concept-page slug
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
415
|
+
* Map every v1 graph-node id to a v2 concept-page slug and group v1 edges by
|
|
416
|
+
* source slug. Edges with either endpoint missing from `slugMap` are dropped
|
|
417
|
+
* silently — those endpoints didn't survive synthesis (e.g. their cluster
|
|
418
|
+
* produced no usable page). Self-loops are dropped; duplicate `(source, target)`
|
|
419
|
+
* pairs collapse via the `Set<string>`.
|
|
420
420
|
*
|
|
421
|
-
* The returned
|
|
422
|
-
*
|
|
421
|
+
* The returned map keys are source slugs and the values are sets of target
|
|
422
|
+
* slugs — i.e. each entry is a page's outgoing-edge list. The runner writes
|
|
423
|
+
* these into the source page's frontmatter.
|
|
423
424
|
*/
|
|
424
425
|
export function collapseEdges(
|
|
425
426
|
v1Edges: V1Edge[],
|
|
426
427
|
slugMap: Map<string, string>,
|
|
427
|
-
):
|
|
428
|
-
const
|
|
428
|
+
): Map<string, Set<string>> {
|
|
429
|
+
const outgoing = new Map<string, Set<string>>();
|
|
429
430
|
for (const edge of v1Edges) {
|
|
430
|
-
const
|
|
431
|
-
const
|
|
432
|
-
if (!
|
|
433
|
-
if (
|
|
434
|
-
|
|
431
|
+
const from = slugMap.get(edge.sourceNodeId);
|
|
432
|
+
const to = slugMap.get(edge.targetNodeId);
|
|
433
|
+
if (!from || !to) continue;
|
|
434
|
+
if (from === to) continue;
|
|
435
|
+
let targets = outgoing.get(from);
|
|
436
|
+
if (!targets) {
|
|
437
|
+
targets = new Set<string>();
|
|
438
|
+
outgoing.set(from, targets);
|
|
439
|
+
}
|
|
440
|
+
targets.add(to);
|
|
435
441
|
}
|
|
436
|
-
return
|
|
442
|
+
return outgoing;
|
|
437
443
|
}
|
|
438
444
|
|
|
439
445
|
// ---------------------------------------------------------------------------
|
|
@@ -476,8 +482,8 @@ export interface RunMemoryV2MigrationParams {
|
|
|
476
482
|
* Re-runs are gated by the sentinel file
|
|
477
483
|
* `memory/.v2-state/.migration-complete-v1-to-v2`. Without `force: true`, a
|
|
478
484
|
* second invocation throws `MigrationAlreadyAppliedError` without mutating
|
|
479
|
-
* anything; with `force: true`, the migration overwrites pages and
|
|
480
|
-
*
|
|
485
|
+
* anything; with `force: true`, the migration overwrites pages and re-appends
|
|
486
|
+
* to the prose files.
|
|
481
487
|
*/
|
|
482
488
|
export class MigrationAlreadyAppliedError extends Error {
|
|
483
489
|
constructor() {
|
|
@@ -548,41 +554,46 @@ export async function runMemoryV2Migration(
|
|
|
548
554
|
}
|
|
549
555
|
}
|
|
550
556
|
|
|
557
|
+
// Resolve outgoing edges per source slug, then attach them to each page's
|
|
558
|
+
// frontmatter before writing. The page is the source of truth for its own
|
|
559
|
+
// outgoing edges — there is no separate edges-index file.
|
|
560
|
+
const outgoingBySource = collapseEdges(v1Edges, slugMap);
|
|
561
|
+
const finalizedPages: ConceptPage[] = pages.map((page) => {
|
|
562
|
+
const targets = outgoingBySource.get(page.slug);
|
|
563
|
+
if (!targets || targets.size === 0) return page;
|
|
564
|
+
return {
|
|
565
|
+
...page,
|
|
566
|
+
frontmatter: {
|
|
567
|
+
...page.frontmatter,
|
|
568
|
+
edges: [...targets].sort(),
|
|
569
|
+
},
|
|
570
|
+
};
|
|
571
|
+
});
|
|
572
|
+
|
|
551
573
|
// Page writes hit different filenames so they're safe to fan out.
|
|
552
|
-
await Promise.all(
|
|
574
|
+
await Promise.all(
|
|
575
|
+
finalizedPages.map((page) => writePage(workspaceDir, page)),
|
|
576
|
+
);
|
|
553
577
|
|
|
554
578
|
const promotions = derivePromotions(items);
|
|
555
579
|
await appendPromotions(workspaceDir, promotions);
|
|
556
580
|
|
|
557
|
-
const
|
|
558
|
-
await writeEdges(workspaceDir, edgesIdx);
|
|
559
|
-
|
|
560
|
-
const embedsEnqueued = enqueueEmbeds(pages.map((p) => p.slug));
|
|
561
|
-
|
|
562
|
-
// Page bodies are written with empty `edges:` frontmatter (the schema is a
|
|
563
|
-
// derived view of `edges.json`). Without this enqueue the frontmatter would
|
|
564
|
-
// stay empty until the next consolidation run, but consolidation bails on an
|
|
565
|
-
// empty buffer — so a freshly-migrated workspace can sit indefinitely with
|
|
566
|
-
// out-of-date frontmatter. The rebuild-edges job propagates `edges.json` into
|
|
567
|
-
// every page's frontmatter and is idempotent, so pairing it with the
|
|
568
|
-
// migration is safe even when nothing else has run yet.
|
|
569
|
-
const rebuildEdgesJobId = enqueueMemoryJob("memory_v2_rebuild_edges", {});
|
|
581
|
+
const embedsEnqueued = enqueueEmbeds(finalizedPages.map((p) => p.slug));
|
|
570
582
|
|
|
571
583
|
await writeSentinel(workspaceDir);
|
|
572
584
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
585
|
+
let edgesWritten = 0;
|
|
586
|
+
for (const targets of outgoingBySource.values()) {
|
|
587
|
+
edgesWritten += targets.size;
|
|
588
|
+
}
|
|
577
589
|
|
|
578
590
|
return {
|
|
579
|
-
pagesCreated:
|
|
580
|
-
edgesWritten
|
|
591
|
+
pagesCreated: finalizedPages.length,
|
|
592
|
+
edgesWritten,
|
|
581
593
|
essentialsLines: promotions.essentials.length,
|
|
582
594
|
threadsLines: promotions.threads.length,
|
|
583
595
|
archiveLines: promotions.archive.length,
|
|
584
596
|
embedsEnqueued,
|
|
585
|
-
rebuildEdgesJobId,
|
|
586
597
|
sentinelWritten: true,
|
|
587
598
|
};
|
|
588
599
|
}
|
|
@@ -634,21 +645,3 @@ async function writeSentinel(workspaceDir: string): Promise<void> {
|
|
|
634
645
|
await mkdir(join(workspaceDir, "memory", ".v2-state"), { recursive: true });
|
|
635
646
|
await writeFile(sentinelPath, `${new Date().toISOString()}\n`, "utf-8");
|
|
636
647
|
}
|
|
637
|
-
|
|
638
|
-
/**
|
|
639
|
-
* Read `memory/edges.json` after writing and return the edge count. Used
|
|
640
|
-
* only to populate the result summary — the file has already been
|
|
641
|
-
* canonicalized by `writeEdges`, so this is just a count, not validation.
|
|
642
|
-
*/
|
|
643
|
-
async function readPersistedEdgeCount(workspaceDir: string): Promise<number> {
|
|
644
|
-
try {
|
|
645
|
-
const raw = await readFile(
|
|
646
|
-
join(workspaceDir, "memory", "edges.json"),
|
|
647
|
-
"utf-8",
|
|
648
|
-
);
|
|
649
|
-
const parsed = JSON.parse(raw) as { edges?: unknown[] };
|
|
650
|
-
return Array.isArray(parsed.edges) ? parsed.edges.length : 0;
|
|
651
|
-
} catch {
|
|
652
|
-
return 0;
|
|
653
|
-
}
|
|
654
|
-
}
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
//
|
|
5
5
|
// The activation formula's `c_now` term needs a snapshot of the prose meta
|
|
6
|
-
// files (`essentials.md`, `threads.md`, `recent.md`)
|
|
7
|
-
// also autoloads (see `prompts/system-prompt.ts buildMemoryV2Section`).
|
|
6
|
+
// files (`essentials.md`, `threads.md`, `recent.md`).
|
|
8
7
|
// Missing or unreadable files are treated as empty so a fresh workspace
|
|
9
8
|
// (no consolidation has run yet) still reaches the v2 injector with a
|
|
10
9
|
// well-defined `nowText`.
|
|
@@ -16,7 +15,7 @@ const NOW_FILES = ["essentials.md", "threads.md", "recent.md"] as const;
|
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
17
|
* Read `memory/{essentials,threads,recent}.md` and concatenate the trimmed
|
|
19
|
-
* non-empty contents
|
|
18
|
+
* non-empty contents.
|
|
20
19
|
*
|
|
21
20
|
* Returns an empty string when none of the files exist or all are empty.
|
|
22
21
|
*/
|