@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
|
@@ -105,6 +105,43 @@ mock.module("../../jobs-store.js", () => ({
|
|
|
105
105
|
isMemoryEnabled: () => true,
|
|
106
106
|
}));
|
|
107
107
|
|
|
108
|
+
// ── v3 health-injection mocks ───────────────────────────────────────
|
|
109
|
+
//
|
|
110
|
+
// The consolidation handler optionally prepends a v3 health block to the
|
|
111
|
+
// prompt when a v3 flag is on AND the rendered report is non-empty. These
|
|
112
|
+
// mocks let each test (a) toggle the flag, (b) decide what health block the
|
|
113
|
+
// renderer produces, and (c) force the health computation to throw — without
|
|
114
|
+
// materializing a real v3 data dir. The tree/core/page-index loaders are
|
|
115
|
+
// stubbed to inert values; `computeV3Health` is a pass-through whose result is
|
|
116
|
+
// fed to the toggleable `renderV3Health`.
|
|
117
|
+
let v3FlagOn = false;
|
|
118
|
+
mock.module("../../../config/assistant-feature-flags.js", () => ({
|
|
119
|
+
isAssistantFeatureFlagEnabled: () => v3FlagOn,
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
let renderedHealth = "";
|
|
123
|
+
let computeThrows = false;
|
|
124
|
+
mock.module("../../v3/health.js", () => ({
|
|
125
|
+
computeV3Health: () => {
|
|
126
|
+
if (computeThrows) throw new Error("simulated health compute failure");
|
|
127
|
+
return {};
|
|
128
|
+
},
|
|
129
|
+
renderV3Health: () => renderedHealth,
|
|
130
|
+
}));
|
|
131
|
+
|
|
132
|
+
mock.module("../../v3/tree.js", () => ({
|
|
133
|
+
loadLeafTree: async () => ({ leaves: new Map(), byPage: new Map() }),
|
|
134
|
+
resolveDataDir: () => "/tmp/v3-data-stub",
|
|
135
|
+
}));
|
|
136
|
+
|
|
137
|
+
mock.module("../../v3/core.js", () => ({
|
|
138
|
+
loadCore: async () => new Set<string>(),
|
|
139
|
+
}));
|
|
140
|
+
|
|
141
|
+
mock.module("../../v2/page-index.js", () => ({
|
|
142
|
+
getPageIndex: async () => ({ entries: [] }),
|
|
143
|
+
}));
|
|
144
|
+
|
|
108
145
|
// ── Workspace pin ───────────────────────────────────────────────────
|
|
109
146
|
let tmpWorkspace: string;
|
|
110
147
|
let previousWorkspaceEnv: string | undefined;
|
|
@@ -173,6 +210,11 @@ beforeEach(() => {
|
|
|
173
210
|
emitCalls.length = 0;
|
|
174
211
|
enqueuedJobs.length = 0;
|
|
175
212
|
nextJobIdCounter = 0;
|
|
213
|
+
|
|
214
|
+
// v3 health injection defaults: flag off, no rendered block, no throw.
|
|
215
|
+
v3FlagOn = false;
|
|
216
|
+
renderedHealth = "";
|
|
217
|
+
computeThrows = false;
|
|
176
218
|
});
|
|
177
219
|
|
|
178
220
|
// ---------------------------------------------------------------------------
|
|
@@ -305,6 +347,25 @@ describe("memoryV2ConsolidateJob — non-empty buffer", () => {
|
|
|
305
347
|
expect(existsSync(lockPath())).toBe(false);
|
|
306
348
|
});
|
|
307
349
|
|
|
350
|
+
test("enqueues memory_v3_maintain as a follow-up when a v3 flag is on", async () => {
|
|
351
|
+
v3FlagOn = true;
|
|
352
|
+
const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
|
|
353
|
+
|
|
354
|
+
expect(result.kind).toBe("invoked");
|
|
355
|
+
expect(enqueuedJobs.map((j) => j.type)).toEqual([
|
|
356
|
+
"memory_v2_reembed",
|
|
357
|
+
"memory_v3_maintain",
|
|
358
|
+
]);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
test("does not enqueue memory_v3_maintain when v3 flags are off", async () => {
|
|
362
|
+
v3FlagOn = false;
|
|
363
|
+
const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
|
|
364
|
+
|
|
365
|
+
expect(result.kind).toBe("invoked");
|
|
366
|
+
expect(enqueuedJobs.map((j) => j.type)).toEqual(["memory_v2_reembed"]);
|
|
367
|
+
});
|
|
368
|
+
|
|
308
369
|
test("returns run_failed and skips follow-ups when the runner reports failure", async () => {
|
|
309
370
|
runnerImpl = async () => ({
|
|
310
371
|
conversationId: "conv-1",
|
|
@@ -348,6 +409,69 @@ describe("memoryV2ConsolidateJob — non-empty buffer", () => {
|
|
|
348
409
|
});
|
|
349
410
|
});
|
|
350
411
|
|
|
412
|
+
describe("memoryV2ConsolidateJob — v3 health injection", () => {
|
|
413
|
+
beforeEach(() => {
|
|
414
|
+
writeFileSync(
|
|
415
|
+
bufferPath(),
|
|
416
|
+
"- [Apr 27, 9:00 AM] Alice prefers VS Code over Vim.\n",
|
|
417
|
+
);
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
test("prepends the health block when a v3 flag is on and the report is actionable", async () => {
|
|
421
|
+
v3FlagOn = true;
|
|
422
|
+
renderedHealth = "memory-v3 health:\n- 2 unassigned slug(s): a, b";
|
|
423
|
+
|
|
424
|
+
const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
|
|
425
|
+
|
|
426
|
+
expect(result.kind).toBe("invoked");
|
|
427
|
+
const prompt = runnerLastArgs?.prompt as string;
|
|
428
|
+
// The health block is PREPENDED, separated by a blank line, with the
|
|
429
|
+
// base consolidation prompt still present underneath it.
|
|
430
|
+
expect(prompt.startsWith(`${renderedHealth}\n\n`)).toBe(true);
|
|
431
|
+
expect(prompt).toContain("memory consolidation");
|
|
432
|
+
expect(prompt).not.toContain(CUTOFF_PLACEHOLDER);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
test("leaves the prompt unchanged when the report is all-green (empty render)", async () => {
|
|
436
|
+
v3FlagOn = true;
|
|
437
|
+
renderedHealth = "";
|
|
438
|
+
|
|
439
|
+
const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
|
|
440
|
+
|
|
441
|
+
expect(result.kind).toBe("invoked");
|
|
442
|
+
const prompt = runnerLastArgs?.prompt as string;
|
|
443
|
+
expect(prompt).not.toContain("memory-v3 health:");
|
|
444
|
+
// Prompt is exactly the resolved consolidation body.
|
|
445
|
+
expect(prompt).toContain("memory consolidation");
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
test("leaves the prompt unchanged when v3 flags are off even if a block would render", async () => {
|
|
449
|
+
v3FlagOn = false;
|
|
450
|
+
renderedHealth = "memory-v3 health:\n- 1 unassigned slug(s): a";
|
|
451
|
+
|
|
452
|
+
const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
|
|
453
|
+
|
|
454
|
+
expect(result.kind).toBe("invoked");
|
|
455
|
+
const prompt = runnerLastArgs?.prompt as string;
|
|
456
|
+
expect(prompt).not.toContain("memory-v3 health:");
|
|
457
|
+
expect(prompt).toContain("memory consolidation");
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
test("falls back to the base prompt when health computation throws", async () => {
|
|
461
|
+
v3FlagOn = true;
|
|
462
|
+
computeThrows = true;
|
|
463
|
+
renderedHealth = "memory-v3 health:\n- should not appear";
|
|
464
|
+
|
|
465
|
+
const result = await memoryV2ConsolidateJob(makeJob(), CONFIG);
|
|
466
|
+
|
|
467
|
+
// A health-compute failure must NEVER break consolidation.
|
|
468
|
+
expect(result.kind).toBe("invoked");
|
|
469
|
+
const prompt = runnerLastArgs?.prompt as string;
|
|
470
|
+
expect(prompt).not.toContain("memory-v3 health:");
|
|
471
|
+
expect(prompt).toContain("memory consolidation");
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
|
|
351
475
|
describe("memoryV2ConsolidateJob — concurrent invocations", () => {
|
|
352
476
|
beforeEach(() => {
|
|
353
477
|
writeFileSync(bufferPath(), "- [Apr 27, 9:00 AM] Alice prefers VS Code.\n");
|
|
@@ -26,7 +26,12 @@
|
|
|
26
26
|
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
27
27
|
|
|
28
28
|
import { makeMockLogger } from "../../../__tests__/helpers/mock-logger.js";
|
|
29
|
-
import type {
|
|
29
|
+
import type {
|
|
30
|
+
Message,
|
|
31
|
+
Provider,
|
|
32
|
+
ProviderResponse,
|
|
33
|
+
SendMessageOptions,
|
|
34
|
+
} from "../../../providers/types.js";
|
|
30
35
|
|
|
31
36
|
// -- Mocks that must be installed before importing the module under test ---
|
|
32
37
|
//
|
|
@@ -416,8 +421,11 @@ describe("synthesizeConceptPage", () => {
|
|
|
416
421
|
let capturedSystem: string | undefined;
|
|
417
422
|
const provider: Provider = {
|
|
418
423
|
name: "stub",
|
|
419
|
-
sendMessage: async (
|
|
420
|
-
|
|
424
|
+
sendMessage: async (
|
|
425
|
+
_messages: Message[],
|
|
426
|
+
options?: SendMessageOptions,
|
|
427
|
+
) => {
|
|
428
|
+
capturedSystem = options?.systemPrompt;
|
|
421
429
|
return {
|
|
422
430
|
content: [{ type: "text", text: "synthesized" }],
|
|
423
431
|
model: "stub-model",
|
|
@@ -76,7 +76,12 @@ afterEach(() => {
|
|
|
76
76
|
|
|
77
77
|
function makePage(
|
|
78
78
|
slug: string,
|
|
79
|
-
opts: {
|
|
79
|
+
opts: {
|
|
80
|
+
edges?: string[];
|
|
81
|
+
summary?: string;
|
|
82
|
+
body?: string;
|
|
83
|
+
leaves?: string[];
|
|
84
|
+
} = {},
|
|
80
85
|
): ConceptPage {
|
|
81
86
|
return {
|
|
82
87
|
slug,
|
|
@@ -85,6 +90,7 @@ function makePage(
|
|
|
85
90
|
ref_files: [],
|
|
86
91
|
ref_urls: [],
|
|
87
92
|
...(opts.summary !== undefined ? { summary: opts.summary } : {}),
|
|
93
|
+
...(opts.leaves !== undefined ? { leaves: opts.leaves } : {}),
|
|
88
94
|
},
|
|
89
95
|
body: opts.body ?? "",
|
|
90
96
|
};
|
|
@@ -230,6 +236,36 @@ describe("getPageIndex", () => {
|
|
|
230
236
|
expect(alice.edges).toEqual([bob.id]);
|
|
231
237
|
});
|
|
232
238
|
|
|
239
|
+
test("exposes frontmatter leaves in the index entry", async () => {
|
|
240
|
+
await writePage(
|
|
241
|
+
workspaceDir,
|
|
242
|
+
makePage("alice", {
|
|
243
|
+
summary: "A",
|
|
244
|
+
leaves: ["page-a", "domain-a/topic-x"],
|
|
245
|
+
}),
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
const idx = await getPageIndex(workspaceDir);
|
|
249
|
+
expect(idx.bySlug.get("alice")?.leaves).toEqual([
|
|
250
|
+
"page-a",
|
|
251
|
+
"domain-a/topic-x",
|
|
252
|
+
]);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test("defaults leaves to an empty array when the field is absent", async () => {
|
|
256
|
+
await writePage(workspaceDir, makePage("alice", { summary: "A" }));
|
|
257
|
+
|
|
258
|
+
const idx = await getPageIndex(workspaceDir);
|
|
259
|
+
expect(idx.bySlug.get("alice")?.leaves).toEqual([]);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test("seeded skill entries carry an empty leaves list", async () => {
|
|
263
|
+
skillState.entries = [{ id: "browser", content: "Drive a browser." }];
|
|
264
|
+
|
|
265
|
+
const idx = await getPageIndex(workspaceDir);
|
|
266
|
+
expect(idx.bySlug.get("skills/browser")?.leaves).toEqual([]);
|
|
267
|
+
});
|
|
268
|
+
|
|
233
269
|
test("falls back to body when frontmatter.summary is absent", async () => {
|
|
234
270
|
await writePage(
|
|
235
271
|
workspaceDir,
|
|
@@ -148,8 +148,13 @@ afterEach(() => {
|
|
|
148
148
|
function makeProvider(response: ProviderResponse): Provider {
|
|
149
149
|
return {
|
|
150
150
|
name: "stub",
|
|
151
|
-
sendMessage: async (messages,
|
|
152
|
-
providerCalls.push({
|
|
151
|
+
sendMessage: async (messages, options) => {
|
|
152
|
+
providerCalls.push({
|
|
153
|
+
messages,
|
|
154
|
+
tools: options?.tools,
|
|
155
|
+
systemPrompt: options?.systemPrompt,
|
|
156
|
+
options,
|
|
157
|
+
});
|
|
153
158
|
// Honor abort like a real provider would — if the signal already
|
|
154
159
|
// aborted, throw the canonical AbortError so callers can assert that
|
|
155
160
|
// signal forwarding actually has teeth.
|
|
@@ -752,9 +757,14 @@ describe("runRouter — batched (batch_size set)", () => {
|
|
|
752
757
|
let callCount = 0;
|
|
753
758
|
providerStub = {
|
|
754
759
|
name: "partial-failure",
|
|
755
|
-
sendMessage: async (messages,
|
|
760
|
+
sendMessage: async (messages, options) => {
|
|
756
761
|
callCount += 1;
|
|
757
|
-
providerCalls.push({
|
|
762
|
+
providerCalls.push({
|
|
763
|
+
messages,
|
|
764
|
+
tools: options?.tools,
|
|
765
|
+
systemPrompt: options?.systemPrompt,
|
|
766
|
+
options,
|
|
767
|
+
});
|
|
758
768
|
if (callCount === 1) throw new Error("batch 1 boom");
|
|
759
769
|
return toolUseResponse([1]);
|
|
760
770
|
},
|
|
@@ -35,8 +35,10 @@ import {
|
|
|
35
35
|
|
|
36
36
|
import { makeMockLogger } from "../../../__tests__/helpers/mock-logger.js";
|
|
37
37
|
import type {
|
|
38
|
+
Message,
|
|
38
39
|
Provider,
|
|
39
40
|
ProviderResponse,
|
|
41
|
+
SendMessageOptions,
|
|
40
42
|
ToolUseContent,
|
|
41
43
|
} from "../../../providers/types.js";
|
|
42
44
|
|
|
@@ -100,9 +102,8 @@ afterAll(() => {
|
|
|
100
102
|
});
|
|
101
103
|
|
|
102
104
|
const { getDb } = await import("../../db-connection.js");
|
|
103
|
-
const { resetDbForTesting } =
|
|
104
|
-
"../../../__tests__/db-test-helpers.js"
|
|
105
|
-
);
|
|
105
|
+
const { resetDbForTesting } =
|
|
106
|
+
await import("../../../__tests__/db-test-helpers.js");
|
|
106
107
|
const { initializeDb } = await import("../../db-init.js");
|
|
107
108
|
const { messages, conversations } = await import("../../schema.js");
|
|
108
109
|
const { memoryV2SweepJob } = await import("../sweep-job.js");
|
|
@@ -144,9 +145,9 @@ function makeJob(): Parameters<typeof memoryV2SweepJob>[0] {
|
|
|
144
145
|
function makeEntriesProvider(entries: string[]): Provider {
|
|
145
146
|
return {
|
|
146
147
|
name: "stub",
|
|
147
|
-
sendMessage: async (msgs
|
|
148
|
+
sendMessage: async (msgs: Message[], options?: SendMessageOptions) => {
|
|
148
149
|
providerCalls.push({
|
|
149
|
-
systemPrompt,
|
|
150
|
+
systemPrompt: options?.systemPrompt,
|
|
150
151
|
userText: extractFirstUserText(msgs),
|
|
151
152
|
});
|
|
152
153
|
return {
|
|
@@ -157,8 +157,14 @@ export async function memoryV2ActivationRecomputeJob(
|
|
|
157
157
|
const workspaceDir = getWorkspaceDir();
|
|
158
158
|
const database = getDb();
|
|
159
159
|
|
|
160
|
+
// Activation maps still need to refresh for archived conversations — a
|
|
161
|
+
// consolidated page can leave stale slugs above epsilon in their persisted
|
|
162
|
+
// state — so this job opts back into seeing archived rows.
|
|
160
163
|
const conversations = listConversations(
|
|
161
164
|
ACTIVATION_RECOMPUTE_CONVERSATION_LIMIT,
|
|
165
|
+
"standard",
|
|
166
|
+
0,
|
|
167
|
+
"all",
|
|
162
168
|
);
|
|
163
169
|
const edgeIndex = await getEdgeIndex(workspaceDir);
|
|
164
170
|
const nowText = await loadNowText(workspaceDir);
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
} from "node:fs";
|
|
62
62
|
import { dirname, join } from "node:path";
|
|
63
63
|
|
|
64
|
+
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
64
65
|
import type { AssistantConfig } from "../../config/types.js";
|
|
65
66
|
import { runBackgroundJob } from "../../runtime/background-job-runner.js";
|
|
66
67
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -72,6 +73,11 @@ import {
|
|
|
72
73
|
type MemoryJob,
|
|
73
74
|
type MemoryJobType,
|
|
74
75
|
} from "../jobs-store.js";
|
|
76
|
+
import { getPageIndex } from "../v2/page-index.js";
|
|
77
|
+
import { loadCore } from "../v3/core.js";
|
|
78
|
+
import { computeV3Health, renderV3Health } from "../v3/health.js";
|
|
79
|
+
import { loadLeafTree, resolveDataDir } from "../v3/tree.js";
|
|
80
|
+
import type { LeafPath, Slug } from "../v3/types.js";
|
|
75
81
|
import { MEMORY_V2_CONSOLIDATION_SOURCE } from "./constants.js";
|
|
76
82
|
import { resolveConsolidationPrompt } from "./prompts/consolidation.js";
|
|
77
83
|
|
|
@@ -80,6 +86,14 @@ const log = getLogger("memory-v2-consolidate");
|
|
|
80
86
|
/** Stable identifier surfaced in `runBackgroundJob` logs and notifications. */
|
|
81
87
|
const JOB_NAME = "memory.consolidate";
|
|
82
88
|
|
|
89
|
+
/**
|
|
90
|
+
* v3 plugin flags. Either being on (a) prepends a v3 health block to the
|
|
91
|
+
* consolidation prompt and (b) enqueues `memory_v3_maintain` as a
|
|
92
|
+
* post-consolidation follow-up. These gate the v3 plugin itself.
|
|
93
|
+
*/
|
|
94
|
+
const MEMORY_V3_SHADOW = "memory-v3-shadow" as const;
|
|
95
|
+
const MEMORY_V3_LIVE = "memory-v3-live" as const;
|
|
96
|
+
|
|
83
97
|
/**
|
|
84
98
|
* Hard timeout for the consolidation run. Consolidation reads the buffer,
|
|
85
99
|
* rewrites several files, and re-encodes essentials/threads — generous
|
|
@@ -95,9 +109,10 @@ const CONSOLIDATION_TIMEOUT_MS = 15 * 60 * 1000;
|
|
|
95
109
|
* agent touched: mtime-diffing is fragile across filesystems, and the
|
|
96
110
|
* embedder's content-hash cache makes unchanged pages effectively free.
|
|
97
111
|
*/
|
|
98
|
-
const FOLLOW_UP_JOB_TYPES: readonly MemoryJobType[] = [
|
|
99
|
-
|
|
100
|
-
|
|
112
|
+
const FOLLOW_UP_JOB_TYPES: readonly MemoryJobType[] = ["memory_v2_reembed"];
|
|
113
|
+
|
|
114
|
+
/** Follow-up enqueued only when a v3 flag is on. */
|
|
115
|
+
const V3_FOLLOW_UP_JOB_TYPE: MemoryJobType = "memory_v3_maintain";
|
|
101
116
|
|
|
102
117
|
/**
|
|
103
118
|
* Job handler. See file header for the full lifecycle. Returns a discriminated
|
|
@@ -167,13 +182,20 @@ export async function memoryV2ConsolidateJob(
|
|
|
167
182
|
// it to a regular file under 1 MiB before substitution so a stray path
|
|
168
183
|
// (or a `/dev/zero`-style pseudo-file) cannot exfiltrate megabytes of
|
|
169
184
|
// bytes through the wake hint.
|
|
185
|
+
//
|
|
186
|
+
// That resolved prompt is the base; `maybePrependV3Health` prepends a
|
|
187
|
+
// freshly computed v3 health block when a v3 flag is on and the tree has
|
|
188
|
+
// actionable drift, leaving it untouched otherwise.
|
|
189
|
+
const basePrompt = resolveConsolidationPrompt(
|
|
190
|
+
config.memory.v2.consolidation_prompt_path,
|
|
191
|
+
cutoff,
|
|
192
|
+
);
|
|
193
|
+
const prompt = await maybePrependV3Health(basePrompt, config);
|
|
194
|
+
|
|
170
195
|
const runResult = await runBackgroundJob({
|
|
171
196
|
jobName: JOB_NAME,
|
|
172
197
|
source: MEMORY_V2_CONSOLIDATION_SOURCE,
|
|
173
|
-
prompt
|
|
174
|
-
config.memory.v2.consolidation_prompt_path,
|
|
175
|
-
cutoff,
|
|
176
|
-
),
|
|
198
|
+
prompt,
|
|
177
199
|
trustContext: { sourceChannel: "vellum", trustClass: "guardian" },
|
|
178
200
|
callSite: "mainAgent",
|
|
179
201
|
timeoutMs: CONSOLIDATION_TIMEOUT_MS,
|
|
@@ -197,9 +219,17 @@ export async function memoryV2ConsolidateJob(
|
|
|
197
219
|
|
|
198
220
|
// Step 5: enqueue follow-up jobs. Enqueueing now keeps the dispatch
|
|
199
221
|
// wiring exercised end-to-end so PR 21 only has to swap in the handler
|
|
200
|
-
// bodies.
|
|
222
|
+
// bodies. v3 maintenance is appended only while a v3 path (shadow or live)
|
|
223
|
+
// is active, so it never fans out on v2-only installs.
|
|
201
224
|
const followUpJobIds: string[] = [];
|
|
202
|
-
|
|
225
|
+
const jobTypes: MemoryJobType[] = [...FOLLOW_UP_JOB_TYPES];
|
|
226
|
+
if (
|
|
227
|
+
isAssistantFeatureFlagEnabled(MEMORY_V3_SHADOW, config) ||
|
|
228
|
+
isAssistantFeatureFlagEnabled(MEMORY_V3_LIVE, config)
|
|
229
|
+
) {
|
|
230
|
+
jobTypes.push(V3_FOLLOW_UP_JOB_TYPE);
|
|
231
|
+
}
|
|
232
|
+
for (const jobType of jobTypes) {
|
|
203
233
|
try {
|
|
204
234
|
followUpJobIds.push(enqueueMemoryJob(jobType, {}));
|
|
205
235
|
} catch (err) {
|
|
@@ -231,6 +261,56 @@ export async function memoryV2ConsolidateJob(
|
|
|
231
261
|
}
|
|
232
262
|
}
|
|
233
263
|
|
|
264
|
+
/**
|
|
265
|
+
* When a v3 flag is enabled and the v3 tree has actionable structural drift,
|
|
266
|
+
* prepend a rendered health block to `basePrompt` so the consolidation run can
|
|
267
|
+
* fold tree maintenance into its pass. Returns `basePrompt` UNCHANGED when:
|
|
268
|
+
* - neither `memory-v3-shadow` nor `memory-v3-live` is enabled,
|
|
269
|
+
* - the health report is all-green (`renderV3Health` returns ""), or
|
|
270
|
+
* - computing the report throws for any reason.
|
|
271
|
+
*
|
|
272
|
+
* The block is computed here (not baked into the prompt template) so an
|
|
273
|
+
* operator's custom consolidation prompt stays untouched and the block reflects
|
|
274
|
+
* the tree state at run time. Health computation is wrapped so a load/compute
|
|
275
|
+
* failure can never break consolidation — the run proceeds on the base prompt.
|
|
276
|
+
*/
|
|
277
|
+
async function maybePrependV3Health(
|
|
278
|
+
basePrompt: string,
|
|
279
|
+
config: AssistantConfig,
|
|
280
|
+
): Promise<string> {
|
|
281
|
+
const v3Enabled =
|
|
282
|
+
isAssistantFeatureFlagEnabled(MEMORY_V3_SHADOW, config) ||
|
|
283
|
+
isAssistantFeatureFlagEnabled(MEMORY_V3_LIVE, config);
|
|
284
|
+
if (!v3Enabled) return basePrompt;
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
const pageIndex = await getPageIndex(getWorkspaceDir());
|
|
288
|
+
const pageLeaves = new Map<Slug, LeafPath[]>();
|
|
289
|
+
const allSlugs: Slug[] = [];
|
|
290
|
+
for (const entry of pageIndex.entries) {
|
|
291
|
+
pageLeaves.set(entry.slug, entry.leaves);
|
|
292
|
+
allSlugs.push(entry.slug);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const dataDir = resolveDataDir();
|
|
296
|
+
const [tree, core] = await Promise.all([
|
|
297
|
+
loadLeafTree(dataDir, pageLeaves),
|
|
298
|
+
loadCore(dataDir),
|
|
299
|
+
]);
|
|
300
|
+
|
|
301
|
+
const report = computeV3Health({ tree, allSlugs, core });
|
|
302
|
+
const healthBlock = renderV3Health(report);
|
|
303
|
+
if (healthBlock.length === 0) return basePrompt;
|
|
304
|
+
return `${healthBlock}\n\n${basePrompt}`;
|
|
305
|
+
} catch (err) {
|
|
306
|
+
log.warn(
|
|
307
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
308
|
+
"consolidation: v3 health computation failed; using base prompt",
|
|
309
|
+
);
|
|
310
|
+
return basePrompt;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
234
314
|
/**
|
|
235
315
|
* Read `memory/buffer.md`. Missing file → empty string so the skip-on-empty
|
|
236
316
|
* branch doesn't have to distinguish "no file" from "blank file".
|
|
@@ -337,9 +337,11 @@ export async function synthesizeConceptPage(
|
|
|
337
337
|
`Synthesize a single concept page from these v1 sources. Slug hint: \`${cluster.slugHint}\`.\n\n${sourceListing}`,
|
|
338
338
|
),
|
|
339
339
|
],
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
340
|
+
{
|
|
341
|
+
tools: [],
|
|
342
|
+
systemPrompt,
|
|
343
|
+
config: { callSite: "memoryV2Migration" as const },
|
|
344
|
+
},
|
|
343
345
|
);
|
|
344
346
|
const body = extractText(response);
|
|
345
347
|
|
|
@@ -55,6 +55,11 @@ export interface PageIndexEntry {
|
|
|
55
55
|
summary: string;
|
|
56
56
|
/** Numeric IDs of outgoing edges, in sorted order. */
|
|
57
57
|
edges: number[];
|
|
58
|
+
/**
|
|
59
|
+
* Leaf slugs declared in the page's `leaves:` frontmatter; `[]` when absent.
|
|
60
|
+
* Synthetic entries (skills, CLI commands) never declare leaves.
|
|
61
|
+
*/
|
|
62
|
+
leaves: string[];
|
|
58
63
|
/**
|
|
59
64
|
* File mtime in epoch ms; 0 for synthetic entries (skills, CLI commands)
|
|
60
65
|
* that have no on-disk source file. Used by `splitTier1` to rank pages
|
|
@@ -118,6 +123,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
118
123
|
slug: string;
|
|
119
124
|
summary: string;
|
|
120
125
|
outgoingSlugs: string[];
|
|
126
|
+
leaves: string[];
|
|
121
127
|
modifiedAt: number;
|
|
122
128
|
}
|
|
123
129
|
|
|
@@ -177,6 +183,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
177
183
|
slug,
|
|
178
184
|
summary: normalizeSummary(summarySource),
|
|
179
185
|
outgoingSlugs: page.frontmatter.edges,
|
|
186
|
+
leaves: page.frontmatter.leaves ?? [],
|
|
180
187
|
modifiedAt: mtimeMs,
|
|
181
188
|
});
|
|
182
189
|
}
|
|
@@ -186,6 +193,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
186
193
|
slug: `${SKILL_SLUG_PREFIX}${entry.id}`,
|
|
187
194
|
summary: normalizeSummary(entry.content),
|
|
188
195
|
outgoingSlugs: [],
|
|
196
|
+
leaves: [],
|
|
189
197
|
modifiedAt: 0,
|
|
190
198
|
});
|
|
191
199
|
}
|
|
@@ -195,6 +203,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
195
203
|
slug: `${CLI_COMMAND_SLUG_PREFIX}${entry.id}`,
|
|
196
204
|
summary: normalizeSummary(entry.description),
|
|
197
205
|
outgoingSlugs: [],
|
|
206
|
+
leaves: [],
|
|
198
207
|
modifiedAt: 0,
|
|
199
208
|
});
|
|
200
209
|
}
|
|
@@ -210,6 +219,7 @@ export async function getPageIndex(workspaceDir: string): Promise<PageIndex> {
|
|
|
210
219
|
slug: draft.slug,
|
|
211
220
|
summary: draft.summary,
|
|
212
221
|
edges: [],
|
|
222
|
+
leaves: draft.leaves,
|
|
213
223
|
modifiedAt: draft.modifiedAt,
|
|
214
224
|
};
|
|
215
225
|
bySlug.set(entry.slug, entry);
|
|
@@ -329,6 +339,7 @@ function buildLocalPageIndex(
|
|
|
329
339
|
slug: src.slug,
|
|
330
340
|
summary: src.summary,
|
|
331
341
|
edges: [],
|
|
342
|
+
leaves: src.leaves,
|
|
332
343
|
modifiedAt: src.modifiedAt,
|
|
333
344
|
};
|
|
334
345
|
localBySlug.set(local.slug, local);
|
package/src/memory/v2/router.ts
CHANGED
|
@@ -453,19 +453,16 @@ async function runRouterBatch(
|
|
|
453
453
|
|
|
454
454
|
let response;
|
|
455
455
|
try {
|
|
456
|
-
response = await provider.sendMessage(
|
|
457
|
-
[
|
|
458
|
-
[routerTool],
|
|
456
|
+
response = await provider.sendMessage([userMsg], {
|
|
457
|
+
tools: [routerTool],
|
|
459
458
|
systemPrompt,
|
|
460
|
-
{
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
disableTurnStartCache: true,
|
|
465
|
-
},
|
|
466
|
-
...(signal ? { signal } : {}),
|
|
459
|
+
config: {
|
|
460
|
+
callSite: "memoryRouter" as const,
|
|
461
|
+
tool_choice: { type: "tool" as const, name: ROUTER_TOOL_NAME },
|
|
462
|
+
disableTurnStartCache: true,
|
|
467
463
|
},
|
|
468
|
-
|
|
464
|
+
...(signal ? { signal } : {}),
|
|
465
|
+
});
|
|
469
466
|
} catch (err) {
|
|
470
467
|
log.warn({ err }, "Router provider call threw; treating as api_error");
|
|
471
468
|
return emptyBatchResult("api_error");
|
|
@@ -76,7 +76,7 @@ const MAX_BUFFER_CHARS = 16_000;
|
|
|
76
76
|
// returns the tool input as `unknown`. The two must stay in sync.
|
|
77
77
|
const SWEEP_TOOL_NAME = "emit_remember_entries";
|
|
78
78
|
|
|
79
|
-
const SWEEP_TOOL
|
|
79
|
+
const SWEEP_TOOL = {
|
|
80
80
|
name: SWEEP_TOOL_NAME,
|
|
81
81
|
description:
|
|
82
82
|
"Emit zero or more remember()-style entries the assistant should commit to long-term memory.",
|
|
@@ -92,7 +92,7 @@ const SWEEP_TOOL: ToolDefinition = {
|
|
|
92
92
|
},
|
|
93
93
|
required: ["entries"],
|
|
94
94
|
},
|
|
95
|
-
};
|
|
95
|
+
} satisfies ToolDefinition;
|
|
96
96
|
|
|
97
97
|
const SweepResultSchema = z.object({
|
|
98
98
|
entries: z.array(z.string()),
|
|
@@ -154,17 +154,14 @@ export async function memoryV2SweepJob(
|
|
|
154
154
|
`## existingBuffer\n\n${existingBuffer || "(empty)"}\n\n` +
|
|
155
155
|
`## recentMessages\n\n${recentText}`;
|
|
156
156
|
|
|
157
|
-
const response = await provider.sendMessage(
|
|
158
|
-
[
|
|
159
|
-
[SWEEP_TOOL],
|
|
157
|
+
const response = await provider.sendMessage([userMessage(userText)], {
|
|
158
|
+
tools: [SWEEP_TOOL],
|
|
160
159
|
systemPrompt,
|
|
161
|
-
{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
tool_choice: { type: "tool" as const, name: SWEEP_TOOL_NAME },
|
|
165
|
-
},
|
|
160
|
+
config: {
|
|
161
|
+
callSite: "memoryV2Sweep" as const,
|
|
162
|
+
tool_choice: { type: "tool" as const, name: SWEEP_TOOL_NAME },
|
|
166
163
|
},
|
|
167
|
-
);
|
|
164
|
+
});
|
|
168
165
|
|
|
169
166
|
const toolBlock = extractToolUse(response);
|
|
170
167
|
if (!toolBlock || toolBlock.name !== SWEEP_TOOL_NAME) {
|
package/src/memory/v2/types.ts
CHANGED