@vellumai/assistant 0.8.3 → 0.8.5
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 +2 -2
- package/docker-entrypoint.sh +0 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +1492 -100
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +302 -33
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
- package/src/__tests__/audit-log-rotation.test.ts +70 -16
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
- package/src/__tests__/btw-routes.test.ts +2 -3
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-guardian.test.ts +3 -3
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +2 -1
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
- package/src/__tests__/computer-use-tools.test.ts +2 -4
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
- package/src/__tests__/conversation-agent-loop.test.ts +188 -129
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +31 -0
- package/src/__tests__/conversation-fork-crud.test.ts +324 -0
- package/src/__tests__/conversation-lifecycle.test.ts +53 -12
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-security-invariants.test.ts +7 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/gateway-flag-listener.test.ts +237 -0
- package/src/__tests__/gemini-provider.test.ts +78 -0
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +7 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +161 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/mcp-abort-signal.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/model-intents.test.ts +2 -4
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +151 -0
- package/src/__tests__/openai-responses-provider.test.ts +118 -16
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -5
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/registry.test.ts +2 -8
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
- package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +161 -124
- package/src/__tests__/terminal-tools.test.ts +12 -2
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
- package/src/__tests__/tool-executor.test.ts +89 -53
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +94 -10
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +1 -1
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +65 -20
- package/src/api/README.md +5 -0
- package/src/api/index.ts +4 -0
- package/src/api/package.json +10 -0
- package/src/background-wake/background-wake-routes.test.ts +233 -0
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +483 -0
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/program.ts +2 -0
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +24 -12
- package/src/config/call-site-defaults.ts +20 -0
- package/src/config/feature-flag-registry.json +115 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
- package/src/config/schemas/call-site-catalog.ts +35 -0
- package/src/config/schemas/llm.ts +14 -0
- package/src/config/schemas/memory-v2.ts +294 -1
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +60 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
- package/src/daemon/conversation-agent-loop.ts +307 -88
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +149 -118
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +145 -84
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +70 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +54 -32
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +2 -0
- package/src/daemon/handlers/conversations.ts +90 -3
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +5 -5
- package/src/daemon/host-file-proxy.ts +5 -5
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +11 -11
- package/src/daemon/lifecycle.ts +40 -23
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +14 -9
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +66 -7
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +52 -0
- package/src/daemon/tool-setup-types.ts +13 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +85 -0
- package/src/home/suggested-prompts.ts +168 -9
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/registries.ts +8 -12
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +191 -100
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-init.ts +26 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +68 -15
- package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
- package/src/memory/llm-request-log-source-local.ts +7 -0
- package/src/memory/llm-request-log-source.ts +9 -2
- package/src/memory/llm-request-log-store.ts +43 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +11 -3
- package/src/memory/memory-retrospective-job.ts +413 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +41 -14
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/index.ts +34 -0
- package/src/memory/migrations/registry.ts +58 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +22 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +158 -112
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +660 -4
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +124 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +224 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +106 -0
- package/src/memory/v2/harness/trace.ts +58 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +42 -25
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +369 -62
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +563 -0
- package/src/memory/v3/__tests__/filter.test.ts +512 -0
- package/src/memory/v3/__tests__/gate.test.ts +574 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
- package/src/memory/v3/__tests__/loop.test.ts +530 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +440 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +469 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
- package/src/memory/v3/__tests__/validate.test.ts +245 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +249 -0
- package/src/memory/v3/filter.ts +281 -0
- package/src/memory/v3/gate.ts +334 -0
- package/src/memory/v3/index-composition.ts +113 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +382 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +420 -0
- package/src/memory/v3/shadow-middleware.ts +305 -0
- package/src/memory/v3/traversal.ts +206 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +351 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +300 -0
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +38 -50
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +8 -5
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +6 -3
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +100 -20
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +11 -16
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +69 -19
- package/src/prompts/system-prompt.ts +118 -216
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +10 -2
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +281 -9
- package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +159 -66
- package/src/providers/call-site-routing.ts +14 -2
- package/src/providers/connection-model-compat.ts +38 -0
- package/src/providers/connection-resolution.ts +16 -2
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/gemini/client.ts +49 -6
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +18 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +91 -1
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +63 -23
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +86 -23
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/provider-send-message.ts +7 -1
- package/src/providers/retry.ts +34 -3
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +152 -56
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +43 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -6
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +50 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +188 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +147 -2
- package/src/runtime/routes/conversation-list-routes.ts +12 -4
- package/src/runtime/routes/conversation-management-routes.ts +77 -20
- package/src/runtime/routes/conversation-query-routes.ts +196 -31
- package/src/runtime/routes/conversation-routes.ts +472 -425
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +24 -8
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +17 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +20 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +427 -0
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +188 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +2 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
- package/src/tools/browser/browser-execution.ts +106 -0
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
- package/src/tools/browser/cdp-client/factory.ts +171 -4
- package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
- package/src/tools/browser/cdp-client/types.ts +101 -0
- package/src/tools/browser/pinned-tabs.ts +146 -0
- package/src/tools/computer-use/definitions.ts +22 -78
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +187 -2
- package/src/tools/execution-target.ts +21 -23
- package/src/tools/executor.ts +6 -1
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -8
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +216 -73
- package/src/tools/network/web-search.ts +216 -98
- package/src/tools/registry.ts +7 -23
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -8
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +31 -98
- package/src/tools/ui-surface/definitions.ts +9 -23
- package/src/types/onboarding-context.ts +4 -0
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -7
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/prompts/cache-boundary.ts +0 -8
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text rendering for `assistant memory v3 validate` and `... tree`.
|
|
3
|
+
*
|
|
4
|
+
* Both functions are pure presentation: they take the daemon route's response
|
|
5
|
+
* shape and return a terminal-ready string. They live CLI-side (mirroring
|
|
6
|
+
* `memory-v2-compare-render.ts`) and import only the response *types* from the
|
|
7
|
+
* daemon route — `cli/no-daemon-internals` permits type-only imports but
|
|
8
|
+
* forbids pulling in daemon runtime modules.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {
|
|
12
|
+
DescentPass,
|
|
13
|
+
LlmCallRecord,
|
|
14
|
+
MemoryV3SimulateResult,
|
|
15
|
+
MemoryV3TreeResult,
|
|
16
|
+
MemoryV3ValidateResult,
|
|
17
|
+
} from "../../runtime/routes/memory-v3-routes.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Render a {@link MemoryV3ValidateResult} into a counts summary plus the
|
|
21
|
+
* offending ids for each non-empty category. Categories with zero entries
|
|
22
|
+
* print `none` so a clean tree reads at a glance.
|
|
23
|
+
*/
|
|
24
|
+
export function renderValidationReport(report: MemoryV3ValidateResult): string {
|
|
25
|
+
const lines: string[] = [
|
|
26
|
+
"Memory v3 Tree Validation",
|
|
27
|
+
"=========================",
|
|
28
|
+
`Dangling child refs: ${report.danglingChildRefCount || "none"}`,
|
|
29
|
+
];
|
|
30
|
+
for (const d of report.danglingChildRefs) {
|
|
31
|
+
lines.push(` - ${d.node} → ${d.kind}:${d.ref}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
lines.push(`Orphan pages: ${report.orphanPageCount || "none"}`);
|
|
35
|
+
for (const slug of report.orphanPages) {
|
|
36
|
+
lines.push(` - ${slug}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
lines.push(`Cycles: ${report.cycleCount || "none"}`);
|
|
40
|
+
for (const c of report.cycles) {
|
|
41
|
+
lines.push(` - ${c.from} → ${c.to}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
lines.push(`Stale index: ${report.staleIndexCount || "none"}`);
|
|
45
|
+
for (const s of report.staleIndex) {
|
|
46
|
+
lines.push(` - ${s.node} (older than child ${s.child})`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
lines.push(
|
|
50
|
+
`Unknown edge targets: ${report.unknownEdgeTargetCount || "none"}`,
|
|
51
|
+
);
|
|
52
|
+
for (const e of report.unknownEdgeTargets) {
|
|
53
|
+
lines.push(` - ${e.from} → ${e.to}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return lines.join("\n");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Whether the validation report has any defect in any category. The CLI uses
|
|
61
|
+
* this to set a non-zero exit code so `validate` is scriptable as a check.
|
|
62
|
+
*/
|
|
63
|
+
export function reportHasDefects(report: MemoryV3ValidateResult): boolean {
|
|
64
|
+
return (
|
|
65
|
+
report.danglingChildRefCount > 0 ||
|
|
66
|
+
report.orphanPageCount > 0 ||
|
|
67
|
+
report.cycleCount > 0 ||
|
|
68
|
+
report.staleIndexCount > 0 ||
|
|
69
|
+
report.unknownEdgeTargetCount > 0
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Render a {@link MemoryV3TreeResult} as an indented tree rooted at `view.root`,
|
|
75
|
+
* descending `node:` children depth-first. A node reached more than once
|
|
76
|
+
* (shared DAG sub-node) is printed once with a `(↑ …)` re-entry marker rather
|
|
77
|
+
* than re-expanded, which also bounds output when the structure contains a
|
|
78
|
+
* cycle. `page:` children are printed as leaves under their parent node.
|
|
79
|
+
*/
|
|
80
|
+
export function renderTree(view: MemoryV3TreeResult): string {
|
|
81
|
+
const childrenById = new Map<string, MemoryV3TreeResult["nodes"][number]>();
|
|
82
|
+
for (const node of view.nodes) {
|
|
83
|
+
childrenById.set(node.id, node);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const lines: string[] = [];
|
|
87
|
+
const expanded = new Set<string>();
|
|
88
|
+
|
|
89
|
+
const walk = (nodeId: string, depth: number): void => {
|
|
90
|
+
const indent = " ".repeat(depth);
|
|
91
|
+
const node = childrenById.get(nodeId);
|
|
92
|
+
|
|
93
|
+
if (!node) {
|
|
94
|
+
lines.push(`${indent}node:${nodeId} (missing)`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (expanded.has(nodeId)) {
|
|
99
|
+
// Shared DAG sub-node (or a cycle's back-edge): print the reference but
|
|
100
|
+
// do not re-expand, so output stays finite and the re-entry is visible.
|
|
101
|
+
lines.push(`${indent}node:${nodeId} (↑ already shown)`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
expanded.add(nodeId);
|
|
105
|
+
lines.push(`${indent}node:${nodeId}`);
|
|
106
|
+
|
|
107
|
+
for (const child of node.children) {
|
|
108
|
+
if (child.kind === "page") {
|
|
109
|
+
lines.push(`${" ".repeat(depth + 1)}page:${child.ref}`);
|
|
110
|
+
} else {
|
|
111
|
+
walk(child.ref, depth + 1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
walk(view.root, 0);
|
|
117
|
+
|
|
118
|
+
if (lines.length === 0) {
|
|
119
|
+
lines.push("(empty tree)");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Surface nodes that exist on disk but were never reached from the root —
|
|
123
|
+
// they would otherwise be invisible in a root-anchored print.
|
|
124
|
+
const unreached = view.nodes
|
|
125
|
+
.map((n) => n.id)
|
|
126
|
+
.filter((id) => !expanded.has(id))
|
|
127
|
+
.sort();
|
|
128
|
+
if (unreached.length > 0) {
|
|
129
|
+
lines.push("", `Unreachable nodes (${unreached.length}):`);
|
|
130
|
+
for (const id of unreached) {
|
|
131
|
+
lines.push(` - node:${id}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return lines.join("\n");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Canonical print order for the loop's provenance lanes. */
|
|
139
|
+
const SIMULATE_LANE_ORDER = ["hot", "sparse", "dense", "tree", "edge"] as const;
|
|
140
|
+
|
|
141
|
+
/** Render the effective lane toggles as a one-line `on` / restricted summary. */
|
|
142
|
+
function renderEffectiveLanes(
|
|
143
|
+
lanes: MemoryV3SimulateResult["effectiveConfig"]["lanes"],
|
|
144
|
+
): string {
|
|
145
|
+
const on = Object.entries(lanes)
|
|
146
|
+
.filter(([, enabled]) => enabled)
|
|
147
|
+
.map(([name]) => name);
|
|
148
|
+
const off = Object.entries(lanes)
|
|
149
|
+
.filter(([, enabled]) => !enabled)
|
|
150
|
+
.map(([name]) => name);
|
|
151
|
+
if (off.length === 0) return on.join(", ");
|
|
152
|
+
return `${on.join(", ")} (off: ${off.join(", ")})`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Render one pass's scout / tree / edge / gate breakdown into `lines`. */
|
|
156
|
+
function renderPass(pass: DescentPass, lines: string[]): void {
|
|
157
|
+
lines.push(`Pass ${pass.passNumber}`);
|
|
158
|
+
|
|
159
|
+
if (pass.scouts && pass.scouts.length > 0) {
|
|
160
|
+
const summary = pass.scouts
|
|
161
|
+
.map((s) => `${s.lane}=${s.slugs.length}`)
|
|
162
|
+
.join(" ");
|
|
163
|
+
lines.push(` scouts: ${summary}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (pass.treeLevels && pass.treeLevels.length > 0) {
|
|
167
|
+
lines.push(` tree: ${pass.treeLevels.length} level(s)`);
|
|
168
|
+
for (const level of pass.treeLevels) {
|
|
169
|
+
const node = level.node === "" ? "[root]" : level.node;
|
|
170
|
+
lines.push(
|
|
171
|
+
` ${node}: considered ${level.considered.length}, descended ${level.descended.length}, skipped ${level.skipped.length}`,
|
|
172
|
+
);
|
|
173
|
+
if (level.descended.length > 0) {
|
|
174
|
+
lines.push(` → ${level.descended.join(", ")}`);
|
|
175
|
+
}
|
|
176
|
+
if (level.reasoning.trim().length > 0) {
|
|
177
|
+
lines.push(` reason: ${level.reasoning.trim()}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (pass.edgeExpansions && pass.edgeExpansions.length > 0) {
|
|
183
|
+
const pulled = pass.edgeExpansions.reduce((n, e) => n + e.pulled.length, 0);
|
|
184
|
+
lines.push(
|
|
185
|
+
` edges: ${pass.edgeExpansions.length} seed(s) expanded, ${pulled} pulled`,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (pass.gate) {
|
|
190
|
+
lines.push(` gate: ${pass.gate.decision}`);
|
|
191
|
+
for (const q of pass.gate.questions ?? []) {
|
|
192
|
+
lines.push(` ? ${q}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Render a {@link MemoryV3SimulateResult} into a query echo, effective config,
|
|
199
|
+
* per-pass descent breakdown, and the final selection grouped by provenance
|
|
200
|
+
* lane (in fanout order). Mirrors the grouped layout of `memory v2 simulate`.
|
|
201
|
+
*/
|
|
202
|
+
export function renderSimulation(result: MemoryV3SimulateResult): string {
|
|
203
|
+
const lines: string[] = [
|
|
204
|
+
"Memory v3 Retrieval Simulation",
|
|
205
|
+
"==============================",
|
|
206
|
+
`Query: ${JSON.stringify(result.query)}`,
|
|
207
|
+
"",
|
|
208
|
+
"Config (effective):",
|
|
209
|
+
` passCap: ${result.effectiveConfig.passCap}`,
|
|
210
|
+
` lanes: ${renderEffectiveLanes(result.effectiveConfig.lanes)}`,
|
|
211
|
+
"",
|
|
212
|
+
];
|
|
213
|
+
|
|
214
|
+
const passes = result.trace.passes;
|
|
215
|
+
lines.push(`Passes: ${passes.length || "none"}`);
|
|
216
|
+
for (const pass of passes) {
|
|
217
|
+
lines.push("");
|
|
218
|
+
renderPass(pass, lines);
|
|
219
|
+
}
|
|
220
|
+
lines.push("");
|
|
221
|
+
|
|
222
|
+
lines.push(`Selected: ${result.selectedSlugs.length} page(s)`);
|
|
223
|
+
const grouped = new Map<string, string[]>();
|
|
224
|
+
for (const slug of result.selectedSlugs) {
|
|
225
|
+
const lane = result.sourceBySlug[slug] ?? "unknown";
|
|
226
|
+
const bucket = grouped.get(lane) ?? [];
|
|
227
|
+
bucket.push(slug);
|
|
228
|
+
grouped.set(lane, bucket);
|
|
229
|
+
}
|
|
230
|
+
const laneRank = (lane: string): number => {
|
|
231
|
+
const i = SIMULATE_LANE_ORDER.indexOf(
|
|
232
|
+
lane as (typeof SIMULATE_LANE_ORDER)[number],
|
|
233
|
+
);
|
|
234
|
+
return i === -1 ? SIMULATE_LANE_ORDER.length : i;
|
|
235
|
+
};
|
|
236
|
+
const lanes = [...grouped.keys()].sort((a, b) => laneRank(a) - laneRank(b));
|
|
237
|
+
for (const lane of lanes) {
|
|
238
|
+
const slugs = grouped.get(lane)!;
|
|
239
|
+
lines.push(` ${lane} (${slugs.length})`);
|
|
240
|
+
for (const slug of slugs) {
|
|
241
|
+
lines.push(` - ${slug}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (result.cost.ms !== undefined) {
|
|
246
|
+
lines.push("", `Cost: ${result.cost.ms} ms`);
|
|
247
|
+
}
|
|
248
|
+
if (result.failureReason) {
|
|
249
|
+
lines.push(`Failure: ${result.failureReason}`);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return lines.join("\n");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ── LLM-call capture ────────────────────────────────────────────────────────
|
|
256
|
+
|
|
257
|
+
type CapturedMessage = LlmCallRecord["request"]["messages"][number];
|
|
258
|
+
type CapturedBlock = LlmCallRecord["response"]["content"][number];
|
|
259
|
+
|
|
260
|
+
/** Concatenate the text blocks of a message (non-text blocks are ignored). */
|
|
261
|
+
function messageText(message: CapturedMessage): string {
|
|
262
|
+
return message.content
|
|
263
|
+
.filter(
|
|
264
|
+
(b): b is Extract<CapturedBlock, { type: "text" }> => b.type === "text",
|
|
265
|
+
)
|
|
266
|
+
.map((b) => b.text)
|
|
267
|
+
.join("\n");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** The forced-tool block from a response, if the model returned one. */
|
|
271
|
+
function toolUseOf(
|
|
272
|
+
call: LlmCallRecord,
|
|
273
|
+
): Extract<CapturedBlock, { type: "tool_use" }> | undefined {
|
|
274
|
+
return call.response.content.find(
|
|
275
|
+
(b): b is Extract<CapturedBlock, { type: "tool_use" }> =>
|
|
276
|
+
b.type === "tool_use",
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function truncate(s: string, max: number): string {
|
|
281
|
+
const oneLine = s.replace(/\s+/g, " ").trim();
|
|
282
|
+
return oneLine.length > max ? `${oneLine.slice(0, max - 1)}…` : oneLine;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function indent(s: string, by = " "): string {
|
|
286
|
+
return s
|
|
287
|
+
.split("\n")
|
|
288
|
+
.map((line) => by + line)
|
|
289
|
+
.join("\n");
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Render the captured v3 LLM calls. Compact (default): one line per call —
|
|
294
|
+
* pass/lane/node, input size, round-trip ms, and the forced-tool summary. Full
|
|
295
|
+
* (`--show-llm`): the system prompt, every message, the tool names, and the
|
|
296
|
+
* tool_use input for each call. Grouped in call order (which is pass order).
|
|
297
|
+
*/
|
|
298
|
+
export function renderLlmCalls(
|
|
299
|
+
calls: readonly LlmCallRecord[],
|
|
300
|
+
opts: { full: boolean },
|
|
301
|
+
): string {
|
|
302
|
+
if (calls.length === 0) return "LLM calls: none";
|
|
303
|
+
|
|
304
|
+
const lines: string[] = [`LLM calls (${calls.length}):`];
|
|
305
|
+
for (const call of calls) {
|
|
306
|
+
const label =
|
|
307
|
+
`pass${call.pass} · ${call.lane}` +
|
|
308
|
+
(call.node ? ` · node=${call.node}` : "");
|
|
309
|
+
const inputChars =
|
|
310
|
+
call.request.systemPrompt.length +
|
|
311
|
+
call.request.messages.reduce((n, m) => n + messageText(m).length, 0);
|
|
312
|
+
const tool = toolUseOf(call);
|
|
313
|
+
const toolSummary = tool
|
|
314
|
+
? `${tool.name}(${truncate(JSON.stringify(tool.input), 80)})`
|
|
315
|
+
: `no tool_use (stop=${call.response.stopReason})`;
|
|
316
|
+
|
|
317
|
+
if (!opts.full) {
|
|
318
|
+
lines.push(
|
|
319
|
+
` ${label} · in ${inputChars}c · ${call.ms}ms · ${truncate(toolSummary, 100)}`,
|
|
320
|
+
);
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
lines.push("", `── ${label} (${call.callSite}, ${call.ms}ms) ──`);
|
|
325
|
+
lines.push("system:", indent(call.request.systemPrompt));
|
|
326
|
+
lines.push("messages:");
|
|
327
|
+
for (const message of call.request.messages) {
|
|
328
|
+
lines.push(
|
|
329
|
+
indent(`[${message.role}]`),
|
|
330
|
+
indent(messageText(message), " "),
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
lines.push(`tools: ${call.request.tools.map((t) => t.name).join(", ")}`);
|
|
334
|
+
lines.push("output:");
|
|
335
|
+
lines.push(
|
|
336
|
+
indent(
|
|
337
|
+
tool
|
|
338
|
+
? `${tool.name} ${JSON.stringify(tool.input, null, 2)}`
|
|
339
|
+
: `(no tool_use, stop=${call.response.stopReason})`,
|
|
340
|
+
),
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
return lines.join("\n");
|
|
344
|
+
}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `assistant memory v3` CLI subgroup.
|
|
3
|
+
*
|
|
4
|
+
* Operator-facing read-only inspection of the v3 memory tree — the DAG overlay
|
|
5
|
+
* the v2 → v3 data-migration hand-authors over the flat concept pages.
|
|
6
|
+
*
|
|
7
|
+
* Subcommands:
|
|
8
|
+
*
|
|
9
|
+
* - `validate` — print a structural health report (dangling refs, orphan
|
|
10
|
+
* pages, cycles, stale indexes, unknown edge targets). Exits non-zero when
|
|
11
|
+
* any defect is found so it is scriptable as a check.
|
|
12
|
+
* - `tree` — print the tree as an indented outline rooted at the tree root,
|
|
13
|
+
* marking shared-DAG re-entries.
|
|
14
|
+
* - `simulate` — dry-run the v3 retrieval loop against an ad-hoc query and
|
|
15
|
+
* print the per-pass descent trace plus the lane-grouped selection.
|
|
16
|
+
*
|
|
17
|
+
* All are read-only: they mutate nothing. `validate`/`tree` run no LLM;
|
|
18
|
+
* `simulate` invokes the loop (filter + gate LLM calls) but persists nothing.
|
|
19
|
+
* `--json` emits the raw daemon payload for any subcommand.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
|
|
25
|
+
import type { Command } from "commander";
|
|
26
|
+
|
|
27
|
+
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
28
|
+
import type {
|
|
29
|
+
MemoryV3SimulateResult,
|
|
30
|
+
MemoryV3TreeResult,
|
|
31
|
+
MemoryV3ValidateResult,
|
|
32
|
+
} from "../../runtime/routes/memory-v3-routes.js";
|
|
33
|
+
import { registerCommand } from "../lib/register-command.js";
|
|
34
|
+
import { log } from "../logger.js";
|
|
35
|
+
import {
|
|
36
|
+
renderLlmCalls,
|
|
37
|
+
renderSimulation,
|
|
38
|
+
renderTree,
|
|
39
|
+
renderValidationReport,
|
|
40
|
+
reportHasDefects,
|
|
41
|
+
} from "./memory-v3-render.js";
|
|
42
|
+
|
|
43
|
+
/** Valid lane names accepted by `--lanes` (matches memory.v3.lanes keys). */
|
|
44
|
+
const V3_LANE_NAMES = ["hot", "sparse", "dense", "tree", "edges"] as const;
|
|
45
|
+
|
|
46
|
+
export function registerMemoryV3Command(program: Command): void {
|
|
47
|
+
// Reuse an existing `memory` parent if a sibling registrar (e.g. v2)
|
|
48
|
+
// attached it first; otherwise create one. Keeps registration order between
|
|
49
|
+
// sibling memory registrars unconstrained.
|
|
50
|
+
const memory =
|
|
51
|
+
program.commands.find((c) => c.name() === "memory") ??
|
|
52
|
+
program
|
|
53
|
+
.command("memory")
|
|
54
|
+
.description("Manage the memory subsystem (concept-page model)");
|
|
55
|
+
|
|
56
|
+
registerCommand(memory, {
|
|
57
|
+
name: "v3",
|
|
58
|
+
transport: "ipc",
|
|
59
|
+
description: "Memory v3 subsystem operations (tree-DAG overlay)",
|
|
60
|
+
build: (v3) => {
|
|
61
|
+
v3.addHelpText(
|
|
62
|
+
"after",
|
|
63
|
+
`
|
|
64
|
+
The v3 memory subsystem layers a hand-authored DAG of tree nodes over the
|
|
65
|
+
flat v2 concept pages. Each node lives under /workspace/memory/tree/ and
|
|
66
|
+
its frontmatter 'children' list references sub-nodes (node:<id>) and leaf
|
|
67
|
+
concept pages (page:<slug>). The structure is authored by the v2 → v3
|
|
68
|
+
data-migration, so these subcommands are read-only inspection only — they
|
|
69
|
+
mutate nothing and run no LLM.
|
|
70
|
+
|
|
71
|
+
Examples:
|
|
72
|
+
$ assistant memory v3 validate
|
|
73
|
+
$ assistant memory v3 tree
|
|
74
|
+
$ assistant memory v3 tree --json | jq '.nodes | length'
|
|
75
|
+
$ assistant memory v3 simulate -q "what should we ship next"`,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// ── validate ──────────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
v3.command("validate")
|
|
81
|
+
.description(
|
|
82
|
+
"Print a structural health report of the v3 tree (read-only)",
|
|
83
|
+
)
|
|
84
|
+
.option("--json", "Emit raw JSON instead of a formatted report")
|
|
85
|
+
.addHelpText(
|
|
86
|
+
"after",
|
|
87
|
+
`
|
|
88
|
+
Walks the hand-authored v3 tree DAG and reports:
|
|
89
|
+
- Dangling child refs (node:/page: targets that do not exist)
|
|
90
|
+
- Orphan pages (concept pages not reachable from the tree root)
|
|
91
|
+
- Cycles (back-edges in the node:/node: adjacency)
|
|
92
|
+
- Stale indexes (a node older than a child it composes)
|
|
93
|
+
- Unknown edge targets (page edges: pointing at a missing slug)
|
|
94
|
+
|
|
95
|
+
Read-only — mutates nothing. Exits non-zero if any defect is reported, so it
|
|
96
|
+
is usable as a pre-flight check while the v2 → v3 migration is in flight.
|
|
97
|
+
|
|
98
|
+
Examples:
|
|
99
|
+
$ assistant memory v3 validate
|
|
100
|
+
$ assistant memory v3 validate --json | jq '.orphanPageCount'`,
|
|
101
|
+
)
|
|
102
|
+
.action(async (opts: { json?: boolean }) => {
|
|
103
|
+
const result = await cliIpcCall<MemoryV3ValidateResult>(
|
|
104
|
+
"memory_v3_validate",
|
|
105
|
+
{ body: {} },
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (!result.ok) {
|
|
109
|
+
log.error(result.error ?? "Failed to validate memory v3 tree");
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const report = result.result!;
|
|
115
|
+
|
|
116
|
+
if (opts.json === true) {
|
|
117
|
+
log.info(JSON.stringify(report, null, 2));
|
|
118
|
+
} else {
|
|
119
|
+
log.info(renderValidationReport(report));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (reportHasDefects(report)) {
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// ── tree ──────────────────────────────────────────────────────────────
|
|
128
|
+
|
|
129
|
+
v3.command("tree")
|
|
130
|
+
.description(
|
|
131
|
+
"Print the v3 tree as an indented outline from the root (read-only)",
|
|
132
|
+
)
|
|
133
|
+
.option("--json", "Emit raw JSON instead of a formatted tree")
|
|
134
|
+
.addHelpText(
|
|
135
|
+
"after",
|
|
136
|
+
`
|
|
137
|
+
Descends the v3 tree depth-first from its root node, printing one line per
|
|
138
|
+
node:/page: ref with indentation by depth. A node reached more than once
|
|
139
|
+
(shared DAG sub-node or a cycle back-edge) is printed once with a re-entry
|
|
140
|
+
marker rather than re-expanded, so output is finite. Nodes that exist on disk
|
|
141
|
+
but are unreachable from the root are listed separately.
|
|
142
|
+
|
|
143
|
+
Read-only — mutates nothing.
|
|
144
|
+
|
|
145
|
+
Examples:
|
|
146
|
+
$ assistant memory v3 tree
|
|
147
|
+
$ assistant memory v3 tree --json | jq '.root'`,
|
|
148
|
+
)
|
|
149
|
+
.action(async (opts: { json?: boolean }) => {
|
|
150
|
+
const result = await cliIpcCall<MemoryV3TreeResult>(
|
|
151
|
+
"memory_v3_tree",
|
|
152
|
+
{
|
|
153
|
+
body: {},
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
if (!result.ok) {
|
|
158
|
+
log.error(result.error ?? "Failed to read memory v3 tree");
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const view = result.result!;
|
|
164
|
+
|
|
165
|
+
if (opts.json === true) {
|
|
166
|
+
log.info(JSON.stringify(view, null, 2));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
log.info(renderTree(view));
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// ── simulate ────────────────────────────────────────────────────────────
|
|
174
|
+
|
|
175
|
+
v3.command("simulate")
|
|
176
|
+
.description(
|
|
177
|
+
"Dry-run the v3 retrieval loop against an ad-hoc query (read-only)",
|
|
178
|
+
)
|
|
179
|
+
.requiredOption(
|
|
180
|
+
"-q, --query <text>",
|
|
181
|
+
"User query to run a single synthetic retrieval turn against",
|
|
182
|
+
)
|
|
183
|
+
.option(
|
|
184
|
+
"--pass-cap <n>",
|
|
185
|
+
"Override memory.v3.passCap for this run (positive integer)",
|
|
186
|
+
)
|
|
187
|
+
.option(
|
|
188
|
+
"--lanes <list>",
|
|
189
|
+
`Restrict to a comma-separated allowlist of lanes (others off): ${V3_LANE_NAMES.join(", ")}`,
|
|
190
|
+
)
|
|
191
|
+
.option("--json", "Emit raw JSON instead of a formatted report")
|
|
192
|
+
.option(
|
|
193
|
+
"--show-llm",
|
|
194
|
+
"Print the full input + output of every v3 LLM call (filter / descender / gate)",
|
|
195
|
+
)
|
|
196
|
+
.option(
|
|
197
|
+
"--dump-llm <dir>",
|
|
198
|
+
"Write one JSON file per v3 LLM call into <dir> (full request + raw response)",
|
|
199
|
+
)
|
|
200
|
+
.addHelpText(
|
|
201
|
+
"after",
|
|
202
|
+
`
|
|
203
|
+
Runs the v3 multi-lane bounded-descent loop read-only against the live page
|
|
204
|
+
index + tree DAG, building a single synthetic turn from the query plus the live
|
|
205
|
+
NOW context. Prints the per-pass descent trace (scouts / tree levels / edge
|
|
206
|
+
expansions / gate verdict) and the final selection grouped by provenance lane.
|
|
207
|
+
|
|
208
|
+
The loop is invoked directly — it does NOT require memory.v3.enabled or
|
|
209
|
+
memory.v3.shadow, so you can probe v3 retrieval before the flags flip. Writes
|
|
210
|
+
nothing (co-activation persistence is forced off), but each pass still spends
|
|
211
|
+
the loop's dense-filter + gate LLM calls, so pass-cap is the cost knob.
|
|
212
|
+
|
|
213
|
+
Examples:
|
|
214
|
+
$ assistant memory v3 simulate -q "what should we ship next"
|
|
215
|
+
$ assistant memory v3 simulate -q "..." --lanes tree,edges
|
|
216
|
+
$ assistant memory v3 simulate -q "..." --pass-cap 1 --json | jq '.selectedSlugs'
|
|
217
|
+
$ assistant memory v3 simulate -q "..." --show-llm
|
|
218
|
+
$ assistant memory v3 simulate -q "..." --dump-llm /tmp/v3-calls`,
|
|
219
|
+
)
|
|
220
|
+
.action(
|
|
221
|
+
async (opts: {
|
|
222
|
+
query: string;
|
|
223
|
+
passCap?: string;
|
|
224
|
+
lanes?: string;
|
|
225
|
+
json?: boolean;
|
|
226
|
+
showLlm?: boolean;
|
|
227
|
+
dumpLlm?: string;
|
|
228
|
+
}) => {
|
|
229
|
+
let passCap: number | undefined;
|
|
230
|
+
if (opts.passCap !== undefined) {
|
|
231
|
+
const parsed = Number(opts.passCap);
|
|
232
|
+
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
233
|
+
log.error(
|
|
234
|
+
`--pass-cap must be a positive integer (got "${opts.passCap}")`,
|
|
235
|
+
);
|
|
236
|
+
process.exitCode = 1;
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
passCap = parsed;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
let lanes: string[] | undefined;
|
|
243
|
+
if (opts.lanes !== undefined) {
|
|
244
|
+
const requested = opts.lanes
|
|
245
|
+
.split(",")
|
|
246
|
+
.map((s) => s.trim())
|
|
247
|
+
.filter((s) => s.length > 0);
|
|
248
|
+
const invalid = requested.filter(
|
|
249
|
+
(l) =>
|
|
250
|
+
!V3_LANE_NAMES.includes(l as (typeof V3_LANE_NAMES)[number]),
|
|
251
|
+
);
|
|
252
|
+
if (invalid.length > 0) {
|
|
253
|
+
log.error(
|
|
254
|
+
`--lanes contains unknown lane(s): ${invalid.join(", ")}. Valid: ${V3_LANE_NAMES.join(", ")}`,
|
|
255
|
+
);
|
|
256
|
+
process.exitCode = 1;
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (requested.length === 0) {
|
|
260
|
+
log.error("--lanes must list at least one lane");
|
|
261
|
+
process.exitCode = 1;
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
lanes = requested;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const result = await cliIpcCall<MemoryV3SimulateResult>(
|
|
268
|
+
"memory_v3_simulate",
|
|
269
|
+
{
|
|
270
|
+
body: {
|
|
271
|
+
query: opts.query,
|
|
272
|
+
...(passCap !== undefined ? { passCap } : {}),
|
|
273
|
+
...(lanes !== undefined ? { lanes } : {}),
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
if (!result.ok) {
|
|
279
|
+
log.error(result.error ?? "Failed to simulate v3 retrieval");
|
|
280
|
+
process.exitCode = 1;
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const payload = result.result!;
|
|
285
|
+
if (opts.json === true) {
|
|
286
|
+
log.info(JSON.stringify(payload, null, 2));
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
log.info(renderSimulation(payload));
|
|
290
|
+
|
|
291
|
+
log.info("");
|
|
292
|
+
log.info(
|
|
293
|
+
renderLlmCalls(payload.llmCalls, { full: opts.showLlm === true }),
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
if (opts.dumpLlm !== undefined) {
|
|
297
|
+
mkdirSync(opts.dumpLlm, { recursive: true });
|
|
298
|
+
for (const call of payload.llmCalls) {
|
|
299
|
+
const nodePart = call.node
|
|
300
|
+
? `-${call.node.replace(/\//g, "_")}`
|
|
301
|
+
: "";
|
|
302
|
+
const file = join(
|
|
303
|
+
opts.dumpLlm,
|
|
304
|
+
`pass${call.pass}-${call.lane}${nodePart}.json`,
|
|
305
|
+
);
|
|
306
|
+
writeFileSync(file, JSON.stringify(call, null, 2));
|
|
307
|
+
}
|
|
308
|
+
log.info(
|
|
309
|
+
`\nWrote ${payload.llmCalls.length} LLM-call file(s) to ${opts.dumpLlm}`,
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
);
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
}
|