@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,287 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 shadow-diff — compare the v3 shadow selection against the live v2
|
|
3
|
-
* router selection, turn-for-turn, from the `memory_v2_activation_logs` table.
|
|
4
|
-
*
|
|
5
|
-
* When v3 runs in shadow mode it logs its per-turn selection as a `v3_shadow`
|
|
6
|
-
* row while the live v2 router logs its own selection as a `router` row on the
|
|
7
|
-
* same turn. This module pairs the two and reports where they agree, what v3
|
|
8
|
-
* surfaced that v2 did not, and what v2 had that v3 dropped — broken down by the
|
|
9
|
-
* v3 provenance lane so a shadow run is analyzable by where its recall comes
|
|
10
|
-
* from.
|
|
11
|
-
*
|
|
12
|
-
* Pairing is by timestamp, NOT by the `turn` column: the shadow middleware logs
|
|
13
|
-
* the orchestrator's per-runtime turn counter while v2 logs the cumulative
|
|
14
|
-
* conversation turn, so the two numbers diverge. The shadow row and its sibling
|
|
15
|
-
* router row are written within the same turn (a second or two apart), so each
|
|
16
|
-
* shadow row is matched to the nearest router row in the same conversation
|
|
17
|
-
* within a tolerance window.
|
|
18
|
-
*
|
|
19
|
-
* The v2 comparand is the router's FRESH per-turn pick (`status: "injected"`),
|
|
20
|
-
* not its full in-context set. v2 accumulates pages across turns (`in_context`
|
|
21
|
-
* carry-over can reach the hundreds on a long conversation) whereas v3 selects
|
|
22
|
-
* fresh each turn; comparing fresh-against-fresh keeps the diff meaningful. The
|
|
23
|
-
* carried-over count is surfaced per turn as context, not folded into the sets.
|
|
24
|
-
*
|
|
25
|
-
* Pure and DB-free: the route handler reads the rows and hands them here.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
import type { MemoryV2ConceptRowRecord } from "../memory-v2-activation-log-store.js";
|
|
29
|
-
|
|
30
|
-
/** An activation-log row reduced to what the diff needs. */
|
|
31
|
-
export interface ShadowDiffLogRow {
|
|
32
|
-
conversationId: string;
|
|
33
|
-
/** Epoch milliseconds. */
|
|
34
|
-
createdAt: number;
|
|
35
|
-
concepts: MemoryV2ConceptRowRecord[];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** One paired (v2 router ↔ v3 shadow) turn. */
|
|
39
|
-
export interface ShadowDiffTurn {
|
|
40
|
-
conversationId: string;
|
|
41
|
-
/** Epoch ms of the v3 shadow row. */
|
|
42
|
-
shadowAt: number;
|
|
43
|
-
/** Epoch ms of the paired v2 router row. */
|
|
44
|
-
routerAt: number;
|
|
45
|
-
/** `routerAt - shadowAt`; small (within tolerance) by construction. */
|
|
46
|
-
deltaMs: number;
|
|
47
|
-
/** Size of the v2 fresh pick (`status: "injected"`). */
|
|
48
|
-
v2Count: number;
|
|
49
|
-
/** Size of the v3 shadow selection. */
|
|
50
|
-
v3Count: number;
|
|
51
|
-
/** v2 pages carried over from prior turns (`in_context`); annotation only. */
|
|
52
|
-
v2CachedCount: number;
|
|
53
|
-
/** `|overlap| / |v2 ∪ v3|`; 0 when both sets are empty. */
|
|
54
|
-
jaccard: number;
|
|
55
|
-
/** Slugs both systems picked, sorted. */
|
|
56
|
-
overlap: string[];
|
|
57
|
-
/** Slugs v3 surfaced but v2 did not freshly inject, sorted. */
|
|
58
|
-
v3Only: string[];
|
|
59
|
-
/** Slugs v2 freshly injected but v3 missed, sorted. */
|
|
60
|
-
v2Only: string[];
|
|
61
|
-
/** Provenance lane for each v3 slug (overlap + v3-only). */
|
|
62
|
-
laneBySlug: Record<string, string>;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** A shadow row with no router row inside the tolerance window. */
|
|
66
|
-
export interface UnpairedShadowTurn {
|
|
67
|
-
conversationId: string;
|
|
68
|
-
shadowAt: number;
|
|
69
|
-
v3Count: number;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** A slug with how many paired turns it appeared in. */
|
|
73
|
-
export interface SlugFrequency {
|
|
74
|
-
slug: string;
|
|
75
|
-
count: number;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface ShadowDiffResult {
|
|
79
|
-
/** Pairing tolerance actually used (ms). */
|
|
80
|
-
toleranceMs: number;
|
|
81
|
-
/** Total v3 shadow rows in the read window. */
|
|
82
|
-
shadowRows: number;
|
|
83
|
-
/** Shadow rows that paired to a router row. */
|
|
84
|
-
turnsCompared: number;
|
|
85
|
-
/** Shadow rows that did not pair. */
|
|
86
|
-
unpaired: UnpairedShadowTurn[];
|
|
87
|
-
agg: {
|
|
88
|
-
meanV2: number;
|
|
89
|
-
meanV3: number;
|
|
90
|
-
meanOverlap: number;
|
|
91
|
-
meanJaccard: number;
|
|
92
|
-
totalOverlap: number;
|
|
93
|
-
totalV3Only: number;
|
|
94
|
-
totalV2Only: number;
|
|
95
|
-
/** v3-only slug count by the lane that surfaced it — v3's extra reach. */
|
|
96
|
-
v3OnlyByLane: Record<string, number>;
|
|
97
|
-
/** overlap slug count by the v3 lane that recovered v2's pick. */
|
|
98
|
-
overlapByLane: Record<string, number>;
|
|
99
|
-
/** Most frequently dropped v2 pages (recall-regression watchlist). */
|
|
100
|
-
v2OnlyTop: SlugFrequency[];
|
|
101
|
-
/** Most frequent v3 extras (associative reach beyond v2). */
|
|
102
|
-
v3OnlyTop: SlugFrequency[];
|
|
103
|
-
};
|
|
104
|
-
/** Per-turn detail, newest first, capped at the requested limit. */
|
|
105
|
-
turns: ShadowDiffTurn[];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** Status on a v2 router row that counts as a fresh per-turn selection. */
|
|
109
|
-
const V2_PICKED_STATUS = "injected";
|
|
110
|
-
/** Status on a v2 router row that means carried-over from a prior turn. */
|
|
111
|
-
const V2_CACHED_STATUS = "in_context";
|
|
112
|
-
/** How many slugs to list in the top-frequency aggregates. */
|
|
113
|
-
const TOP_FREQUENCY_LIMIT = 15;
|
|
114
|
-
|
|
115
|
-
function selectedV2Slugs(concepts: MemoryV2ConceptRowRecord[]): Set<string> {
|
|
116
|
-
const slugs = new Set<string>();
|
|
117
|
-
for (const c of concepts) {
|
|
118
|
-
if (c.status === V2_PICKED_STATUS) slugs.add(c.slug);
|
|
119
|
-
}
|
|
120
|
-
return slugs;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function cachedV2Count(concepts: MemoryV2ConceptRowRecord[]): number {
|
|
124
|
-
let n = 0;
|
|
125
|
-
for (const c of concepts) {
|
|
126
|
-
if (c.status === V2_CACHED_STATUS) n += 1;
|
|
127
|
-
}
|
|
128
|
-
return n;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function v3LaneBySlug(
|
|
132
|
-
concepts: MemoryV2ConceptRowRecord[],
|
|
133
|
-
): Map<string, string> {
|
|
134
|
-
const bySlug = new Map<string, string>();
|
|
135
|
-
for (const c of concepts) {
|
|
136
|
-
bySlug.set(c.slug, c.lane ?? "unknown");
|
|
137
|
-
}
|
|
138
|
-
return bySlug;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/** Increment a string-keyed tally in place. */
|
|
142
|
-
function bump(tally: Record<string, number>, key: string): void {
|
|
143
|
-
tally[key] = (tally[key] ?? 0) + 1;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** Sort a frequency map into the top-N slugs, ties broken by slug name. */
|
|
147
|
-
function topSlugs(freq: Map<string, number>, limit: number): SlugFrequency[] {
|
|
148
|
-
return [...freq.entries()]
|
|
149
|
-
.map(([slug, count]) => ({ slug, count }))
|
|
150
|
-
.sort((a, b) => b.count - a.count || a.slug.localeCompare(b.slug))
|
|
151
|
-
.slice(0, limit);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Pair each shadow row to the nearest unconsumed router row in the same
|
|
156
|
-
* conversation within `toleranceMs`, then diff the two selections. Pairing is
|
|
157
|
-
* greedy by absolute time delta; since real turns are minutes apart while a
|
|
158
|
-
* shadow/router sibling pair lands a second or two apart, the greedy match is a
|
|
159
|
-
* clean bijection in practice.
|
|
160
|
-
*/
|
|
161
|
-
export function computeShadowDiff(
|
|
162
|
-
shadow: readonly ShadowDiffLogRow[],
|
|
163
|
-
router: readonly ShadowDiffLogRow[],
|
|
164
|
-
opts: { toleranceMs: number; detailLimit: number },
|
|
165
|
-
): ShadowDiffResult {
|
|
166
|
-
const { toleranceMs, detailLimit } = opts;
|
|
167
|
-
|
|
168
|
-
// Index router rows by conversation, time-sorted, with a consumed flag so a
|
|
169
|
-
// router row pairs to at most one shadow row.
|
|
170
|
-
const routerByConv = new Map<
|
|
171
|
-
string,
|
|
172
|
-
Array<{ row: ShadowDiffLogRow; consumed: boolean }>
|
|
173
|
-
>();
|
|
174
|
-
for (const row of router) {
|
|
175
|
-
const bucket = routerByConv.get(row.conversationId) ?? [];
|
|
176
|
-
bucket.push({ row, consumed: false });
|
|
177
|
-
routerByConv.set(row.conversationId, bucket);
|
|
178
|
-
}
|
|
179
|
-
for (const bucket of routerByConv.values()) {
|
|
180
|
-
bucket.sort((a, b) => a.row.createdAt - b.row.createdAt);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const sortedShadow = [...shadow].sort((a, b) => a.createdAt - b.createdAt);
|
|
184
|
-
|
|
185
|
-
const turns: ShadowDiffTurn[] = [];
|
|
186
|
-
const unpaired: UnpairedShadowTurn[] = [];
|
|
187
|
-
const v3OnlyByLane: Record<string, number> = {};
|
|
188
|
-
const overlapByLane: Record<string, number> = {};
|
|
189
|
-
const v2OnlyFreq = new Map<string, number>();
|
|
190
|
-
const v3OnlyFreq = new Map<string, number>();
|
|
191
|
-
|
|
192
|
-
for (const sh of sortedShadow) {
|
|
193
|
-
const bucket = routerByConv.get(sh.conversationId);
|
|
194
|
-
let best: { row: ShadowDiffLogRow; consumed: boolean } | undefined;
|
|
195
|
-
let bestDelta = Number.POSITIVE_INFINITY;
|
|
196
|
-
for (const candidate of bucket ?? []) {
|
|
197
|
-
if (candidate.consumed) continue;
|
|
198
|
-
const delta = Math.abs(candidate.row.createdAt - sh.createdAt);
|
|
199
|
-
if (delta < bestDelta) {
|
|
200
|
-
bestDelta = delta;
|
|
201
|
-
best = candidate;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (!best || bestDelta > toleranceMs) {
|
|
206
|
-
unpaired.push({
|
|
207
|
-
conversationId: sh.conversationId,
|
|
208
|
-
shadowAt: sh.createdAt,
|
|
209
|
-
v3Count: new Set(sh.concepts.map((c) => c.slug)).size,
|
|
210
|
-
});
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
best.consumed = true;
|
|
214
|
-
|
|
215
|
-
const v2Set = selectedV2Slugs(best.row.concepts);
|
|
216
|
-
const laneBySlug = v3LaneBySlug(sh.concepts);
|
|
217
|
-
const v3Set = new Set(laneBySlug.keys());
|
|
218
|
-
|
|
219
|
-
const overlap: string[] = [];
|
|
220
|
-
const v3Only: string[] = [];
|
|
221
|
-
for (const slug of v3Set) {
|
|
222
|
-
if (v2Set.has(slug)) {
|
|
223
|
-
overlap.push(slug);
|
|
224
|
-
bump(overlapByLane, laneBySlug.get(slug)!);
|
|
225
|
-
} else {
|
|
226
|
-
v3Only.push(slug);
|
|
227
|
-
bump(v3OnlyByLane, laneBySlug.get(slug)!);
|
|
228
|
-
v3OnlyFreq.set(slug, (v3OnlyFreq.get(slug) ?? 0) + 1);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
const v2Only: string[] = [];
|
|
232
|
-
for (const slug of v2Set) {
|
|
233
|
-
if (!v3Set.has(slug)) {
|
|
234
|
-
v2Only.push(slug);
|
|
235
|
-
v2OnlyFreq.set(slug, (v2OnlyFreq.get(slug) ?? 0) + 1);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const unionSize = new Set([...v2Set, ...v3Set]).size;
|
|
240
|
-
turns.push({
|
|
241
|
-
conversationId: sh.conversationId,
|
|
242
|
-
shadowAt: sh.createdAt,
|
|
243
|
-
routerAt: best.row.createdAt,
|
|
244
|
-
deltaMs: best.row.createdAt - sh.createdAt,
|
|
245
|
-
v2Count: v2Set.size,
|
|
246
|
-
v3Count: v3Set.size,
|
|
247
|
-
v2CachedCount: cachedV2Count(best.row.concepts),
|
|
248
|
-
jaccard: unionSize === 0 ? 0 : overlap.length / unionSize,
|
|
249
|
-
overlap: overlap.sort(),
|
|
250
|
-
v3Only: v3Only.sort(),
|
|
251
|
-
v2Only: v2Only.sort(),
|
|
252
|
-
laneBySlug: Object.fromEntries(laneBySlug),
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const n = turns.length;
|
|
257
|
-
const sum = (pick: (t: ShadowDiffTurn) => number): number =>
|
|
258
|
-
turns.reduce((acc, t) => acc + pick(t), 0);
|
|
259
|
-
const mean = (pick: (t: ShadowDiffTurn) => number): number =>
|
|
260
|
-
n === 0 ? 0 : sum(pick) / n;
|
|
261
|
-
|
|
262
|
-
// Newest-first for the detail listing; aggregates are order-independent.
|
|
263
|
-
const detail = [...turns]
|
|
264
|
-
.sort((a, b) => b.shadowAt - a.shadowAt)
|
|
265
|
-
.slice(0, detailLimit);
|
|
266
|
-
|
|
267
|
-
return {
|
|
268
|
-
toleranceMs,
|
|
269
|
-
shadowRows: shadow.length,
|
|
270
|
-
turnsCompared: n,
|
|
271
|
-
unpaired,
|
|
272
|
-
agg: {
|
|
273
|
-
meanV2: mean((t) => t.v2Count),
|
|
274
|
-
meanV3: mean((t) => t.v3Count),
|
|
275
|
-
meanOverlap: mean((t) => t.overlap.length),
|
|
276
|
-
meanJaccard: mean((t) => t.jaccard),
|
|
277
|
-
totalOverlap: sum((t) => t.overlap.length),
|
|
278
|
-
totalV3Only: sum((t) => t.v3Only.length),
|
|
279
|
-
totalV2Only: sum((t) => t.v2Only.length),
|
|
280
|
-
v3OnlyByLane,
|
|
281
|
-
overlapByLane,
|
|
282
|
-
v2OnlyTop: topSlugs(v2OnlyFreq, TOP_FREQUENCY_LIMIT),
|
|
283
|
-
v3OnlyTop: topSlugs(v3OnlyFreq, TOP_FREQUENCY_LIMIT),
|
|
284
|
-
},
|
|
285
|
-
turns: detail,
|
|
286
|
-
};
|
|
287
|
-
}
|
|
@@ -1,347 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — live-shadow `memoryRetrieval` middleware.
|
|
3
|
-
*
|
|
4
|
-
* Registered unconditionally into the `memoryRetrieval` pipeline, but inert
|
|
5
|
-
* unless BOTH `config.memory.v3.enabled` and `config.memory.v3.shadow` are on.
|
|
6
|
-
* When inert it is a byte-for-byte pass-through: it returns `next(args)`
|
|
7
|
-
* verbatim and performs zero extra work (no v3 call, no DB read, no log write).
|
|
8
|
-
*
|
|
9
|
-
* When active, it:
|
|
10
|
-
* 1. Returns the real (v2/default) `MemoryResult` from `next(args)` promptly —
|
|
11
|
-
* the injected context is ALWAYS the v2 result, never v3.
|
|
12
|
-
* 2. Kicks off the v3 retrieval loop DETACHED (not awaited on the path that
|
|
13
|
-
* returns the result), so the shadow run can never block or slow the turn.
|
|
14
|
-
* 3. Logs v3's selection set to `memory_v2_activation_logs` with
|
|
15
|
-
* `mode = "v3_shadow"`. The harness oracle filters `mode='router'`, so
|
|
16
|
-
* shadow rows never pollute it; the inspector can still surface them.
|
|
17
|
-
*
|
|
18
|
-
* The shadow build mirrors the inputs the v2 router receives (recent turn
|
|
19
|
-
* pairs, NOW context, prior-ever-injected slugs, config) so its recall is
|
|
20
|
-
* measured against the same situational context the live path saw. Failures
|
|
21
|
-
* are swallowed with a warn — the shadow is observational only and must never
|
|
22
|
-
* affect the live turn.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { desc, eq } from "drizzle-orm";
|
|
26
|
-
|
|
27
|
-
import { getConfig } from "../../config/loader.js";
|
|
28
|
-
import { registerPlugin } from "../../plugins/registry.js";
|
|
29
|
-
import {
|
|
30
|
-
type MemoryArgs,
|
|
31
|
-
type MemoryResult,
|
|
32
|
-
type Middleware,
|
|
33
|
-
type Plugin,
|
|
34
|
-
PluginExecutionError,
|
|
35
|
-
} from "../../plugins/types.js";
|
|
36
|
-
import type { ContentBlock } from "../../providers/types.js";
|
|
37
|
-
import { isUntrustedTrustClass } from "../../runtime/actor-trust-resolver.js";
|
|
38
|
-
import { getLogger } from "../../util/logger.js";
|
|
39
|
-
import { getWorkspaceDir } from "../../util/platform.js";
|
|
40
|
-
import type { DrizzleDb } from "../db-connection.js";
|
|
41
|
-
import { getDb } from "../db-connection.js";
|
|
42
|
-
import {
|
|
43
|
-
type MemoryV2ConceptRowRecord,
|
|
44
|
-
type MemoryV2ConfigSnapshot,
|
|
45
|
-
recordMemoryV2ActivationLog,
|
|
46
|
-
} from "../memory-v2-activation-log-store.js";
|
|
47
|
-
import { messages } from "../schema.js";
|
|
48
|
-
import { hydrate } from "../v2/activation-store.js";
|
|
49
|
-
import type { RetrievalInput } from "../v2/harness/retriever.js";
|
|
50
|
-
import { loadNowText } from "../v2/now-text.js";
|
|
51
|
-
import type { RouterTurnPair } from "../v2/router.js";
|
|
52
|
-
import type { EverInjectedEntry } from "../v2/types.js";
|
|
53
|
-
import { runRetrievalLoop } from "./loop.js";
|
|
54
|
-
|
|
55
|
-
const log = getLogger("memory-v3-shadow");
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Extract the recent (assistant, user) turn pairs from a conversation's
|
|
59
|
-
* message list, newest-pair-last, capped at `k`. Mirrors production
|
|
60
|
-
* `extractRecentTurnPairs` in `conversation-graph-memory.ts` (and its harness
|
|
61
|
-
* twin in `replay-input.ts`) so the shadow's `recentTurnPairs` matches what the
|
|
62
|
-
* live router was fed.
|
|
63
|
-
*/
|
|
64
|
-
function extractRecentTurnPairs(
|
|
65
|
-
msgs: ReadonlyArray<{ role: string; content: ContentBlock[] }>,
|
|
66
|
-
k: number,
|
|
67
|
-
): RouterTurnPair[] {
|
|
68
|
-
const messageText = (content: ContentBlock[]): string =>
|
|
69
|
-
content
|
|
70
|
-
.filter(
|
|
71
|
-
(b): b is Extract<ContentBlock, { type: "text" }> => b.type === "text",
|
|
72
|
-
)
|
|
73
|
-
.map((b) => b.text)
|
|
74
|
-
.join(" ");
|
|
75
|
-
|
|
76
|
-
const pairs: RouterTurnPair[] = [];
|
|
77
|
-
let pendingUser: string | null = null;
|
|
78
|
-
for (let i = msgs.length - 1; i >= 0 && pairs.length < k; i--) {
|
|
79
|
-
const msg = msgs[i]!;
|
|
80
|
-
if (msg.role === "user" && pendingUser === null) {
|
|
81
|
-
pendingUser = messageText(msg.content);
|
|
82
|
-
} else if (msg.role === "assistant" && pendingUser !== null) {
|
|
83
|
-
pairs.unshift({
|
|
84
|
-
assistantMessage: messageText(msg.content),
|
|
85
|
-
userMessage: pendingUser,
|
|
86
|
-
});
|
|
87
|
-
pendingUser = null;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
if (pendingUser !== null && pairs.length < k) {
|
|
91
|
-
pairs.unshift({ assistantMessage: "", userMessage: pendingUser });
|
|
92
|
-
}
|
|
93
|
-
if (pairs.length === 0) {
|
|
94
|
-
pairs.push({ assistantMessage: "", userMessage: "" });
|
|
95
|
-
}
|
|
96
|
-
return pairs;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** Parse a persisted JSON content-block string; tolerate malformed rows. */
|
|
100
|
-
function parseContent(raw: string): ContentBlock[] {
|
|
101
|
-
try {
|
|
102
|
-
const parsed = JSON.parse(raw);
|
|
103
|
-
return Array.isArray(parsed) ? (parsed as ContentBlock[]) : [];
|
|
104
|
-
} catch {
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Load the most recent messages for a conversation, oldest-first, bounded to a
|
|
111
|
-
* small generous multiple of `historicalPairs`. Pair extraction only needs the
|
|
112
|
-
* tail, so a bounded `LIMIT` query avoids loading an entire (potentially
|
|
113
|
-
* multi-GB) conversation on every shadow turn — mirrors the harness's bounded
|
|
114
|
-
* fetch in `replay-input.ts`.
|
|
115
|
-
*/
|
|
116
|
-
function loadRecentMessages(
|
|
117
|
-
db: DrizzleDb,
|
|
118
|
-
conversationId: string,
|
|
119
|
-
historicalPairs: number,
|
|
120
|
-
): Array<{ role: string; content: ContentBlock[] }> {
|
|
121
|
-
const fetchWindow = Math.max(20, historicalPairs * 12);
|
|
122
|
-
const rows = db
|
|
123
|
-
.select({ role: messages.role, content: messages.content })
|
|
124
|
-
.from(messages)
|
|
125
|
-
.where(eq(messages.conversationId, conversationId))
|
|
126
|
-
.orderBy(desc(messages.createdAt), desc(messages.id))
|
|
127
|
-
.limit(fetchWindow)
|
|
128
|
-
.all();
|
|
129
|
-
return rows
|
|
130
|
-
.reverse()
|
|
131
|
-
.map((r) => ({ role: r.role, content: parseContent(r.content) }));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Empty config snapshot for shadow log rows. The activation-state values are
|
|
136
|
-
* meaningless for a v3 selection (it computes no spreading-activation scores),
|
|
137
|
-
* so they are zeroed — exactly as the v2 router-mode rows do.
|
|
138
|
-
*/
|
|
139
|
-
const SHADOW_CONFIG_SNAPSHOT: MemoryV2ConfigSnapshot = {
|
|
140
|
-
d: 0,
|
|
141
|
-
c_user: 0,
|
|
142
|
-
c_assistant: 0,
|
|
143
|
-
c_now: 0,
|
|
144
|
-
k: 0,
|
|
145
|
-
hops: 0,
|
|
146
|
-
top_k: 0,
|
|
147
|
-
epsilon: 0,
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Build the concept rows logged for a v3 shadow selection. Each selected slug
|
|
152
|
-
* becomes a zeroed concept row tagged `source: "router"` and
|
|
153
|
-
* `status: "injected"` — the shadow has no activation scores to record, and the
|
|
154
|
-
* `mode='v3_shadow'` row tag (not the concept source) is what distinguishes
|
|
155
|
-
* shadow telemetry from live router selections. Each row also carries the
|
|
156
|
-
* `lane` that surfaced the slug (from `sourceBySlug`) so a shadow run can be
|
|
157
|
-
* analyzed by provenance.
|
|
158
|
-
*/
|
|
159
|
-
function buildShadowConceptRows(
|
|
160
|
-
selectedSlugs: readonly string[],
|
|
161
|
-
sourceBySlug: ReadonlyMap<string, string>,
|
|
162
|
-
): MemoryV2ConceptRowRecord[] {
|
|
163
|
-
return selectedSlugs.map((slug) => ({
|
|
164
|
-
slug,
|
|
165
|
-
finalActivation: 0,
|
|
166
|
-
ownActivation: 0,
|
|
167
|
-
priorActivation: 0,
|
|
168
|
-
simUser: 0,
|
|
169
|
-
simAssistant: 0,
|
|
170
|
-
simNow: 0,
|
|
171
|
-
simUserRerankBoost: 0,
|
|
172
|
-
simAssistantRerankBoost: 0,
|
|
173
|
-
inRerankPool: false,
|
|
174
|
-
spreadContribution: 0,
|
|
175
|
-
source: "router",
|
|
176
|
-
status: "injected",
|
|
177
|
-
...(sourceBySlug.get(slug) ? { lane: sourceBySlug.get(slug) } : {}),
|
|
178
|
-
}));
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Run the v3 retrieval loop for the shadow and log its selection. Best-effort:
|
|
183
|
-
* any failure is logged and swallowed. Honors `signal` so a cancelled turn
|
|
184
|
-
* stops the shadow's lane work.
|
|
185
|
-
*/
|
|
186
|
-
async function runShadowAndLog(
|
|
187
|
-
args: MemoryArgs,
|
|
188
|
-
signal: AbortSignal,
|
|
189
|
-
): Promise<void> {
|
|
190
|
-
try {
|
|
191
|
-
if (signal.aborted) return;
|
|
192
|
-
|
|
193
|
-
const config = getConfig();
|
|
194
|
-
const workspaceDir = getWorkspaceDir();
|
|
195
|
-
const db = getDb();
|
|
196
|
-
|
|
197
|
-
const historicalPairs = config.memory.v2.router.historical_pairs;
|
|
198
|
-
const recentMessages = loadRecentMessages(
|
|
199
|
-
db,
|
|
200
|
-
args.conversationId,
|
|
201
|
-
historicalPairs,
|
|
202
|
-
);
|
|
203
|
-
const recentTurnPairs = extractRecentTurnPairs(
|
|
204
|
-
recentMessages,
|
|
205
|
-
historicalPairs,
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
const nowText = await loadNowText(workspaceDir);
|
|
209
|
-
|
|
210
|
-
let priorEverInjected: readonly EverInjectedEntry[] = [];
|
|
211
|
-
try {
|
|
212
|
-
const state = await hydrate(db, args.conversationId);
|
|
213
|
-
priorEverInjected = state?.everInjected ?? [];
|
|
214
|
-
} catch (err) {
|
|
215
|
-
log.warn(
|
|
216
|
-
{ err, conversationId: args.conversationId },
|
|
217
|
-
"v3 shadow: failed to hydrate prior-ever-injected; continuing with empty set",
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (signal.aborted) return;
|
|
222
|
-
|
|
223
|
-
const input: RetrievalInput = {
|
|
224
|
-
workspaceDir,
|
|
225
|
-
recentTurnPairs,
|
|
226
|
-
nowText,
|
|
227
|
-
priorEverInjected,
|
|
228
|
-
config,
|
|
229
|
-
signal,
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
const output = await runRetrievalLoop(input, {
|
|
233
|
-
db,
|
|
234
|
-
conversationId: args.conversationId,
|
|
235
|
-
turn: args.turnIndex,
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
if (signal.aborted) return;
|
|
239
|
-
|
|
240
|
-
// Per-turn summary so a shadow run is analyzable from the logs — the pool
|
|
241
|
-
// shape, how many passes ran, and the gate's verdict + rationale. The
|
|
242
|
-
// selection set + per-slug lane land in the activation log below.
|
|
243
|
-
const passes = output.trace?.passes ?? [];
|
|
244
|
-
const lastGate = passes[passes.length - 1]?.gate;
|
|
245
|
-
const laneTally: Record<string, number> = {};
|
|
246
|
-
for (const lane of output.sourceBySlug.values()) {
|
|
247
|
-
laneTally[lane] = (laneTally[lane] ?? 0) + 1;
|
|
248
|
-
}
|
|
249
|
-
log.info(
|
|
250
|
-
{
|
|
251
|
-
conversationId: args.conversationId,
|
|
252
|
-
turn: args.turnIndex,
|
|
253
|
-
selected: output.selectedSlugs.length,
|
|
254
|
-
poolSize: output.sourceBySlug.size,
|
|
255
|
-
laneTally,
|
|
256
|
-
passes: passes.length,
|
|
257
|
-
gateDecision: lastGate?.decision,
|
|
258
|
-
gateReasoning: lastGate?.reasoning,
|
|
259
|
-
},
|
|
260
|
-
"v3 shadow selection",
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
recordMemoryV2ActivationLog({
|
|
264
|
-
conversationId: args.conversationId,
|
|
265
|
-
turn: args.turnIndex,
|
|
266
|
-
mode: "v3_shadow",
|
|
267
|
-
concepts: buildShadowConceptRows(
|
|
268
|
-
output.selectedSlugs,
|
|
269
|
-
output.sourceBySlug,
|
|
270
|
-
),
|
|
271
|
-
config: SHADOW_CONFIG_SNAPSHOT,
|
|
272
|
-
});
|
|
273
|
-
} catch (err) {
|
|
274
|
-
log.warn(
|
|
275
|
-
{ err, conversationId: args.conversationId, turn: args.turnIndex },
|
|
276
|
-
"v3 shadow retrieval failed; live turn unaffected",
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Live-shadow `memoryRetrieval` middleware.
|
|
283
|
-
*
|
|
284
|
-
* Flag-gated INSIDE the middleware (per-turn, live-toggle): when v3 shadow is
|
|
285
|
-
* off it is a pure pass-through. When on, it fires the v3 loop detached and
|
|
286
|
-
* returns the unchanged downstream (v2) result immediately.
|
|
287
|
-
*
|
|
288
|
-
* The shadow loop spends filter + gate LLM calls, so — like the other
|
|
289
|
-
* guardian-trust background memory loops (`enqueueAutoAnalysisOnCompaction`,
|
|
290
|
-
* `enqueueMemoryRetrospectiveOnCompaction`) — it is gated on actor trust: an
|
|
291
|
-
* untrusted turn passes through without kicking off the v3 loop.
|
|
292
|
-
*/
|
|
293
|
-
export const memoryV3ShadowMiddleware: Middleware<MemoryArgs, MemoryResult> =
|
|
294
|
-
async function memoryV3Shadow(args, next) {
|
|
295
|
-
const v3 = getConfig().memory.v3;
|
|
296
|
-
if (!v3?.enabled || !v3?.shadow) {
|
|
297
|
-
// Inert: byte-for-byte pass-through, zero extra work.
|
|
298
|
-
return next(args);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (isUntrustedTrustClass(args.trustContext?.trustClass)) {
|
|
302
|
-
// Untrusted actor: don't spend shadow retrieval LLM calls — mirrors the
|
|
303
|
-
// live path's trust gate. Pure pass-through, no detached work.
|
|
304
|
-
return next(args);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// Detached — never awaited on the path that returns the result, so the
|
|
308
|
-
// shadow can neither block nor slow the live turn. Errors are swallowed
|
|
309
|
-
// inside `runShadowAndLog`.
|
|
310
|
-
void runShadowAndLog(args, args.signal);
|
|
311
|
-
|
|
312
|
-
return next(args);
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* First-party plugin contributing the live-shadow `memoryRetrieval`
|
|
317
|
-
* middleware. Registered unconditionally by the plugin bootstrap (it is inert
|
|
318
|
-
* unless both v3 flags are on), so the registration is always present but does
|
|
319
|
-
* zero work in the default (flags-off) configuration.
|
|
320
|
-
*/
|
|
321
|
-
export const memoryV3ShadowPlugin: Plugin = {
|
|
322
|
-
manifest: {
|
|
323
|
-
name: "memory-v3-shadow",
|
|
324
|
-
version: "0.0.1",
|
|
325
|
-
},
|
|
326
|
-
middleware: {
|
|
327
|
-
memoryRetrieval: memoryV3ShadowMiddleware,
|
|
328
|
-
},
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
// Module-load side effect: register the shadow plugin at import time so the
|
|
332
|
-
// registry is populated even in tests that skip `bootstrapPlugins()`, matching
|
|
333
|
-
// the first-party `default-*` plugins. Idempotent via the swallowed
|
|
334
|
-
// duplicate-name check (the defaults aggregator also lists this plugin).
|
|
335
|
-
try {
|
|
336
|
-
registerPlugin(memoryV3ShadowPlugin);
|
|
337
|
-
} catch (err) {
|
|
338
|
-
if (
|
|
339
|
-
err instanceof PluginExecutionError &&
|
|
340
|
-
err.message.includes("already registered")
|
|
341
|
-
) {
|
|
342
|
-
// already registered — expected when both the defaults aggregator and the
|
|
343
|
-
// direct module import run in the same process.
|
|
344
|
-
} else {
|
|
345
|
-
throw err;
|
|
346
|
-
}
|
|
347
|
-
}
|