@vellumai/assistant 0.8.6 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -4
- package/Dockerfile +1 -0
- package/bun.lock +11 -2
- package/docker-entrypoint.sh +8 -6
- package/docs/plugins.md +63 -28
- package/examples/plugins/echo/register.ts +4 -7
- package/knip.json +1 -0
- package/node_modules/@vellumai/environments/bun.lock +24 -0
- package/node_modules/@vellumai/environments/package.json +18 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
- package/node_modules/@vellumai/environments/src/index.ts +11 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
- package/node_modules/@vellumai/environments/src/types.ts +70 -0
- package/node_modules/@vellumai/environments/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +3 -4
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -2
- package/openapi.yaml +3735 -353
- package/package.json +7 -3
- package/scripts/generate-openapi.ts +20 -13
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +240 -39
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +19 -32
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +6 -4
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +207 -341
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +4 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
- package/src/__tests__/anthropic-provider.test.ts +201 -55
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +5 -0
- package/src/__tests__/approval-cascade.test.ts +4 -11
- package/src/__tests__/approval-routes-http.test.ts +4 -2
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/avatar-e2e.test.ts +7 -37
- package/src/__tests__/avatar-generator.test.ts +12 -42
- package/src/__tests__/avatar-identity-sync.test.ts +28 -3
- package/src/__tests__/background-shell-bash.test.ts +3 -7
- package/src/__tests__/btw-routes.test.ts +7 -12
- package/src/__tests__/call-pointer-messages.test.ts +5 -3
- package/src/__tests__/call-site-routing-provider.test.ts +22 -40
- package/src/__tests__/catalog-files.test.ts +1 -0
- package/src/__tests__/channel-approval-routes.test.ts +48 -20
- package/src/__tests__/channel-approvals.test.ts +3 -1
- package/src/__tests__/channel-invite-transport.test.ts +1 -5
- package/src/__tests__/channel-readiness-routes.test.ts +0 -4
- package/src/__tests__/channel-readiness-slack-remote.test.ts +2 -7
- package/src/__tests__/channel-retry-sweep.test.ts +71 -79
- package/src/__tests__/circuit-breaker-pipeline.test.ts +3 -3
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-events.test.ts +5 -17
- package/src/__tests__/compaction-pipeline.test.ts +1 -1
- package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
- package/src/__tests__/compaction-trail-store.test.ts +1 -79
- package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
- package/src/__tests__/computer-use-tools.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +28 -0
- package/src/__tests__/context-search-agent-runner.test.ts +6 -3
- package/src/__tests__/context-token-estimator.test.ts +34 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +14 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +12 -27
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +430 -90
- package/src/__tests__/conversation-agent-loop.test.ts +581 -62
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -3
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clear-safety.test.ts +20 -10
- package/src/__tests__/conversation-confirmation-signals.test.ts +15 -45
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-disk-view.test.ts +10 -17
- package/src/__tests__/conversation-fork-crud.test.ts +86 -172
- package/src/__tests__/conversation-fork-route.test.ts +16 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
- package/src/__tests__/conversation-lifecycle.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +3 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +1 -1
- package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
- package/src/__tests__/conversation-pairing.test.ts +34 -4
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -0
- package/src/__tests__/conversation-process-callsite.test.ts +27 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +53 -44
- package/src/__tests__/conversation-queue.test.ts +270 -164
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +20 -22
- package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
- package/src/__tests__/conversation-slash-queue.test.ts +37 -31
- package/src/__tests__/conversation-slash-unknown.test.ts +13 -15
- package/src/__tests__/conversation-speed-override.test.ts +8 -22
- package/src/__tests__/conversation-stream-state.test.ts +484 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +6 -15
- package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
- package/src/__tests__/conversation-surfaces-state-update.test.ts +5 -2
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -15
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +23 -11
- package/src/__tests__/conversation-unread-route.test.ts +14 -2
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-wipe.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +3 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +48 -22
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +27 -7
- package/src/__tests__/credential-execution-tools.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/cross-provider-web-search.test.ts +6 -2
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +11 -0
- package/src/__tests__/disk-pressure-guard.test.ts +66 -0
- package/src/__tests__/disk-pressure-routes.test.ts +9 -2
- package/src/__tests__/dm-persistence.test.ts +7 -2
- package/src/__tests__/dynamic-page-surface.test.ts +68 -0
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-pipeline.test.ts +127 -5
- package/src/__tests__/filing-service.test.ts +2 -2
- package/src/__tests__/first-greeting.test.ts +55 -14
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +351 -28
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +9 -7
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +2 -1
- package/src/__tests__/history-repair-hook.test.ts +161 -0
- package/src/__tests__/history-repair-observability.test.ts +1 -1
- package/src/__tests__/history-repair.test.ts +2 -1
- package/src/__tests__/host-app-control-proxy.test.ts +2 -0
- package/src/__tests__/host-cu-proxy.test.ts +2 -0
- package/src/__tests__/host-file-edit-tool.test.ts +4 -2
- package/src/__tests__/host-file-proxy.test.ts +31 -0
- package/src/__tests__/host-file-read-tool.test.ts +4 -2
- package/src/__tests__/host-file-write-tool.test.ts +9 -3
- package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
- package/src/__tests__/host-shell-tool.test.ts +9 -4
- package/src/__tests__/http-user-message-parity.test.ts +2 -2
- package/src/__tests__/identity-intro-cache.test.ts +35 -14
- package/src/__tests__/inbound-slack-persistence.test.ts +7 -2
- package/src/__tests__/injector-background-turn.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +1 -1
- package/src/__tests__/injector-document-comments.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
- package/src/__tests__/injector-v3-suppression.test.ts +220 -0
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +17 -15
- package/src/__tests__/list-messages-page-latest.test.ts +0 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
- package/src/__tests__/llm-call-pipeline.test.ts +21 -15
- package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
- package/src/__tests__/llm-resolver.test.ts +23 -47
- package/src/__tests__/llm-usage-store.test.ts +45 -0
- package/src/__tests__/log-export-routes.test.ts +59 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
- package/src/__tests__/mcp-auth-routes.test.ts +15 -10
- package/src/__tests__/mcp-health-check.test.ts +18 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +1 -1
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +8 -4
- package/src/__tests__/migration-export-http.test.ts +12 -12
- package/src/__tests__/migration-import-commit-http.test.ts +8 -8
- package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +14 -20
- package/src/__tests__/notification-decision-identity.test.ts +9 -18
- package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
- package/src/__tests__/oauth-commands-routes.test.ts +1 -1
- package/src/__tests__/onboarding-template-contract.test.ts +10 -0
- package/src/__tests__/openai-provider.test.ts +66 -70
- package/src/__tests__/openai-responses-provider.test.ts +21 -77
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -1
- package/src/__tests__/overflow-reduce-pipeline.test.ts +2 -4
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persistence-pipeline.test.ts +15 -26
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -1
- package/src/__tests__/pipeline-runner.test.ts +2 -3
- package/src/__tests__/plugin-bootstrap.test.ts +51 -25
- package/src/__tests__/plugin-route-contribution.test.ts +6 -16
- package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
- package/src/__tests__/plugin-tool-contribution.test.ts +10 -26
- package/src/__tests__/plugin-types.test.ts +7 -14
- package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
- package/src/__tests__/process-message-background-slack.test.ts +17 -16
- package/src/__tests__/process-message-display-content.test.ts +30 -42
- package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
- package/src/__tests__/provider-error-scenarios.test.ts +7 -6
- package/src/__tests__/provider-platform-proxy-integration.test.ts +3 -8
- package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
- package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
- package/src/__tests__/provider-usage-tracking.test.ts +0 -6
- package/src/__tests__/ratelimit.test.ts +9 -4
- package/src/__tests__/relay-server.test.ts +20 -13
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
- package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
- package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +353 -0
- package/src/__tests__/schedule-routes.test.ts +80 -10
- package/src/__tests__/schedule-store.test.ts +67 -0
- package/src/__tests__/schedule-tools.test.ts +125 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
- package/src/__tests__/secret-response-routing.test.ts +13 -11
- package/src/__tests__/send-endpoint-busy.test.ts +2 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +11 -11
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +10 -10
- package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
- package/src/__tests__/skillssh-files.test.ts +1 -0
- package/src/__tests__/starter-task-flow.test.ts +6 -6
- package/src/__tests__/strip-memory-injections.test.ts +102 -14
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +19 -16
- package/src/__tests__/system-prompt.test.ts +54 -0
- package/src/__tests__/terminal-tools.test.ts +3 -24
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-pipeline.test.ts +1 -1
- package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
- package/src/__tests__/tool-error-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
- package/src/__tests__/tool-preview-lifecycle.test.ts +13 -11
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
- package/src/__tests__/tool-result-truncation.test.ts +3 -1
- package/src/__tests__/tools-audio-read.test.ts +113 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
- package/src/__tests__/turn-events-store.test.ts +11 -7
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +8 -6
- package/src/__tests__/voice-session-bridge.test.ts +13 -7
- package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/agent/compaction-circuit.ts +140 -0
- package/src/agent/loop.ts +409 -85
- package/src/api/README.md +19 -17
- package/src/api/constants/tool-execution.ts +21 -0
- package/src/api/events/assistant-activity-state.ts +75 -0
- package/src/api/events/assistant-outbound-attachment.ts +25 -27
- package/src/api/events/assistant-text-delta.ts +6 -8
- package/src/api/events/assistant-turn-start.ts +5 -7
- package/src/api/events/avatar-updated.ts +24 -0
- package/src/api/events/compaction-circuit-closed.ts +26 -0
- package/src/api/events/compaction-circuit-open.ts +28 -0
- package/src/api/events/confirmation-request.ts +114 -0
- package/src/api/events/contact-request.ts +33 -0
- package/src/api/events/conversation-error.ts +77 -0
- package/src/api/events/conversation-list-invalidated.ts +38 -0
- package/src/api/events/conversation-title-updated.ts +24 -0
- package/src/api/events/disk-pressure-status-changed.ts +61 -0
- package/src/api/events/document-comment-created.ts +24 -28
- package/src/api/events/document-comment-deleted.ts +6 -8
- package/src/api/events/document-comment-reopened.ts +6 -8
- package/src/api/events/document-comment-resolved.ts +8 -10
- package/src/api/events/document-editor-update.ts +27 -0
- package/src/api/events/error.ts +32 -0
- package/src/api/events/generation-cancelled.ts +4 -6
- package/src/api/events/generation-handoff.ts +13 -15
- package/src/api/events/home-feed-updated.ts +26 -0
- package/src/api/events/identity-changed.ts +32 -0
- package/src/api/events/interaction-resolved.ts +50 -0
- package/src/api/events/message-complete.ts +10 -12
- package/src/api/events/message-dequeued.ts +21 -0
- package/src/api/events/message-queued-deleted.ts +23 -0
- package/src/api/events/message-queued.ts +22 -0
- package/src/api/events/message-request-complete.ts +29 -0
- package/src/api/events/navigate-settings.ts +20 -0
- package/src/api/events/notification-intent.ts +33 -0
- package/src/api/events/open-url.ts +6 -8
- package/src/api/events/question-request.ts +67 -0
- package/src/api/events/relationship-state-updated.ts +4 -6
- package/src/api/events/secret-request.ts +42 -0
- package/src/api/events/subagent-event.ts +79 -0
- package/src/api/events/subagent-spawned.ts +40 -0
- package/src/api/events/subagent-status-changed.ts +65 -0
- package/src/api/events/sync-changed.ts +29 -0
- package/src/api/events/tool-result.ts +129 -0
- package/src/api/events/tool-use-start.ts +8 -10
- package/src/api/events/turn-profile-auto-routed.ts +28 -0
- package/src/api/events/ui-surface-complete.ts +30 -0
- package/src/api/events/ui-surface-dismiss.ts +22 -0
- package/src/api/events/ui-surface-show.ts +67 -0
- package/src/api/events/ui-surface-update.ts +26 -0
- package/src/api/events/usage-update.ts +34 -0
- package/src/api/events/user-message-echo.ts +35 -0
- package/src/api/index.ts +354 -0
- package/src/api/requests/dictation.ts +45 -0
- package/src/api/responses/disk-pressure-status.ts +26 -0
- package/src/api/responses/home.ts +217 -0
- package/src/api/responses/llm-context-response.ts +2 -0
- package/src/api/responses/memory-v3-selection-log.ts +50 -0
- package/src/api/responses/subagent-detail.ts +48 -0
- package/src/approvals/guardian-decision-primitive.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +6 -9
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +193 -0
- package/src/avatar/avatar-manifest.ts +195 -0
- package/src/avatar/avatar-store.ts +113 -0
- package/src/avatar/traits-png-sync.ts +8 -2
- package/src/background-wake/next-wake.test.ts +31 -1
- package/src/background-wake/next-wake.ts +4 -1
- package/src/calls/call-conversation-messages.ts +6 -4
- package/src/calls/guardian-action-sweep.ts +6 -4
- package/src/calls/relay-server.ts +12 -8
- package/src/calls/voice-session-bridge.ts +13 -27
- package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
- package/src/cli/commands/avatar.ts +17 -11
- package/src/cli/commands/conversations.ts +15 -1
- package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
- package/src/cli/commands/db/__tests__/status.test.ts +253 -0
- package/src/cli/commands/db/format.ts +48 -0
- package/src/cli/commands/db/index.ts +29 -0
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
- package/src/cli/commands/db/repair-step-integrity.ts +146 -0
- package/src/cli/commands/db/repair-steps.ts +164 -0
- package/src/cli/commands/db/repair.ts +141 -0
- package/src/cli/commands/db/status.ts +366 -0
- package/src/cli/commands/memory-v3.ts +159 -445
- package/src/cli/lib/cli-colors.ts +24 -6
- package/src/cli/program.ts +4 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/assistant-feature-flags.ts +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/call-site-defaults.ts +2 -7
- package/src/config/feature-flag-registry.json +25 -9
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -226
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/llm.ts +2 -3
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +0 -253
- package/src/config/schemas/memory-v3.ts +39 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/context/compactor.ts +54 -31
- package/src/context/token-estimator.ts +19 -0
- package/src/context/tool-result-truncation.ts +1 -43
- package/src/context/window-manager.ts +138 -20
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
- package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +225 -88
- package/src/daemon/conversation-agent-loop.ts +284 -584
- package/src/daemon/conversation-error.ts +7 -7
- package/src/daemon/conversation-history.ts +22 -6
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +10 -38
- package/src/daemon/conversation-messaging.ts +1 -3
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +100 -79
- package/src/daemon/conversation-runtime-assembly.ts +47 -21
- package/src/daemon/conversation-store.ts +6 -5
- package/src/daemon/conversation-surfaces.ts +55 -69
- package/src/daemon/conversation-tool-setup.ts +3 -0
- package/src/daemon/conversation.ts +91 -126
- package/src/daemon/daemon-skill-host.ts +2 -6
- package/src/daemon/disk-pressure-guard.ts +35 -29
- package/src/daemon/external-plugins-bootstrap.ts +46 -24
- package/src/daemon/first-greeting.ts +26 -4
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/conversations.ts +6 -22
- package/src/daemon/handlers/shared.ts +4 -0
- package/src/daemon/handlers/skills.ts +15 -14
- package/src/daemon/host-app-control-proxy.ts +54 -1
- package/src/daemon/host-cu-proxy.ts +46 -22
- package/src/daemon/host-file-proxy.ts +25 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -6
- package/src/daemon/lifecycle.ts +28 -55
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- package/src/daemon/message-types/contacts.ts +3 -20
- package/src/daemon/message-types/conversations.ts +13 -111
- package/src/daemon/message-types/documents.ts +3 -9
- package/src/daemon/message-types/home.ts +4 -17
- package/src/daemon/message-types/integrations.ts +2 -6
- package/src/daemon/message-types/messages.ts +28 -343
- package/src/daemon/message-types/notifications.ts +2 -32
- package/src/daemon/message-types/settings.ts +3 -8
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/process-message.ts +49 -46
- package/src/daemon/server.ts +12 -0
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +11 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -1
- package/src/heartbeat/heartbeat-run-store.ts +31 -0
- package/src/heartbeat/heartbeat-service.ts +16 -0
- package/src/home/feature-gate.ts +22 -0
- package/src/home/feed-types.ts +36 -221
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
- package/src/ipc/routes/route-adapter.ts +45 -6
- package/src/ipc/skill-routes/__tests__/memory.test.ts +18 -9
- package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
- package/src/ipc/skill-routes/__tests__/registries.test.ts +28 -18
- package/src/ipc/skill-routes/memory.ts +26 -13
- package/src/ipc/skill-routes/providers.ts +5 -6
- package/src/ipc/skill-routes/registries.ts +13 -61
- package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
- package/src/memory/__tests__/conversation-queries.test.ts +192 -8
- package/src/memory/__tests__/db-maintenance.test.ts +128 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
- package/src/memory/__tests__/memory-retrospective-job.test.ts +10 -6
- package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
- package/src/memory/context-search/agent-runner.ts +2 -4
- package/src/memory/conversation-crud.ts +39 -8
- package/src/memory/conversation-queries.ts +78 -22
- package/src/memory/db-init.ts +8 -0
- package/src/memory/db-maintenance.ts +18 -2
- package/src/memory/graph/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +41 -8
- package/src/memory/graph/extraction.ts +6 -9
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.ts +20 -26
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/job-handlers/conversation-starters.ts +32 -32
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs-store.ts +3 -1
- package/src/memory/jobs-worker.ts +51 -39
- package/src/memory/llm-request-log-source-clickhouse.ts +5 -31
- package/src/memory/llm-request-log-source-local.ts +0 -11
- package/src/memory/llm-request-log-source.ts +9 -25
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +10 -0
- package/src/memory/memory-marker.ts +17 -0
- package/src/memory/memory-retrospective-job.ts +6 -2
- package/src/memory/memory-v2-activation-log-store.ts +1 -83
- package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
- package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
- package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
- package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
- package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/schema/infrastructure.ts +11 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
- package/src/memory/v2/__tests__/migration.test.ts +11 -3
- package/src/memory/v2/__tests__/page-index.test.ts +37 -1
- package/src/memory/v2/__tests__/router.test.ts +14 -4
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -5
- package/src/memory/v2/backfill-jobs.ts +6 -0
- package/src/memory/v2/consolidation-job.ts +89 -9
- package/src/memory/v2/migration.ts +5 -3
- package/src/memory/v2/page-index.ts +11 -0
- package/src/memory/v2/router.ts +8 -11
- package/src/memory/v2/sweep-job.ts +8 -11
- package/src/memory/v2/types.ts +1 -0
- package/src/memory/v3/__tests__/assign.test.ts +242 -0
- package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
- package/src/memory/v3/__tests__/core.test.ts +39 -0
- package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
- package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
- package/src/memory/v3/__tests__/health.test.ts +203 -0
- package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
- package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
- package/src/memory/v3/__tests__/needle.test.ts +107 -0
- package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
- package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
- package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
- package/src/memory/v3/__tests__/router.test.ts +260 -0
- package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
- package/src/memory/v3/__tests__/selector.test.ts +404 -0
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
- package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
- package/src/memory/v3/__tests__/tree.test.ts +192 -0
- package/src/memory/v3/__tests__/types.test.ts +54 -0
- package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
- package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/memory/v3/assign.ts +268 -0
- package/src/memory/v3/capabilities.ts +124 -0
- package/src/memory/v3/core.ts +26 -0
- package/src/memory/v3/data/README.md +84 -0
- package/src/memory/v3/data/assignments.json +5 -0
- package/src/memory/v3/data/core.json +1 -0
- package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
- package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
- package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +314 -0
- package/src/memory/v3/needle.ts +115 -0
- package/src/memory/v3/orchestrate.ts +114 -0
- package/src/memory/v3/page-content.ts +34 -0
- package/src/memory/v3/provider-blocks.ts +16 -0
- package/src/memory/v3/reconcile.ts +523 -0
- package/src/memory/v3/render-injection.ts +32 -0
- package/src/memory/v3/router.ts +184 -0
- package/src/memory/v3/selection-log-store.ts +84 -0
- package/src/memory/v3/selector.ts +211 -0
- package/src/memory/v3/shadow-plugin.ts +379 -0
- package/src/memory/v3/snapshot.ts +209 -0
- package/src/memory/v3/tree.ts +174 -0
- package/src/memory/v3/types.ts +46 -60
- package/src/memory/v3/working-set.ts +88 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
- package/src/messaging/providers/slack/render-transcript.ts +2 -2
- package/src/messaging/style-analyzer.ts +8 -11
- package/src/notifications/conversation-pairing.ts +8 -6
- package/src/notifications/decision-engine.ts +10 -13
- package/src/notifications/preference-extractor.ts +11 -14
- package/src/permissions/prompter.ts +42 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- package/src/plugin-api/index.ts +2 -0
- package/src/plugin-api/types.ts +25 -3
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
- package/src/plugins/defaults/circuit-breaker/package.json +15 -0
- package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +35 -0
- package/src/plugins/defaults/compaction/terminal.ts +73 -0
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +28 -0
- package/src/plugins/defaults/empty-response/terminal.ts +106 -0
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/history-repair/package.json +15 -0
- package/src/plugins/defaults/history-repair/register.ts +24 -0
- package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
- package/src/plugins/defaults/index.ts +29 -40
- package/src/plugins/defaults/injectors/package.json +15 -0
- package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +14 -38
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
- package/src/plugins/defaults/llm-call/package.json +15 -0
- package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
- package/src/plugins/defaults/memory-retrieval/package.json +15 -0
- package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
- package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
- package/src/plugins/defaults/overflow-reduce/package.json +15 -0
- package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
- package/src/plugins/defaults/persistence/package.json +15 -0
- package/src/plugins/defaults/persistence/register.ts +38 -0
- package/src/plugins/defaults/persistence/terminal.ts +83 -0
- package/src/plugins/defaults/title-generate/package.json +15 -0
- package/src/plugins/defaults/title-generate/register.ts +35 -0
- package/src/plugins/defaults/title-generate/terminal.ts +31 -0
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
- package/src/plugins/defaults/token-estimate/package.json +15 -0
- package/src/plugins/defaults/token-estimate/register.ts +34 -0
- package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +35 -0
- package/src/plugins/defaults/tool-error/terminal.ts +47 -0
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
- package/src/plugins/defaults/tool-execute/package.json +15 -0
- package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
- package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +0 -12
- package/src/plugins/types.ts +51 -90
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +0 -1
- package/src/proactive-artifact/job.test.ts +20 -8
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +5 -1
- package/src/prompts/templates/system-sections.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +25 -25
- package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
- package/src/providers/anthropic/client.ts +24 -5
- package/src/providers/call-site-routing.ts +1 -9
- package/src/providers/gemini/client.ts +152 -34
- package/src/providers/gemini/inline-media.ts +74 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +0 -2
- package/src/providers/openai/chat-completions-provider.ts +1 -4
- package/src/providers/openai/responses-provider.ts +1 -4
- package/src/providers/openrouter/client.ts +1 -6
- package/src/providers/provider-send-message.ts +6 -6
- package/src/providers/ratelimit.ts +1 -9
- package/src/providers/retry.ts +0 -5
- package/src/providers/types.ts +11 -2
- package/src/providers/usage-tracking.ts +1 -9
- package/src/runtime/__tests__/agent-wake.test.ts +131 -26
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
- package/src/runtime/agent-wake.ts +93 -18
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
- package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
- package/src/runtime/auth/route-policy.ts +42 -1079
- package/src/runtime/background-job-runner.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -1
- package/src/runtime/channel-approvals.ts +3 -14
- package/src/runtime/channel-invite-transport.ts +5 -6
- package/src/runtime/channel-readiness-service.ts +2 -5
- package/src/runtime/channel-retry-sweep.ts +12 -16
- package/src/runtime/conversation-stream-state.ts +294 -0
- package/src/runtime/http-router.ts +19 -22
- package/src/runtime/http-types.ts +12 -6
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +62 -32
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -22
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +7 -2
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
- package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
- package/src/runtime/routes/__tests__/tts-routes.test.ts +3 -3
- package/src/runtime/routes/acp-routes.test.ts +97 -75
- package/src/runtime/routes/acp-routes.ts +29 -6
- package/src/runtime/routes/app-management-routes.ts +97 -24
- package/src/runtime/routes/app-routes.ts +25 -5
- package/src/runtime/routes/approval-routes.ts +16 -4
- package/src/runtime/routes/attachment-routes.ts +25 -1
- package/src/runtime/routes/audio-routes.ts +1 -0
- package/src/runtime/routes/audit-routes.ts +5 -0
- package/src/runtime/routes/auth-routes.ts +5 -0
- package/src/runtime/routes/avatar-routes.ts +238 -59
- package/src/runtime/routes/background-tool-routes.ts +9 -0
- package/src/runtime/routes/background-wake-routes.ts +13 -3
- package/src/runtime/routes/backup-routes.ts +45 -0
- package/src/runtime/routes/bookmark-routes.ts +13 -0
- package/src/runtime/routes/brain-graph-routes.ts +9 -0
- package/src/runtime/routes/browser-routes.ts +5 -0
- package/src/runtime/routes/browser-tabs-routes.ts +5 -0
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/cache-routes.ts +13 -0
- package/src/runtime/routes/call-routes.ts +21 -10
- package/src/runtime/routes/channel-availability-routes.ts +5 -1
- package/src/runtime/routes/channel-readiness-routes.ts +37 -4
- package/src/runtime/routes/channel-route-definitions.ts +21 -0
- package/src/runtime/routes/channel-verification-routes.ts +21 -0
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
- package/src/runtime/routes/client-routes.ts +9 -0
- package/src/runtime/routes/consolidation-routes.ts +13 -5
- package/src/runtime/routes/contact-prompt-routes.ts +9 -0
- package/src/runtime/routes/contact-routes.ts +90 -23
- package/src/runtime/routes/content-source-routes.ts +5 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +5 -1
- package/src/runtime/routes/conversation-attention-routes.ts +5 -0
- package/src/runtime/routes/conversation-cli-routes.ts +54 -7
- package/src/runtime/routes/conversation-compaction-routes.ts +54 -25
- package/src/runtime/routes/conversation-list-routes.ts +81 -12
- package/src/runtime/routes/conversation-management-routes.ts +57 -14
- package/src/runtime/routes/conversation-query-routes.ts +88 -41
- package/src/runtime/routes/conversation-routes.ts +74 -19
- package/src/runtime/routes/conversation-starter-routes.ts +22 -13
- package/src/runtime/routes/conversations-import-routes.ts +6 -1
- package/src/runtime/routes/credential-prompt-routes.ts +5 -0
- package/src/runtime/routes/credential-routes.ts +25 -6
- package/src/runtime/routes/debug-bash-routes.ts +5 -0
- package/src/runtime/routes/debug-routes.ts +11 -2
- package/src/runtime/routes/defer-routes.ts +13 -0
- package/src/runtime/routes/diagnostics-routes.ts +37 -46
- package/src/runtime/routes/disk-pressure-routes.ts +17 -31
- package/src/runtime/routes/document-comments-routes.ts +46 -27
- package/src/runtime/routes/documents-routes.ts +21 -10
- package/src/runtime/routes/domain-routes.ts +61 -28
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/events-routes.ts +114 -9
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +5 -0
- package/src/runtime/routes/global-search-routes.ts +53 -50
- package/src/runtime/routes/group-routes.ts +21 -5
- package/src/runtime/routes/guardian-action-routes.ts +9 -0
- package/src/runtime/routes/guardian-approval-interception.ts +0 -31
- package/src/runtime/routes/heartbeat-routes.ts +25 -9
- package/src/runtime/routes/home-feed-routes.ts +23 -19
- package/src/runtime/routes/home-state-routes.ts +8 -40
- package/src/runtime/routes/host-app-control-routes.ts +5 -0
- package/src/runtime/routes/host-bash-routes.ts +5 -0
- package/src/runtime/routes/host-browser-routes.ts +13 -0
- package/src/runtime/routes/host-cu-routes.ts +5 -0
- package/src/runtime/routes/host-file-routes.ts +26 -6
- package/src/runtime/routes/host-transfer-routes.ts +13 -2
- package/src/runtime/routes/http-adapter.ts +1 -2
- package/src/runtime/routes/identity-intro-cache.ts +17 -6
- package/src/runtime/routes/identity-routes.ts +12 -2
- package/src/runtime/routes/image-generation-routes.ts +5 -0
- package/src/runtime/routes/inbound-message-handler.ts +15 -11
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
- package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
- package/src/runtime/routes/inference-provider-connection-routes.ts +21 -5
- package/src/runtime/routes/inference-send-routes.ts +11 -11
- package/src/runtime/routes/integrations/a2a.ts +30 -7
- package/src/runtime/routes/integrations/slack/channel.ts +19 -3
- package/src/runtime/routes/integrations/slack/share.ts +9 -2
- package/src/runtime/routes/integrations/telegram.ts +28 -9
- package/src/runtime/routes/integrations/twilio.ts +35 -7
- package/src/runtime/routes/integrations/vercel.ts +3 -3
- package/src/runtime/routes/internal-oauth-routes.ts +5 -0
- package/src/runtime/routes/internal-twilio-routes.ts +13 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
- package/src/runtime/routes/log-export-routes.ts +28 -10
- package/src/runtime/routes/mcp-auth-routes.ts +25 -0
- package/src/runtime/routes/memory-item-routes.ts +21 -10
- package/src/runtime/routes/memory-v2-routes.ts +90 -36
- package/src/runtime/routes/memory-v3-routes.ts +273 -407
- package/src/runtime/routes/migration-rollback-routes.ts +5 -1
- package/src/runtime/routes/migration-routes.ts +29 -0
- package/src/runtime/routes/notification-routes.ts +17 -1
- package/src/runtime/routes/oauth-apps.ts +33 -11
- package/src/runtime/routes/oauth-commands-routes.ts +37 -14
- package/src/runtime/routes/oauth-connect-routes.ts +9 -0
- package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
- package/src/runtime/routes/oauth-providers.ts +35 -10
- package/src/runtime/routes/platform-routes.ts +21 -0
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
- package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +0 -1
- package/src/runtime/routes/playground/inject-failures.ts +13 -8
- package/src/runtime/routes/playground/reset-circuit.ts +14 -9
- package/src/runtime/routes/playground/seed-conversation.ts +1 -1
- package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
- package/src/runtime/routes/playground/state.ts +4 -3
- package/src/runtime/routes/plugins-routes.ts +22 -19
- package/src/runtime/routes/profiler-routes.ts +17 -4
- package/src/runtime/routes/ps-routes.ts +5 -0
- package/src/runtime/routes/publish-routes.ts +13 -3
- package/src/runtime/routes/question-routes.ts +5 -0
- package/src/runtime/routes/recording-routes.ts +25 -12
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +137 -47
- package/src/runtime/routes/secret-routes.ts +17 -4
- package/src/runtime/routes/sequence-routes.ts +33 -0
- package/src/runtime/routes/settings-routes.ts +65 -19
- package/src/runtime/routes/skills-routes.ts +133 -69
- package/src/runtime/routes/slack-channel-routes.ts +5 -0
- package/src/runtime/routes/stt-routes.ts +13 -6
- package/src/runtime/routes/subagents-routes.ts +24 -18
- package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
- package/src/runtime/routes/surface-action-routes.ts +9 -0
- package/src/runtime/routes/surface-content-routes.ts +10 -2
- package/src/runtime/routes/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +5 -0
- package/src/runtime/routes/tts-routes.ts +13 -6
- package/src/runtime/routes/types.ts +17 -8
- package/src/runtime/routes/ui-request-routes.ts +5 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
- package/src/runtime/routes/usage-routes.ts +71 -3
- package/src/runtime/routes/user-routes-cli.ts +9 -0
- package/src/runtime/routes/user-routes.ts +5 -1
- package/src/runtime/routes/wake-conversation-routes.ts +5 -0
- package/src/runtime/routes/watcher-routes.ts +21 -0
- package/src/runtime/routes/webhook-routes.ts +9 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
- package/src/runtime/routes/work-items-routes.ts +47 -19
- package/src/runtime/routes/workspace-commit-routes.ts +5 -0
- package/src/runtime/routes/workspace-routes.test.ts +42 -0
- package/src/runtime/routes/workspace-routes.ts +120 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -4
- package/src/runtime/services/analyze-conversation.ts +3 -6
- package/src/runtime/services/conversation-serializer.ts +24 -2
- package/src/runtime/sync/resource-sync-events.ts +16 -2
- package/src/runtime/sync/sync-publisher.ts +2 -2
- package/src/schedule/run-script.ts +28 -3
- package/src/schedule/schedule-store.ts +8 -0
- package/src/schedule/scheduler.ts +3 -1
- package/src/signals/user-message.ts +5 -8
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/clawhub-files.ts +2 -0
- package/src/skills/skillssh-files.ts +2 -0
- package/src/subagent/manager.ts +3 -6
- package/src/telemetry/types.ts +26 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
- package/src/telemetry/usage-telemetry-reporter.ts +31 -0
- package/src/tools/acp/spawn.test.ts +88 -38
- package/src/tools/apps/definitions.ts +8 -4
- package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
- package/src/tools/ask-question/ask-question-tool.ts +85 -90
- package/src/tools/computer-use/definitions.ts +28 -24
- package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
- package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
- package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
- package/src/tools/credentials/vault.ts +112 -111
- package/src/tools/execution-target.ts +1 -1
- package/src/tools/execution-timeout.ts +3 -4
- package/src/tools/filesystem/edit.ts +45 -42
- package/src/tools/filesystem/list.ts +33 -30
- package/src/tools/filesystem/read.ts +54 -35
- package/src/tools/filesystem/write.ts +34 -31
- package/src/tools/host-filesystem/edit.ts +44 -42
- package/src/tools/host-filesystem/read.ts +49 -35
- package/src/tools/host-filesystem/transfer.ts +121 -108
- package/src/tools/host-filesystem/write.ts +33 -31
- package/src/tools/host-terminal/host-shell.ts +50 -48
- package/src/tools/memory/register.ts +23 -24
- package/src/tools/network/web-fetch.ts +49 -46
- package/src/tools/network/web-search.ts +16 -13
- package/src/tools/registry.ts +39 -16
- package/src/tools/schedule/create.ts +11 -0
- package/src/tools/schedule/update.ts +16 -0
- package/src/tools/shared/filesystem/audio-read.ts +122 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/execute.ts +34 -31
- package/src/tools/skills/load.ts +29 -23
- package/src/tools/subagent/notify-parent.ts +35 -32
- package/src/tools/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- package/src/tools/terminal/shell.ts +190 -61
- package/src/tools/tool-defaults.ts +20 -9
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/types.ts +74 -23
- package/src/tools/ui-surface/definitions.ts +69 -9
- package/src/usage/types.ts +10 -0
- package/src/util/errors.ts +2 -2
- package/src/util/map-limit.ts +27 -0
- package/src/util/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
- package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
- package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
- package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
- package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
- package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
- package/src/cli/commands/memory-v3-render.ts +0 -491
- package/src/daemon/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
- package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -466
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +0 -270
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
- package/src/memory/v3/__tests__/edges.test.ts +0 -706
- package/src/memory/v3/__tests__/filter.test.ts +0 -560
- package/src/memory/v3/__tests__/gate.test.ts +0 -637
- package/src/memory/v3/__tests__/index-composition.test.ts +0 -291
- package/src/memory/v3/__tests__/loop.test.ts +0 -775
- package/src/memory/v3/__tests__/retriever.test.ts +0 -226
- package/src/memory/v3/__tests__/scouts.test.ts +0 -489
- package/src/memory/v3/__tests__/shadow-diff.test.ts +0 -225
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -398
- package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
- package/src/memory/v3/__tests__/traversal.test.ts +0 -508
- package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
- package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
- package/src/memory/v3/__tests__/tree-walk.test.ts +0 -784
- package/src/memory/v3/__tests__/validate.test.ts +0 -277
- package/src/memory/v3/auto-edges.ts +0 -223
- package/src/memory/v3/coactivation-store.ts +0 -124
- package/src/memory/v3/consolidation-job.ts +0 -323
- package/src/memory/v3/coretrieval-seed.ts +0 -240
- package/src/memory/v3/edge-learning-job.ts +0 -160
- package/src/memory/v3/edges.ts +0 -286
- package/src/memory/v3/filter.ts +0 -286
- package/src/memory/v3/gate.ts +0 -349
- package/src/memory/v3/index-composition.ts +0 -126
- package/src/memory/v3/llm-capture.ts +0 -46
- package/src/memory/v3/loop.ts +0 -430
- package/src/memory/v3/maintenance.ts +0 -144
- package/src/memory/v3/prompt-context.ts +0 -33
- package/src/memory/v3/prompts/consolidation.ts +0 -458
- package/src/memory/v3/prompts/system-prompts.ts +0 -196
- package/src/memory/v3/retriever.ts +0 -33
- package/src/memory/v3/scouts.ts +0 -431
- package/src/memory/v3/shadow-diff.ts +0 -287
- package/src/memory/v3/shadow-middleware.ts +0 -347
- package/src/memory/v3/traversal.ts +0 -211
- package/src/memory/v3/tree-index.ts +0 -237
- package/src/memory/v3/tree-store.ts +0 -394
- package/src/memory/v3/tree-walk.ts +0 -356
- package/src/memory/v3/validate.ts +0 -323
- package/src/plugins/defaults/circuit-breaker.ts +0 -141
- package/src/plugins/defaults/compaction.ts +0 -141
- package/src/plugins/defaults/empty-response.ts +0 -124
- package/src/plugins/defaults/history-repair.ts +0 -83
- package/src/plugins/defaults/persistence.ts +0 -146
- package/src/plugins/defaults/title-generate.ts +0 -90
- package/src/plugins/defaults/token-estimate.ts +0 -101
- package/src/plugins/defaults/tool-error.ts +0 -119
- package/src/plugins/defaults/tool-result-truncate.ts +0 -84
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for `assistant/src/memory/v3/validate.ts`.
|
|
3
|
-
*
|
|
4
|
-
* Coverage matrix — one fixture per defect category plus a clean-tree control:
|
|
5
|
-
* - clean tree → every list empty, every count 0.
|
|
6
|
-
* - danglingChildRefs → a `node:` ref and a `page:` ref to absent targets.
|
|
7
|
-
* - orphanPages → a concept page on disk not wired into the tree; synthetic
|
|
8
|
-
* page-index entries (none here) and reachable pages excluded.
|
|
9
|
-
* - cycles → A → B → A back-edge detected during the full descent.
|
|
10
|
-
* - staleIndex → a parent node whose mtime predates a `node:` child's mtime.
|
|
11
|
-
* - unknownEdgeTargets → a page `edges:` entry pointing at a missing slug.
|
|
12
|
-
*
|
|
13
|
-
* Tests use temp workspaces under `os.tmpdir()`; they never touch `~/.vellum/`.
|
|
14
|
-
* mtimes are pinned with `utimes` so the freshness check is deterministic and
|
|
15
|
-
* independent of write ordering / filesystem timestamp granularity.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
19
|
-
import { utimes } from "node:fs/promises";
|
|
20
|
-
import { tmpdir } from "node:os";
|
|
21
|
-
import { join } from "node:path";
|
|
22
|
-
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
23
|
-
|
|
24
|
-
import { invalidateEdgeIndex } from "../../v2/edge-index.js";
|
|
25
|
-
import { invalidatePageIndex } from "../../v2/page-index.js";
|
|
26
|
-
import { writePage } from "../../v2/page-store.js";
|
|
27
|
-
import type { ConceptPage } from "../../v2/types.js";
|
|
28
|
-
import { invalidateTreeIndex } from "../tree-index.js";
|
|
29
|
-
import { getTreeDir, ROOT_NODE_ID, writeNode } from "../tree-store.js";
|
|
30
|
-
import type { TreeNode } from "../types.js";
|
|
31
|
-
import { validateTree } from "../validate.js";
|
|
32
|
-
|
|
33
|
-
let workspaceDir: string;
|
|
34
|
-
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
workspaceDir = mkdtempSync(join(tmpdir(), "vellum-tree-validate-test-"));
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterEach(() => {
|
|
40
|
-
invalidateTreeIndex();
|
|
41
|
-
invalidatePageIndex();
|
|
42
|
-
invalidateEdgeIndex();
|
|
43
|
-
rmSync(workspaceDir, { recursive: true, force: true });
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
function node(id: string, children: string[], body = `body ${id}`): TreeNode {
|
|
47
|
-
return { id, frontmatter: { children }, body };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function page(slug: string, edges: string[] = []): ConceptPage {
|
|
51
|
-
return {
|
|
52
|
-
slug,
|
|
53
|
-
frontmatter: { edges, ref_files: [], ref_urls: [] },
|
|
54
|
-
body: `body ${slug}`,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** Pin a node file's mtime (and atime) to an explicit epoch-ms value. */
|
|
59
|
-
async function setNodeMtime(id: string, mtimeMs: number): Promise<void> {
|
|
60
|
-
const path = join(getTreeDir(workspaceDir), `${id}.md`);
|
|
61
|
-
const t = new Date(mtimeMs);
|
|
62
|
-
await utimes(path, t, t);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Invalidate every cached index after seeding so the first `validateTree` of a
|
|
67
|
-
* test body sees the on-disk fixture rather than a stale cache.
|
|
68
|
-
*/
|
|
69
|
-
function resetCaches(): void {
|
|
70
|
-
invalidateTreeIndex();
|
|
71
|
-
invalidatePageIndex();
|
|
72
|
-
invalidateEdgeIndex();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
describe("validateTree — clean tree", () => {
|
|
76
|
-
test("returns an empty report for a well-formed tree", async () => {
|
|
77
|
-
// _root → node:people → page:alice ; all refs resolve, alice reachable.
|
|
78
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, ["node:people"]));
|
|
79
|
-
await writeNode(workspaceDir, node("people", ["page:alice"]));
|
|
80
|
-
await writePage(workspaceDir, page("alice"));
|
|
81
|
-
// Parent newest so the freshness check never fires on a clean tree.
|
|
82
|
-
await setNodeMtime("people", 1_000);
|
|
83
|
-
await setNodeMtime(ROOT_NODE_ID, 2_000);
|
|
84
|
-
resetCaches();
|
|
85
|
-
|
|
86
|
-
const report = await validateTree(workspaceDir);
|
|
87
|
-
|
|
88
|
-
expect(report.danglingChildRefs).toEqual([]);
|
|
89
|
-
expect(report.danglingChildRefCount).toBe(0);
|
|
90
|
-
expect(report.orphanPages).toEqual([]);
|
|
91
|
-
expect(report.orphanPageCount).toBe(0);
|
|
92
|
-
expect(report.cycles).toEqual([]);
|
|
93
|
-
expect(report.cycleCount).toBe(0);
|
|
94
|
-
expect(report.staleIndex).toEqual([]);
|
|
95
|
-
expect(report.staleIndexCount).toBe(0);
|
|
96
|
-
expect(report.unknownEdgeTargets).toEqual([]);
|
|
97
|
-
expect(report.unknownEdgeTargetCount).toBe(0);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
describe("validateTree — danglingChildRefs", () => {
|
|
102
|
-
test("flags node: and page: refs whose targets are missing", async () => {
|
|
103
|
-
await writeNode(
|
|
104
|
-
workspaceDir,
|
|
105
|
-
node(ROOT_NODE_ID, ["node:ghost", "page:missing-page"]),
|
|
106
|
-
);
|
|
107
|
-
resetCaches();
|
|
108
|
-
|
|
109
|
-
const report = await validateTree(workspaceDir);
|
|
110
|
-
|
|
111
|
-
expect(report.danglingChildRefs).toEqual([
|
|
112
|
-
{ node: ROOT_NODE_ID, ref: "ghost", kind: "node" },
|
|
113
|
-
{ node: ROOT_NODE_ID, ref: "missing-page", kind: "page" },
|
|
114
|
-
]);
|
|
115
|
-
expect(report.danglingChildRefCount).toBe(2);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
test("does not flag refs whose targets exist", async () => {
|
|
119
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, ["node:child"]));
|
|
120
|
-
await writeNode(workspaceDir, node("child", ["page:alice"]));
|
|
121
|
-
await writePage(workspaceDir, page("alice"));
|
|
122
|
-
resetCaches();
|
|
123
|
-
|
|
124
|
-
const report = await validateTree(workspaceDir);
|
|
125
|
-
|
|
126
|
-
expect(report.danglingChildRefs).toEqual([]);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
describe("validateTree — orphanPages", () => {
|
|
131
|
-
test("flags concept pages not reachable from the root", async () => {
|
|
132
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, ["page:reached"]));
|
|
133
|
-
await writePage(workspaceDir, page("reached"));
|
|
134
|
-
await writePage(workspaceDir, page("orphan"));
|
|
135
|
-
resetCaches();
|
|
136
|
-
|
|
137
|
-
const report = await validateTree(workspaceDir);
|
|
138
|
-
|
|
139
|
-
expect(report.orphanPages).toEqual(["orphan"]);
|
|
140
|
-
expect(report.orphanPageCount).toBe(1);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
test("a page hanging off an unreachable node is still an orphan", async () => {
|
|
144
|
-
// `floating` is not referenced by _root, so its page child is unreachable.
|
|
145
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, []));
|
|
146
|
-
await writeNode(workspaceDir, node("floating", ["page:detached"]));
|
|
147
|
-
await writePage(workspaceDir, page("detached"));
|
|
148
|
-
resetCaches();
|
|
149
|
-
|
|
150
|
-
const report = await validateTree(workspaceDir);
|
|
151
|
-
|
|
152
|
-
expect(report.orphanPages).toEqual(["detached"]);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
describe("validateTree — cycles", () => {
|
|
157
|
-
test("detects an A → B → A node cycle as a back-edge", async () => {
|
|
158
|
-
// _root → node:a → node:b → node:a (cycle closes on the b → a edge).
|
|
159
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, ["node:a"]));
|
|
160
|
-
await writeNode(workspaceDir, node("a", ["node:b"]));
|
|
161
|
-
await writeNode(workspaceDir, node("b", ["node:a"]));
|
|
162
|
-
resetCaches();
|
|
163
|
-
|
|
164
|
-
const report = await validateTree(workspaceDir);
|
|
165
|
-
|
|
166
|
-
expect(report.cycles).toEqual([{ from: "b", to: "a" }]);
|
|
167
|
-
expect(report.cycleCount).toBe(1);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
test("a shared DAG sub-node (two parents, no cycle) is not a cycle", async () => {
|
|
171
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, ["node:p1", "node:p2"]));
|
|
172
|
-
await writeNode(workspaceDir, node("p1", ["node:shared"]));
|
|
173
|
-
await writeNode(workspaceDir, node("p2", ["node:shared"]));
|
|
174
|
-
await writeNode(workspaceDir, node("shared", []));
|
|
175
|
-
resetCaches();
|
|
176
|
-
|
|
177
|
-
const report = await validateTree(workspaceDir);
|
|
178
|
-
|
|
179
|
-
expect(report.cycles).toEqual([]);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
test("detects a cycle in a component unreachable from the root", async () => {
|
|
183
|
-
// _root is a leaf with no edges; the x ↔ y cycle lives in a disconnected
|
|
184
|
-
// component the root can never reach. The sweep over unvisited nodes must
|
|
185
|
-
// still surface it.
|
|
186
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, []));
|
|
187
|
-
await writeNode(workspaceDir, node("x", ["node:y"]));
|
|
188
|
-
await writeNode(workspaceDir, node("y", ["node:x"]));
|
|
189
|
-
resetCaches();
|
|
190
|
-
|
|
191
|
-
const report = await validateTree(workspaceDir);
|
|
192
|
-
|
|
193
|
-
expect(report.cycleCount).toBe(1);
|
|
194
|
-
// The back-edge closes on whichever of the pair the sweep enters second.
|
|
195
|
-
const [{ from, to }] = report.cycles;
|
|
196
|
-
expect(new Set([from, to])).toEqual(new Set(["x", "y"]));
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
test("a page off an unreachable cyclic node stays an orphan", async () => {
|
|
200
|
-
// The disconnected-component sweep covers x/y for cycle detection but must
|
|
201
|
-
// not mark them root-reachable — `detached` therefore remains an orphan.
|
|
202
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, []));
|
|
203
|
-
await writeNode(workspaceDir, node("x", ["node:y", "page:detached"]));
|
|
204
|
-
await writeNode(workspaceDir, node("y", ["node:x"]));
|
|
205
|
-
await writePage(workspaceDir, page("detached"));
|
|
206
|
-
resetCaches();
|
|
207
|
-
|
|
208
|
-
const report = await validateTree(workspaceDir);
|
|
209
|
-
|
|
210
|
-
expect(report.cycleCount).toBe(1);
|
|
211
|
-
expect(report.orphanPages).toEqual(["detached"]);
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe("validateTree — staleIndex", () => {
|
|
216
|
-
test("flags a node whose mtime predates a node: child's mtime", async () => {
|
|
217
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, ["node:child"]));
|
|
218
|
-
await writeNode(workspaceDir, node("child", []));
|
|
219
|
-
// Parent older than child → stale.
|
|
220
|
-
await setNodeMtime(ROOT_NODE_ID, 1_000);
|
|
221
|
-
await setNodeMtime("child", 5_000);
|
|
222
|
-
resetCaches();
|
|
223
|
-
|
|
224
|
-
const report = await validateTree(workspaceDir);
|
|
225
|
-
|
|
226
|
-
expect(report.staleIndex).toEqual([
|
|
227
|
-
{
|
|
228
|
-
node: ROOT_NODE_ID,
|
|
229
|
-
child: "child",
|
|
230
|
-
nodeMtimeMs: 1_000,
|
|
231
|
-
childMtimeMs: 5_000,
|
|
232
|
-
},
|
|
233
|
-
]);
|
|
234
|
-
expect(report.staleIndexCount).toBe(1);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
test("a parent newer than its child is not stale", async () => {
|
|
238
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, ["node:child"]));
|
|
239
|
-
await writeNode(workspaceDir, node("child", []));
|
|
240
|
-
await setNodeMtime("child", 1_000);
|
|
241
|
-
await setNodeMtime(ROOT_NODE_ID, 5_000);
|
|
242
|
-
resetCaches();
|
|
243
|
-
|
|
244
|
-
const report = await validateTree(workspaceDir);
|
|
245
|
-
|
|
246
|
-
expect(report.staleIndex).toEqual([]);
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
describe("validateTree — unknownEdgeTargets", () => {
|
|
251
|
-
test("flags a page edge pointing at a missing slug", async () => {
|
|
252
|
-
await writeNode(workspaceDir, node(ROOT_NODE_ID, ["page:alice"]));
|
|
253
|
-
await writePage(workspaceDir, page("alice", ["nonexistent"]));
|
|
254
|
-
resetCaches();
|
|
255
|
-
|
|
256
|
-
const report = await validateTree(workspaceDir);
|
|
257
|
-
|
|
258
|
-
expect(report.unknownEdgeTargets).toEqual([
|
|
259
|
-
{ from: "alice", to: "nonexistent" },
|
|
260
|
-
]);
|
|
261
|
-
expect(report.unknownEdgeTargetCount).toBe(1);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
test("an edge to an existing page is not flagged", async () => {
|
|
265
|
-
await writeNode(
|
|
266
|
-
workspaceDir,
|
|
267
|
-
node(ROOT_NODE_ID, ["page:alice", "page:bob"]),
|
|
268
|
-
);
|
|
269
|
-
await writePage(workspaceDir, page("alice", ["bob"]));
|
|
270
|
-
await writePage(workspaceDir, page("bob"));
|
|
271
|
-
resetCaches();
|
|
272
|
-
|
|
273
|
-
const report = await validateTree(workspaceDir);
|
|
274
|
-
|
|
275
|
-
expect(report.unknownEdgeTargets).toEqual([]);
|
|
276
|
-
});
|
|
277
|
-
});
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — learned weighted auto-edge store.
|
|
3
|
-
*
|
|
4
|
-
* Read/write helpers over `memory_v3_auto_edges` (migration 263) — the
|
|
5
|
-
* **learned** association graph, a distinct class from the curated `edges:`
|
|
6
|
-
* frontmatter graph. Each row is a weighted directed pair `source → target`
|
|
7
|
-
* that the edge-learning job accrues from *used* co-activations and decays over
|
|
8
|
-
* wall-clock time.
|
|
9
|
-
*
|
|
10
|
-
* Three primitives:
|
|
11
|
-
* - {@link reinforce} — bump a pair's weight, but only for a *used*
|
|
12
|
-
* co-activation (we reinforce usefulness, not mere retrieval).
|
|
13
|
-
* - {@link decay} — multiplicatively decay all weights toward zero on a
|
|
14
|
-
* half-life schedule, so a pair that stops being reinforced fades. This is
|
|
15
|
-
* the rich-get-richer counterweight: weight is a leaky integrator, not a
|
|
16
|
-
* monotone counter.
|
|
17
|
-
* - {@link aboveThreshold} — project the learned graph to the
|
|
18
|
-
* `ReadonlyMap<source, ReadonlySet<target>>` adjacency that edge
|
|
19
|
-
* expansion's `extraAdjacency` seam consumes (only pairs at/above a weight
|
|
20
|
-
* threshold traverse).
|
|
21
|
-
*
|
|
22
|
-
* The decay model mirrors v2's injection-events EMA: `λ = ln 2 / halfLife`, and
|
|
23
|
-
* a pair decays by `exp(-λ × elapsed)` since its `last_reinforced_at`.
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import { getLogger } from "../../util/logger.js";
|
|
27
|
-
import type { DrizzleDb } from "../db-connection.js";
|
|
28
|
-
import { getSqliteFrom } from "../db-connection.js";
|
|
29
|
-
|
|
30
|
-
const log = getLogger("memory-v3-auto-edges");
|
|
31
|
-
|
|
32
|
-
/** Weight added to a pair per *used* co-activation reinforcement. */
|
|
33
|
-
export const REINFORCE_INCREMENT = 1;
|
|
34
|
-
|
|
35
|
-
/** Weights below this after decay are pruned rather than kept as dead rows. */
|
|
36
|
-
export const PRUNE_FLOOR = 0.01;
|
|
37
|
-
|
|
38
|
-
/** A learned auto-edge, as read back from the table. */
|
|
39
|
-
export interface AutoEdgeRow {
|
|
40
|
-
sourceSlug: string;
|
|
41
|
-
targetSlug: string;
|
|
42
|
-
weight: number;
|
|
43
|
-
lastReinforcedAt: number;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Reinforce the directed pair `source → target`: bump its weight by
|
|
48
|
-
* {@link REINFORCE_INCREMENT} and stamp `last_reinforced_at = now`. **Only call
|
|
49
|
-
* this for a *used* co-activation** — the edge graph encodes which associations
|
|
50
|
-
* actually proved load-bearing for a turn, not which pages merely surfaced
|
|
51
|
-
* together. (The caller decides usedness from the co-activation's `used` flag;
|
|
52
|
-
* this primitive is unconditional so it stays composable.)
|
|
53
|
-
*
|
|
54
|
-
* UPSERT on the `(source, target)` primary key: a new pair starts at the
|
|
55
|
-
* increment; an existing pair accrues on top of its current weight (after the
|
|
56
|
-
* latest decay pass, since decay rewrites weight in place).
|
|
57
|
-
*
|
|
58
|
-
* Best-effort: a failed write must never abort the edge-learning job.
|
|
59
|
-
*/
|
|
60
|
-
export function reinforce(
|
|
61
|
-
database: DrizzleDb,
|
|
62
|
-
source: string,
|
|
63
|
-
target: string,
|
|
64
|
-
now: number,
|
|
65
|
-
): void {
|
|
66
|
-
try {
|
|
67
|
-
const raw = getSqliteFrom(database);
|
|
68
|
-
raw
|
|
69
|
-
.prepare(
|
|
70
|
-
`INSERT INTO memory_v3_auto_edges
|
|
71
|
-
(source_slug, target_slug, weight, last_reinforced_at)
|
|
72
|
-
VALUES (?, ?, ?, ?)
|
|
73
|
-
ON CONFLICT(source_slug, target_slug) DO UPDATE SET
|
|
74
|
-
weight = weight + ?,
|
|
75
|
-
last_reinforced_at = ?`,
|
|
76
|
-
)
|
|
77
|
-
.run(source, target, REINFORCE_INCREMENT, now, REINFORCE_INCREMENT, now);
|
|
78
|
-
} catch (err) {
|
|
79
|
-
log.warn(
|
|
80
|
-
{ err, source, target },
|
|
81
|
-
"failed to reinforce auto-edge; continuing",
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Multiplicatively decay every auto-edge weight toward zero on a half-life
|
|
88
|
-
* schedule: `weight ← weight × exp(-λ × (now − last_reinforced_at))`, with
|
|
89
|
-
* `λ = ln 2 / halfLifeMs`. A pair last reinforced one half-life ago halves; two
|
|
90
|
-
* half-lives ago quarters; and so on. `last_reinforced_at` advances to `now`
|
|
91
|
-
* so successive decay passes don't double-count the same elapsed interval.
|
|
92
|
-
*
|
|
93
|
-
* Pairs whose decayed weight falls below {@link PRUNE_FLOOR} are deleted so the
|
|
94
|
-
* learned graph doesn't accumulate a long tail of effectively-dead edges.
|
|
95
|
-
*
|
|
96
|
-
* Returns the number of rows pruned, for the job's structured log.
|
|
97
|
-
*/
|
|
98
|
-
export function decay(
|
|
99
|
-
database: DrizzleDb,
|
|
100
|
-
now: number,
|
|
101
|
-
halfLifeMs: number,
|
|
102
|
-
): number {
|
|
103
|
-
if (halfLifeMs <= 0) return 0;
|
|
104
|
-
const lambda = Math.LN2 / halfLifeMs;
|
|
105
|
-
try {
|
|
106
|
-
const raw = getSqliteFrom(database);
|
|
107
|
-
const rows = raw
|
|
108
|
-
.query(
|
|
109
|
-
`SELECT source_slug, target_slug, weight, last_reinforced_at
|
|
110
|
-
FROM memory_v3_auto_edges`,
|
|
111
|
-
)
|
|
112
|
-
.all() as Array<{
|
|
113
|
-
source_slug: string;
|
|
114
|
-
target_slug: string;
|
|
115
|
-
weight: number;
|
|
116
|
-
last_reinforced_at: number;
|
|
117
|
-
}>;
|
|
118
|
-
if (rows.length === 0) return 0;
|
|
119
|
-
|
|
120
|
-
const update = raw.prepare(
|
|
121
|
-
`UPDATE memory_v3_auto_edges
|
|
122
|
-
SET weight = ?, last_reinforced_at = ?
|
|
123
|
-
WHERE source_slug = ? AND target_slug = ?`,
|
|
124
|
-
);
|
|
125
|
-
const prune = raw.prepare(
|
|
126
|
-
`DELETE FROM memory_v3_auto_edges
|
|
127
|
-
WHERE source_slug = ? AND target_slug = ?`,
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
let pruned = 0;
|
|
131
|
-
const apply = raw.transaction(() => {
|
|
132
|
-
for (const row of rows) {
|
|
133
|
-
// Future timestamps (clock skew) would amplify rather than decay — clamp
|
|
134
|
-
// elapsed at 0 so decay only ever shrinks weight.
|
|
135
|
-
const elapsed = Math.max(0, now - row.last_reinforced_at);
|
|
136
|
-
const decayed = row.weight * Math.exp(-lambda * elapsed);
|
|
137
|
-
if (decayed < PRUNE_FLOOR) {
|
|
138
|
-
prune.run(row.source_slug, row.target_slug);
|
|
139
|
-
pruned += 1;
|
|
140
|
-
} else {
|
|
141
|
-
update.run(decayed, now, row.source_slug, row.target_slug);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
apply();
|
|
146
|
-
return pruned;
|
|
147
|
-
} catch (err) {
|
|
148
|
-
log.warn({ err }, "failed to decay auto-edges; continuing");
|
|
149
|
-
return 0;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Project the learned graph to the `extraAdjacency` shape edge expansion
|
|
155
|
-
* consumes: `source → Set<target>` for every pair whose weight is at or above
|
|
156
|
-
* `threshold`. Edge expansion thresholds nothing itself — it merges whatever
|
|
157
|
-
* adjacency it's handed — so this read is where the weight cutoff is applied.
|
|
158
|
-
*
|
|
159
|
-
* Returns an empty map on any read failure so the caller (a best-effort read
|
|
160
|
-
* lane) degrades to "no learned edges" rather than aborting retrieval.
|
|
161
|
-
*/
|
|
162
|
-
export function aboveThreshold(
|
|
163
|
-
database: DrizzleDb,
|
|
164
|
-
threshold: number,
|
|
165
|
-
): Map<string, Set<string>> {
|
|
166
|
-
const adjacency = new Map<string, Set<string>>();
|
|
167
|
-
try {
|
|
168
|
-
const raw = getSqliteFrom(database);
|
|
169
|
-
const rows = raw
|
|
170
|
-
.query(
|
|
171
|
-
`SELECT source_slug, target_slug
|
|
172
|
-
FROM memory_v3_auto_edges
|
|
173
|
-
WHERE weight >= ?
|
|
174
|
-
ORDER BY source_slug ASC, target_slug ASC`,
|
|
175
|
-
)
|
|
176
|
-
.all(threshold) as Array<{ source_slug: string; target_slug: string }>;
|
|
177
|
-
for (const row of rows) {
|
|
178
|
-
let targets = adjacency.get(row.source_slug);
|
|
179
|
-
if (!targets) {
|
|
180
|
-
targets = new Set<string>();
|
|
181
|
-
adjacency.set(row.source_slug, targets);
|
|
182
|
-
}
|
|
183
|
-
targets.add(row.target_slug);
|
|
184
|
-
}
|
|
185
|
-
} catch (err) {
|
|
186
|
-
log.warn({ err, threshold }, "failed to read auto-edges; continuing");
|
|
187
|
-
}
|
|
188
|
-
return adjacency;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Read the top-weight auto-edges, heaviest first, capped at `limit`. The
|
|
193
|
-
* edge-learning job surfaces these as advisory promotion candidates for the
|
|
194
|
-
* assistant to ratify into curated `edges:` during consolidation.
|
|
195
|
-
*/
|
|
196
|
-
export function topByWeight(database: DrizzleDb, limit: number): AutoEdgeRow[] {
|
|
197
|
-
if (limit <= 0) return [];
|
|
198
|
-
try {
|
|
199
|
-
const raw = getSqliteFrom(database);
|
|
200
|
-
const rows = raw
|
|
201
|
-
.query(
|
|
202
|
-
`SELECT source_slug, target_slug, weight, last_reinforced_at
|
|
203
|
-
FROM memory_v3_auto_edges
|
|
204
|
-
ORDER BY weight DESC, source_slug ASC, target_slug ASC
|
|
205
|
-
LIMIT ?`,
|
|
206
|
-
)
|
|
207
|
-
.all(limit) as Array<{
|
|
208
|
-
source_slug: string;
|
|
209
|
-
target_slug: string;
|
|
210
|
-
weight: number;
|
|
211
|
-
last_reinforced_at: number;
|
|
212
|
-
}>;
|
|
213
|
-
return rows.map((r) => ({
|
|
214
|
-
sourceSlug: r.source_slug,
|
|
215
|
-
targetSlug: r.target_slug,
|
|
216
|
-
weight: r.weight,
|
|
217
|
-
lastReinforcedAt: r.last_reinforced_at,
|
|
218
|
-
}));
|
|
219
|
-
} catch (err) {
|
|
220
|
-
log.warn({ err, limit }, "failed to read top auto-edges; continuing");
|
|
221
|
-
return [];
|
|
222
|
-
}
|
|
223
|
-
}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — co-activation store.
|
|
3
|
-
*
|
|
4
|
-
* Best-effort read/write helpers over `memory_v3_coactivation` (migration
|
|
5
|
-
* 262). Each row is a pass-1 → pass-N co-activation pair observed during a
|
|
6
|
-
* single v3 retrieval loop: a `target_slug` first surfaced on a later descent
|
|
7
|
-
* pass was co-selected alongside a `source_slug` that surfaced on pass 1,
|
|
8
|
-
* `pass_gap = passOf(target) − passOf(source)`.
|
|
9
|
-
*
|
|
10
|
-
* This is the raw gradient signal — edge-learning reconciles it into curated
|
|
11
|
-
* graph edge weights later. Writes are off the retrieval critical path: a
|
|
12
|
-
* failed insert here must never abort the turn on top of a successful
|
|
13
|
-
* retrieval the caller already depends on.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { getLogger } from "../../util/logger.js";
|
|
17
|
-
import type { DrizzleDb } from "../db-connection.js";
|
|
18
|
-
import { getSqliteFrom } from "../db-connection.js";
|
|
19
|
-
|
|
20
|
-
const log = getLogger("memory-v3-coactivation");
|
|
21
|
-
|
|
22
|
-
/** One co-activation pair to persist. */
|
|
23
|
-
export interface CoactivationRow {
|
|
24
|
-
conversationId: string;
|
|
25
|
-
turn: number;
|
|
26
|
-
sourceSlug: string;
|
|
27
|
-
targetSlug: string;
|
|
28
|
-
passGap: number;
|
|
29
|
-
/** Usefulness flag. 0 at emit time; reconciled later by edge-learning. */
|
|
30
|
-
used: number;
|
|
31
|
-
createdAt: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** A persisted co-activation row, as read back from the table. */
|
|
35
|
-
export interface PersistedCoactivationRow {
|
|
36
|
-
id: number;
|
|
37
|
-
conversationId: string;
|
|
38
|
-
turn: number;
|
|
39
|
-
sourceSlug: string;
|
|
40
|
-
targetSlug: string;
|
|
41
|
-
passGap: number;
|
|
42
|
-
used: number;
|
|
43
|
-
createdAt: number;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Append co-activation rows. Best-effort — a SQLite write must never abort the
|
|
48
|
-
* agent turn on top of a successful retrieval the rest of the caller depends
|
|
49
|
-
* on. Mirrors {@link recordInjectionEvents}.
|
|
50
|
-
*/
|
|
51
|
-
export function recordCoactivations(
|
|
52
|
-
database: DrizzleDb,
|
|
53
|
-
rows: readonly CoactivationRow[],
|
|
54
|
-
): void {
|
|
55
|
-
if (rows.length === 0) return;
|
|
56
|
-
try {
|
|
57
|
-
const raw = getSqliteFrom(database);
|
|
58
|
-
const insert = raw.prepare(
|
|
59
|
-
`INSERT INTO memory_v3_coactivation
|
|
60
|
-
(conversation_id, turn, source_slug, target_slug, pass_gap, used, created_at)
|
|
61
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
62
|
-
);
|
|
63
|
-
const append = raw.transaction((items: readonly CoactivationRow[]) => {
|
|
64
|
-
for (const r of items) {
|
|
65
|
-
insert.run(
|
|
66
|
-
r.conversationId,
|
|
67
|
-
r.turn,
|
|
68
|
-
r.sourceSlug,
|
|
69
|
-
r.targetSlug,
|
|
70
|
-
r.passGap,
|
|
71
|
-
r.used,
|
|
72
|
-
r.createdAt,
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
append(rows);
|
|
77
|
-
} catch (err) {
|
|
78
|
-
log.warn(
|
|
79
|
-
{ err, rowCount: rows.length },
|
|
80
|
-
"failed to record co-activations; continuing",
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Read co-activation rows, oldest first. When `since` is provided, only rows
|
|
87
|
-
* with `created_at >= since` are returned.
|
|
88
|
-
*/
|
|
89
|
-
export function readCoactivations(
|
|
90
|
-
database: DrizzleDb,
|
|
91
|
-
since?: number,
|
|
92
|
-
): PersistedCoactivationRow[] {
|
|
93
|
-
const raw = getSqliteFrom(database);
|
|
94
|
-
const where = since !== undefined ? `WHERE created_at >= ?` : ``;
|
|
95
|
-
const params = since !== undefined ? [since] : [];
|
|
96
|
-
const rows = raw
|
|
97
|
-
.query(
|
|
98
|
-
`SELECT id, conversation_id, turn, source_slug, target_slug,
|
|
99
|
-
pass_gap, used, created_at
|
|
100
|
-
FROM memory_v3_coactivation
|
|
101
|
-
${where}
|
|
102
|
-
ORDER BY created_at ASC, id ASC`,
|
|
103
|
-
)
|
|
104
|
-
.all(...params) as Array<{
|
|
105
|
-
id: number;
|
|
106
|
-
conversation_id: string;
|
|
107
|
-
turn: number;
|
|
108
|
-
source_slug: string;
|
|
109
|
-
target_slug: string;
|
|
110
|
-
pass_gap: number;
|
|
111
|
-
used: number;
|
|
112
|
-
created_at: number;
|
|
113
|
-
}>;
|
|
114
|
-
return rows.map((r) => ({
|
|
115
|
-
id: r.id,
|
|
116
|
-
conversationId: r.conversation_id,
|
|
117
|
-
turn: r.turn,
|
|
118
|
-
sourceSlug: r.source_slug,
|
|
119
|
-
targetSlug: r.target_slug,
|
|
120
|
-
passGap: r.pass_gap,
|
|
121
|
-
used: r.used,
|
|
122
|
-
createdAt: r.created_at,
|
|
123
|
-
}));
|
|
124
|
-
}
|