@vellumai/assistant 0.8.4 → 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/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/openapi.yaml +809 -11
- package/package.json +1 -1
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- 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 +3 -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-guardian.test.ts +3 -3
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -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__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +197 -2
- package/src/__tests__/conversation-agent-loop.test.ts +163 -122
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- 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 +178 -15
- package/src/__tests__/conversation-lifecycle.test.ts +52 -11
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +13 -13
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
- 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-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -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 +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- 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__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- 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 +77 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- 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__/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 +46 -0
- package/src/__tests__/openai-responses-provider.test.ts +114 -12
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- 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__/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__/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__/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 +145 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- 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 +9 -62
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- 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__/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__/workspace-git-service.test.ts +6 -5
- 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/loop.ts +8 -0
- 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/runtime-registry.ts +24 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- 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 +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/domain.ts +91 -41
- 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 +176 -1
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/document-editor/SKILL.md +11 -2
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.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/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-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +7 -6
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +213 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/llm.ts +12 -1
- package/src/config/schemas/memory-v2.ts +246 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +52 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -13
- package/src/daemon/conversation-agent-loop.ts +126 -76
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-runtime-assembly.ts +10 -9
- package/src/daemon/conversation-tool-setup.ts +63 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +14 -29
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +23 -20
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-types/conversations.ts +6 -9
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +6 -14
- package/src/daemon/message-types/sync.ts +14 -0
- 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/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -1
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +0 -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__/memory-retrospective-job.test.ts +7 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +71 -70
- 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 +10 -0
- package/src/memory/db-maintenance.ts +30 -21
- 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 +55 -22
- 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-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +15 -6
- 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 +17 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +1 -1
- package/src/memory/schema/infrastructure.ts +21 -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.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- 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.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- 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/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/emit-signal.ts +29 -49
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- 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 +18 -11
- 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__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +50 -185
- package/src/prompts/templates/BOOTSTRAP.md +2 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- 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 +32 -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/gemini/client.ts +49 -6
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +43 -0
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +6 -3
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +78 -21
- 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/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +36 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +106 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +25 -6
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -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/conversation-cli-routes.ts +1 -1
- 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 +142 -36
- package/src/runtime/routes/conversation-routes.ts +252 -410
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- 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/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/index.ts +8 -0
- 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/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- 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 +5 -4
- package/src/runtime/routes/workspace-routes.ts +25 -10
- 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/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 +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- 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-tool.ts +59 -0
- 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/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +25 -32
- 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/shell.ts +3 -9
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +27 -98
- package/src/tools/ui-surface/definitions.ts +6 -22
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +2 -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/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory v3 — tree-walk model driver.
|
|
3
|
+
*
|
|
4
|
+
* The *intelligence* half of the v3 tree descent. `traversal.ts` owns the
|
|
5
|
+
* mechanical, provider-free walk (`walkTree`); this module supplies the
|
|
6
|
+
* per-node `descend` decision that walk injects, and wires the whole thing into
|
|
7
|
+
* a single `runTreeWalk` entry point.
|
|
8
|
+
*
|
|
9
|
+
* Per visited node the driver makes one cheap LLM call (`memoryV3Descent`) over
|
|
10
|
+
* the node's *composed* index — `composeNodeIndex` renders one line per child
|
|
11
|
+
* (sub-node summary or leaf page summary) plus the node's routing hints — and
|
|
12
|
+
* asks two things: which child *nodes* to descend into, and which leaf *pages*
|
|
13
|
+
* offered at this node to keep for the answer. Selecting pages at every level is
|
|
14
|
+
* what makes the walk a curated retrieval rather than a bulk dump: only pages
|
|
15
|
+
* the model keeps reach the candidate set.
|
|
16
|
+
*
|
|
17
|
+
* The walk descends from `tree.root` only — it is not seeded mid-tree. Scout
|
|
18
|
+
* hits steer it solely as **descend pressure**: the surviving scout slugs are
|
|
19
|
+
* rendered into every descend prompt so the model prefers (but is not forced
|
|
20
|
+
* onto) branches that contain them. The scout-surfaced pages themselves already
|
|
21
|
+
* reach the gate directly via the loop, so the walk's job is to find the
|
|
22
|
+
* relevant pages the scouts missed and to keep only what bears on the turn.
|
|
23
|
+
*
|
|
24
|
+
* The decision returned per node — `{ descend, keep, reasoning }` — is handed
|
|
25
|
+
* straight to `walkTree`, so every emitted `TreeLevel` carries the model's
|
|
26
|
+
* reason for its descend/skip split, making a wrong high-level skip observable
|
|
27
|
+
* rather than silent.
|
|
28
|
+
*
|
|
29
|
+
* Fail-safe. When no provider is configured (or a per-node call errors / returns
|
|
30
|
+
* an unusable response) the descender descends *nothing* and keeps *nothing* for
|
|
31
|
+
* that node, recording the reason. The walk still terminates; it just stops
|
|
32
|
+
* exploring and collecting from the affected node. Failing closed keeps a broken
|
|
33
|
+
* provider from blowing the breadth budget, and the scout hits already in the
|
|
34
|
+
* candidate set keep the turn from going memory-blind.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import { z } from "zod";
|
|
38
|
+
|
|
39
|
+
import {
|
|
40
|
+
extractToolUse,
|
|
41
|
+
getConfiguredProvider,
|
|
42
|
+
} from "../../providers/provider-send-message.js";
|
|
43
|
+
import type {
|
|
44
|
+
Message,
|
|
45
|
+
Provider,
|
|
46
|
+
ToolDefinition,
|
|
47
|
+
} from "../../providers/types.js";
|
|
48
|
+
import { getLogger } from "../../util/logger.js";
|
|
49
|
+
import type { RetrievalInput } from "../v2/harness/retriever.js";
|
|
50
|
+
import type { ScoutResult } from "../v2/harness/trace.js";
|
|
51
|
+
import type { PageIndex } from "../v2/page-index.js";
|
|
52
|
+
import { composeNodeIndex } from "./index-composition.js";
|
|
53
|
+
import type { LlmCallSink } from "./llm-capture.js";
|
|
54
|
+
import { renderConversationContext } from "./prompt-context.js";
|
|
55
|
+
import {
|
|
56
|
+
DESCENT_SYSTEM_PROMPT,
|
|
57
|
+
resolveV3SystemPrompt,
|
|
58
|
+
} from "./prompts/system-prompts.js";
|
|
59
|
+
import type {
|
|
60
|
+
DescendDecision,
|
|
61
|
+
DescendResult,
|
|
62
|
+
WalkResult,
|
|
63
|
+
} from "./traversal.js";
|
|
64
|
+
import { walkTree } from "./traversal.js";
|
|
65
|
+
import type { ChildRef, TreeIndex } from "./tree-index.js";
|
|
66
|
+
|
|
67
|
+
const log = getLogger("memory-v3-tree-walk");
|
|
68
|
+
|
|
69
|
+
/** Tool name forced via `tool_choice`. Shared constant so tests can match it. */
|
|
70
|
+
const DESCEND_TOOL_NAME = "choose_branches";
|
|
71
|
+
|
|
72
|
+
/** Arguments to {@link createDescender}. */
|
|
73
|
+
export interface CreateDescenderArgs {
|
|
74
|
+
input: RetrievalInput;
|
|
75
|
+
tree: TreeIndex;
|
|
76
|
+
pages: PageIndex;
|
|
77
|
+
/** Surviving scout hits — rendered into the prompt as descend pressure. */
|
|
78
|
+
scouts: ScoutResult[];
|
|
79
|
+
/** Optional debug sink — emits one record per descender LLM call (per node). */
|
|
80
|
+
capture?: LlmCallSink;
|
|
81
|
+
/**
|
|
82
|
+
* Provider override seam for tests. Production omits it and the descender
|
|
83
|
+
* resolves `getConfiguredProvider("memoryV3Descent")` per call. Explicit
|
|
84
|
+
* `null` is distinct from `undefined`: it simulates "no provider configured"
|
|
85
|
+
* and exercises the fail-safe path without touching the real registry.
|
|
86
|
+
*/
|
|
87
|
+
provider?: Provider | null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Arguments to {@link runTreeWalk}. Identical to the descender's args. */
|
|
91
|
+
export type RunTreeWalkArgs = CreateDescenderArgs;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The forced-tool input schema. `descend` lists the bare node ids the model
|
|
95
|
+
* chose to recurse into; `keep_pages` lists the leaf page slugs it chose to keep
|
|
96
|
+
* for the answer; `reasoning` is its stated rationale. Mirrors v2's
|
|
97
|
+
* `select_pages_to_inject` forced-tool shape.
|
|
98
|
+
*/
|
|
99
|
+
const DescendToolResultSchema = z.object({
|
|
100
|
+
descend: z.array(z.string()),
|
|
101
|
+
keep_pages: z.array(z.string()).optional(),
|
|
102
|
+
reasoning: z.string().optional(),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Build the forced tool definition for one node. `descend` is constrained to the
|
|
107
|
+
* offered `node:` child ids and `keep_pages` to the offered `page:` child slugs,
|
|
108
|
+
* so the model can only pick from genuine children (the walk filters anyway, but
|
|
109
|
+
* constraining the schema keeps the model honest and the trace clean).
|
|
110
|
+
*/
|
|
111
|
+
function buildDescendTool(
|
|
112
|
+
offeredNodeIds: readonly string[],
|
|
113
|
+
offeredPageSlugs: readonly string[],
|
|
114
|
+
): ToolDefinition {
|
|
115
|
+
return {
|
|
116
|
+
name: DESCEND_TOOL_NAME,
|
|
117
|
+
description:
|
|
118
|
+
"At the current memory-tree node, decide two things for the current " +
|
|
119
|
+
"turn: which child NODES to descend into to find more relevant pages, " +
|
|
120
|
+
"and which leaf PAGES offered here to keep for the answer. Prefer " +
|
|
121
|
+
"branches and pages likely to bear on the turn; lean toward keeping a " +
|
|
122
|
+
"plausibly-relevant page over dropping it — missing a relevant page or " +
|
|
123
|
+
"subtree is worse than including an extra one. Return empty lists only " +
|
|
124
|
+
"when nothing here plausibly bears on the turn.",
|
|
125
|
+
input_schema: {
|
|
126
|
+
type: "object",
|
|
127
|
+
properties: {
|
|
128
|
+
descend: {
|
|
129
|
+
type: "array",
|
|
130
|
+
items:
|
|
131
|
+
offeredNodeIds.length > 0
|
|
132
|
+
? { type: "string", enum: [...offeredNodeIds] }
|
|
133
|
+
: { type: "string" },
|
|
134
|
+
description:
|
|
135
|
+
"Bare ids of the child NODES to descend into. Choose only from " +
|
|
136
|
+
"the offered node children.",
|
|
137
|
+
},
|
|
138
|
+
keep_pages: {
|
|
139
|
+
type: "array",
|
|
140
|
+
items:
|
|
141
|
+
offeredPageSlugs.length > 0
|
|
142
|
+
? { type: "string", enum: [...offeredPageSlugs] }
|
|
143
|
+
: { type: "string" },
|
|
144
|
+
description:
|
|
145
|
+
"Slugs of the leaf PAGES offered at this node to keep for the " +
|
|
146
|
+
"answer. Choose only from the offered page children.",
|
|
147
|
+
},
|
|
148
|
+
reasoning: {
|
|
149
|
+
type: "string",
|
|
150
|
+
description:
|
|
151
|
+
"One short sentence: why these branches and pages were chosen " +
|
|
152
|
+
"and the rest skipped.",
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
required: ["descend"],
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Render the surviving scout hits as descend pressure — the page slugs each
|
|
162
|
+
* lane surfaced, grouped by lane. Empty string when there are no scout hits, so
|
|
163
|
+
* the prompt omits the block entirely.
|
|
164
|
+
*/
|
|
165
|
+
function renderScoutHits(scouts: readonly ScoutResult[]): string {
|
|
166
|
+
const lines: string[] = [];
|
|
167
|
+
for (const scout of scouts) {
|
|
168
|
+
if (scout.slugs.length === 0) continue;
|
|
169
|
+
lines.push(`[${scout.lane}]: ${scout.slugs.join(", ")}`);
|
|
170
|
+
}
|
|
171
|
+
if (lines.length === 0) return "";
|
|
172
|
+
return `<scout_hits>\n${lines.join("\n")}\n</scout_hits>`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Fail-safe decision: descend nothing and keep nothing, recording why. */
|
|
176
|
+
function failClosed(reasoning: string): DescendResult {
|
|
177
|
+
return { descend: [], keep: [], reasoning };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Resolve the bare ids/slugs the model returned back to the `ChildRef`s the node
|
|
182
|
+
* actually offered, dropping anything not offered. The walk filters again, but
|
|
183
|
+
* resolving here keeps the returned refs canonical.
|
|
184
|
+
*/
|
|
185
|
+
function resolveOffered(
|
|
186
|
+
refs: readonly string[],
|
|
187
|
+
offered: Map<string, ChildRef>,
|
|
188
|
+
): ChildRef[] {
|
|
189
|
+
const out: ChildRef[] = [];
|
|
190
|
+
for (const ref of refs) {
|
|
191
|
+
const child = offered.get(ref);
|
|
192
|
+
if (child) out.push(child);
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Create the per-node decision driving {@link walkTree}.
|
|
199
|
+
*
|
|
200
|
+
* The returned {@link DescendDecision} makes one forced-tool `memoryV3Descent`
|
|
201
|
+
* call per node that has any children, over its composed index, and returns the
|
|
202
|
+
* `node:` children to descend plus the `page:` children to keep — with the
|
|
203
|
+
* model's reasoning inline. A node with no children at all skips the call.
|
|
204
|
+
*
|
|
205
|
+
* Provider resolution honors the `provider` arg (including explicit `null` for
|
|
206
|
+
* the fail-safe path) and otherwise resolves the configured call site once per
|
|
207
|
+
* call. Any failure — no provider, provider throw, missing/mismatched tool_use
|
|
208
|
+
* — fails closed (descend and keep nothing) with the reason recorded.
|
|
209
|
+
*/
|
|
210
|
+
export function createDescender(args: CreateDescenderArgs): DescendDecision {
|
|
211
|
+
const { input, tree, pages, scouts } = args;
|
|
212
|
+
const conversationContext = renderConversationContext(input);
|
|
213
|
+
const scoutHits = renderScoutHits(scouts);
|
|
214
|
+
// Resolve the descent system prompt once for the whole walk — config is
|
|
215
|
+
// stable across the per-node calls, so there is no reason to re-resolve
|
|
216
|
+
// (and re-read any override file) per node.
|
|
217
|
+
const systemPrompt = resolveV3SystemPrompt(
|
|
218
|
+
DESCENT_SYSTEM_PROMPT,
|
|
219
|
+
input.config.memory?.v3?.prompts?.descent,
|
|
220
|
+
input.workspaceDir,
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
return async (
|
|
224
|
+
nodeId: string,
|
|
225
|
+
children: ReadonlyArray<ChildRef>,
|
|
226
|
+
): Promise<DescendResult> => {
|
|
227
|
+
const offeredNodes = children.filter((c) => c.kind === "node");
|
|
228
|
+
const offeredPages = children.filter((c) => c.kind === "page");
|
|
229
|
+
// No children at all — nothing to ask the model.
|
|
230
|
+
if (offeredNodes.length === 0 && offeredPages.length === 0) {
|
|
231
|
+
return { descend: [], keep: [], reasoning: "" };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const provider =
|
|
235
|
+
args.provider !== undefined
|
|
236
|
+
? args.provider
|
|
237
|
+
: await getConfiguredProvider("memoryV3Descent");
|
|
238
|
+
if (!provider) {
|
|
239
|
+
log.warn(
|
|
240
|
+
{ nodeId },
|
|
241
|
+
"memoryV3Descent provider unavailable; descending and keeping nothing",
|
|
242
|
+
);
|
|
243
|
+
return failClosed("no provider configured — descended and kept nothing");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const indexBlock = composeNodeIndex(nodeId, tree, pages);
|
|
247
|
+
const offeredNodeIds = offeredNodes.map((c) => c.ref);
|
|
248
|
+
const offeredPageSlugs = offeredPages.map((c) => c.ref);
|
|
249
|
+
|
|
250
|
+
const userMsg: Message = {
|
|
251
|
+
role: "user",
|
|
252
|
+
content: [
|
|
253
|
+
{ type: "text", text: conversationContext },
|
|
254
|
+
{
|
|
255
|
+
type: "text",
|
|
256
|
+
text:
|
|
257
|
+
(scoutHits ? `${scoutHits}\n\n` : "") +
|
|
258
|
+
`<node id="${nodeId}">\n${indexBlock}\n</node>`,
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const descendTool = buildDescendTool(offeredNodeIds, offeredPageSlugs);
|
|
264
|
+
|
|
265
|
+
const startedAt = Date.now();
|
|
266
|
+
let response;
|
|
267
|
+
try {
|
|
268
|
+
response = await provider.sendMessage(
|
|
269
|
+
[userMsg],
|
|
270
|
+
[descendTool],
|
|
271
|
+
systemPrompt,
|
|
272
|
+
{
|
|
273
|
+
config: {
|
|
274
|
+
callSite: "memoryV3Descent" as const,
|
|
275
|
+
tool_choice: { type: "tool" as const, name: DESCEND_TOOL_NAME },
|
|
276
|
+
},
|
|
277
|
+
...(input.signal ? { signal: input.signal } : {}),
|
|
278
|
+
},
|
|
279
|
+
);
|
|
280
|
+
} catch (err) {
|
|
281
|
+
log.warn(
|
|
282
|
+
{ err, nodeId },
|
|
283
|
+
"Descent provider call threw; descending and keeping nothing",
|
|
284
|
+
);
|
|
285
|
+
return failClosed("descent call failed — descended and kept nothing");
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
args.capture?.({
|
|
289
|
+
lane: "descent",
|
|
290
|
+
callSite: "memoryV3Descent",
|
|
291
|
+
node: nodeId,
|
|
292
|
+
request: { systemPrompt, messages: [userMsg], tools: [descendTool] },
|
|
293
|
+
response,
|
|
294
|
+
ms: Date.now() - startedAt,
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const toolBlock = extractToolUse(response);
|
|
298
|
+
if (!toolBlock || toolBlock.name !== DESCEND_TOOL_NAME) {
|
|
299
|
+
log.warn(
|
|
300
|
+
{ stopReason: response.stopReason, nodeId },
|
|
301
|
+
"Descent model returned no choose_branches tool_use; descending and keeping nothing",
|
|
302
|
+
);
|
|
303
|
+
return failClosed(
|
|
304
|
+
"model returned no descend decision — descended and kept nothing",
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const parsed = DescendToolResultSchema.safeParse(toolBlock.input);
|
|
309
|
+
if (!parsed.success) {
|
|
310
|
+
log.warn(
|
|
311
|
+
{ error: parsed.error.message, nodeId },
|
|
312
|
+
"Descent tool input did not match schema; descending and keeping nothing",
|
|
313
|
+
);
|
|
314
|
+
return failClosed(
|
|
315
|
+
"descend decision failed validation — descended and kept nothing",
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const descend = resolveOffered(
|
|
320
|
+
parsed.data.descend,
|
|
321
|
+
new Map(offeredNodes.map((c) => [c.ref, c])),
|
|
322
|
+
);
|
|
323
|
+
const keep = resolveOffered(
|
|
324
|
+
parsed.data.keep_pages ?? [],
|
|
325
|
+
new Map(offeredPages.map((c) => [c.ref, c])),
|
|
326
|
+
);
|
|
327
|
+
return { descend, keep, reasoning: parsed.data.reasoning ?? "" };
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Drive a full tree walk for one retrieval pass.
|
|
333
|
+
*
|
|
334
|
+
* Wires {@link createDescender} into {@link walkTree} with `breadthBudget` /
|
|
335
|
+
* `maxDepth` drawn from `config.memory.v3` (on `input.config`). The walk starts
|
|
336
|
+
* at `tree.root` only — scout hits steer it as descend pressure in the prompt,
|
|
337
|
+
* not as mid-tree start points. Returns the kept leaf pages and the per-node
|
|
338
|
+
* `TreeLevel[]`, each level carrying the model's recorded reasoning.
|
|
339
|
+
*/
|
|
340
|
+
export async function runTreeWalk(args: RunTreeWalkArgs): Promise<WalkResult> {
|
|
341
|
+
const { input, tree } = args;
|
|
342
|
+
const v3 = input.config.memory?.v3;
|
|
343
|
+
const breadthBudget = v3?.breadthBudget ?? 6;
|
|
344
|
+
const maxDepth = v3?.maxDepth ?? 6;
|
|
345
|
+
|
|
346
|
+
return walkTree(tree, {
|
|
347
|
+
breadthBudget,
|
|
348
|
+
maxDepth,
|
|
349
|
+
descend: createDescender(args),
|
|
350
|
+
});
|
|
351
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Memory v3 — Shared types
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// Types shared across the v3 memory subsystem. Like v2, every value here
|
|
6
|
+
// crosses a serialization boundary — YAML frontmatter on disk — so it ships as
|
|
7
|
+
// a Zod schema with an inferred TypeScript type so runtime validation runs
|
|
8
|
+
// wherever a node is read.
|
|
9
|
+
//
|
|
10
|
+
// This file must not import from any other `memory/v3/*` module — it is the
|
|
11
|
+
// leaf of the v3 dependency graph.
|
|
12
|
+
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Tree nodes
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* YAML frontmatter at the top of a v3 tree node (`memory/tree/<id>.md`).
|
|
21
|
+
*
|
|
22
|
+
* The v3 tree is a DAG *overlay* over the existing flat `memory/concepts/`
|
|
23
|
+
* pages. A node organizes a region of the graph: its markdown body is the
|
|
24
|
+
* node's full self-description and `children` is the list of outgoing edges.
|
|
25
|
+
*
|
|
26
|
+
* `children` is the canonical, ordered list of child *references*. Each entry
|
|
27
|
+
* is either:
|
|
28
|
+
* - `"page:<page-slug>"` — a leaf concept page (canonical content stays in
|
|
29
|
+
* `memory/concepts/<page-slug>.md`, shared and untouched by v3), or
|
|
30
|
+
* - `"node:<node-id>"` — a sub-node in the v3 tree.
|
|
31
|
+
*
|
|
32
|
+
* This reference list IS the DAG edge — it is the portable replacement for the
|
|
33
|
+
* filesystem symlinks an earlier design would have used. A page or node may be
|
|
34
|
+
* referenced by more than one parent (hence DAG, not tree).
|
|
35
|
+
*
|
|
36
|
+
* `routing_hints` is a thin, hand-written line of cross-branch disambiguation
|
|
37
|
+
* — e.g. "for *work* relationships see people/colleagues, not this node".
|
|
38
|
+
* Kept deliberately small so it stays cheap to inject during routing.
|
|
39
|
+
*
|
|
40
|
+
* `summary` is the node's self-description headline (1-line); the markdown body
|
|
41
|
+
* is the full self-description. Optional so a freshly authored node with only a
|
|
42
|
+
* body still parses.
|
|
43
|
+
*/
|
|
44
|
+
export const TreeNodeFrontmatterSchema = z
|
|
45
|
+
.object({
|
|
46
|
+
children: z.array(z.string()).default([]),
|
|
47
|
+
routing_hints: z.string().optional(),
|
|
48
|
+
summary: z.string().optional(),
|
|
49
|
+
})
|
|
50
|
+
.strict();
|
|
51
|
+
|
|
52
|
+
export type TreeNodeFrontmatter = z.infer<typeof TreeNodeFrontmatterSchema>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A single tree node on disk. The id is the relative path from
|
|
56
|
+
* `memory/tree/` minus `.md`, using forward slashes — so `people` and
|
|
57
|
+
* `people/colleagues` are both valid ids. The id is the stable identity used
|
|
58
|
+
* in `children` references (`node:<id>`) and is the portable node handle a
|
|
59
|
+
* future data-migration authors by hand.
|
|
60
|
+
*/
|
|
61
|
+
export type TreeNode = {
|
|
62
|
+
id: string;
|
|
63
|
+
frontmatter: TreeNodeFrontmatter;
|
|
64
|
+
body: string;
|
|
65
|
+
};
|