@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
package/src/memory/v3/filter.ts
DELETED
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — fast dense-hit filter.
|
|
3
|
-
*
|
|
4
|
-
* The dense scout lane surfaces embedding-similarity candidates that span
|
|
5
|
-
* subtrees: some are meaningful cross-domain associations worth carrying into
|
|
6
|
-
* the gate, others are spurious near-neighbors that only crowd the slate. This
|
|
7
|
-
* module makes **one cheap LLM call** to keep the meaningful associations and
|
|
8
|
-
* drop the noise, *before* the more expensive selection gate runs.
|
|
9
|
-
*
|
|
10
|
-
* What it judges. Only the bounded dense candidate set (the scout lane is
|
|
11
|
-
* already capped at ~50–200 by quota/MMR — the filter never sees the whole
|
|
12
|
-
* corpus). Hot pages and near-exact sparse hits arrive via the scouts'
|
|
13
|
-
* `sticky` / `bypass` sets and are **never judged**: a literal keyword hit or a
|
|
14
|
-
* page the user has been touching is a strong enough signal that we shouldn't
|
|
15
|
-
* make it earn its place through a fallible cheap judgment, and the downstream
|
|
16
|
-
* gate force-injects every sticky slug regardless — judging it could not change
|
|
17
|
-
* its fate. The `bypass` subset is additionally unioned straight into `kept`.
|
|
18
|
-
*
|
|
19
|
-
* Fail-open. If no provider is configured or the call errors / returns an
|
|
20
|
-
* unusable response, the filter keeps *all* judged dense candidates and surfaces
|
|
21
|
-
* a `failureReason` so the loop can record that the filter was bypassed.
|
|
22
|
-
* Dropping candidates on a model outage would silently starve retrieval; keeping
|
|
23
|
-
* them is the safe degradation (the downstream gate still narrows the slate).
|
|
24
|
-
*
|
|
25
|
-
* No LLM call when there is nothing to judge. A dense set fully covered by
|
|
26
|
-
* sticky short-circuits to `kept` = the bypass-relevant slugs (no judged
|
|
27
|
-
* additions), with no provider round-trip.
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
import { z } from "zod";
|
|
31
|
-
|
|
32
|
-
import {
|
|
33
|
-
extractToolUse,
|
|
34
|
-
getConfiguredProvider,
|
|
35
|
-
} from "../../providers/provider-send-message.js";
|
|
36
|
-
import type {
|
|
37
|
-
Message,
|
|
38
|
-
Provider,
|
|
39
|
-
ToolDefinition,
|
|
40
|
-
} from "../../providers/types.js";
|
|
41
|
-
import { getLogger } from "../../util/logger.js";
|
|
42
|
-
import type { RetrievalInput } from "../v2/harness/retriever.js";
|
|
43
|
-
import type { ScoutResult } from "../v2/harness/trace.js";
|
|
44
|
-
import type { LlmCallSink } from "./llm-capture.js";
|
|
45
|
-
import { renderConversationContext } from "./prompt-context.js";
|
|
46
|
-
import {
|
|
47
|
-
FILTER_SYSTEM_PROMPT,
|
|
48
|
-
resolveV3SystemPrompt,
|
|
49
|
-
} from "./prompts/system-prompts.js";
|
|
50
|
-
|
|
51
|
-
const log = getLogger("memory-v3-filter");
|
|
52
|
-
|
|
53
|
-
/** Tool name forced via `tool_choice`. Shared constant so tests can match it. */
|
|
54
|
-
const FILTER_TOOL_NAME = "filter_dense_hits";
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Arguments to one filter invocation.
|
|
58
|
-
*
|
|
59
|
-
* `dense` is the bounded dense scout result; only its slugs that are *not*
|
|
60
|
-
* already in `sticky` are judged. `sticky` is the keep-in-the-running set (hot +
|
|
61
|
-
* near-exact sparse) the downstream gate force-injects regardless of this
|
|
62
|
-
* filter, so judging a sticky page wastes an LLM call that can never change its
|
|
63
|
-
* fate. `bypass` is the subset of sticky strong enough to skip judgment that the
|
|
64
|
-
* filter also unions straight into `kept`. Sticky slugs that also appear in the
|
|
65
|
-
* dense lane are excluded from the judged set and never sent to the model.
|
|
66
|
-
*/
|
|
67
|
-
export interface FilterDenseHitsArgs {
|
|
68
|
-
input: RetrievalInput;
|
|
69
|
-
dense: ScoutResult;
|
|
70
|
-
sticky: Set<string>;
|
|
71
|
-
bypass: Set<string>;
|
|
72
|
-
/** Optional debug sink — emits one record for the filter's LLM call. */
|
|
73
|
-
capture?: LlmCallSink;
|
|
74
|
-
/**
|
|
75
|
-
* Provider override seam for tests. Production leaves this unset and the
|
|
76
|
-
* filter resolves `getConfiguredProvider("memoryV3Filter")`. `null` is
|
|
77
|
-
* distinct from `undefined`: passing `null` simulates "no provider
|
|
78
|
-
* configured" and exercises the fail-open path without resolving the real
|
|
79
|
-
* registry.
|
|
80
|
-
*/
|
|
81
|
-
provider?: Provider | null;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export interface FilterDenseHitsResult {
|
|
85
|
-
/** Final kept slugs: bypass ∪ judged-kept. */
|
|
86
|
-
kept: string[];
|
|
87
|
-
/** Inspection trace: which dense slugs were judged and which were dropped. */
|
|
88
|
-
trace: { judged: string[]; dropped: string[] };
|
|
89
|
-
/**
|
|
90
|
-
* Non-null when the filter could not judge (no provider, provider throw,
|
|
91
|
-
* missing tool_use, schema mismatch) and therefore failed open by keeping all
|
|
92
|
-
* dense candidates. The loop can surface this to flag a bypassed filter.
|
|
93
|
-
*/
|
|
94
|
-
failureReason?: string;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Build the forced tool definition. `keep_slugs` is the model's subset of the
|
|
99
|
-
* judged candidate set to retain; everything judged-but-not-kept is dropped.
|
|
100
|
-
* Mirrors the forced-tool pattern of v2's `select_pages_to_inject`.
|
|
101
|
-
*/
|
|
102
|
-
function buildFilterTool(judgedSlugs: readonly string[]): ToolDefinition {
|
|
103
|
-
return {
|
|
104
|
-
name: FILTER_TOOL_NAME,
|
|
105
|
-
description:
|
|
106
|
-
"From the candidate concept pages surfaced by embedding similarity for " +
|
|
107
|
-
"the current turn, keep the ones that are meaningful associations worth " +
|
|
108
|
-
"surfacing and drop the spurious near-neighbors. Return keep_slugs as the " +
|
|
109
|
-
"subset to retain — choose only from the candidate set. Lean toward " +
|
|
110
|
-
"keeping a plausible cross-domain association over dropping it.",
|
|
111
|
-
input_schema: {
|
|
112
|
-
type: "object",
|
|
113
|
-
properties: {
|
|
114
|
-
keep_slugs: {
|
|
115
|
-
type: "array",
|
|
116
|
-
items: { type: "string", enum: [...judgedSlugs] },
|
|
117
|
-
description:
|
|
118
|
-
"The subset of candidate page slugs to keep. Choose only from the candidate set.",
|
|
119
|
-
},
|
|
120
|
-
reasoning: {
|
|
121
|
-
type: "string",
|
|
122
|
-
description:
|
|
123
|
-
"One short sentence: why these hits were kept and the rest dropped.",
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
required: ["keep_slugs"],
|
|
127
|
-
},
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const FilterToolResultSchema = z.object({
|
|
132
|
-
keep_slugs: z.array(z.string()),
|
|
133
|
-
reasoning: z.string().optional(),
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Compose the final result. `kept` = bypass slugs ∪ judged-kept (de-duplicated,
|
|
138
|
-
* bypass first then judged-kept in the model's returned order). `trace` records
|
|
139
|
-
* exactly which dense slugs were judged and which the model dropped.
|
|
140
|
-
*/
|
|
141
|
-
function buildResult(
|
|
142
|
-
bypass: Set<string>,
|
|
143
|
-
judged: readonly string[],
|
|
144
|
-
judgedKept: readonly string[],
|
|
145
|
-
failureReason?: string,
|
|
146
|
-
): FilterDenseHitsResult {
|
|
147
|
-
const keptSet = new Set<string>(bypass);
|
|
148
|
-
const kept: string[] = [...bypass];
|
|
149
|
-
for (const slug of judgedKept) {
|
|
150
|
-
if (keptSet.has(slug)) continue;
|
|
151
|
-
keptSet.add(slug);
|
|
152
|
-
kept.push(slug);
|
|
153
|
-
}
|
|
154
|
-
const keptJudged = new Set(judgedKept);
|
|
155
|
-
const dropped = judged.filter((slug) => !keptJudged.has(slug));
|
|
156
|
-
return {
|
|
157
|
-
kept,
|
|
158
|
-
trace: { judged: [...judged], dropped },
|
|
159
|
-
...(failureReason !== undefined ? { failureReason } : {}),
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Run the fast dense-hit filter for one pass.
|
|
165
|
-
*
|
|
166
|
-
* Makes at most one forced-tool LLM call over the *judged* set (dense slugs not
|
|
167
|
-
* already in `sticky`). Sticky slugs are force-selected by the downstream gate
|
|
168
|
-
* regardless of this filter, so they are excluded from judgment; bypass slugs
|
|
169
|
-
* are additionally kept unconditionally here. On an empty judged set no call is
|
|
170
|
-
* made. Any failure (no provider, provider throw, missing tool_use, schema
|
|
171
|
-
* mismatch) fails open: every judged dense candidate is kept and a
|
|
172
|
-
* `failureReason` is returned.
|
|
173
|
-
*/
|
|
174
|
-
export async function filterDenseHits(
|
|
175
|
-
args: FilterDenseHitsArgs,
|
|
176
|
-
): Promise<FilterDenseHitsResult> {
|
|
177
|
-
const { input, dense, sticky, bypass } = args;
|
|
178
|
-
|
|
179
|
-
// Sticky slugs (hot + near-exact sparse) are force-selected by the gate
|
|
180
|
-
// regardless of this filter, so judging them wastes an LLM call that can't
|
|
181
|
-
// change their fate. Exclude the full sticky set (a superset of bypass) from
|
|
182
|
-
// the judged set; only the remaining dense near-neighbors are judged.
|
|
183
|
-
const judged = dense.slugs.filter((slug) => !sticky.has(slug));
|
|
184
|
-
|
|
185
|
-
// Nothing to judge → no LLM call. Kept is just the bypass-relevant slugs.
|
|
186
|
-
if (judged.length === 0) {
|
|
187
|
-
return buildResult(bypass, judged, judged);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Resolve the provider. A `provider` key in args (including explicit `null`)
|
|
191
|
-
// takes precedence so tests inject a stub; production omits it and resolves
|
|
192
|
-
// the configured `memoryV3Filter` call site.
|
|
193
|
-
const provider =
|
|
194
|
-
args.provider !== undefined
|
|
195
|
-
? args.provider
|
|
196
|
-
: await getConfiguredProvider("memoryV3Filter");
|
|
197
|
-
|
|
198
|
-
if (!provider) {
|
|
199
|
-
log.warn(
|
|
200
|
-
"memoryV3Filter provider unavailable; failing open (keeping all dense)",
|
|
201
|
-
);
|
|
202
|
-
return buildResult(bypass, judged, judged, "no_provider");
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const systemPrompt = resolveV3SystemPrompt(
|
|
206
|
-
FILTER_SYSTEM_PROMPT,
|
|
207
|
-
input.config.memory?.v3?.prompts?.filter,
|
|
208
|
-
input.workspaceDir,
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
const userMsg: Message = {
|
|
212
|
-
role: "user",
|
|
213
|
-
content: [
|
|
214
|
-
{
|
|
215
|
-
type: "text",
|
|
216
|
-
text: renderConversationContext(input),
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
type: "text",
|
|
220
|
-
text: `<candidate_slugs>\n${judged.join("\n")}\n</candidate_slugs>`,
|
|
221
|
-
},
|
|
222
|
-
],
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
const filterTool = buildFilterTool(judged);
|
|
226
|
-
|
|
227
|
-
const startedAt = Date.now();
|
|
228
|
-
let response;
|
|
229
|
-
try {
|
|
230
|
-
response = await provider.sendMessage(
|
|
231
|
-
[userMsg],
|
|
232
|
-
[filterTool],
|
|
233
|
-
systemPrompt,
|
|
234
|
-
{
|
|
235
|
-
config: {
|
|
236
|
-
callSite: "memoryV3Filter" as const,
|
|
237
|
-
tool_choice: { type: "tool" as const, name: FILTER_TOOL_NAME },
|
|
238
|
-
},
|
|
239
|
-
...(input.signal ? { signal: input.signal } : {}),
|
|
240
|
-
},
|
|
241
|
-
);
|
|
242
|
-
} catch (err) {
|
|
243
|
-
log.warn({ err }, "Filter provider call threw; failing open (keep all)");
|
|
244
|
-
return buildResult(bypass, judged, judged, "api_error");
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
args.capture?.({
|
|
248
|
-
lane: "filter",
|
|
249
|
-
callSite: "memoryV3Filter",
|
|
250
|
-
request: { systemPrompt, messages: [userMsg], tools: [filterTool] },
|
|
251
|
-
response,
|
|
252
|
-
ms: Date.now() - startedAt,
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
const toolBlock = extractToolUse(response);
|
|
256
|
-
if (!toolBlock || toolBlock.name !== FILTER_TOOL_NAME) {
|
|
257
|
-
log.warn(
|
|
258
|
-
{ stopReason: response.stopReason },
|
|
259
|
-
"Filter model returned no filter_dense_hits tool_use; failing open (keep all)",
|
|
260
|
-
);
|
|
261
|
-
return buildResult(bypass, judged, judged, "tool_use_missing");
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const parsed = FilterToolResultSchema.safeParse(toolBlock.input);
|
|
265
|
-
if (!parsed.success) {
|
|
266
|
-
log.warn(
|
|
267
|
-
{ error: parsed.error.message },
|
|
268
|
-
"Filter tool input did not match schema; failing open (keep all)",
|
|
269
|
-
);
|
|
270
|
-
return buildResult(bypass, judged, judged, "schema_mismatch");
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Restrict the model's keep set to the judged candidates (it can only keep
|
|
274
|
-
// what it was shown) and preserve its returned order.
|
|
275
|
-
const judgedSet = new Set(judged);
|
|
276
|
-
const seen = new Set<string>();
|
|
277
|
-
const judgedKept: string[] = [];
|
|
278
|
-
for (const slug of parsed.data.keep_slugs) {
|
|
279
|
-
if (!judgedSet.has(slug)) continue;
|
|
280
|
-
if (seen.has(slug)) continue;
|
|
281
|
-
seen.add(slug);
|
|
282
|
-
judgedKept.push(slug);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return buildResult(bypass, judged, judgedKept);
|
|
286
|
-
}
|
package/src/memory/v3/gate.ts
DELETED
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory v3 — selection gate.
|
|
3
|
-
*
|
|
4
|
-
* The gate is the final step of one retrieval pass. After the scouts, the tree
|
|
5
|
-
* walk, the edge expansion, and the sticky carry-over have each contributed
|
|
6
|
-
* candidate page slugs, the gate makes one capable LLM call over the *unioned*
|
|
7
|
-
* candidate set and decides:
|
|
8
|
-
*
|
|
9
|
-
* - **ready** — finalize the selection and inject for the next reply, or
|
|
10
|
-
* - **more** — the candidates don't yet cover the turn; emit follow-up
|
|
11
|
-
* questions that seed the next pass. These questions are the gate's own
|
|
12
|
-
* *generated* queries (a refined sub-question), NOT a replay of the
|
|
13
|
-
* original user message — the loop feeds them back to the scouts/tree on
|
|
14
|
-
* the next iteration.
|
|
15
|
-
*
|
|
16
|
-
* The gate also returns the final ordered `selectedSlugs` (the order the model
|
|
17
|
-
* returned, with sticky slugs guaranteed present). Sticky pages are never
|
|
18
|
-
* dropped: they were injected on a prior turn and removing them mid-conversation
|
|
19
|
-
* would silently amnesia the assistant, so we union them back in even when the
|
|
20
|
-
* model omits them.
|
|
21
|
-
*
|
|
22
|
-
* Scope — brief generation is deferred. The full v3 design pairs the selection
|
|
23
|
-
* with a ~1000-token voice brief, but that brief is only consumed when v3 is
|
|
24
|
-
* actually injected (a later cutover). In shadow mode the harness injects v2
|
|
25
|
-
* and only compares selections, so this module produces the selection +
|
|
26
|
-
* `GateDecision` only — matching what the harness trace already models. The
|
|
27
|
-
* brief-generation seam is marked below; do not build voice synthesis here.
|
|
28
|
-
*
|
|
29
|
-
* Fail-safe. If no provider is configured or the provider call errors/returns
|
|
30
|
-
* an unusable response, the gate fails *open*: it returns
|
|
31
|
-
* `decision: { decision: "ready" }` and selects every candidate. A retrieval
|
|
32
|
-
* loop that can't reach the model should still inject what it found rather than
|
|
33
|
-
* inject nothing.
|
|
34
|
-
*
|
|
35
|
-
* This module is currently unwired — a later PR composes it into the loop.
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
import { z } from "zod";
|
|
39
|
-
|
|
40
|
-
import {
|
|
41
|
-
extractToolUse,
|
|
42
|
-
getConfiguredProvider,
|
|
43
|
-
} from "../../providers/provider-send-message.js";
|
|
44
|
-
import type {
|
|
45
|
-
Message,
|
|
46
|
-
Provider,
|
|
47
|
-
ToolDefinition,
|
|
48
|
-
} from "../../providers/types.js";
|
|
49
|
-
import { getLogger } from "../../util/logger.js";
|
|
50
|
-
import type { RetrievalInput } from "../v2/harness/retriever.js";
|
|
51
|
-
import type { GateDecision } from "../v2/harness/trace.js";
|
|
52
|
-
import type { LlmCallSink } from "./llm-capture.js";
|
|
53
|
-
import { renderConversationContext } from "./prompt-context.js";
|
|
54
|
-
import {
|
|
55
|
-
GATE_SYSTEM_PROMPT,
|
|
56
|
-
resolveV3SystemPrompt,
|
|
57
|
-
} from "./prompts/system-prompts.js";
|
|
58
|
-
|
|
59
|
-
const log = getLogger("memory-v3-gate");
|
|
60
|
-
|
|
61
|
-
/** Tool name forced via `tool_choice`. Shared constant so tests can match it. */
|
|
62
|
-
const GATE_TOOL_NAME = "decide_selection";
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Arguments to one gate invocation.
|
|
66
|
-
*
|
|
67
|
-
* `candidates` is the accumulated candidate set for this pass — the union of
|
|
68
|
-
* scouts-kept, tree pages, edge-pulled, and sticky slugs. `sticky` is the
|
|
69
|
-
* subset that was injected on a prior turn and must survive: it is always a
|
|
70
|
-
* subset of `candidates` in practice, but the gate unions it back into both
|
|
71
|
-
* the prompt and the final selection defensively.
|
|
72
|
-
*/
|
|
73
|
-
export interface RunGateArgs {
|
|
74
|
-
input: RetrievalInput;
|
|
75
|
-
candidates: Set<string>;
|
|
76
|
-
sticky: Set<string>;
|
|
77
|
-
passNumber: number;
|
|
78
|
-
/**
|
|
79
|
-
* Per-candidate one-line summaries, keyed by slug. When present, candidates
|
|
80
|
-
* are rendered to the model as `slug — summary` so the gate can judge
|
|
81
|
-
* relevance on page content rather than the slug alone. Missing entries fall
|
|
82
|
-
* back to the bare slug; the model answers with the candidate's `[N]` number
|
|
83
|
-
* (`selected_ids`) regardless, so summaries never change the answer format. The
|
|
84
|
-
* loop passes this only when `memory.v3.gateCandidateSummaries` is set.
|
|
85
|
-
*/
|
|
86
|
-
summaryBySlug?: ReadonlyMap<string, string>;
|
|
87
|
-
/** Optional debug sink — emits one record for the gate's LLM call. */
|
|
88
|
-
capture?: LlmCallSink;
|
|
89
|
-
/**
|
|
90
|
-
* Provider override seam for tests. Production leaves this unset and the
|
|
91
|
-
* gate resolves `getConfiguredProvider("memoryV3Gate")`. `null` is distinct
|
|
92
|
-
* from `undefined`: passing `null` simulates "no provider configured" and
|
|
93
|
-
* exercises the fail-safe path without resolving the real registry.
|
|
94
|
-
*/
|
|
95
|
-
provider?: Provider | null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface RunGateResult {
|
|
99
|
-
decision: GateDecision;
|
|
100
|
-
/** Final page slugs in the model's returned order; sticky guaranteed present. */
|
|
101
|
-
selectedSlugs: string[];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Build the forced tool definition. `selected_ids` is the list of bracketed
|
|
106
|
-
* `[N]` candidate numbers to keep; `decision` is the ready/more verdict;
|
|
107
|
-
* `questions` carries the generated follow-up queries on "more" (ignored on
|
|
108
|
-
* "ready"). The schema is candidate-independent — no per-turn enum — so it stays
|
|
109
|
-
* byte-identical across turns (cache-friendly) and the model answers with the
|
|
110
|
-
* line numbers rather than reproducing exact slug strings, mirroring the
|
|
111
|
-
* integer-id output of v2's `select_pages_to_inject`.
|
|
112
|
-
*/
|
|
113
|
-
function buildGateTool(): ToolDefinition {
|
|
114
|
-
return {
|
|
115
|
-
name: GATE_TOOL_NAME,
|
|
116
|
-
description:
|
|
117
|
-
"Decide whether the accumulated candidate pages are sufficient to answer " +
|
|
118
|
-
"the next turn. Return decision='ready' with the final selection " +
|
|
119
|
-
"when the candidates cover the turn; return decision='more' with one or " +
|
|
120
|
-
"more generated follow-up questions (NOT the original message) to seed " +
|
|
121
|
-
"another retrieval pass when coverage is incomplete.",
|
|
122
|
-
input_schema: {
|
|
123
|
-
type: "object",
|
|
124
|
-
properties: {
|
|
125
|
-
decision: { type: "string", enum: ["ready", "more"] },
|
|
126
|
-
selected_ids: {
|
|
127
|
-
type: "array",
|
|
128
|
-
items: { type: "integer" },
|
|
129
|
-
description:
|
|
130
|
-
"The bracketed `[N]` numbers of the candidate pages to keep. Prefer " +
|
|
131
|
-
"keeping a plausibly-relevant page over dropping it; for a list / " +
|
|
132
|
-
"'all of X' / breadth request, include every candidate that plausibly " +
|
|
133
|
-
"applies rather than trimming to the most prominent few.",
|
|
134
|
-
},
|
|
135
|
-
questions: {
|
|
136
|
-
type: "array",
|
|
137
|
-
items: { type: "string" },
|
|
138
|
-
description:
|
|
139
|
-
"When decision='more', the generated follow-up questions seeding the next pass.",
|
|
140
|
-
},
|
|
141
|
-
reasoning: {
|
|
142
|
-
type: "string",
|
|
143
|
-
description:
|
|
144
|
-
"One short sentence: why this ready/more verdict, and which " +
|
|
145
|
-
"candidates were kept or dropped.",
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
required: ["decision", "selected_ids"],
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const GateToolResultSchema = z.object({
|
|
154
|
-
decision: z.enum(["ready", "more"]),
|
|
155
|
-
selected_ids: z.array(z.coerce.number()).optional(),
|
|
156
|
-
questions: z.array(z.string()).optional(),
|
|
157
|
-
reasoning: z.string().optional(),
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Render the candidate list for the prompt. Each line is `[N] slug — summary`
|
|
162
|
-
* (or `[N] slug` without a summary), numbered from 1 in candidate order. The
|
|
163
|
-
* model answers with the `[N]` numbers via `selected_ids`, which the caller maps
|
|
164
|
-
* back to slugs by index — so the tool schema stays candidate-independent.
|
|
165
|
-
*/
|
|
166
|
-
function renderCandidateLines(
|
|
167
|
-
slugs: readonly string[],
|
|
168
|
-
summaryBySlug: ReadonlyMap<string, string> | undefined,
|
|
169
|
-
): string {
|
|
170
|
-
return slugs
|
|
171
|
-
.map((slug, i) => {
|
|
172
|
-
const summary = summaryBySlug?.get(slug);
|
|
173
|
-
const body = summary ? `${slug} — ${summary}` : slug;
|
|
174
|
-
return `[${i + 1}] ${body}`;
|
|
175
|
-
})
|
|
176
|
-
.join("\n");
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Order a slug selection: keep the model's returned order, restricted to the
|
|
181
|
-
* candidate set, then append any sticky slugs the model omitted (sticky is
|
|
182
|
-
* never dropped). De-duplicates while preserving first-seen order.
|
|
183
|
-
*/
|
|
184
|
-
function orderSelection(
|
|
185
|
-
modelSlugs: readonly string[],
|
|
186
|
-
candidates: Set<string>,
|
|
187
|
-
sticky: Set<string>,
|
|
188
|
-
): string[] {
|
|
189
|
-
const seen = new Set<string>();
|
|
190
|
-
const out: string[] = [];
|
|
191
|
-
for (const slug of modelSlugs) {
|
|
192
|
-
if (!candidates.has(slug)) continue; // model can only pick from candidates
|
|
193
|
-
if (seen.has(slug)) continue;
|
|
194
|
-
seen.add(slug);
|
|
195
|
-
out.push(slug);
|
|
196
|
-
}
|
|
197
|
-
for (const slug of sticky) {
|
|
198
|
-
if (seen.has(slug)) continue;
|
|
199
|
-
seen.add(slug);
|
|
200
|
-
out.push(slug);
|
|
201
|
-
}
|
|
202
|
-
return out;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Fail-safe result: inject every candidate and declare the pass ready. Used
|
|
207
|
-
* when the provider is unavailable or the call cannot produce a usable
|
|
208
|
-
* decision. Ordering puts sticky last via `orderSelection` with an empty
|
|
209
|
-
* model selection, so candidates come first then any sticky not already in
|
|
210
|
-
* the set.
|
|
211
|
-
*/
|
|
212
|
-
function failSafe(candidates: Set<string>, sticky: Set<string>): RunGateResult {
|
|
213
|
-
return {
|
|
214
|
-
decision: { decision: "ready" },
|
|
215
|
-
selectedSlugs: orderSelection([...candidates], candidates, sticky),
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Run the gate for one pass.
|
|
221
|
-
*
|
|
222
|
-
* Makes one forced-tool LLM call over the candidate set and maps the result to
|
|
223
|
-
* a `GateDecision` plus the final ordered selection. Sticky slugs are always
|
|
224
|
-
* present in the selection. Any failure (no provider, provider throw, missing
|
|
225
|
-
* tool_use, schema mismatch) falls back to selecting all candidates with a
|
|
226
|
-
* "ready" decision.
|
|
227
|
-
*/
|
|
228
|
-
export async function runGate(args: RunGateArgs): Promise<RunGateResult> {
|
|
229
|
-
const { input, candidates, sticky, passNumber } = args;
|
|
230
|
-
|
|
231
|
-
const candidateSlugs = [...candidates];
|
|
232
|
-
|
|
233
|
-
// Resolve the provider. A `provider` key in args (including explicit `null`)
|
|
234
|
-
// takes precedence so tests inject a stub; production omits it and resolves
|
|
235
|
-
// the configured `memoryV3Gate` call site.
|
|
236
|
-
const provider =
|
|
237
|
-
args.provider !== undefined
|
|
238
|
-
? args.provider
|
|
239
|
-
: await getConfiguredProvider("memoryV3Gate");
|
|
240
|
-
|
|
241
|
-
if (!provider) {
|
|
242
|
-
log.warn("memoryV3Gate provider unavailable; gate failing open (ready)");
|
|
243
|
-
return failSafe(candidates, sticky);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const systemPrompt = resolveV3SystemPrompt(
|
|
247
|
-
GATE_SYSTEM_PROMPT,
|
|
248
|
-
input.config.memory?.v3?.prompts?.gate,
|
|
249
|
-
input.workspaceDir,
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
const stickySlugs = [...sticky];
|
|
253
|
-
const userMsg: Message = {
|
|
254
|
-
role: "user",
|
|
255
|
-
content: [
|
|
256
|
-
{
|
|
257
|
-
type: "text",
|
|
258
|
-
text: renderConversationContext(input),
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
type: "text",
|
|
262
|
-
text:
|
|
263
|
-
`<pass_number>${passNumber}</pass_number>\n\n` +
|
|
264
|
-
`<sticky_slugs>\n${stickySlugs.join("\n")}\n</sticky_slugs>\n\n` +
|
|
265
|
-
`<candidates>\n` +
|
|
266
|
-
`${renderCandidateLines(candidateSlugs, args.summaryBySlug)}\n` +
|
|
267
|
-
`</candidates>`,
|
|
268
|
-
},
|
|
269
|
-
],
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
const gateTool = buildGateTool();
|
|
273
|
-
|
|
274
|
-
const startedAt = Date.now();
|
|
275
|
-
let response;
|
|
276
|
-
try {
|
|
277
|
-
response = await provider.sendMessage([userMsg], [gateTool], systemPrompt, {
|
|
278
|
-
config: {
|
|
279
|
-
callSite: "memoryV3Gate" as const,
|
|
280
|
-
tool_choice: { type: "tool" as const, name: GATE_TOOL_NAME },
|
|
281
|
-
},
|
|
282
|
-
...(input.signal ? { signal: input.signal } : {}),
|
|
283
|
-
});
|
|
284
|
-
} catch (err) {
|
|
285
|
-
log.warn({ err }, "Gate provider call threw; failing open (ready)");
|
|
286
|
-
return failSafe(candidates, sticky);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
args.capture?.({
|
|
290
|
-
lane: "gate",
|
|
291
|
-
callSite: "memoryV3Gate",
|
|
292
|
-
request: { systemPrompt, messages: [userMsg], tools: [gateTool] },
|
|
293
|
-
response,
|
|
294
|
-
ms: Date.now() - startedAt,
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
const toolBlock = extractToolUse(response);
|
|
298
|
-
if (!toolBlock || toolBlock.name !== GATE_TOOL_NAME) {
|
|
299
|
-
log.warn(
|
|
300
|
-
{ stopReason: response.stopReason },
|
|
301
|
-
"Gate model returned no decide_selection tool_use; failing open (ready)",
|
|
302
|
-
);
|
|
303
|
-
return failSafe(candidates, sticky);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const parsed = GateToolResultSchema.safeParse(toolBlock.input);
|
|
307
|
-
if (!parsed.success) {
|
|
308
|
-
log.warn(
|
|
309
|
-
{ error: parsed.error.message },
|
|
310
|
-
"Gate tool input did not match schema; failing open (ready)",
|
|
311
|
-
);
|
|
312
|
-
return failSafe(candidates, sticky);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Recall-safe fallback: an *omitted* `selected_ids` means the model gave no
|
|
316
|
-
// instruction, so keep everything that was surfaced — dropping all non-sticky
|
|
317
|
-
// context on a silent omission is the worse failure. An *explicit* `[]` is the
|
|
318
|
-
// model genuinely choosing nothing and is honored as-is. Ids are 1-based
|
|
319
|
-
// indices into the rendered candidate list; out-of-range ids are dropped.
|
|
320
|
-
const modelSlugs =
|
|
321
|
-
parsed.data.selected_ids === undefined
|
|
322
|
-
? [...candidates]
|
|
323
|
-
: parsed.data.selected_ids
|
|
324
|
-
.map((id) => candidateSlugs[Math.trunc(id) - 1])
|
|
325
|
-
.filter((slug): slug is string => slug !== undefined);
|
|
326
|
-
const selectedSlugs = orderSelection(modelSlugs, candidates, sticky);
|
|
327
|
-
|
|
328
|
-
const reasoning = parsed.data.reasoning?.trim() || undefined;
|
|
329
|
-
|
|
330
|
-
if (parsed.data.decision === "more") {
|
|
331
|
-
const questions = (parsed.data.questions ?? []).filter(
|
|
332
|
-
(q) => q.trim().length > 0,
|
|
333
|
-
);
|
|
334
|
-
const decision: GateDecision = {
|
|
335
|
-
decision: "more",
|
|
336
|
-
...(questions.length > 0 ? { questions } : {}),
|
|
337
|
-
...(reasoning ? { reasoning } : {}),
|
|
338
|
-
};
|
|
339
|
-
return { decision, selectedSlugs };
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// brief generation lands at cutover (P5) — shadow mode injects v2, so this
|
|
343
|
-
// gate produces only the selection + decision. Do NOT synthesize a voice
|
|
344
|
-
// brief here.
|
|
345
|
-
return {
|
|
346
|
-
decision: { decision: "ready", ...(reasoning ? { reasoning } : {}) },
|
|
347
|
-
selectedSlugs,
|
|
348
|
-
};
|
|
349
|
-
}
|