@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,126 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — Compositional index rendering.
|
|
3
|
-
*
|
|
4
|
-
* A v3 tree node has no stored "index" of its own. Instead, a parent node's
|
|
5
|
-
* index is *composed at read time* by concatenating one description line per
|
|
6
|
-
* child (a `node:` sub-node's summary or a `page:` leaf's summary) plus a thin
|
|
7
|
-
* `Routing hints:` trailer drawn from the node's own frontmatter. Nothing here
|
|
8
|
-
* is persisted — the block is generated fresh every time a descent prompt needs
|
|
9
|
-
* it, so it always reflects the current state of the children.
|
|
10
|
-
*
|
|
11
|
-
* {@link composeNodeIndex} is a **pure function** over an already-built
|
|
12
|
-
* {@link TreeIndex} (from `tree-index.ts`) and {@link PageIndex} (from
|
|
13
|
-
* `../v2/page-index.ts`). It does no I/O: the tree walk / driver PR is
|
|
14
|
-
* responsible for building those indices and feeding them in.
|
|
15
|
-
*
|
|
16
|
-
* Resolution rules, per child ref of `nodeId` (in authored order):
|
|
17
|
-
* - `kind:"node"` → look up the child in `tree.nodes`; emit
|
|
18
|
-
* `"[node:<id>] <summary>"` where summary is the child's
|
|
19
|
-
* `frontmatter.summary` if non-empty, else the first non-empty line of its
|
|
20
|
-
* body. A node with neither still emits its header (`"[node:<id>]"`).
|
|
21
|
-
* - `kind:"page"` → look up `pages.bySlug.get(ref)`; emit
|
|
22
|
-
* `"[page:<slug>] <entry.summary>"`.
|
|
23
|
-
* - Either lookup missing → emit nothing for that ref. Reporting dangling
|
|
24
|
-
* refs is validation's job, not this renderer's.
|
|
25
|
-
*
|
|
26
|
-
* The node's own `routing_hints` (when present) are appended last under a
|
|
27
|
-
* `Routing hints:` trailer. A node with no resolvable children and no routing
|
|
28
|
-
* hints composes to the empty string.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
import type { PageIndex } from "../v2/page-index.js";
|
|
32
|
-
import type { TreeIndex } from "./tree-index.js";
|
|
33
|
-
import type { TreeNode } from "./types.js";
|
|
34
|
-
|
|
35
|
-
/** Trailer label introducing a node's own routing hints. */
|
|
36
|
-
const ROUTING_HINTS_LABEL = "Routing hints:";
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Flatten a summary to a single line. The index is parsed by the descender as
|
|
40
|
-
* one child per line, so any embedded newline (or other whitespace run) in a
|
|
41
|
-
* summary would corrupt that format — collapse every whitespace run to a single
|
|
42
|
-
* space and trim the ends.
|
|
43
|
-
*/
|
|
44
|
-
function collapseToSingleLine(text: string): string {
|
|
45
|
-
return text.replace(/\s+/g, " ").trim();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Resolve a node's display summary: its frontmatter `summary` if non-empty,
|
|
50
|
-
* otherwise the first non-empty line of its body, otherwise the empty string.
|
|
51
|
-
* Whitespace is trimmed so a leading blank line in the body never wins.
|
|
52
|
-
*/
|
|
53
|
-
function nodeSummary(node: TreeNode): string {
|
|
54
|
-
const summary = node.frontmatter.summary?.trim();
|
|
55
|
-
if (summary) return summary;
|
|
56
|
-
for (const line of node.body.split("\n")) {
|
|
57
|
-
const trimmed = line.trim();
|
|
58
|
-
if (trimmed) return trimmed;
|
|
59
|
-
}
|
|
60
|
-
return "";
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Render one child ref into its index line, or `null` when the ref's target is
|
|
65
|
-
* absent from the supplied indices (validation owns reporting those).
|
|
66
|
-
*
|
|
67
|
-
* A resolvable child always yields a line — its header (`[node:<id>]` /
|
|
68
|
-
* `[page:<slug>]`) with a trailing summary when one exists. Each summary is
|
|
69
|
-
* collapsed to a single line so an embedded newline can't break the one-child-
|
|
70
|
-
* per-line format the descender parses; the v2 page index already truncates
|
|
71
|
-
* `page:` summaries.
|
|
72
|
-
*/
|
|
73
|
-
function renderChild(
|
|
74
|
-
kind: "page" | "node",
|
|
75
|
-
ref: string,
|
|
76
|
-
tree: TreeIndex,
|
|
77
|
-
pages: PageIndex,
|
|
78
|
-
): string | null {
|
|
79
|
-
if (kind === "node") {
|
|
80
|
-
const child = tree.nodes.get(ref);
|
|
81
|
-
if (!child) return null;
|
|
82
|
-
const summary = collapseToSingleLine(nodeSummary(child));
|
|
83
|
-
return summary ? `[node:${ref}] ${summary}` : `[node:${ref}]`;
|
|
84
|
-
}
|
|
85
|
-
const entry = pages.bySlug.get(ref);
|
|
86
|
-
if (!entry) return null;
|
|
87
|
-
const summary = collapseToSingleLine(entry.summary);
|
|
88
|
-
return summary ? `[page:${ref}] ${summary}` : `[page:${ref}]`;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Compose the prompt-ready index block for `nodeId` from its children's
|
|
93
|
-
* descriptions plus the node's own routing hints.
|
|
94
|
-
*
|
|
95
|
-
* Pure and deterministic: children are emitted in authored order (the order
|
|
96
|
-
* `tree.childrenByNode` preserves from the node's `children` frontmatter), refs
|
|
97
|
-
* whose targets are absent are silently skipped, and the node's
|
|
98
|
-
* `routing_hints` (if present) are appended under a {@link ROUTING_HINTS_LABEL}
|
|
99
|
-
* trailer. A node with no entry in `childrenByNode`, no resolvable children,
|
|
100
|
-
* and no routing hints composes to the empty string.
|
|
101
|
-
*
|
|
102
|
-
* The result is a plain string with no trailing newline, suitable to drop
|
|
103
|
-
* directly into an LLM descent prompt.
|
|
104
|
-
*/
|
|
105
|
-
export function composeNodeIndex(
|
|
106
|
-
nodeId: string,
|
|
107
|
-
tree: TreeIndex,
|
|
108
|
-
pages: PageIndex,
|
|
109
|
-
): string {
|
|
110
|
-
const blocks: string[] = [];
|
|
111
|
-
|
|
112
|
-
const childRefs = tree.childrenByNode.get(nodeId) ?? [];
|
|
113
|
-
for (const { kind, ref } of childRefs) {
|
|
114
|
-
const line = renderChild(kind, ref, tree, pages);
|
|
115
|
-
if (line !== null) blocks.push(line);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const routingHints = tree.nodes
|
|
119
|
-
.get(nodeId)
|
|
120
|
-
?.frontmatter.routing_hints?.trim();
|
|
121
|
-
if (routingHints) {
|
|
122
|
-
blocks.push(`${ROUTING_HINTS_LABEL} ${routingHints}`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return blocks.join("\n");
|
|
126
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — LLM-call capture types.
|
|
3
|
-
*
|
|
4
|
-
* A debugging seam: when a sink is threaded into the retrieval loop, every v3
|
|
5
|
-
* LLM call (dense filter, each tree-walk descender call, the gate) emits one
|
|
6
|
-
* {@link LlmCallRecord} carrying the full input it sent and the raw response it
|
|
7
|
-
* got back. The `simulate` path collects these so an operator can inspect what
|
|
8
|
-
* each call actually saw and returned. Nothing here is persisted, and the sink
|
|
9
|
-
* is `undefined` on every non-simulate path, so production pays zero cost.
|
|
10
|
-
*
|
|
11
|
-
* Leaf module: it imports only provider types, so the lanes and the loop can
|
|
12
|
-
* depend on it without a cycle.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type {
|
|
16
|
-
Message,
|
|
17
|
-
ProviderResponse,
|
|
18
|
-
ToolDefinition,
|
|
19
|
-
} from "../../providers/types.js";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* One captured v3 LLM call — its full input (system prompt, messages, tool
|
|
23
|
-
* schema) and raw output (provider response). `pass` is the 1-based retrieval
|
|
24
|
-
* pass the call ran in; `node` is set only for the tree-walk descender (the
|
|
25
|
-
* node whose composed index it judged). `ms` is the provider round-trip time.
|
|
26
|
-
*/
|
|
27
|
-
export interface LlmCallRecord {
|
|
28
|
-
pass: number;
|
|
29
|
-
lane: "filter" | "descent" | "gate";
|
|
30
|
-
callSite: string;
|
|
31
|
-
node?: string;
|
|
32
|
-
request: {
|
|
33
|
-
systemPrompt: string;
|
|
34
|
-
messages: Message[];
|
|
35
|
-
tools: ToolDefinition[];
|
|
36
|
-
};
|
|
37
|
-
response: ProviderResponse;
|
|
38
|
-
ms: number;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* The sink a lane calls to emit a capture record. Lanes don't know their pass
|
|
43
|
-
* number, so they emit without `pass` and the loop wraps the sink to stamp the
|
|
44
|
-
* current pass. `undefined` on every non-capturing path (the common case).
|
|
45
|
-
*/
|
|
46
|
-
export type LlmCallSink = (record: Omit<LlmCallRecord, "pass">) => void;
|
package/src/memory/v3/loop.ts
DELETED
|
@@ -1,430 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — retrieval-loop orchestration.
|
|
3
|
-
*
|
|
4
|
-
* The composition layer that wires the v3 lanes into a single bounded-descent
|
|
5
|
-
* retrieval loop. Each pass runs the lanes in a fixed order:
|
|
6
|
-
*
|
|
7
|
-
* 1. {@link runScouts} — always-on hot / sparse / dense fanout. Surfaces
|
|
8
|
-
* candidate slugs plus the `sticky` (keep-in-the-
|
|
9
|
-
* running) and `bypass` (skip-the-tree) sets.
|
|
10
|
-
* 2. {@link filterDenseHits} — one cheap LLM call over the *dense* lane only.
|
|
11
|
-
* Hot + near-exact-sparse hits arrive via
|
|
12
|
-
* sticky/bypass and are never judged; the dense
|
|
13
|
-
* near-neighbors are filtered down to meaningful
|
|
14
|
-
* associations.
|
|
15
|
-
* 3. {@link runTreeWalk} — root-only hierarchical descent that selects
|
|
16
|
-
* pages per node. Scout hits steer it as descend
|
|
17
|
-
* pressure in the prompt; the descender keeps only
|
|
18
|
-
* the relevant leaf pages it finds.
|
|
19
|
-
* 4. {@link expandEdges} — provider-free 1–2 hop curated-graph expansion
|
|
20
|
-
* over every accumulated confident seed.
|
|
21
|
-
* 5. {@link runGate} — one capable LLM call over the unioned candidate
|
|
22
|
-
* set. Returns `ready` (finalize) or `more`
|
|
23
|
-
* (its generated follow-up questions seed the next
|
|
24
|
-
* pass's query).
|
|
25
|
-
*
|
|
26
|
-
* Pass control. The loop runs at most `config.memory.v3.passCap` passes. When
|
|
27
|
-
* the gate says `more` and another pass is allowed, the gate's questions become
|
|
28
|
-
* the next pass's query (folded into `nowText`); otherwise the loop force-exits
|
|
29
|
-
* with the current selection. The standing-context files conveyed via
|
|
30
|
-
* `input.nowText` are consumed as situational context for the scouts, descent,
|
|
31
|
-
* and gate — the loop selects concept pages to layer on top and NEVER rewrites
|
|
32
|
-
* or re-injects the standing-context files.
|
|
33
|
-
*
|
|
34
|
-
* Lane toggles. `config.memory.v3.lanes.tree` and `.edges` gate the tree-walk
|
|
35
|
-
* and edge-expansion lanes here; the hot/sparse/dense toggles are honored inside
|
|
36
|
-
* {@link runScouts}. Toggling a lane off removes its contribution from the
|
|
37
|
-
* candidate set so the offline harness can measure each lane's marginal recall.
|
|
38
|
-
*
|
|
39
|
-
* Cross-pass accumulation. The `candidates` pool is unioned across every pass
|
|
40
|
-
* and the gate judges that cumulative pool, so a multi-pass `more` never drops
|
|
41
|
-
* the non-sticky hits earlier passes surfaced. Each slug is tagged with the
|
|
42
|
-
* most trusted lane that surfaced it (`sourceBySlug`). The full
|
|
43
|
-
* {@link DescentTrace}
|
|
44
|
-
* carries one {@link DescentPass} per pass (scouts / treeLevels /
|
|
45
|
-
* edgeExpansions / gate), and {@link RetrievalCost} (wall-clock `ms`, the one
|
|
46
|
-
* dimension observable at this composition layer) accumulates across every pass.
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
import { getLogger } from "../../util/logger.js";
|
|
50
|
-
import type { DrizzleDb } from "../db-connection.js";
|
|
51
|
-
import type {
|
|
52
|
-
RetrievalCost,
|
|
53
|
-
RetrievalInput,
|
|
54
|
-
RetrievalOutput,
|
|
55
|
-
} from "../v2/harness/retriever.js";
|
|
56
|
-
import type {
|
|
57
|
-
DescentPass,
|
|
58
|
-
DescentTrace,
|
|
59
|
-
GateDecision,
|
|
60
|
-
} from "../v2/harness/trace.js";
|
|
61
|
-
import { getPageIndex } from "../v2/page-index.js";
|
|
62
|
-
import { aboveThreshold } from "./auto-edges.js";
|
|
63
|
-
import {
|
|
64
|
-
type CoactivationRow,
|
|
65
|
-
recordCoactivations,
|
|
66
|
-
} from "./coactivation-store.js";
|
|
67
|
-
import { expandEdges } from "./edges.js";
|
|
68
|
-
import { filterDenseHits } from "./filter.js";
|
|
69
|
-
import { runGate } from "./gate.js";
|
|
70
|
-
import type { LlmCallRecord, LlmCallSink } from "./llm-capture.js";
|
|
71
|
-
import { runScouts } from "./scouts.js";
|
|
72
|
-
import { getTreeIndex } from "./tree-index.js";
|
|
73
|
-
import { runTreeWalk } from "./tree-walk.js";
|
|
74
|
-
|
|
75
|
-
/** Lane label used to tag each selected slug's provenance in `sourceBySlug`. */
|
|
76
|
-
type LaneSource = "hot" | "sparse" | "dense" | "tree" | "edge";
|
|
77
|
-
|
|
78
|
-
const log = getLogger("memory-v3-loop");
|
|
79
|
-
|
|
80
|
-
/** Injected dependencies — the SQLite handle the scout hot lane reads. */
|
|
81
|
-
export interface RetrievalLoopDeps {
|
|
82
|
-
db: DrizzleDb;
|
|
83
|
-
/**
|
|
84
|
-
* Conversation this retrieval is running for. Stamped on co-activation rows
|
|
85
|
-
* when `config.memory.v3.write.coactivation` is on. Empty string when the
|
|
86
|
-
* loop runs in the offline harness (no live conversation).
|
|
87
|
-
*/
|
|
88
|
-
conversationId?: string;
|
|
89
|
-
/** Turn number within the conversation, for co-activation provenance. */
|
|
90
|
-
turn?: number;
|
|
91
|
-
/**
|
|
92
|
-
* Optional debug sink. When set, every v3 LLM call (filter / each descender /
|
|
93
|
-
* gate) emits one {@link LlmCallRecord} with its full input + raw response.
|
|
94
|
-
* Undefined on the live/shadow path, so production captures nothing.
|
|
95
|
-
*/
|
|
96
|
-
capture?: (record: LlmCallRecord) => void;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Run the full v3 retrieval loop for one turn.
|
|
101
|
-
*
|
|
102
|
-
* Composes the scout / filter / tree / edge / gate lanes over up to
|
|
103
|
-
* `config.memory.v3.passCap` passes, returning the P1 {@link RetrievalOutput}:
|
|
104
|
-
* the final selection, per-lane provenance, the complete multi-pass
|
|
105
|
-
* {@link DescentTrace}, and accumulated {@link RetrievalCost}. `failureReason`
|
|
106
|
-
* is set when the dense filter had to fail open on any pass (the loop still
|
|
107
|
-
* returns a usable selection — the filter degradation is recorded, not fatal).
|
|
108
|
-
*/
|
|
109
|
-
export async function runRetrievalLoop(
|
|
110
|
-
input: RetrievalInput,
|
|
111
|
-
deps: RetrievalLoopDeps,
|
|
112
|
-
): Promise<RetrievalOutput> {
|
|
113
|
-
const v3 = input.config.memory.v3;
|
|
114
|
-
const passCap = Math.max(1, v3.passCap);
|
|
115
|
-
const lanes = v3.lanes;
|
|
116
|
-
|
|
117
|
-
// Learned co-retrieval adjacency (memory_v3_auto_edges), read once and merged
|
|
118
|
-
// into the edge lane's curated graph when the threshold is set. At threshold 0
|
|
119
|
-
// (the default) this is undefined and edge behavior is identical to before.
|
|
120
|
-
const learnedAdjacencyThreshold = v3.edges?.learnedAdjacencyThreshold ?? 0;
|
|
121
|
-
const learnedAdjacency =
|
|
122
|
-
learnedAdjacencyThreshold > 0
|
|
123
|
-
? aboveThreshold(deps.db, learnedAdjacencyThreshold)
|
|
124
|
-
: undefined;
|
|
125
|
-
|
|
126
|
-
// Cross-pass accumulators.
|
|
127
|
-
const sourceBySlug = new Map<string, LaneSource>();
|
|
128
|
-
// Candidate pool unioned across every pass. Each pass adds its own surfaced
|
|
129
|
-
// slugs (hot/sparse, dense-filter survivors, tree, edge) and the gate judges
|
|
130
|
-
// the cumulative pool, so a multi-pass `more` never discards earlier passes'
|
|
131
|
-
// non-sticky hits.
|
|
132
|
-
const candidates = new Set<string>();
|
|
133
|
-
// The first pass each slug entered the candidate set. Drives co-activation
|
|
134
|
-
// emission below — pass-1 hits (gap source) vs. later-surfaced pages (target).
|
|
135
|
-
const firstPassBySlug = new Map<string, number>();
|
|
136
|
-
const sticky = new Set<string>();
|
|
137
|
-
const passes: DescentPass[] = [];
|
|
138
|
-
// `ms` is the one cost dimension observable at this composition layer — the
|
|
139
|
-
// lanes consume their own LLM usage internally and don't surface tokens.
|
|
140
|
-
const cost: RetrievalCost & { ms: number } = { ms: 0 };
|
|
141
|
-
let failureReason: string | null = null;
|
|
142
|
-
|
|
143
|
-
// The query feeding each pass. Pass 1 uses the turn's NOW context verbatim;
|
|
144
|
-
// a gate `more` verdict appends its generated follow-up questions for the
|
|
145
|
-
// next pass. The standing-context files are never rewritten — questions are
|
|
146
|
-
// layered on as additional situational context only.
|
|
147
|
-
let passNowText = input.nowText;
|
|
148
|
-
|
|
149
|
-
// Final selection — replaced by the gate each pass; the last pass's selection
|
|
150
|
-
// is what the loop returns (capped at passCap on a forced exit).
|
|
151
|
-
let selectedSlugs: string[] = [];
|
|
152
|
-
|
|
153
|
-
for (let passNumber = 1; passNumber <= passCap; passNumber++) {
|
|
154
|
-
const passStart = Date.now();
|
|
155
|
-
const passInput: RetrievalInput = { ...input, nowText: passNowText };
|
|
156
|
-
|
|
157
|
-
// Per-pass capture sink: stamp the current pass onto each lane's emitted
|
|
158
|
-
// record. Stays undefined (inert) unless a capture sink was injected.
|
|
159
|
-
const sink = deps.capture;
|
|
160
|
-
const passSink: LlmCallSink | undefined = sink
|
|
161
|
-
? (record) => sink({ ...record, pass: passNumber })
|
|
162
|
-
: undefined;
|
|
163
|
-
|
|
164
|
-
// 1. Scouts — always-on hot / sparse / dense fanout.
|
|
165
|
-
const scoutResult = await runScouts(passInput, { db: deps.db });
|
|
166
|
-
for (const slug of scoutResult.sticky) sticky.add(slug);
|
|
167
|
-
|
|
168
|
-
// Tag hot + sparse scout hits with their lane (most trusted lane wins —
|
|
169
|
-
// see tagSlug). Dense slugs are tagged only if they survive the filter
|
|
170
|
-
// below — a dropped dense near-neighbor never enters the candidate set, so
|
|
171
|
-
// it earns no source tag.
|
|
172
|
-
for (const scout of scoutResult.scouts) {
|
|
173
|
-
if (scout.lane === "dense") continue;
|
|
174
|
-
for (const slug of scout.slugs) tagSlug(sourceBySlug, slug, scout.lane);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// 2. Dense filter — judges only the dense lane (hot/sparse bypass it). Only
|
|
178
|
-
// the surviving dense slugs enter the candidate pool; a dropped dense
|
|
179
|
-
// near-neighbor never joins it (and so never reaches the gate).
|
|
180
|
-
const denseScout = scoutResult.scouts.find((s) => s.lane === "dense");
|
|
181
|
-
|
|
182
|
-
// Hot + sparse lane hits enter the candidate set directly.
|
|
183
|
-
for (const scout of scoutResult.scouts) {
|
|
184
|
-
if (scout.lane === "dense") continue;
|
|
185
|
-
for (const slug of scout.slugs) candidates.add(slug);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (denseScout) {
|
|
189
|
-
const filtered = await filterDenseHits({
|
|
190
|
-
input: passInput,
|
|
191
|
-
dense: denseScout,
|
|
192
|
-
sticky: scoutResult.sticky,
|
|
193
|
-
bypass: scoutResult.bypass,
|
|
194
|
-
capture: passSink,
|
|
195
|
-
});
|
|
196
|
-
for (const slug of filtered.kept) {
|
|
197
|
-
candidates.add(slug);
|
|
198
|
-
tagSlug(sourceBySlug, slug, "dense");
|
|
199
|
-
}
|
|
200
|
-
if (filtered.failureReason !== undefined) {
|
|
201
|
-
failureReason = filtered.failureReason;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// 3. Tree walk — root-only hierarchical descent that selects pages per
|
|
206
|
-
// node. Scout hits steer it as descend pressure in the prompt (the scout
|
|
207
|
-
// pages themselves already entered `candidates` above). Gated by `lanes.tree`.
|
|
208
|
-
let treeLevels: DescentPass["treeLevels"];
|
|
209
|
-
if (lanes.tree) {
|
|
210
|
-
const [tree, pages] = await Promise.all([
|
|
211
|
-
getTreeIndex(passInput.workspaceDir),
|
|
212
|
-
getPageIndex(passInput.workspaceDir),
|
|
213
|
-
]);
|
|
214
|
-
const walk = await runTreeWalk({
|
|
215
|
-
input: passInput,
|
|
216
|
-
tree,
|
|
217
|
-
pages,
|
|
218
|
-
scouts: scoutResult.scouts,
|
|
219
|
-
capture: passSink,
|
|
220
|
-
});
|
|
221
|
-
treeLevels = walk.levels;
|
|
222
|
-
for (const slug of walk.pages) {
|
|
223
|
-
candidates.add(slug);
|
|
224
|
-
tagSlug(sourceBySlug, slug, "tree");
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// 4. Edge expansion — 1–2 hop curated-graph pull over every accumulated
|
|
229
|
-
// confident seed. Gated by `lanes.edges`.
|
|
230
|
-
let edgeExpansions: DescentPass["edgeExpansions"];
|
|
231
|
-
if (lanes.edges) {
|
|
232
|
-
const expansion = await expandEdges({
|
|
233
|
-
workspaceDir: passInput.workspaceDir,
|
|
234
|
-
seeds: [...candidates],
|
|
235
|
-
// Rank seeds by the lane that surfaced them (tree/dense/sparse before
|
|
236
|
-
// hot) so the seed cap spends its budget on query-relevant seeds, not
|
|
237
|
-
// recency. `sourceBySlug` holds each candidate's first-seen lane.
|
|
238
|
-
laneBySlug: sourceBySlug,
|
|
239
|
-
// Merge the learned co-retrieval graph with the curated edges when
|
|
240
|
-
// enabled (undefined = curated-only, the default).
|
|
241
|
-
...(learnedAdjacency ? { extraAdjacency: learnedAdjacency } : {}),
|
|
242
|
-
// Cap the lane's contribution to the gate pool (default 400).
|
|
243
|
-
maxTotalPulls: v3.edges?.maxPulls,
|
|
244
|
-
});
|
|
245
|
-
edgeExpansions = expansion.expansions;
|
|
246
|
-
for (const slug of expansion.pulled) {
|
|
247
|
-
candidates.add(slug);
|
|
248
|
-
tagSlug(sourceBySlug, slug, "edge");
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Record the first pass each candidate surfaced on. The candidate set is
|
|
253
|
-
// the union of every lane's contribution this pass; a slug keeps the
|
|
254
|
-
// earliest pass it appeared on (first write wins).
|
|
255
|
-
for (const slug of candidates) {
|
|
256
|
-
if (!firstPassBySlug.has(slug)) firstPassBySlug.set(slug, passNumber);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// When gateCandidateSummaries is enabled (opt-in), render candidates to the
|
|
260
|
-
// gate as `slug — summary` so it can judge relevance on page content rather
|
|
261
|
-
// than the slug alone. getPageIndex is cached, so this reuses the index the
|
|
262
|
-
// scouts/tree lanes already built this pass.
|
|
263
|
-
let summaryBySlug: Map<string, string> | undefined;
|
|
264
|
-
if (passInput.config.memory.v3.gateCandidateSummaries) {
|
|
265
|
-
const pageIndex = await getPageIndex(passInput.workspaceDir);
|
|
266
|
-
summaryBySlug = new Map<string, string>();
|
|
267
|
-
for (const slug of candidates) {
|
|
268
|
-
const summary = pageIndex.bySlug.get(slug)?.summary;
|
|
269
|
-
if (summary) summaryBySlug.set(slug, summary);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// 5. Gate — one capable LLM call over the unioned candidate set.
|
|
274
|
-
const gateResult = await runGate({
|
|
275
|
-
input: passInput,
|
|
276
|
-
candidates,
|
|
277
|
-
sticky,
|
|
278
|
-
passNumber,
|
|
279
|
-
summaryBySlug,
|
|
280
|
-
capture: passSink,
|
|
281
|
-
});
|
|
282
|
-
selectedSlugs = gateResult.selectedSlugs;
|
|
283
|
-
|
|
284
|
-
// Record this pass's trace.
|
|
285
|
-
const pass: DescentPass = {
|
|
286
|
-
passNumber,
|
|
287
|
-
scouts: scoutResult.scouts,
|
|
288
|
-
...(treeLevels !== undefined ? { treeLevels } : {}),
|
|
289
|
-
...(edgeExpansions !== undefined ? { edgeExpansions } : {}),
|
|
290
|
-
gate: gateResult.decision,
|
|
291
|
-
};
|
|
292
|
-
passes.push(pass);
|
|
293
|
-
|
|
294
|
-
cost.ms += Date.now() - passStart;
|
|
295
|
-
|
|
296
|
-
// Pass control. A `more` verdict with another pass available feeds the
|
|
297
|
-
// gate's generated questions into the next pass's query; otherwise (ready,
|
|
298
|
-
// or passCap reached) the loop exits with the current selection.
|
|
299
|
-
if (gateResult.decision.decision !== "more") break;
|
|
300
|
-
if (passNumber >= passCap) break;
|
|
301
|
-
passNowText = nextPassNowText(input.nowText, gateResult.decision);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Co-activation logging — off the critical path. Gated by
|
|
305
|
-
// `write.coactivation` (default off). Emits one pass-1 → pass-N pair per
|
|
306
|
-
// (pass-1 hit, later-surfaced page) in the final selection. Best-effort:
|
|
307
|
-
// wrapped so neither the computation nor the insert can delay or break the
|
|
308
|
-
// RetrievalOutput the caller depends on.
|
|
309
|
-
if (v3.write?.coactivation) {
|
|
310
|
-
emitCoactivations({
|
|
311
|
-
db: deps.db,
|
|
312
|
-
conversationId: deps.conversationId ?? "",
|
|
313
|
-
turn: deps.turn ?? 0,
|
|
314
|
-
selectedSlugs,
|
|
315
|
-
firstPassBySlug,
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const trace: DescentTrace = { passes };
|
|
320
|
-
return {
|
|
321
|
-
selectedSlugs,
|
|
322
|
-
sourceBySlug,
|
|
323
|
-
trace,
|
|
324
|
-
cost,
|
|
325
|
-
failureReason,
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Emit pass-1 → pass-N co-activation rows for the final selection.
|
|
331
|
-
*
|
|
332
|
-
* For each selected page B first surfaced on pass ≥2, pair it with each
|
|
333
|
-
* selected page A first surfaced on pass 1 (`pass_gap = passOf(B) − 1`). Pages
|
|
334
|
-
* only surfaced on pass 1 (or never recorded) emit nothing — the gradient is
|
|
335
|
-
* the gap between an early hit and a later-surfaced association. `used` is 0:
|
|
336
|
-
* the loop cannot know whether B was load-bearing for the turn; edge-learning
|
|
337
|
-
* reconciles usefulness later.
|
|
338
|
-
*
|
|
339
|
-
* Best-effort and off the retrieval critical path — any failure is swallowed.
|
|
340
|
-
*/
|
|
341
|
-
function emitCoactivations(args: {
|
|
342
|
-
db: DrizzleDb;
|
|
343
|
-
conversationId: string;
|
|
344
|
-
turn: number;
|
|
345
|
-
selectedSlugs: readonly string[];
|
|
346
|
-
firstPassBySlug: ReadonlyMap<string, number>;
|
|
347
|
-
}): void {
|
|
348
|
-
try {
|
|
349
|
-
const { db, conversationId, turn, selectedSlugs, firstPassBySlug } = args;
|
|
350
|
-
const pass1Hits = selectedSlugs.filter(
|
|
351
|
-
(slug) => firstPassBySlug.get(slug) === 1,
|
|
352
|
-
);
|
|
353
|
-
if (pass1Hits.length === 0) return;
|
|
354
|
-
|
|
355
|
-
const createdAt = Date.now();
|
|
356
|
-
const rows: CoactivationRow[] = [];
|
|
357
|
-
for (const target of selectedSlugs) {
|
|
358
|
-
const targetPass = firstPassBySlug.get(target);
|
|
359
|
-
if (targetPass === undefined || targetPass < 2) continue;
|
|
360
|
-
for (const source of pass1Hits) {
|
|
361
|
-
rows.push({
|
|
362
|
-
conversationId,
|
|
363
|
-
turn,
|
|
364
|
-
sourceSlug: source,
|
|
365
|
-
targetSlug: target,
|
|
366
|
-
passGap: targetPass - 1,
|
|
367
|
-
used: 0,
|
|
368
|
-
createdAt,
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
recordCoactivations(db, rows);
|
|
374
|
-
} catch (err) {
|
|
375
|
-
log.warn({ err }, "failed to emit co-activations; continuing");
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* Lane-trust order for `sourceBySlug` provenance (lower = more trusted). A slug
|
|
381
|
-
* surfaced by several lanes is tagged with the most trusted one. Mirrors
|
|
382
|
-
* `SEED_LANE_RANK` in {@link expandEdges}'s module, the downstream consumer that
|
|
383
|
-
* ranks seeds by this tag before the candidate cap: LLM-vetted tree/dense seeds
|
|
384
|
-
* rank above lexical sparse, recency-only hot, and associative edge pulls.
|
|
385
|
-
* Keeping the two orders aligned ensures the upgrade picks the lane the cap
|
|
386
|
-
* actually trusts. Any lane absent here (or an edge pull) ranks last.
|
|
387
|
-
*/
|
|
388
|
-
const LANE_TRUST_RANK: Readonly<Record<LaneSource, number>> = {
|
|
389
|
-
tree: 0,
|
|
390
|
-
dense: 1,
|
|
391
|
-
sparse: 2,
|
|
392
|
-
hot: 3,
|
|
393
|
-
edge: 4,
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Tag `slug`'s provenance with `lane`, upgrading to the most trusted lane that
|
|
398
|
-
* surfaces it (see {@link LANE_TRUST_RANK}). A slug first seen via a low-trust
|
|
399
|
-
* lane (e.g. `edge`) is relabeled when a higher-trust lane (e.g. `dense`) also
|
|
400
|
-
* surfaces it, so the downstream seed cap ranks it by its strongest signal
|
|
401
|
-
* rather than a stale first-seen lane. Pass provenance (`firstPassBySlug`) is
|
|
402
|
-
* tracked separately and keeps earliest-pass semantics — only the lane upgrades.
|
|
403
|
-
*/
|
|
404
|
-
function tagSlug(
|
|
405
|
-
sourceBySlug: Map<string, LaneSource>,
|
|
406
|
-
slug: string,
|
|
407
|
-
lane: LaneSource,
|
|
408
|
-
): void {
|
|
409
|
-
const current = sourceBySlug.get(slug);
|
|
410
|
-
if (
|
|
411
|
-
current === undefined ||
|
|
412
|
-
LANE_TRUST_RANK[lane] < LANE_TRUST_RANK[current]
|
|
413
|
-
) {
|
|
414
|
-
sourceBySlug.set(slug, lane);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Build the next pass's NOW text from the original standing context plus the
|
|
420
|
-
* gate's generated follow-up questions. The standing-context files are never
|
|
421
|
-
* rewritten — the questions are appended as an additional situational-context
|
|
422
|
-
* block the scouts/descent/gate read on top of NOW. With no questions the
|
|
423
|
-
* original NOW is reused verbatim.
|
|
424
|
-
*/
|
|
425
|
-
function nextPassNowText(baseNowText: string, decision: GateDecision): string {
|
|
426
|
-
const questions = decision.questions ?? [];
|
|
427
|
-
if (questions.length === 0) return baseNowText;
|
|
428
|
-
const block = `<follow_up_questions>\n${questions.join("\n")}\n</follow_up_questions>`;
|
|
429
|
-
return `${baseNowText}\n\n${block}`;
|
|
430
|
-
}
|