@vellumai/assistant 0.10.12 → 0.11.0-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/ARCHITECTURE.md +4 -5
- package/README.md +1 -1
- package/docs/architecture/memory.md +60 -23
- package/docs/error-handling.md +3 -3
- package/docs/guardian-request-flow.md +112 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/openapi.yaml +264 -14
- package/package.json +2 -2
- package/src/__tests__/acp-session.test.ts +3 -3
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
- package/src/__tests__/anthropic-provider.test.ts +40 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +33 -2
- package/src/__tests__/app-conversation-ids.test.ts +204 -0
- package/src/__tests__/approval-cascade.test.ts +5 -5
- package/src/__tests__/approval-routes-http.test.ts +3 -3
- package/src/__tests__/ask-question-resolver.test.ts +207 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
- package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
- package/src/__tests__/assistant-event-hub.test.ts +13 -11
- package/src/__tests__/assistant-event.test.ts +12 -9
- package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
- package/src/__tests__/assistant-stream-state.test.ts +17 -7
- package/src/__tests__/avatar-identity-sync.test.ts +3 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +134 -18
- package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
- package/src/__tests__/channel-approvals.test.ts +0 -27
- package/src/__tests__/channel-guardian.test.ts +85 -512
- package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
- package/src/__tests__/channel-retry-sweep.test.ts +88 -1
- package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
- package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
- package/src/__tests__/compaction-events.test.ts +8 -8
- package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
- package/src/__tests__/config-model-image-provider.test.ts +20 -0
- package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
- package/src/__tests__/config-schema.test.ts +14 -2
- package/src/__tests__/config-set-platform-guard.test.ts +11 -12
- package/src/__tests__/config-sounds-sync.test.ts +4 -4
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
- package/src/__tests__/context-search-memory-source.test.ts +1 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
- package/src/__tests__/context-token-estimator.test.ts +54 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
- package/src/__tests__/conversation-agent-loop.test.ts +39 -30
- package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
- package/src/__tests__/conversation-evictor.test.ts +49 -0
- package/src/__tests__/conversation-fork-crud.test.ts +1 -1
- package/src/__tests__/conversation-group-tools.test.ts +279 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
- package/src/__tests__/conversation-lineage.test.ts +235 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
- package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
- package/src/__tests__/conversation-queue.test.ts +81 -81
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
- package/src/__tests__/conversation-slash-queue.test.ts +11 -11
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
- package/src/__tests__/conversation-speed-override.test.ts +2 -2
- package/src/__tests__/conversation-summarize-route.test.ts +9 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
- package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
- package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
- package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
- package/src/__tests__/conversation-sync-tags.test.ts +5 -5
- package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
- package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/daemon-assistant-events.test.ts +14 -15
- package/src/__tests__/db-test-helpers.ts +13 -27
- package/src/__tests__/disk-pressure-routes.test.ts +12 -3
- package/src/__tests__/document-tool-security.test.ts +95 -0
- package/src/__tests__/drain-kick-guard.test.ts +232 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
- package/src/__tests__/emit-event-signal.test.ts +5 -6
- package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
- package/src/__tests__/events-tail-route.test.ts +6 -4
- package/src/__tests__/feature-flag-test-helpers.ts +10 -20
- package/src/__tests__/file-edit-tool.test.ts +24 -4
- package/src/__tests__/file-list-tool.test.ts +2 -1
- package/src/__tests__/file-read-tool.test.ts +62 -10
- package/src/__tests__/file-write-tool.test.ts +24 -5
- package/src/__tests__/followup-tools.test.ts +58 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
- package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
- package/src/__tests__/guardian-question-mode.test.ts +42 -3
- package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
- package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
- package/src/__tests__/host-browser-proxy.test.ts +1 -1
- package/src/__tests__/host-file-edit-tool.test.ts +3 -3
- package/src/__tests__/host-file-read-tool.test.ts +2 -2
- package/src/__tests__/host-file-write-tool.test.ts +7 -3
- package/src/__tests__/host-shell-tool.test.ts +17 -5
- package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
- package/src/__tests__/image-credentials.test.ts +65 -8
- package/src/__tests__/injection-block.test.ts +4 -4
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
- package/src/__tests__/injector-v3-suppression.test.ts +6 -4
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
- package/src/__tests__/list-messages-page-latest.test.ts +2 -2
- package/src/__tests__/llm-usage-store.test.ts +67 -4
- package/src/__tests__/log-redact.test.ts +18 -0
- package/src/__tests__/managed-profile-guard.test.ts +27 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +62 -11
- package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
- package/src/__tests__/notification-decision-strategy.test.ts +115 -11
- package/src/__tests__/notification-deep-link.test.ts +12 -12
- package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
- package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +315 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
- package/src/__tests__/persistence-layering-guard.test.ts +2 -2
- package/src/__tests__/pkb-autoinject.test.ts +1 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
- package/src/__tests__/platform-callback-registration.test.ts +10 -10
- package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
- package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
- package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
- package/src/__tests__/require-fresh-approval.test.ts +38 -38
- package/src/__tests__/resolve-app-id.test.ts +32 -0
- package/src/__tests__/run-due-schedules.test.ts +72 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +44 -5
- package/src/__tests__/schedule-store.test.ts +3 -3
- package/src/__tests__/schedule-tools.test.ts +176 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
- package/src/__tests__/secret-response-routing.test.ts +3 -3
- package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
- package/src/__tests__/secret-scanner.test.ts +36 -0
- package/src/__tests__/send-endpoint-busy.test.ts +7 -7
- package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
- package/src/__tests__/starter-task-flow.test.ts +26 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/subagent-disposal.test.ts +40 -11
- package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
- package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
- package/src/__tests__/subagent-manager-notify.test.ts +73 -14
- package/src/__tests__/subagent-notify-parent.test.ts +48 -4
- package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
- package/src/__tests__/subagent-tools.test.ts +64 -0
- package/src/__tests__/sync-message-contract.test.ts +3 -3
- package/src/__tests__/terminal-tools.test.ts +12 -3
- package/src/__tests__/test-preload.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +587 -43
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
- package/src/__tests__/tool-executor.test.ts +116 -0
- package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +4 -4
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
- package/src/__tests__/ui-work-result-surface.test.ts +3 -3
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
- package/src/__tests__/voice-session-bridge.test.ts +44 -44
- package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
- package/src/__tests__/workspace-policy.test.ts +482 -2
- package/src/acp/__tests__/client-handler.test.ts +3 -3
- package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
- package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
- package/src/acp/client-handler.ts +3 -3
- package/src/acp/session-manager.ts +8 -8
- package/src/api/events/subagent-event.ts +2 -2
- package/src/api/responses/memory-v2-activation-log.ts +2 -2
- package/src/api/responses/subagent-detail.ts +13 -0
- package/src/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/apps/app-store.ts +95 -4
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
- package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
- package/src/calls/call-controller.ts +27 -27
- package/src/calls/call-conversation-messages.ts +58 -18
- package/src/calls/voice-control-protocol.ts +56 -0
- package/src/calls/voice-session-bridge.ts +178 -65
- package/src/calls/voice-triage-escalate.ts +2 -3
- package/src/channels/config.ts +8 -0
- package/src/channels/types.ts +1 -0
- package/src/cli/commands/config.ts +49 -13
- package/src/cli/commands/memory/index.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +5 -0
- package/src/cli/commands/webhooks.help.ts +9 -4
- package/src/cli/lib/bundled-marketplace.json +12 -0
- package/src/cli.ts +2 -109
- package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
- package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
- package/src/config/assistant-feature-flags.ts +1 -1
- package/src/config/bundled-skills/conversation-groups/SKILL.md +29 -0
- package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/bundled-skills/schedule/SKILL.md +2 -0
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -38
- package/src/config/loader.ts +7 -1
- package/src/config/memory-tier.ts +15 -10
- package/src/config/memory-v3-gate.test.ts +278 -1
- package/src/config/memory-v3-gate.ts +88 -26
- package/src/config/raw-config-utils.ts +1 -1
- package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/live-voice.ts +33 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrospective.ts +13 -0
- package/src/config/schemas/memory-substrate.ts +183 -0
- package/src/config/schemas/memory-v2.ts +3 -2
- package/src/config/schemas/memory-v3.ts +11 -4
- package/src/config/schemas/memory.ts +35 -1
- package/src/config/schemas/services.ts +10 -2
- package/src/config/substrate-twin-shadowing.ts +195 -0
- package/src/config/webhook-routing.ts +67 -0
- package/src/context/compactor.ts +10 -3
- package/src/context/token-estimator.ts +21 -0
- package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
- package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
- package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
- package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
- package/src/daemon/channel-ui-capability.ts +70 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
- package/src/daemon/conversation-agent-loop.ts +12 -5
- package/src/daemon/conversation-evictor.ts +26 -4
- package/src/daemon/conversation-launch.ts +11 -14
- package/src/daemon/conversation-lineage.ts +76 -0
- package/src/daemon/conversation-messaging.ts +14 -14
- package/src/daemon/conversation-notifiers.ts +2 -2
- package/src/daemon/conversation-process.ts +133 -21
- package/src/daemon/conversation-queue-manager.ts +7 -7
- package/src/daemon/conversation-runtime-assembly.ts +16 -0
- package/src/daemon/conversation-store.ts +11 -3
- package/src/daemon/conversation-surfaces.ts +8 -14
- package/src/daemon/conversation-tool-setup.ts +13 -7
- package/src/daemon/conversation-usage.ts +12 -11
- package/src/daemon/conversation.ts +38 -15
- package/src/daemon/disk-pressure-guard.ts +5 -12
- package/src/daemon/embedding-reconcile.ts +14 -9
- package/src/daemon/handlers/config-channels.ts +40 -134
- package/src/daemon/handlers/config-model.ts +15 -7
- package/src/daemon/handlers/conversations.ts +4 -2
- package/src/daemon/handlers/shared.ts +29 -0
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/lifecycle.ts +13 -0
- package/src/daemon/message-protocol.ts +8 -144
- package/src/daemon/message-types/computer-use.ts +0 -12
- package/src/daemon/message-types/conversations.ts +9 -345
- package/src/daemon/message-types/host-app-control.ts +0 -9
- package/src/daemon/message-types/host-browser.ts +0 -7
- package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
- package/src/daemon/message-types/messages.ts +0 -48
- package/src/daemon/message-types/notifications.ts +0 -7
- package/src/daemon/message-types/skills.ts +0 -5
- package/src/daemon/message-types/surfaces.ts +0 -9
- package/src/daemon/message-types/sync.ts +0 -2
- package/src/daemon/process-message.ts +5 -5
- package/src/daemon/skill-memory-refresh.ts +5 -5
- package/src/daemon/tool-side-effects.ts +32 -16
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +4 -4
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
- package/src/heartbeat/heartbeat-run-store.ts +81 -4
- package/src/heartbeat/heartbeat-service.ts +32 -1
- package/src/home/__tests__/feed-writer.test.ts +7 -7
- package/src/home/__tests__/home-content-refresh.test.ts +3 -0
- package/src/home/__tests__/suggested-prompts.test.ts +1 -0
- package/src/home/feed-writer.ts +6 -13
- package/src/home/home-content-refresh.ts +6 -9
- package/src/home/relationship-state-writer.ts +5 -12
- package/src/home/suggested-prompts-cache.ts +6 -19
- package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
- package/src/ipc/events-publish-client.ts +44 -0
- package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
- package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
- package/src/ipc/routes/events-ipc-routes.ts +11 -31
- package/src/live-voice/__tests__/front-decision.test.ts +4 -176
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
- package/src/live-voice/__tests__/live-voice-continuation-fork-hydration.test.ts +286 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
- package/src/live-voice/__tests__/live-voice-vad.test.ts +1154 -636
- package/src/live-voice/front-decision.ts +5 -155
- package/src/live-voice/live-voice-metrics.ts +4 -1
- package/src/live-voice/live-voice-session.ts +1288 -439
- package/src/live-voice/progress-phrases.ts +17 -0
- package/src/live-voice/protocol.ts +15 -0
- package/src/media/app-icon-generator.ts +15 -8
- package/src/media/avatar-router.ts +9 -5
- package/src/media/image-credentials.ts +42 -10
- package/src/media/image-service.ts +1 -13
- package/src/media/types.ts +26 -3
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/__tests__/broadcaster.test.ts +95 -0
- package/src/notifications/adapters/macos.ts +3 -3
- package/src/notifications/broadcaster.ts +57 -0
- package/src/notifications/copy-composer.ts +0 -15
- package/src/notifications/decision-engine.ts +21 -22
- package/src/notifications/guardian-question-mode.ts +57 -2
- package/src/notifications/home-feed-side-effect.ts +4 -0
- package/src/notifications/signal.ts +6 -4
- package/src/notifications/trusted-contact-payloads.ts +3 -4
- package/src/notifications/vellum-card-affinity.ts +39 -0
- package/src/oauth/AGENTS.md +1 -1
- package/src/permissions/channel-permission-query.test.ts +69 -0
- package/src/permissions/channel-permission-query.ts +73 -1
- package/src/permissions/checker.test.ts +298 -15
- package/src/permissions/checker.ts +102 -36
- package/src/permissions/confirmation-guardian-request.test.ts +2 -2
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/gateway-threshold-reader.test.ts +224 -17
- package/src/permissions/gateway-threshold-reader.ts +82 -10
- package/src/permissions/ipc-risk-types.ts +8 -0
- package/src/permissions/prompter.ts +5 -5
- package/src/permissions/question-guardian-request.test.ts +222 -0
- package/src/permissions/question-guardian-request.ts +179 -0
- package/src/permissions/question-prompter.test.ts +8 -8
- package/src/permissions/question-prompter.ts +18 -0
- package/src/permissions/secret-prompter.ts +2 -4
- package/src/permissions/workspace-policy.ts +269 -34
- package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
- package/src/persistence/__tests__/message-content-file.test.ts +58 -3
- package/src/persistence/conversation-crud.ts +93 -0
- package/src/persistence/conversation-key-store.ts +63 -0
- package/src/persistence/conversation-parent.ts +27 -0
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-singleton.ts +14 -27
- package/src/persistence/delivery-crud.ts +45 -0
- package/src/persistence/embeddings/embedding-backend.ts +2 -1
- package/src/persistence/embeddings/embedding-identity.ts +7 -3
- package/src/persistence/job-utils.ts +32 -27
- package/src/persistence/jobs-store.ts +92 -3
- package/src/persistence/lifecycle-quiesce.ts +80 -0
- package/src/persistence/llm-usage-store.ts +45 -8
- package/src/persistence/message-content-file.ts +4 -4
- package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
- package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
- package/src/persistence/migrations/354-backfill-app-conversation-lineage.ts +41 -0
- package/src/persistence/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +9 -1
- package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
- package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
- package/src/plugin-api/conversation-turn.ts +4 -4
- package/src/plugin-api/event-hub-facade.ts +15 -6
- package/src/plugin-api/index.ts +10 -4
- package/src/plugin-api/publish-event.ts +36 -0
- package/src/plugins/AGENTS.md +2 -0
- package/src/plugins/defaults/compaction/window-manager.ts +9 -0
- package/src/plugins/defaults/index.ts +9 -13
- package/src/plugins/defaults/memory/AGENTS.md +775 -0
- package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
- package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
- package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
- package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
- package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
- package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
- package/src/plugins/defaults/memory/graph/store.ts +1 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
- package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
- package/src/plugins/defaults/memory/indexer.ts +146 -89
- package/src/plugins/defaults/memory/injectors.ts +86 -41
- package/src/plugins/defaults/memory/job-handlers.ts +130 -39
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
- package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
- package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
- package/src/plugins/defaults/memory/startup.ts +58 -21
- package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
- package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
- package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
- package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
- package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
- package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
- package/src/plugins/defaults/memory/tools.test.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/README.md +5 -0
- package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
- package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
- package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
- package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
- package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
- package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
- package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
- package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
- package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
- package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
- package/src/plugins/defaults/memory/v2/activation.ts +30 -163
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
- package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
- package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
- package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
- package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/injection.ts +36 -26
- package/src/plugins/defaults/memory/v2/migration.ts +2 -2
- package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
- package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
- package/src/plugins/defaults/memory/v2/router.ts +38 -15
- package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
- package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
- package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
- package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
- package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
- package/src/plugins/defaults/memory/v3/card.ts +25 -9
- package/src/plugins/defaults/memory/v3/edge.ts +52 -18
- package/src/plugins/defaults/memory/v3/gate.ts +4 -4
- package/src/plugins/defaults/memory/v3/injector.ts +10 -3
- package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
- package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
- package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
- package/src/plugins/defaults/memory/v3/prune.ts +40 -16
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
- package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
- package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
- package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
- package/src/plugins/defaults/memory/v3/types.ts +4 -1
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
- package/src/plugins/defaults/memory/validation.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -1
- package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
- package/src/plugins/types.ts +2 -2
- package/src/prompts/sections.ts +4 -16
- package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
- package/src/providers/anthropic/client.ts +15 -6
- package/src/providers/content-block-schema.ts +26 -0
- package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +30 -14
- package/src/providers/model-catalog.ts +77 -0
- package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
- package/src/providers/openai/chat-completions-provider.ts +65 -17
- package/src/providers/openai/input-audio.ts +76 -0
- package/src/providers/openrouter/client.ts +0 -2
- package/src/providers/platform-proxy/constants.ts +4 -0
- package/src/providers/poolside/client.ts +42 -0
- package/src/providers/registry.ts +40 -8
- package/src/providers/retry.ts +2 -0
- package/src/providers/types.ts +39 -1
- package/src/providers/vercel-ai-gateway/client.ts +0 -2
- package/src/runtime/AGENTS.md +7 -5
- package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
- package/src/runtime/__tests__/question-resolution.test.ts +111 -0
- package/src/runtime/access-request-helper.ts +7 -15
- package/src/runtime/assistant-event-hub.ts +43 -31
- package/src/runtime/assistant-event-publish-options.ts +31 -0
- package/src/runtime/assistant-event.ts +19 -30
- package/src/runtime/assistant-stream-state.ts +4 -4
- package/src/runtime/channel-approvals.ts +0 -25
- package/src/runtime/channel-readiness-service.ts +99 -40
- package/src/runtime/channel-retry-sweep.ts +38 -15
- package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
- package/src/runtime/guardian-reply-router.ts +108 -0
- package/src/runtime/http-server.ts +8 -0
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/process-role.ts +42 -0
- package/src/runtime/question-request-guardian-bridge.ts +184 -0
- package/src/runtime/question-resolution.ts +153 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/subagents-routes.test.ts +250 -0
- package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
- package/src/runtime/routes/acp-routes.ts +2 -2
- package/src/runtime/routes/bookmark-routes.ts +3 -15
- package/src/runtime/routes/canned-message-complete.ts +2 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -2
- package/src/runtime/routes/conversation-list-routes.ts +3 -19
- package/src/runtime/routes/conversation-management-routes.ts +1 -5
- package/src/runtime/routes/conversation-query-routes.ts +52 -8
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-request-routes.ts +0 -1
- package/src/runtime/routes/filing-routes.ts +7 -7
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
- package/src/runtime/routes/image-generation-routes.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +17 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
- package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
- package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/lifecycle-routes.ts +199 -0
- package/src/runtime/routes/platform-routes.ts +3 -8
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
- package/src/runtime/routes/question-routes.ts +34 -87
- package/src/runtime/routes/secret-routes.ts +11 -1
- package/src/runtime/routes/settings-routes.ts +8 -18
- package/src/runtime/routes/subagents-routes.ts +35 -8
- package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
- package/src/runtime/routes/webhook-routes.ts +89 -30
- package/src/runtime/routes/workspace-routes.test.ts +7 -4
- package/src/runtime/slack-reply-session.test.ts +12 -12
- package/src/runtime/slack-reply-session.ts +17 -17
- package/src/runtime/sync/sync-publisher.test.ts +7 -5
- package/src/runtime/tool-grant-request-helper.ts +4 -0
- package/src/schedule/schedule-store.ts +70 -0
- package/src/schedule/scheduler.ts +27 -0
- package/src/security/AGENTS.md +1 -1
- package/src/security/credential-key.ts +17 -0
- package/src/security/secret-ingress.ts +14 -105
- package/src/security/secret-patterns.ts +8 -139
- package/src/security/secret-scanner.ts +8 -3
- package/src/security/store-path-override.ts +6 -16
- package/src/sequence/store.ts +8 -0
- package/src/signals/emit-event.ts +5 -10
- package/src/signals/event-stream.ts +20 -10
- package/src/subagent/manager.ts +76 -25
- package/src/subagent/notify.ts +8 -0
- package/src/subagent/types.ts +13 -3
- package/src/telegram/__tests__/webhook-health.test.ts +442 -0
- package/src/telegram/webhook-health.ts +478 -0
- package/src/telemetry/AGENTS.md +6 -0
- package/src/telemetry/memory-corpus-size.test.ts +129 -0
- package/src/telemetry/memory-corpus-size.ts +184 -0
- package/src/telemetry/memory-tier-reporter.test.ts +67 -2
- package/src/telemetry/memory-tier-reporter.ts +30 -3
- package/src/tools/__tests__/conversation-group-tool-input-schemas.test.ts +61 -0
- package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
- package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
- package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
- package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
- package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
- package/src/tools/acp/abort.ts +21 -1
- package/src/tools/acp/context.ts +5 -5
- package/src/tools/acp/spawn.test.ts +15 -5
- package/src/tools/acp/spawn.ts +26 -3
- package/src/tools/acp/status.ts +20 -1
- package/src/tools/acp/steer.test.ts +20 -0
- package/src/tools/acp/steer.ts +23 -2
- package/src/tools/apps/resolve-app-id.ts +15 -3
- package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
- package/src/tools/ask-question/ask-question-tool.ts +68 -92
- package/src/tools/browser/browser-screencast.ts +6 -6
- package/src/tools/calls/call-end.ts +24 -3
- package/src/tools/calls/call-start.ts +35 -11
- package/src/tools/calls/call-status.ts +20 -1
- package/src/tools/conversation-groups/group_create.ts +63 -0
- package/src/tools/conversation-groups/group_list.ts +20 -0
- package/src/tools/conversation-groups/group_shared.ts +52 -0
- package/src/tools/conversation-groups/move_to_group.ts +106 -0
- package/src/tools/document/document-comment-tool.test.ts +49 -0
- package/src/tools/document/document-comment-tool.ts +45 -6
- package/src/tools/document/document-tool.ts +142 -24
- package/src/tools/executor.ts +27 -13
- package/src/tools/filesystem/edit.ts +62 -60
- package/src/tools/filesystem/list.ts +36 -29
- package/src/tools/filesystem/read.ts +56 -39
- package/src/tools/filesystem/write.ts +44 -38
- package/src/tools/followups/followup_create.ts +41 -12
- package/src/tools/followups/followup_list.ts +34 -6
- package/src/tools/followups/followup_resolve.ts +26 -4
- package/src/tools/host-filesystem/edit.ts +50 -60
- package/src/tools/host-filesystem/read.ts +45 -39
- package/src/tools/host-filesystem/write.ts +31 -36
- package/src/tools/host-terminal/host-shell.ts +76 -62
- package/src/tools/policy-context.ts +27 -10
- package/src/tools/schedule/create.ts +76 -33
- package/src/tools/schedule/delete.ts +21 -2
- package/src/tools/schedule/list.ts +25 -3
- package/src/tools/schedule/update.ts +105 -48
- package/src/tools/shared/filesystem/path-policy.ts +246 -40
- package/src/tools/shared/zod-tool-schema.ts +117 -0
- package/src/tools/subagent/abort.ts +12 -4
- package/src/tools/subagent/consult-deadline.ts +9 -3
- package/src/tools/subagent/message.ts +21 -5
- package/src/tools/subagent/notify-parent.ts +44 -23
- package/src/tools/subagent/read.ts +15 -4
- package/src/tools/subagent/resolve.ts +26 -4
- package/src/tools/subagent/spawn.ts +37 -13
- package/src/tools/subagent/status.ts +12 -4
- package/src/tools/system/request-permission.ts +35 -26
- package/src/tools/terminal/shell.ts +68 -55
- package/src/tools/tool-approval-handler.ts +327 -53
- package/src/tools/tool-input-schemas.ts +85 -0
- package/src/tools/tool-types.ts +7 -0
- package/src/tools/types.ts +8 -0
- package/src/tools/workflows/manage-workflows.ts +30 -2
- package/src/tools/workflows/run-workflow.test.ts +54 -2
- package/src/tools/workflows/run-workflow.ts +32 -4
- package/src/util/fs-symlinks.ts +30 -0
- package/src/util/log-redact.ts +7 -3
- package/src/util/platform.ts +15 -0
- package/src/vellum-assistant-namespace.d.ts +80 -0
- package/src/watcher/watcher-store.ts +8 -0
- package/src/workflows/leaf-runner.test.ts +104 -2
- package/src/workflows/leaf-runner.ts +31 -6
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
- package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
- package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
- package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
- package/src/workspace/migrations/registry.ts +4 -0
- package/tsconfig.plugin-api.json +1 -1
- package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
- package/src/__tests__/secret-patterns.test.ts +0 -27
- package/src/config/__tests__/proc-to-skills.test.ts +0 -21
- package/src/config/memory-tier.test.ts +0 -44
- package/src/daemon/message-types/acp.ts +0 -20
- package/src/daemon/message-types/apps.ts +0 -11
- package/src/daemon/message-types/background-tools.ts +0 -14
- package/src/daemon/message-types/bookmarks.ts +0 -13
- package/src/daemon/message-types/contacts.ts +0 -13
- package/src/daemon/message-types/document-comments.ts +0 -14
- package/src/daemon/message-types/documents.ts +0 -13
- package/src/daemon/message-types/home.ts +0 -15
- package/src/daemon/message-types/host-bash.ts +0 -12
- package/src/daemon/message-types/host-cu.ts +0 -10
- package/src/daemon/message-types/host-file.ts +0 -12
- package/src/daemon/message-types/host-transfer.ts +0 -12
- package/src/daemon/message-types/integrations.ts +0 -90
- package/src/daemon/message-types/memory.ts +0 -10
- package/src/daemon/message-types/schedules.ts +0 -14
- package/src/daemon/message-types/settings.ts +0 -17
- package/src/daemon/message-types/subagents.ts +0 -63
- package/src/daemon/message-types/upgrades.ts +0 -14
- package/src/daemon/message-types/workflows.ts +0 -25
- package/src/daemon/message-types/workspace.ts +0 -137
- package/src/live-voice/ack-phrases.ts +0 -58
- package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
- package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
- package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
- package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
isInteractiveInterface,
|
|
55
55
|
parseInterfaceId,
|
|
56
56
|
} from "../../../channels/types.js";
|
|
57
|
-
import {
|
|
57
|
+
import { isV3TierActive } from "../../../config/memory-v3-gate.js";
|
|
58
58
|
import type { AssistantConfig } from "../../../config/types.js";
|
|
59
59
|
import { getGuardianDelivery } from "../../../contacts/guardian-delivery-reader.js";
|
|
60
60
|
import { extractTurnContextTimestamp } from "../../../context/compactor.js";
|
|
@@ -97,6 +97,7 @@ import {
|
|
|
97
97
|
getRetrospectiveState,
|
|
98
98
|
upsertRetrospectiveState,
|
|
99
99
|
} from "./memory-retrospective-state.js";
|
|
100
|
+
import { effectiveSweepLookbackMs } from "./memory-retrospective-sweep.js";
|
|
100
101
|
|
|
101
102
|
const log = getLogger("memory-retrospective-job");
|
|
102
103
|
|
|
@@ -124,6 +125,7 @@ const MEMORY_RETROSPECTIVE_RUN_CHECK_NAME = "memory_retrospective_run";
|
|
|
124
125
|
export type MemoryRetrospectiveOutcome =
|
|
125
126
|
| { kind: "disabled" }
|
|
126
127
|
| { kind: "no_new_messages" }
|
|
128
|
+
| { kind: "source_dormant" }
|
|
127
129
|
| { kind: "source_processing" }
|
|
128
130
|
| { kind: "wake_failed"; reason?: string; conversationId?: string }
|
|
129
131
|
| {
|
|
@@ -170,7 +172,9 @@ export async function memoryRetrospectiveJob(
|
|
|
170
172
|
|
|
171
173
|
let outcome: MemoryRetrospectiveOutcome;
|
|
172
174
|
try {
|
|
173
|
-
outcome = await runForkBasedRetrospective(sourceConversationId, config
|
|
175
|
+
outcome = await runForkBasedRetrospective(sourceConversationId, config, {
|
|
176
|
+
enforceSweepLookback: true,
|
|
177
|
+
});
|
|
174
178
|
} catch (err) {
|
|
175
179
|
emitRunOutcome("error", err instanceof Error ? err.message : String(err));
|
|
176
180
|
throw err;
|
|
@@ -196,6 +200,16 @@ export async function memoryRetrospectiveJob(
|
|
|
196
200
|
export async function runForkBasedRetrospective(
|
|
197
201
|
sourceConversationId: string,
|
|
198
202
|
config: AssistantConfig,
|
|
203
|
+
opts?: {
|
|
204
|
+
/**
|
|
205
|
+
* Skip the run when the source's last message is older than
|
|
206
|
+
* `memory.retrospective.sweepLookbackMs`. The queue handler passes this so
|
|
207
|
+
* a stale pending backlog is completed as no-ops instead of run; the CLI's
|
|
208
|
+
* manual command omits it — an operator's explicit request overrides the
|
|
209
|
+
* window.
|
|
210
|
+
*/
|
|
211
|
+
enforceSweepLookback?: boolean;
|
|
212
|
+
},
|
|
199
213
|
): Promise<MemoryRetrospectiveOutcome> {
|
|
200
214
|
// Start stamp for the retrospective's end-to-end wall time, surfaced as
|
|
201
215
|
// `durationMs` on the "invoked" log (start → invoked).
|
|
@@ -209,6 +223,29 @@ export async function runForkBasedRetrospective(
|
|
|
209
223
|
return { kind: "no_new_messages" };
|
|
210
224
|
}
|
|
211
225
|
|
|
226
|
+
// Execution-time twin of the sweep's lookback window (see
|
|
227
|
+
// memory-retrospective-sweep.ts). Event triggers enqueue in response to a
|
|
228
|
+
// just-persisted message, so a legitimately-enqueued job's source sits
|
|
229
|
+
// inside the window when the job runs; a numeric stamp older than the
|
|
230
|
+
// window means the row is stale backlog, and running it would burn an
|
|
231
|
+
// inference pass on a conversation the sweep no longer considers stalled.
|
|
232
|
+
// A missing stamp is NOT dormancy here — the enqueue itself evidences
|
|
233
|
+
// activity, unlike the sweep's scan where the stamp is the only signal.
|
|
234
|
+
// Both state pointers stay untouched.
|
|
235
|
+
if (opts?.enforceSweepLookback === true) {
|
|
236
|
+
const lastMessageAt = sourceConversation.lastMessageAt;
|
|
237
|
+
if (
|
|
238
|
+
typeof lastMessageAt === "number" &&
|
|
239
|
+
startedAtMs - lastMessageAt > effectiveSweepLookbackMs(config)
|
|
240
|
+
) {
|
|
241
|
+
log.info(
|
|
242
|
+
{ sourceConversationId, lastMessageAt },
|
|
243
|
+
"memory-retrospective (fork): source dormant beyond the sweep lookback; skipping",
|
|
244
|
+
);
|
|
245
|
+
return { kind: "source_dormant" };
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
212
249
|
// Forking mid-turn would capture a half-finished display turn — incremental
|
|
213
250
|
// checkpoint persistence writes complete tool turns to the DB while the
|
|
214
251
|
// agent loop is still running. Check the persisted `processing_started_at`
|
|
@@ -335,7 +372,7 @@ export async function runForkBasedRetrospective(
|
|
|
335
372
|
}
|
|
336
373
|
const forkId = forkConversationRow.id;
|
|
337
374
|
|
|
338
|
-
const procToSkillsActive =
|
|
375
|
+
const procToSkillsActive = isV3TierActive(config);
|
|
339
376
|
const instruction = buildForkInstruction({
|
|
340
377
|
windowStartTimestamp,
|
|
341
378
|
windowAnchorKind: turnContextTimestamp ? "turn_context" : "created_at",
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
// (filtered in `EXCLUDED_SOURCES`).
|
|
28
28
|
//
|
|
29
29
|
// Cost discipline:
|
|
30
|
+
// - The scan is bounded to conversations whose last message falls inside
|
|
31
|
+
// `memory.retrospective.sweepLookbackMs`. A crash-orphaned turn is by
|
|
32
|
+
// definition recent, so a conversation dormant beyond the window is not
|
|
33
|
+
// stalled work — its unprocessed tail is an ordinary end-of-conversation
|
|
34
|
+
// remainder. Without this bound, the scan degenerates into a full-history
|
|
35
|
+
// backfill: nearly every conversation ever carries a tail past its final
|
|
36
|
+
// retrospective cursor, so a cold start would enqueue an inference pass
|
|
37
|
+
// per conversation across the entire history.
|
|
30
38
|
// - The per-conversation gate skips any conversation whose last retrospective
|
|
31
39
|
// attempt is newer than the sweep interval, so the sweep never competes
|
|
32
40
|
// with the responsive event triggers on active conversations — it only
|
|
@@ -35,11 +43,22 @@
|
|
|
35
43
|
// `upsertMemoryRetrospectiveJob` coalesces against any already-pending job,
|
|
36
44
|
// so a conversation already queued by an event trigger is never
|
|
37
45
|
// double-processed.
|
|
46
|
+
// - Enqueues are capped at `SWEEP_MAX_ENQUEUES_PER_PASS` per pass. Inside
|
|
47
|
+
// the lookback window, organic stalled work is a handful of conversations;
|
|
48
|
+
// a pass wanting more signals an anomalous backlog. Each pass re-scans
|
|
49
|
+
// from the start, so the deferred remainder is picked up by later passes.
|
|
50
|
+
// Sources with an already-pending retrospective job are skipped before
|
|
51
|
+
// the cap, so coalescing no-ops never consume it; a running job does not
|
|
52
|
+
// suppress the sweep (its cursor is a pre-run snapshot — a mid-run
|
|
53
|
+
// arrival needs a follow-up row behind it).
|
|
38
54
|
// - The scan is keyset-paginated in bounded batches with a yield between
|
|
39
55
|
// pages (mirrors `conversation-memory-orphan-sweep.ts`), so a large history
|
|
40
|
-
// never materializes all ids at once or holds the event loop.
|
|
41
|
-
//
|
|
42
|
-
//
|
|
56
|
+
// never materializes all ids at once or holds the event loop.
|
|
57
|
+
//
|
|
58
|
+
// The retrospective job re-applies the lookback window at execution time
|
|
59
|
+
// (`runForkBasedRetrospective`'s `enforceSweepLookback` gate), so pending rows
|
|
60
|
+
// that outlive the window — e.g. a backlog drained long after enqueue — are
|
|
61
|
+
// completed as no-ops instead of run.
|
|
43
62
|
|
|
44
63
|
import { and, asc, gt, ne, notInArray } from "drizzle-orm";
|
|
45
64
|
|
|
@@ -48,20 +67,32 @@ import { AUTO_ANALYSIS_SOURCE } from "../../../persistence/auto-analysis-constan
|
|
|
48
67
|
import { getConversationRecentProvenanceTrustClass } from "../../../persistence/conversation-crud.js";
|
|
49
68
|
import { getDb } from "../../../persistence/db-connection.js";
|
|
50
69
|
import type { MemoryJob } from "../../../persistence/jobs-store.js";
|
|
51
|
-
import {
|
|
70
|
+
import {
|
|
71
|
+
isMemoryEnabled,
|
|
72
|
+
listPendingMemoryRetrospectiveSourceConversationIds,
|
|
73
|
+
} from "../../../persistence/jobs-store.js";
|
|
52
74
|
import { conversations } from "../../../persistence/schema/index.js";
|
|
53
75
|
import { getLogger } from "./logging.js";
|
|
54
76
|
import { countRetrospectiveMessagesAfter } from "./memory-retrospective-accounting.js";
|
|
55
77
|
import { MEMORY_RETROSPECTIVE_SOURCES } from "./memory-retrospective-constants.js";
|
|
56
78
|
import { enqueueMemoryRetrospectiveIfEnabled } from "./memory-retrospective-enqueue.js";
|
|
57
79
|
import { getRetrospectiveState } from "./memory-retrospective-state.js";
|
|
58
|
-
import { MEMORY_V2_CONSOLIDATION_SOURCE } from "./
|
|
80
|
+
import { MEMORY_V2_CONSOLIDATION_SOURCE } from "./substrate/constants.js";
|
|
59
81
|
|
|
60
82
|
const log = getLogger("memory-retrospective-sweep");
|
|
61
83
|
|
|
62
84
|
/** Rows per keyset-paginated page — bounds each statement and the id set held. */
|
|
63
85
|
const SWEEP_BATCH = 200;
|
|
64
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Hard ceiling on retrospectives enqueued by a single sweep pass. Each
|
|
89
|
+
* enqueue fans out an LLM inference pass, so a pass that wants more than this
|
|
90
|
+
* many is anomalous (organic in-window stalled work is a handful of
|
|
91
|
+
* conversations at most) and gets clamped with a warning. Safe to defer: every
|
|
92
|
+
* pass re-scans from the start, so the remainder is enqueued by later passes.
|
|
93
|
+
*/
|
|
94
|
+
export const SWEEP_MAX_ENQUEUES_PER_PASS = 50;
|
|
95
|
+
|
|
65
96
|
/**
|
|
66
97
|
* Conversation `source` values excluded from the sweep up front:
|
|
67
98
|
* - retrospective background conversations — recursion guard (never run a
|
|
@@ -107,15 +138,44 @@ function breathe(): Promise<void> {
|
|
|
107
138
|
return Bun.sleep(0);
|
|
108
139
|
}
|
|
109
140
|
|
|
141
|
+
/**
|
|
142
|
+
* The lookback window the sweep actually applies: never smaller than TWICE
|
|
143
|
+
* `sweepIntervalMs`. One interval is not enough — the pass checkpoint is
|
|
144
|
+
* stamped at enqueue but the cutoff is computed at execution, so tick, queue,
|
|
145
|
+
* and runtime delay stretch the gap between consecutive executions past the
|
|
146
|
+
* nominal cadence, and a message landing in that skew right after a pass
|
|
147
|
+
* would sit permanently outside an exact-interval window. The doubled floor
|
|
148
|
+
* absorbs the skew while staying BOUNDED: deriving the window from elapsed
|
|
149
|
+
* time since the previous pass would cover arbitrary gaps, but after
|
|
150
|
+
* extended downtime it would recreate the cold-start backfill this window
|
|
151
|
+
* exists to prevent. Outages longer than a full interval can therefore still
|
|
152
|
+
* leave tails outside the window — accepted by design, like the cold start.
|
|
153
|
+
* Shared by the sweep scan and the retrospective job's execution-time gate;
|
|
154
|
+
* the two must agree or the gate would kill jobs the scan legitimately
|
|
155
|
+
* enqueued.
|
|
156
|
+
*/
|
|
157
|
+
export function effectiveSweepLookbackMs(config: AssistantConfig): number {
|
|
158
|
+
return Math.max(
|
|
159
|
+
config.memory.retrospective.sweepLookbackMs,
|
|
160
|
+
2 * config.memory.retrospective.sweepIntervalMs,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
110
164
|
/**
|
|
111
165
|
* One keyset page of sweep-eligible conversation ids past `cursor`. The empty
|
|
112
166
|
* string sorts before any real id, so the first page starts at the beginning.
|
|
113
167
|
* `scheduled`-type conversations are filtered here (low-yield, matching the
|
|
114
168
|
* enqueue guard); other low-yield cases are caught by the enqueue itself.
|
|
169
|
+
*
|
|
170
|
+
* `lastMessageAtCutoff` bounds the scan to the sweep's lookback window
|
|
171
|
+
* (indexed via `idx_conversations_last_message_at`). `gt` NULL semantics
|
|
172
|
+
* exclude rows with no recorded message stamp: absent any evidence of recent
|
|
173
|
+
* activity, a conversation is not sweepable.
|
|
115
174
|
*/
|
|
116
175
|
export function listSweepCandidateConversationIds(
|
|
117
176
|
cursor: string,
|
|
118
177
|
limit: number,
|
|
178
|
+
lastMessageAtCutoff: number,
|
|
119
179
|
): string[] {
|
|
120
180
|
return getDb()
|
|
121
181
|
.select({ id: conversations.id })
|
|
@@ -123,6 +183,7 @@ export function listSweepCandidateConversationIds(
|
|
|
123
183
|
.where(
|
|
124
184
|
and(
|
|
125
185
|
gt(conversations.id, cursor),
|
|
186
|
+
gt(conversations.lastMessageAt, lastMessageAtCutoff),
|
|
126
187
|
notInArray(conversations.source, EXCLUDED_SOURCES),
|
|
127
188
|
ne(conversations.conversationType, "scheduled"),
|
|
128
189
|
),
|
|
@@ -141,11 +202,12 @@ export interface RetrospectiveSweepResult {
|
|
|
141
202
|
}
|
|
142
203
|
|
|
143
204
|
/**
|
|
144
|
-
* Scan
|
|
145
|
-
* retrospective for any with unprocessed
|
|
146
|
-
* than `sweepIntervalMs
|
|
147
|
-
*
|
|
148
|
-
*
|
|
205
|
+
* Scan sweep-eligible conversations with activity inside the lookback window
|
|
206
|
+
* and enqueue a `sweep`-triggered retrospective for any with unprocessed
|
|
207
|
+
* messages whose last attempt is older than `sweepIntervalMs`, up to
|
|
208
|
+
* {@link SWEEP_MAX_ENQUEUES_PER_PASS} per pass. Idempotent and best-effort:
|
|
209
|
+
* enqueue coalescing prevents duplicates, and the scan degrades to a no-op
|
|
210
|
+
* when memory is disabled.
|
|
149
211
|
*/
|
|
150
212
|
export async function runRetrospectiveSweep(
|
|
151
213
|
config: AssistantConfig,
|
|
@@ -155,12 +217,20 @@ export async function runRetrospectiveSweep(
|
|
|
155
217
|
return { scanned: 0, enqueued: 0 };
|
|
156
218
|
}
|
|
157
219
|
const sweepIntervalMs = config.memory.retrospective.sweepIntervalMs;
|
|
220
|
+
const lookbackCutoff = now - effectiveSweepLookbackMs(config);
|
|
221
|
+
const pendingSourceIds = new Set(
|
|
222
|
+
listPendingMemoryRetrospectiveSourceConversationIds(),
|
|
223
|
+
);
|
|
158
224
|
|
|
159
225
|
let scanned = 0;
|
|
160
226
|
let enqueued = 0;
|
|
161
227
|
let cursor = "";
|
|
162
228
|
for (;;) {
|
|
163
|
-
const page = listSweepCandidateConversationIds(
|
|
229
|
+
const page = listSweepCandidateConversationIds(
|
|
230
|
+
cursor,
|
|
231
|
+
SWEEP_BATCH,
|
|
232
|
+
lookbackCutoff,
|
|
233
|
+
);
|
|
164
234
|
if (page.length === 0) {
|
|
165
235
|
break;
|
|
166
236
|
}
|
|
@@ -169,6 +239,17 @@ export async function runRetrospectiveSweep(
|
|
|
169
239
|
for (const conversationId of page) {
|
|
170
240
|
scanned += 1;
|
|
171
241
|
|
|
242
|
+
// A source with a pending row has nothing for the sweep to add — the
|
|
243
|
+
// row runs on its own. Skipping it up front keeps coalescing upserts
|
|
244
|
+
// from consuming the per-pass enqueue cap: counted no-ops would starve
|
|
245
|
+
// conversations later in id order across passes (every pass restarts
|
|
246
|
+
// from the lowest id). A RUNNING job does not suppress the sweep — its
|
|
247
|
+
// cursor is a pre-run snapshot, so a mid-run arrival needs a follow-up
|
|
248
|
+
// row, and the upsert's pending-only coalescing creates exactly that.
|
|
249
|
+
if (pendingSourceIds.has(conversationId)) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
|
|
172
253
|
// Memory trust boundary: never enqueue a retrospective (which runs under
|
|
173
254
|
// guardian trust with `remember`) for a conversation whose actor isn't
|
|
174
255
|
// memory-trusted. This is the sweep's equivalent of the per-message
|
|
@@ -198,6 +279,13 @@ export async function runRetrospectiveSweep(
|
|
|
198
279
|
|
|
199
280
|
enqueueMemoryRetrospectiveIfEnabled({ conversationId, trigger: "sweep" });
|
|
200
281
|
enqueued += 1;
|
|
282
|
+
if (enqueued >= SWEEP_MAX_ENQUEUES_PER_PASS) {
|
|
283
|
+
log.warn(
|
|
284
|
+
{ scanned, enqueued },
|
|
285
|
+
"Memory retrospective sweep hit the per-pass enqueue cap; deferring the remainder to the next pass",
|
|
286
|
+
);
|
|
287
|
+
return { scanned, enqueued };
|
|
288
|
+
}
|
|
201
289
|
}
|
|
202
290
|
|
|
203
291
|
await breathe();
|
|
@@ -14,8 +14,8 @@ import { join } from "node:path";
|
|
|
14
14
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
15
15
|
|
|
16
16
|
import type { RouteDefinition } from "../../../../../runtime/routes/types.js";
|
|
17
|
-
import { writePage } from "../../
|
|
18
|
-
import type { ConceptPage } from "../../
|
|
17
|
+
import { writePage } from "../../substrate/page-store.js";
|
|
18
|
+
import type { ConceptPage } from "../../substrate/types.js";
|
|
19
19
|
import type { MemoryV2ListConceptPagesResult } from "../memory-v2-routes.js";
|
|
20
20
|
import { ROUTES } from "../memory-v2-routes.js";
|
|
21
21
|
|
|
@@ -26,7 +26,9 @@ let origWorkspaceDir: string | undefined;
|
|
|
26
26
|
|
|
27
27
|
function findHandler(operationId: string): RouteDefinition["handler"] {
|
|
28
28
|
const route = ROUTES.find((r) => r.operationId === operationId);
|
|
29
|
-
if (!route)
|
|
29
|
+
if (!route) {
|
|
30
|
+
throw new Error(`Route ${operationId} not found`);
|
|
31
|
+
}
|
|
30
32
|
return route.handler;
|
|
31
33
|
}
|
|
32
34
|
|
|
@@ -32,7 +32,7 @@ import type { ToolDefinition } from "../../llm-helpers.js";
|
|
|
32
32
|
// ---------------------------------------------------------------------------
|
|
33
33
|
|
|
34
34
|
// Skill store: empty by default so the page index only contains test pages.
|
|
35
|
-
mock.module("../../
|
|
35
|
+
mock.module("../../substrate/skill-store.js", () => ({
|
|
36
36
|
SKILL_SLUG_PREFIX: "skills/",
|
|
37
37
|
listSkillEntries: () => [],
|
|
38
38
|
seedV2SkillEntries: async () => undefined,
|
|
@@ -118,9 +118,8 @@ mock.module("../../../../../util/platform.js", () => ({
|
|
|
118
118
|
// ---------------------------------------------------------------------------
|
|
119
119
|
|
|
120
120
|
const { handleSimulateRouter } = await import("../memory-v2-routes.js");
|
|
121
|
-
const { writePage } = await import("../../
|
|
122
|
-
const { invalidatePageIndex } =
|
|
123
|
-
await import("../../v3/substrate/page-index.js");
|
|
121
|
+
const { writePage } = await import("../../substrate/page-store.js");
|
|
122
|
+
const { invalidatePageIndex } = await import("../../substrate/page-index.js");
|
|
124
123
|
|
|
125
124
|
// ---------------------------------------------------------------------------
|
|
126
125
|
// Helpers
|
|
@@ -61,7 +61,8 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
61
61
|
{
|
|
62
62
|
name: "id",
|
|
63
63
|
schema: { type: "string" },
|
|
64
|
-
description:
|
|
64
|
+
description:
|
|
65
|
+
"Node id from the graph payload (memory-v3: the concept-page slug).",
|
|
65
66
|
},
|
|
66
67
|
],
|
|
67
68
|
responseBody: MemoryGraphNodeDetailSchema,
|
|
@@ -68,7 +68,7 @@ mock.module(
|
|
|
68
68
|
// stats test seed synthetic (modifiedAt: 0) rows and assert they're excluded.
|
|
69
69
|
let mockSkillEntries: Array<{ id: string; content: string }> = [];
|
|
70
70
|
|
|
71
|
-
mock.module("../
|
|
71
|
+
mock.module("../substrate/skill-store.js", () => ({
|
|
72
72
|
SKILL_SLUG_PREFIX: "skills/",
|
|
73
73
|
listSkillEntries: () => mockSkillEntries,
|
|
74
74
|
}));
|
|
@@ -92,9 +92,9 @@ import {
|
|
|
92
92
|
} from "../../../../runtime/routes/errors.js";
|
|
93
93
|
import type { RouteDefinition } from "../../../../runtime/routes/types.js";
|
|
94
94
|
import { readPendingBufferEntries } from "../graph-topology/pending-buffer.js";
|
|
95
|
-
import { invalidatePageIndex } from "../
|
|
96
|
-
import { writePage } from "../
|
|
97
|
-
import type { ConceptPage } from "../
|
|
95
|
+
import { invalidatePageIndex } from "../substrate/page-index.js";
|
|
96
|
+
import { writePage } from "../substrate/page-store.js";
|
|
97
|
+
import type { ConceptPage } from "../substrate/types.js";
|
|
98
98
|
import { ROUTES } from "./memory-item-routes.js";
|
|
99
99
|
|
|
100
100
|
// ---------------------------------------------------------------------------
|
|
@@ -105,7 +105,9 @@ function getRoute(endpoint: string, method: string): RouteDefinition {
|
|
|
105
105
|
const route = ROUTES.find(
|
|
106
106
|
(r: RouteDefinition) => r.endpoint === endpoint && r.method === method,
|
|
107
107
|
);
|
|
108
|
-
if (!route)
|
|
108
|
+
if (!route) {
|
|
109
|
+
throw new Error(`No route: ${method} ${endpoint}`);
|
|
110
|
+
}
|
|
109
111
|
return route;
|
|
110
112
|
}
|
|
111
113
|
|
|
@@ -33,7 +33,7 @@ import { z } from "zod";
|
|
|
33
33
|
|
|
34
34
|
import { getConfig } from "../../../../config/loader.js";
|
|
35
35
|
import {
|
|
36
|
-
|
|
36
|
+
isV3TierActive,
|
|
37
37
|
usesConceptPageMemory,
|
|
38
38
|
} from "../../../../config/memory-v3-gate.js";
|
|
39
39
|
import type { AssistantConfig } from "../../../../config/types.js";
|
|
@@ -81,7 +81,8 @@ import { consolidationBackoffRemainingMs } from "../jobs-worker.js";
|
|
|
81
81
|
import { getLogger } from "../logging.js";
|
|
82
82
|
import { memoryDbOrNull } from "../memory-db.js";
|
|
83
83
|
import { getWorkspaceDir } from "../paths.js";
|
|
84
|
-
import { getPageIndex } from "../
|
|
84
|
+
import { getPageIndex } from "../substrate/page-index.js";
|
|
85
|
+
import { resolveSubstrateTuning } from "../substrate/tuning.js";
|
|
85
86
|
|
|
86
87
|
const log = getLogger("memory-item-routes");
|
|
87
88
|
|
|
@@ -211,13 +212,19 @@ async function searchNodesSemantic(
|
|
|
211
212
|
// search (the caller's `null` branch) instead of querying the v1
|
|
212
213
|
// collection, which is in active retirement and a corrupted sparse
|
|
213
214
|
// segment can OOM-crash the shared Qdrant process.
|
|
214
|
-
if (usesConceptPageMemory(config.memory))
|
|
215
|
+
if (usesConceptPageMemory(config.memory)) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
215
218
|
const backendStatus = await getMemoryBackendStatus(config);
|
|
216
|
-
if (!backendStatus.provider)
|
|
219
|
+
if (!backendStatus.provider) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
217
222
|
|
|
218
223
|
const embedded = await embedWithBackend(config, [query]);
|
|
219
224
|
const queryVector = embedded.vectors[0];
|
|
220
|
-
if (!queryVector)
|
|
225
|
+
if (!queryVector) {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
221
228
|
|
|
222
229
|
const sparse = generateSparseEmbedding(query);
|
|
223
230
|
const sparseVector = { indices: sparse.indices, values: sparse.values };
|
|
@@ -320,7 +327,9 @@ async function handleListMemoryItems(queryParams: Record<string, string>) {
|
|
|
320
327
|
}
|
|
321
328
|
|
|
322
329
|
const db = memoryDbOrNull("listMemoryItems");
|
|
323
|
-
if (!db)
|
|
330
|
+
if (!db) {
|
|
331
|
+
throw new Error("memory database unavailable");
|
|
332
|
+
}
|
|
324
333
|
|
|
325
334
|
// Build fidelity filter based on status param
|
|
326
335
|
const fidelityFilter =
|
|
@@ -343,7 +352,9 @@ async function handleListMemoryItems(queryParams: Record<string, string>) {
|
|
|
343
352
|
const kindCountConditions = [
|
|
344
353
|
inArray(memoryGraphNodes.id, semanticResult.ids),
|
|
345
354
|
];
|
|
346
|
-
if (fidelityFilter)
|
|
355
|
+
if (fidelityFilter) {
|
|
356
|
+
kindCountConditions.push(fidelityFilter);
|
|
357
|
+
}
|
|
347
358
|
|
|
348
359
|
const kindCountRows = db
|
|
349
360
|
.select({ kind: memoryGraphNodes.type, count: count() })
|
|
@@ -365,7 +376,9 @@ async function handleListMemoryItems(queryParams: Record<string, string>) {
|
|
|
365
376
|
if (kindParam) {
|
|
366
377
|
filterConditions.push(eq(memoryGraphNodes.type, kindParam));
|
|
367
378
|
}
|
|
368
|
-
if (fidelityFilter)
|
|
379
|
+
if (fidelityFilter) {
|
|
380
|
+
filterConditions.push(fidelityFilter);
|
|
381
|
+
}
|
|
369
382
|
|
|
370
383
|
if (filterConditions.length > 1) {
|
|
371
384
|
const validIdSet = new Set(
|
|
@@ -393,9 +406,12 @@ async function handleListMemoryItems(queryParams: Record<string, string>) {
|
|
|
393
406
|
|
|
394
407
|
// Hydrate nodes from DB
|
|
395
408
|
const hydrationConditions = [inArray(memoryGraphNodes.id, pageIds)];
|
|
396
|
-
if (fidelityFilter)
|
|
397
|
-
|
|
409
|
+
if (fidelityFilter) {
|
|
410
|
+
hydrationConditions.push(fidelityFilter);
|
|
411
|
+
}
|
|
412
|
+
if (kindParam) {
|
|
398
413
|
hydrationConditions.push(eq(memoryGraphNodes.type, kindParam));
|
|
414
|
+
}
|
|
399
415
|
|
|
400
416
|
const rows = db
|
|
401
417
|
.select()
|
|
@@ -419,7 +435,9 @@ async function handleListMemoryItems(queryParams: Record<string, string>) {
|
|
|
419
435
|
|
|
420
436
|
// ── Kind counts for SQL path ───────────────────────────────────────
|
|
421
437
|
const kindCountConditions = [];
|
|
422
|
-
if (fidelityFilter)
|
|
438
|
+
if (fidelityFilter) {
|
|
439
|
+
kindCountConditions.push(fidelityFilter);
|
|
440
|
+
}
|
|
423
441
|
if (searchParam) {
|
|
424
442
|
kindCountConditions.push(
|
|
425
443
|
like(memoryGraphNodes.content, `%${searchParam}%`),
|
|
@@ -441,8 +459,12 @@ async function handleListMemoryItems(queryParams: Record<string, string>) {
|
|
|
441
459
|
|
|
442
460
|
// ── SQL path (default or fallback) ──────────────────────────────────
|
|
443
461
|
const conditions = [];
|
|
444
|
-
if (fidelityFilter)
|
|
445
|
-
|
|
462
|
+
if (fidelityFilter) {
|
|
463
|
+
conditions.push(fidelityFilter);
|
|
464
|
+
}
|
|
465
|
+
if (kindParam) {
|
|
466
|
+
conditions.push(eq(memoryGraphNodes.type, kindParam));
|
|
467
|
+
}
|
|
446
468
|
if (searchParam) {
|
|
447
469
|
conditions.push(like(memoryGraphNodes.content, `%${searchParam}%`));
|
|
448
470
|
}
|
|
@@ -497,7 +519,7 @@ function handleGetMemoryItem(id: string) {
|
|
|
497
519
|
* concept graph is deliberately kept off identity-page load.
|
|
498
520
|
*
|
|
499
521
|
* `graph_supported` reports whether the memory-concept graph is available for
|
|
500
|
-
* this assistant — the same `
|
|
522
|
+
* this assistant — the same `isV3TierActive` condition under which
|
|
501
523
|
* `GET /memory-graph` returns `supported: true` (memory enabled + v3 live). It
|
|
502
524
|
* is a cheap config read (no page I/O), so glanceable surfaces can gate the
|
|
503
525
|
* graph entry point on real availability without triggering the graph build.
|
|
@@ -507,7 +529,7 @@ async function handleGetMemoryStats(
|
|
|
507
529
|
): Promise<{ concepts: number; graph_supported: boolean }> {
|
|
508
530
|
const pageIndex = await getPageIndex(getWorkspaceDir());
|
|
509
531
|
const concepts = pageIndex.entries.filter((e) => e.modifiedAt > 0).length;
|
|
510
|
-
return { concepts, graph_supported:
|
|
532
|
+
return { concepts, graph_supported: isV3TierActive(config) };
|
|
511
533
|
}
|
|
512
534
|
|
|
513
535
|
async function handleCreateMemoryItem(body: Record<string, unknown>) {
|
|
@@ -538,7 +560,9 @@ async function handleCreateMemoryItem(body: Record<string, unknown>) {
|
|
|
538
560
|
|
|
539
561
|
// Check for duplicate content
|
|
540
562
|
const db = memoryDbOrNull("createMemoryItem");
|
|
541
|
-
if (!db)
|
|
563
|
+
if (!db) {
|
|
564
|
+
throw new Error("memory database unavailable");
|
|
565
|
+
}
|
|
542
566
|
const existing = db
|
|
543
567
|
.select({ id: memoryGraphNodes.id })
|
|
544
568
|
.from(memoryGraphNodes)
|
|
@@ -658,7 +682,9 @@ async function handleUpdateMemoryItem(
|
|
|
658
682
|
if (contentChanged || reactivating) {
|
|
659
683
|
const contentToCheck = changes.content ?? existing.content;
|
|
660
684
|
const db = memoryDbOrNull("updateMemoryItem");
|
|
661
|
-
if (!db)
|
|
685
|
+
if (!db) {
|
|
686
|
+
throw new Error("memory database unavailable");
|
|
687
|
+
}
|
|
662
688
|
const collision = db
|
|
663
689
|
.select({ id: memoryGraphNodes.id })
|
|
664
690
|
.from(memoryGraphNodes)
|
|
@@ -705,14 +731,20 @@ async function handleUpdateMemoryItem(
|
|
|
705
731
|
*/
|
|
706
732
|
function maybeEnqueueConsolidationForCreate(config: AssistantConfig): void {
|
|
707
733
|
try {
|
|
708
|
-
|
|
734
|
+
// `usesConceptPageMemory` already covers the memory-off case (an explicit
|
|
735
|
+
// `memory.enabled === false` makes it false), so a second
|
|
736
|
+
// `isMemoryEnabled()` clause would be unreachable.
|
|
737
|
+
if (!usesConceptPageMemory(config.memory)) {
|
|
709
738
|
return;
|
|
710
739
|
}
|
|
711
740
|
if (hasActiveJobOfType("memory_v2_consolidate")) {
|
|
712
741
|
return;
|
|
713
742
|
}
|
|
714
743
|
const intervalMs =
|
|
715
|
-
config.memory.
|
|
744
|
+
resolveSubstrateTuning(config.memory).consolidation_interval_hours *
|
|
745
|
+
60 *
|
|
746
|
+
60 *
|
|
747
|
+
1000;
|
|
716
748
|
if (consolidationBackoffRemainingMs(intervalMs, Date.now()) > 0) {
|
|
717
749
|
return;
|
|
718
750
|
}
|
|
@@ -21,11 +21,25 @@ import { RouteError } from "../../../../runtime/routes/errors.js";
|
|
|
21
21
|
import type { RouteDefinition } from "../../../../runtime/routes/types.js";
|
|
22
22
|
import type { RouteHandlerArgs } from "../../../../runtime/routes/types.js";
|
|
23
23
|
import { getLogger } from "../logging.js";
|
|
24
|
+
import { getWorkspaceDir } from "../paths.js";
|
|
25
|
+
import {
|
|
26
|
+
getEdgeIndex,
|
|
27
|
+
totalEdgeCount,
|
|
28
|
+
validateEdgeTargets,
|
|
29
|
+
} from "../substrate/edge-index.js";
|
|
30
|
+
import { getPageIndex } from "../substrate/page-index.js";
|
|
31
|
+
import {
|
|
32
|
+
getConceptsDir,
|
|
33
|
+
listPages,
|
|
34
|
+
readPage,
|
|
35
|
+
renderPageContent,
|
|
36
|
+
} from "../substrate/page-store.js";
|
|
37
|
+
import { seedV2SkillEntries } from "../substrate/skill-store.js";
|
|
38
|
+
import { resolveSubstrateTuning } from "../substrate/tuning.js";
|
|
24
39
|
import {
|
|
25
40
|
type ConceptFrequencyResponse,
|
|
26
41
|
getConceptFrequencySummary,
|
|
27
|
-
} from "../
|
|
28
|
-
import { getWorkspaceDir } from "../paths.js";
|
|
42
|
+
} from "../v2/concept-frequency.js";
|
|
29
43
|
import { runComparisonOverHistory } from "../v2/harness/compare.js";
|
|
30
44
|
import type { Retriever } from "../v2/harness/retriever.js";
|
|
31
45
|
import { createRouterRetriever } from "../v2/harness/router-retriever.js";
|
|
@@ -34,19 +48,6 @@ import { computeInjectionScores } from "../v2/injection-events.js";
|
|
|
34
48
|
import { loadNowText } from "../v2/now-text.js";
|
|
35
49
|
import { ROUTER_PROMPT } from "../v2/prompts/router.js";
|
|
36
50
|
import { type RouterSource, runRouter } from "../v2/router.js";
|
|
37
|
-
import {
|
|
38
|
-
getEdgeIndex,
|
|
39
|
-
totalEdgeCount,
|
|
40
|
-
validateEdgeTargets,
|
|
41
|
-
} from "../v3/substrate/edge-index.js";
|
|
42
|
-
import { getPageIndex } from "../v3/substrate/page-index.js";
|
|
43
|
-
import {
|
|
44
|
-
getConceptsDir,
|
|
45
|
-
listPages,
|
|
46
|
-
readPage,
|
|
47
|
-
renderPageContent,
|
|
48
|
-
} from "../v3/substrate/page-store.js";
|
|
49
|
-
import { seedV2SkillEntries } from "../v3/substrate/skill-store.js";
|
|
50
51
|
|
|
51
52
|
const log = getLogger("memory-v2-routes");
|
|
52
53
|
|
|
@@ -133,7 +134,9 @@ async function handleValidate({
|
|
|
133
134
|
MemoryV2ValidateParams.parse(body);
|
|
134
135
|
|
|
135
136
|
const workspaceDir = getWorkspaceDir();
|
|
136
|
-
const maxPageChars =
|
|
137
|
+
const maxPageChars = resolveSubstrateTuning(
|
|
138
|
+
loadConfig().memory,
|
|
139
|
+
).max_page_chars;
|
|
137
140
|
|
|
138
141
|
const slugs = await listPages(workspaceDir);
|
|
139
142
|
const knownSlugs = new Set<string>();
|
|
@@ -143,7 +146,9 @@ async function handleValidate({
|
|
|
143
146
|
for (const slug of slugs) {
|
|
144
147
|
try {
|
|
145
148
|
const page = await readPage(workspaceDir, slug);
|
|
146
|
-
if (!page)
|
|
149
|
+
if (!page) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
147
152
|
knownSlugs.add(slug);
|
|
148
153
|
const chars = page.body.length;
|
|
149
154
|
if (chars > maxPageChars) {
|
|
@@ -242,7 +247,9 @@ async function handleListConceptPages({
|
|
|
242
247
|
slugs.map(async (slug) => {
|
|
243
248
|
try {
|
|
244
249
|
const page = await readPage(workspaceDir, slug);
|
|
245
|
-
if (!page)
|
|
250
|
+
if (!page) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
246
253
|
const stats = await stat(join(conceptsDir, `${slug}.md`));
|
|
247
254
|
return {
|
|
248
255
|
slug,
|
|
@@ -346,7 +353,9 @@ async function handleEmaScores({
|
|
|
346
353
|
modifiedAt: entry.modifiedAt,
|
|
347
354
|
}));
|
|
348
355
|
entries.sort((a, b) => {
|
|
349
|
-
if (a.score !== b.score)
|
|
356
|
+
if (a.score !== b.score) {
|
|
357
|
+
return b.score - a.score;
|
|
358
|
+
}
|
|
350
359
|
return a.slug < b.slug ? -1 : a.slug > b.slug ? 1 : 0;
|
|
351
360
|
});
|
|
352
361
|
return { entries };
|
|
@@ -455,7 +464,9 @@ function applySimulateOverrides(
|
|
|
455
464
|
live: AssistantConfig,
|
|
456
465
|
overrides: z.infer<typeof SimulateRouterOverridesSchema> | undefined,
|
|
457
466
|
): AssistantConfig {
|
|
458
|
-
if (!overrides)
|
|
467
|
+
if (!overrides) {
|
|
468
|
+
return live;
|
|
469
|
+
}
|
|
459
470
|
const liveRouter = live.memory.v2.router;
|
|
460
471
|
const mergedRouter = {
|
|
461
472
|
...liveRouter,
|