@vellumai/assistant 0.8.7 → 0.8.8-dev.202606052332.17fc8ea
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/Dockerfile +20 -4
- package/bun.lock +2 -2
- package/docker-entrypoint.sh +4 -2
- package/docker-init-apt-root.sh +3 -1
- package/docker-kata-apt-env.sh +3 -1
- package/docker-kata-runtime-family.sh +12 -0
- package/docs/architecture/memory.md +1 -1
- package/examples/plugins/echo/README.md +61 -66
- package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
- package/examples/plugins/echo/hooks/stop.ts +16 -0
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
- package/examples/plugins/echo/package.json +1 -2
- package/examples/plugins/echo/src/emit.ts +19 -0
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
- package/openapi.yaml +3378 -335
- package/package.json +2 -2
- package/scripts/generate-openapi.ts +68 -41
- package/src/__tests__/agent-loop-exit-reason.test.ts +35 -93
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +37 -87
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -3
- package/src/__tests__/anthropic-provider.test.ts +95 -2
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/assistant-event-hub.test.ts +25 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
- package/src/__tests__/{conversation-stream-state.test.ts → assistant-stream-state.test.ts} +252 -91
- package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
- package/src/__tests__/btw-routes.test.ts +62 -3
- package/src/__tests__/build-persisted-content.test.ts +184 -0
- package/src/__tests__/catalog-files.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/clawhub-files.test.ts +1 -1
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction.benchmark.test.ts +0 -30
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +57 -19
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +6 -5
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -7
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +316 -1143
- package/src/__tests__/conversation-agent-loop.test.ts +638 -1655
- package/src/__tests__/conversation-analysis-routes.test.ts +6 -0
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-history-web-search.test.ts +11 -1
- package/src/__tests__/conversation-pairing.test.ts +4 -31
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +6 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -10
- package/src/__tests__/conversation-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +6 -5
- package/src/__tests__/conversation-runtime-assembly.test.ts +310 -300
- package/src/__tests__/conversation-runtime-workspace.test.ts +105 -45
- package/src/__tests__/conversation-slash-commands.test.ts +8 -42
- package/src/__tests__/conversation-slash-queue.test.ts +6 -1
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +84 -0
- package/src/__tests__/conversation-sync-tags.test.ts +27 -15
- package/src/__tests__/conversation-title-service.test.ts +135 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +17 -16
- package/src/__tests__/conversation-workspace-injection.test.ts +67 -2
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +7 -6
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/cross-provider-web-search.test.ts +214 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +5 -0
- package/src/__tests__/dm-persistence.test.ts +5 -1
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +304 -0
- package/src/__tests__/feature-flag-test-helpers.ts +2 -2
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +12 -2
- package/src/__tests__/gemini-image-service.test.ts +13 -0
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/mock-provider.ts +110 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
- package/src/__tests__/history-repair-hook.test.ts +1 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/identity-intro-cache.test.ts +12 -100
- package/src/__tests__/identity-routes.test.ts +248 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +5 -1
- package/src/__tests__/injector-background-turn.test.ts +3 -9
- package/src/__tests__/injector-chain.test.ts +139 -275
- package/src/__tests__/injector-disk-pressure.test.ts +75 -41
- package/src/__tests__/injector-document-comments.test.ts +3 -3
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
- package/src/__tests__/injector-v3-suppression.test.ts +31 -37
- package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/list-messages-page-latest.test.ts +60 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +20 -0
- package/src/__tests__/llm-usage-store.test.ts +223 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
- package/src/__tests__/native-web-search.test.ts +191 -0
- package/src/__tests__/onboarding-template-contract.test.ts +2 -0
- package/src/__tests__/openai-image-service.test.ts +17 -0
- package/src/__tests__/openai-provider.test.ts +31 -1
- package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -284
- package/src/__tests__/persist-unsendable-image.test.ts +215 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +1 -0
- package/src/__tests__/pkb-autoinject.test.ts +2 -5
- package/src/__tests__/plugin-api-shim.test.ts +3 -6
- package/src/__tests__/plugin-bootstrap.test.ts +14 -40
- package/src/__tests__/plugin-registry.test.ts +3 -76
- package/src/__tests__/plugin-types.test.ts +0 -193
- package/src/__tests__/process-message-display-content.test.ts +6 -2
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
- package/src/__tests__/resolve-trust-class.test.ts +4 -4
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +60 -23
- package/src/__tests__/schedule-routes.test.ts +603 -2
- package/src/__tests__/schedule-store.test.ts +41 -0
- package/src/__tests__/schedule-tools.test.ts +35 -0
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/server-history-render.test.ts +314 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
- package/src/__tests__/skillssh-files.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/system-prompt.test.ts +20 -0
- package/src/__tests__/task-scheduler.test.ts +162 -1
- package/src/__tests__/terminal-tools.test.ts +6 -1
- package/src/__tests__/title-generate-hook.test.ts +319 -0
- package/src/__tests__/tool-error-hook.test.ts +278 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +468 -5
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -2
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
- package/src/__tests__/ui-work-result-surface.test.ts +159 -0
- package/src/__tests__/usage-routes.test.ts +285 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/voice-session-bridge.test.ts +6 -3
- package/src/__tests__/web-search-backend-failure.test.ts +166 -0
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +137 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +736 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +196 -0
- package/src/acp/auto-install.ts +177 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +83 -29
- package/src/acp/resolve-agent.test.ts +320 -7
- package/src/acp/resolve-agent.ts +182 -18
- package/src/acp/resume-hint.ts +25 -0
- package/src/acp/session-manager.ts +495 -73
- package/src/acp/types.ts +8 -0
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +362 -485
- package/src/api/events/assistant-thinking-delta.ts +33 -0
- package/src/api/events/tool-output-chunk.ts +45 -0
- package/src/api/events/tool-use-preview-start.ts +32 -0
- package/src/api/events/trace-event.ts +69 -0
- package/src/api/index.ts +48 -13
- package/src/api/responses/conversation-message.ts +374 -0
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/avatar/__tests__/avatar-store.test.ts +34 -29
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/notifications.test.ts +58 -14
- package/src/cli/commands/notifications.ts +112 -60
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +6 -0
- package/src/config/assistant-feature-flags.ts +22 -11
- package/src/config/bundled-skills/acp/SKILL.md +83 -31
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -398
- package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
- package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
- package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
- package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +0 -7
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/feature-flag-cache.ts +3 -3
- package/src/config/feature-flag-registry.json +48 -7
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-v2.ts +8 -0
- package/src/config/schemas/memory-v3.ts +8 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills.ts +13 -0
- package/src/context/compactor.ts +1 -1
- package/src/context/strip-injections.ts +128 -0
- package/src/context/token-estimator.ts +23 -0
- package/src/context/tool-result-truncation.ts +0 -23
- package/src/context/window-manager.ts +5 -7
- package/src/credential-execution/executable-discovery.ts +16 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
- package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/config-watcher.ts +2 -2
- package/src/daemon/context-overflow-reducer.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +594 -153
- package/src/daemon/conversation-agent-loop.ts +301 -997
- package/src/daemon/conversation-history.ts +5 -4
- package/src/daemon/conversation-lifecycle.ts +3 -4
- package/src/daemon/conversation-messaging.ts +7 -6
- package/src/daemon/conversation-process.ts +11 -16
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +218 -398
- package/src/daemon/conversation-slash.ts +6 -25
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +222 -4
- package/src/daemon/conversation-tool-setup.ts +2 -29
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +32 -20
- package/src/daemon/external-plugins-bootstrap.ts +17 -18
- package/src/daemon/handlers/config-a2a.ts +51 -36
- package/src/daemon/handlers/config-slack-channel.ts +20 -14
- package/src/daemon/handlers/config-telegram.ts +16 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/shared.ts +156 -84
- package/src/daemon/handlers/skills.ts +42 -10
- package/src/daemon/lifecycle.ts +25 -0
- package/src/daemon/message-types/apps.ts +1 -29
- package/src/daemon/message-types/messages.ts +9 -57
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +136 -3
- package/src/daemon/now-scratchpad.ts +21 -0
- package/src/daemon/orphan-reaper.test.ts +210 -0
- package/src/daemon/orphan-reaper.ts +240 -0
- package/src/daemon/overflow-reduction-loop.ts +230 -0
- package/src/daemon/persist-unsendable-image.ts +117 -0
- package/src/daemon/process-message.ts +1 -3
- package/src/daemon/server.ts +2 -0
- package/src/daemon/trace-emitter.ts +6 -4
- package/src/daemon/trust-context.ts +19 -0
- package/src/daemon/wake-target-adapter.ts +3 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
- package/src/heartbeat/heartbeat-run-store.ts +23 -1
- package/src/heartbeat/heartbeat-service.ts +26 -0
- package/src/home/home-greeting-cache.ts +24 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/gateway-client.test.ts +2 -2
- package/src/ipc/gateway-client.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
- package/src/ipc/skill-routes/memory.ts +4 -2
- package/src/media/gemini-image-service.ts +15 -0
- package/src/media/openai-image-service.ts +14 -0
- package/src/media/types.ts +34 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
- package/src/memory/auth-fallback-events-store.ts +94 -0
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/conversation-title-service.ts +65 -41
- package/src/memory/db-init.ts +6 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
- package/src/memory/graph/conversation-graph-memory.ts +65 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs-store.ts +33 -0
- package/src/memory/jobs-worker.ts +32 -5
- package/src/memory/llm-usage-store.ts +224 -50
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
- package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
- package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/pkb/autoinject.ts +61 -0
- package/src/memory/pkb/context.ts +50 -0
- package/src/memory/pkb/types.ts +14 -0
- package/src/memory/schedule-attribution-sql.ts +104 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +16 -0
- package/src/memory/usage-grouped-buckets.ts +6 -1
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -4
- package/src/memory/v2/consolidation-job.ts +14 -5
- package/src/notifications/conversation-pairing.ts +8 -15
- package/src/notifications/decision-engine.ts +6 -3
- package/src/notifications/home-feed-side-effect.ts +12 -1
- package/src/permissions/prompter.ts +4 -0
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +7 -5
- package/src/plugin-api/types.ts +151 -1
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/plugins/defaults/compaction/package.json +1 -1
- package/src/plugins/defaults/compaction/register.ts +8 -19
- package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
- package/src/plugins/defaults/empty-response/register.ts +8 -13
- package/src/plugins/defaults/index.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +288 -81
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +16 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +48 -12
- package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +104 -32
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +96 -30
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +34 -16
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
- package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +26 -14
- package/src/plugins/defaults/{llm-call → memory-v3-shadow}/package.json +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +3 -3
- package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +51 -45
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +61 -46
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +69 -99
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +8 -0
- package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/title-generate/package.json +1 -1
- package/src/plugins/defaults/title-generate/register.ts +18 -18
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
- package/src/plugins/defaults/tool-error/package.json +1 -1
- package/src/plugins/defaults/tool-error/register.ts +9 -21
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +10 -21
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +37 -18
- package/src/plugins/external-api.ts +2 -2
- package/src/plugins/pipeline.ts +6 -305
- package/src/plugins/registry.ts +10 -55
- package/src/plugins/types.ts +62 -797
- package/src/plugins/user-loader.ts +30 -127
- package/src/proactive-artifact/aux-message-injector.ts +4 -4
- package/src/proactive-artifact/job.test.ts +8 -13
- package/src/prompts/__tests__/system-prompt.test.ts +42 -0
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
- package/src/prompts/templates/BOOTSTRAP.md +2 -2
- package/src/prompts/templates/system-sections.ts +15 -0
- package/src/providers/anthropic/client.ts +37 -29
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -0
- package/src/providers/openrouter/client.ts +1 -0
- package/src/providers/placeholder-sentinels.ts +35 -0
- package/src/runtime/__tests__/agent-wake.test.ts +10 -6
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +2 -5
- package/src/runtime/assistant-event-hub.ts +37 -7
- package/src/runtime/{conversation-stream-state.ts → assistant-stream-state.ts} +132 -58
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/http-router.ts +16 -21
- package/src/runtime/http-types.ts +16 -70
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +283 -55
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.test.ts +89 -25
- package/src/runtime/routes/acp-routes.ts +81 -29
- package/src/runtime/routes/app-management-routes.ts +6 -117
- package/src/runtime/routes/app-routes.ts +13 -15
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/attachment-routes.ts +26 -15
- package/src/runtime/routes/avatar-routes.ts +26 -0
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/btw-routes.ts +29 -23
- package/src/runtime/routes/consolidation-routes.ts +120 -20
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +3 -1
- package/src/runtime/routes/conversation-routes.ts +372 -185
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- package/src/runtime/routes/documents-routes.ts +4 -0
- package/src/runtime/routes/domain-routes.ts +51 -37
- package/src/runtime/routes/epoch-millis-range.ts +34 -0
- package/src/runtime/routes/events-routes.ts +28 -34
- package/src/runtime/routes/gateway-log-routes.ts +26 -4
- package/src/runtime/routes/heartbeat-routes.ts +32 -12
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-intro-cache.ts +11 -34
- package/src/runtime/routes/identity-routes.ts +224 -18
- package/src/runtime/routes/image-generation-routes.ts +40 -2
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/a2a.ts +12 -10
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
- package/src/runtime/routes/integrations/slack/channel.ts +4 -0
- package/src/runtime/routes/integrations/slack/share.ts +27 -6
- package/src/runtime/routes/integrations/telegram.ts +6 -0
- package/src/runtime/routes/integrations/twilio.ts +42 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
- package/src/runtime/routes/log-export-routes.ts +8 -0
- package/src/runtime/routes/memory-v2-routes.ts +15 -8
- package/src/runtime/routes/memory-v3-routes.ts +66 -34
- package/src/runtime/routes/oauth-apps.ts +66 -12
- package/src/runtime/routes/oauth-providers.ts +44 -5
- package/src/runtime/routes/platform-routes.ts +81 -5
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +6 -4
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/schedule-routes.ts +152 -42
- package/src/runtime/routes/secret-routes.ts +14 -2
- package/src/runtime/routes/skills-routes.ts +43 -14
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
- package/src/runtime/routes/trust-rules-routes.ts +26 -2
- package/src/runtime/routes/tts-routes.ts +35 -0
- package/src/runtime/routes/types.ts +66 -8
- package/src/runtime/routes/usage-routes.ts +47 -39
- package/src/runtime/routes/webhook-routes.ts +41 -2
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +4 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +6 -0
- package/src/runtime/services/analyze-conversation.ts +2 -2
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/schedule/schedule-store.ts +20 -1
- package/src/schedule/schedule-usage-store.ts +83 -0
- package/src/schedule/scheduler.ts +12 -5
- package/src/signals/cancel.ts +2 -4
- package/src/skills/catalog-files.ts +2 -2
- package/src/skills/catalog-install.ts +3 -0
- package/src/skills/categories-cache.ts +118 -0
- package/src/skills/clawhub-files.ts +1 -2
- package/src/skills/skillssh-files.ts +1 -2
- package/src/subagent/manager.ts +17 -5
- package/src/telemetry/types.ts +29 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +112 -3
- package/src/telemetry/usage-telemetry-reporter.ts +57 -2
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +7 -1
- package/src/tools/acp/spawn.test.ts +158 -55
- package/src/tools/acp/spawn.ts +47 -72
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +13 -8
- package/src/tools/executor.ts +1 -53
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
- package/src/tools/network/__tests__/web-search.test.ts +11 -3
- package/src/tools/network/web-search-error.test.ts +248 -0
- package/src/tools/network/web-search-error.ts +267 -0
- package/src/tools/network/web-search.ts +207 -48
- package/src/tools/schedule/create.ts +2 -0
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/terminal/safe-env.ts +10 -1
- package/src/tools/ui-surface/definitions.ts +34 -5
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
- package/src/tts/provider-catalog.ts +76 -1
- package/src/util/mutex.ts +47 -0
- package/src/workspace/git-service.ts +1 -42
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
- package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/docs/plugins.md +0 -836
- package/examples/plugins/echo/register.ts +0 -184
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
- package/src/__tests__/empty-response-pipeline.test.ts +0 -423
- package/src/__tests__/llm-call-pipeline.test.ts +0 -287
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
- package/src/__tests__/persistence-pipeline.test.ts +0 -503
- package/src/__tests__/pipeline-runner.test.ts +0 -564
- package/src/__tests__/title-generate-pipeline.test.ts +0 -211
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -479
- package/src/__tests__/tool-error-pipeline.test.ts +0 -241
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -341
- package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
- package/src/gallery/default-gallery.ts +0 -1359
- package/src/gallery/gallery-manifest.ts +0 -28
- package/src/home/feature-gate.ts +0 -22
- package/src/memory/v3/provider-blocks.ts +0 -16
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
- package/src/plugins/defaults/circuit-breaker/package.json +0 -15
- package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +0 -22
- package/src/plugins/defaults/empty-response/terminal.ts +0 -106
- package/src/plugins/defaults/injectors/package.json +0 -15
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +0 -17
- package/src/plugins/defaults/llm-call/register.ts +0 -45
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +0 -17
- package/src/plugins/defaults/memory-retrieval/package.json +0 -15
- package/src/plugins/defaults/memory-retrieval/register.ts +0 -181
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
- package/src/plugins/defaults/overflow-reduce/package.json +0 -15
- package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +0 -19
- package/src/plugins/defaults/persistence/package.json +0 -15
- package/src/plugins/defaults/persistence/register.ts +0 -38
- package/src/plugins/defaults/persistence/terminal.ts +0 -83
- package/src/plugins/defaults/title-generate/terminal.ts +0 -31
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +0 -23
- package/src/plugins/defaults/token-estimate/package.json +0 -15
- package/src/plugins/defaults/token-estimate/register.ts +0 -34
- package/src/plugins/defaults/token-estimate/terminal.ts +0 -40
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +0 -21
- package/src/plugins/defaults/tool-error/terminal.ts +0 -47
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +0 -23
- package/src/plugins/defaults/tool-execute/package.json +0 -15
- package/src/plugins/defaults/tool-execute/register.ts +0 -49
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/types.ts +0 -22
- package/src/skills/category-inference.ts +0 -111
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
|
@@ -22,8 +22,8 @@ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
|
22
22
|
|
|
23
23
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
24
24
|
|
|
25
|
-
import { migrateAddMemoryV3Selections } from "
|
|
26
|
-
import * as schema from "
|
|
25
|
+
import { migrateAddMemoryV3Selections } from "../../../../memory/migrations/268-add-memory-v3-selections.js";
|
|
26
|
+
import * as schema from "../../../../memory/schema.js";
|
|
27
27
|
import type { LeafTree, SelectionSource } from "../types.js";
|
|
28
28
|
|
|
29
29
|
// `mock.module` is process-global and, in Bun, neither `mock.restore()` nor a
|
|
@@ -41,10 +41,10 @@ const realTree = { ...(await import("../tree.js")) };
|
|
|
41
41
|
const realCore = { ...(await import("../core.js")) };
|
|
42
42
|
const realNeedle = { ...(await import("../needle.js")) };
|
|
43
43
|
const realOrchestrate = { ...(await import("../orchestrate.js")) };
|
|
44
|
-
const realPlatform = { ...(await import("
|
|
45
|
-
const realPageStore = { ...(await import("
|
|
44
|
+
const realPlatform = { ...(await import("../../../../util/platform.js")) };
|
|
45
|
+
const realPageStore = { ...(await import("../../../../memory/v2/page-store.js")) };
|
|
46
46
|
const realConversationCrud = {
|
|
47
|
-
...(await import("
|
|
47
|
+
...(await import("../../../../memory/conversation-crud.js")),
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
let shadowMockActive = false;
|
|
@@ -68,6 +68,7 @@ const orchestrateSpy = mock(async () => ({
|
|
|
68
68
|
let treeLoads = 0;
|
|
69
69
|
let coreLoads = 0;
|
|
70
70
|
let needleBuilds = 0;
|
|
71
|
+
let configL2Concurrency = 16;
|
|
71
72
|
|
|
72
73
|
// Shared in-memory DB so writes are observable from the test. We hold the raw
|
|
73
74
|
// sqlite handle alongside the drizzle wrapper so the test can both read rows
|
|
@@ -94,7 +95,7 @@ const FAKE_TREE = {
|
|
|
94
95
|
|
|
95
96
|
// ─── module mocks (installed before the plugin import) ──────────────────────
|
|
96
97
|
|
|
97
|
-
mock.module("
|
|
98
|
+
mock.module("../../../../config/assistant-feature-flags.js", () => ({
|
|
98
99
|
isAssistantFeatureFlagEnabled: (key: string) =>
|
|
99
100
|
key === "memory-v3-live"
|
|
100
101
|
? liveEnabled
|
|
@@ -103,9 +104,14 @@ mock.module("../../../config/assistant-feature-flags.js", () => ({
|
|
|
103
104
|
: false,
|
|
104
105
|
}));
|
|
105
106
|
|
|
106
|
-
mock.module("
|
|
107
|
+
mock.module("../../../../config/loader.js", () => ({
|
|
107
108
|
getConfig: () => ({
|
|
108
|
-
memory: {
|
|
109
|
+
memory: {
|
|
110
|
+
v3: {
|
|
111
|
+
workingSet: { maxPages: 150, evictWindow: 5 },
|
|
112
|
+
l2Concurrency: configL2Concurrency,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
109
115
|
}),
|
|
110
116
|
}));
|
|
111
117
|
|
|
@@ -113,12 +119,12 @@ mock.module("../../../config/loader.js", () => ({
|
|
|
113
119
|
// (e.g. `getMessageById` via page-content.ts) stays present — replacing the
|
|
114
120
|
// whole module with a bare `{ getMessages }` made those consumers fail to load.
|
|
115
121
|
// Only `getMessages` is overridden, since that's the one the plugin reads.
|
|
116
|
-
mock.module("
|
|
122
|
+
mock.module("../../../../memory/conversation-crud.js", () => ({
|
|
117
123
|
...realConversationCrud,
|
|
118
124
|
getMessages: () => messages.map((m, i) => ({ ...m, id: `m${i}` })),
|
|
119
125
|
}));
|
|
120
126
|
|
|
121
|
-
mock.module("
|
|
127
|
+
mock.module("../../../../memory/db-connection.js", () => ({
|
|
122
128
|
getDb: () => testDb,
|
|
123
129
|
getSqliteFrom: () => testSqlite,
|
|
124
130
|
}));
|
|
@@ -130,7 +136,7 @@ mock.module("../v2/page-index.js", () => ({
|
|
|
130
136
|
// `pageContent` (live mode) reads the full page via `readPage`/`renderPageContent`.
|
|
131
137
|
// Stub them to return a deterministic body per slug so the rendered `<memory>`
|
|
132
138
|
// block is assertable without touching the filesystem.
|
|
133
|
-
mock.module("
|
|
139
|
+
mock.module("../../../../memory/v2/page-store.js", () => ({
|
|
134
140
|
...realPageStore,
|
|
135
141
|
readPage: async (workspaceDir: string, slug: string) =>
|
|
136
142
|
shadowMockActive
|
|
@@ -144,7 +150,7 @@ mock.module("../../v2/page-store.js", () => ({
|
|
|
144
150
|
),
|
|
145
151
|
}));
|
|
146
152
|
|
|
147
|
-
mock.module("
|
|
153
|
+
mock.module("../../../../util/platform.js", () => ({
|
|
148
154
|
...realPlatform,
|
|
149
155
|
getWorkspaceDir: () =>
|
|
150
156
|
shadowMockActive
|
|
@@ -203,8 +209,8 @@ const {
|
|
|
203
209
|
runShadowObservation,
|
|
204
210
|
resetShadowLanesForTests,
|
|
205
211
|
invalidateLanes,
|
|
206
|
-
memoryV3ShadowPlugin,
|
|
207
212
|
} = await import("../shadow-plugin.js");
|
|
213
|
+
const { memoryV3Injector } = await import("../injector.js");
|
|
208
214
|
|
|
209
215
|
// The module stubs above stay installed for the rest of the process (Bun can't
|
|
210
216
|
// reliably uninstall them), but `shadowMockActive` gates their fake behavior to
|
|
@@ -235,14 +241,14 @@ beforeEach(() => {
|
|
|
235
241
|
treeLoads = 0;
|
|
236
242
|
coreLoads = 0;
|
|
237
243
|
needleBuilds = 0;
|
|
244
|
+
configL2Concurrency = 16;
|
|
238
245
|
testDb = makeDb();
|
|
239
246
|
resetShadowLanesForTests();
|
|
240
247
|
});
|
|
241
248
|
|
|
242
|
-
/** Invoke the
|
|
249
|
+
/** Invoke the memory-v3 injector's `produce()` for a turn. */
|
|
243
250
|
function produce(conversationId: string, turnIndex: number) {
|
|
244
|
-
|
|
245
|
-
return injector.produce({
|
|
251
|
+
return memoryV3Injector.produce({
|
|
246
252
|
requestId: "r1",
|
|
247
253
|
conversationId,
|
|
248
254
|
turnIndex,
|
|
@@ -289,6 +295,18 @@ describe("memory-v3 shadow plugin", () => {
|
|
|
289
295
|
expect(turn.currentMessage).toBe("hello world");
|
|
290
296
|
});
|
|
291
297
|
|
|
298
|
+
test("orchestrate receives the configured L2 concurrency", async () => {
|
|
299
|
+
shadowEnabled = true;
|
|
300
|
+
configL2Concurrency = 9;
|
|
301
|
+
await runShadowObservation("conv-1", 0);
|
|
302
|
+
const deps = (
|
|
303
|
+
orchestrateSpy.mock.calls as unknown as unknown[][]
|
|
304
|
+
)[0]![1] as {
|
|
305
|
+
l2Concurrency?: number;
|
|
306
|
+
};
|
|
307
|
+
expect(deps.l2Concurrency).toBe(9);
|
|
308
|
+
});
|
|
309
|
+
|
|
292
310
|
test("both flags OFF → produce returns null, no orchestrate, no writes", async () => {
|
|
293
311
|
liveEnabled = false;
|
|
294
312
|
shadowEnabled = false;
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
* omitted, resolves the `memoryV3RouteL1` callsite provider.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import { listPages, readPage, writePage } from "../../../memory/v2/page-store.js";
|
|
22
|
+
import type { ConceptPage } from "../../../memory/v2/types.js";
|
|
21
23
|
import {
|
|
22
24
|
extractToolUse,
|
|
23
25
|
getConfiguredProvider,
|
|
24
26
|
userMessage,
|
|
25
|
-
} from "
|
|
26
|
-
import type { Provider, ToolDefinition } from "
|
|
27
|
-
import { getLogger } from "
|
|
28
|
-
import { listPages, readPage, writePage } from "../v2/page-store.js";
|
|
29
|
-
import type { ConceptPage } from "../v2/types.js";
|
|
27
|
+
} from "../../../providers/provider-send-message.js";
|
|
28
|
+
import type { Provider, ToolDefinition } from "../../../providers/types.js";
|
|
29
|
+
import { getLogger } from "../../../util/logger.js";
|
|
30
30
|
import type { LeafPath, LeafTree, Slug } from "./types.js";
|
|
31
31
|
|
|
32
32
|
const log = getLogger("memory-v3-assign");
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
import {
|
|
29
29
|
getCliCommandCapability,
|
|
30
30
|
isCliCommandSlug,
|
|
31
|
-
} from "
|
|
32
|
-
import { getSkillCapability, isSkillSlug } from "
|
|
31
|
+
} from "../../../memory/v2/cli-command-store.js";
|
|
32
|
+
import { getSkillCapability, isSkillSlug } from "../../../memory/v2/skill-store.js";
|
|
33
33
|
import type { LeafNode, LeafPath, LeafTree, Slug } from "./types.js";
|
|
34
34
|
|
|
35
35
|
/** Path of the always-on synthetic leaf that owns skill + CLI capability rows. */
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No-op `post-compact` scaffolding for the memory-v3-shadow plugin.
|
|
3
|
+
*
|
|
4
|
+
* v3 re-injection after mid-turn compaction is not yet owned by this plugin —
|
|
5
|
+
* the active injector still runs through the static chain. Once the
|
|
6
|
+
* post-compaction hook API stabilizes we will import `memoryV3Injector` from
|
|
7
|
+
* `../injector.js` and re-apply it here. Until then this hook does nothing.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { PluginHookFn } from "@vellumai/plugin-api";
|
|
11
|
+
|
|
12
|
+
const postCompact: PluginHookFn = async () => {};
|
|
13
|
+
|
|
14
|
+
export default postCompact;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No-op `user-prompt-submit` scaffolding for the memory-v3-shadow plugin.
|
|
3
|
+
*
|
|
4
|
+
* The v3 injector currently runs through the static injector chain
|
|
5
|
+
* (`memory-retrieval/injector-chain.ts`), not through this hook. Once the
|
|
6
|
+
* prompt-submit hook API stabilizes we will import `memoryV3Injector` from
|
|
7
|
+
* `../injector.js` and run it here, so v3 injection is owned by the plugin's
|
|
8
|
+
* own lifecycle rather than the loop-driven chain. Until then this hook
|
|
9
|
+
* intentionally does nothing.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
PluginHookFn,
|
|
14
|
+
UserPromptSubmitContext,
|
|
15
|
+
} from "@vellumai/plugin-api";
|
|
16
|
+
|
|
17
|
+
const userPromptSubmit: PluginHookFn<UserPromptSubmitContext> = async () => {};
|
|
18
|
+
|
|
19
|
+
export default userPromptSubmit;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The memory-v3 {@link Injector}. Reads both v3 flags:
|
|
3
|
+
* - `memory-v3-live` on → orchestrate, log, render the working-set selection
|
|
4
|
+
* into a `<memory>` block, and return it at v2's dynamic-memory placement.
|
|
5
|
+
* - `memory-v3-shadow` on (live off) → orchestrate + log only, return `null`.
|
|
6
|
+
* - both off → return `null` (no orchestration).
|
|
7
|
+
*
|
|
8
|
+
* Empty selection and any failure return `null` (no v3 injection). v2
|
|
9
|
+
* suppression keys off BOTH the flag AND this return value, so a `null` here
|
|
10
|
+
* (failure or empty selection) falls back to v2 memory rather than dropping all
|
|
11
|
+
* memory.
|
|
12
|
+
*
|
|
13
|
+
* Orchestration and telemetry live in {@link observeTurn}; this module is the
|
|
14
|
+
* thin injector wrapper that renders the result for live injection.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { isAssistantFeatureFlagEnabled } from "../../../config/assistant-feature-flags.js";
|
|
18
|
+
import { getConfig } from "../../../config/loader.js";
|
|
19
|
+
import { getLogger } from "../../../util/logger.js";
|
|
20
|
+
import {
|
|
21
|
+
type InjectionBlock,
|
|
22
|
+
type Injector,
|
|
23
|
+
type TurnContext as PluginTurnContext,
|
|
24
|
+
} from "../../types.js";
|
|
25
|
+
import { renderV3PageContent } from "./page-content.js";
|
|
26
|
+
import { renderMemoryBlock } from "./render-injection.js";
|
|
27
|
+
import {
|
|
28
|
+
MEMORY_V3_LIVE,
|
|
29
|
+
MEMORY_V3_SHADOW,
|
|
30
|
+
observeTurn,
|
|
31
|
+
} from "./shadow-plugin.js";
|
|
32
|
+
import { MEMORY_V3_BLOCK_ID } from "./types.js";
|
|
33
|
+
|
|
34
|
+
const log = getLogger("memory-v3-shadow");
|
|
35
|
+
|
|
36
|
+
export const memoryV3Injector: Injector = {
|
|
37
|
+
name: "memory-v3-shadow",
|
|
38
|
+
// High order so it sorts last; the live `<memory>` block uses the
|
|
39
|
+
// after-memory-prefix placement so it lands at the memory boundary regardless
|
|
40
|
+
// of this sort key, which only orders content-producing injectors.
|
|
41
|
+
order: 1000,
|
|
42
|
+
async produce(ctx: PluginTurnContext): Promise<InjectionBlock | null> {
|
|
43
|
+
const config = getConfig();
|
|
44
|
+
const live = isAssistantFeatureFlagEnabled(MEMORY_V3_LIVE, config);
|
|
45
|
+
const shadow = isAssistantFeatureFlagEnabled(MEMORY_V3_SHADOW, config);
|
|
46
|
+
if (!live && !shadow) return null;
|
|
47
|
+
|
|
48
|
+
const result = await observeTurn(ctx.conversationId, ctx.turnIndex);
|
|
49
|
+
if (!live || !result) return null;
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
// `renderMemoryBlock` returns "" for an empty selection; inject nothing.
|
|
53
|
+
const text = await renderMemoryBlock(
|
|
54
|
+
result.finalInjection,
|
|
55
|
+
renderV3PageContent,
|
|
56
|
+
);
|
|
57
|
+
if (text.length === 0) return null;
|
|
58
|
+
return {
|
|
59
|
+
id: MEMORY_V3_BLOCK_ID,
|
|
60
|
+
text,
|
|
61
|
+
// Mirror v2's dynamic `<memory>` block placement.
|
|
62
|
+
placement: "after-memory-prefix",
|
|
63
|
+
};
|
|
64
|
+
} catch (err) {
|
|
65
|
+
log.warn(
|
|
66
|
+
{
|
|
67
|
+
err: err instanceof Error ? err.message : String(err),
|
|
68
|
+
conversationId: ctx.conversationId,
|
|
69
|
+
},
|
|
70
|
+
"memory-v3 live render failed (non-fatal) — falling back to v2",
|
|
71
|
+
);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory v3 — shared retry helper for the L1 router and L2 selector model calls.
|
|
3
|
+
*
|
|
4
|
+
* The configured provider is already wrapped in `RetryProvider`
|
|
5
|
+
* (`../../providers/retry.ts`), which retries transient transport failures
|
|
6
|
+
* (network errors, 429s, 5xx, stream aborts) with exponential backoff before it
|
|
7
|
+
* ever throws. This helper therefore adds NO backoff of its own; it exists to:
|
|
8
|
+
* (a) re-prompt on a malformed-but-successful response — a 200 whose body has
|
|
9
|
+
* no usable forced `tool_use`, or whose tool input fails schema validation
|
|
10
|
+
* (the provider's retry never re-runs these, since nothing threw); and
|
|
11
|
+
* (b) cheaply re-attempt a call that threw after the provider exhausted its
|
|
12
|
+
* own retries, before the lane degrades to its deterministic fallback.
|
|
13
|
+
*
|
|
14
|
+
* `attempt` signals "unusable, retry me" by returning `null` (or throwing). The
|
|
15
|
+
* first non-null result wins; `null` after `maxAttempts` tells the caller to
|
|
16
|
+
* degrade to the deterministic recall lanes.
|
|
17
|
+
*/
|
|
18
|
+
export async function retryForResult<T>(
|
|
19
|
+
attempt: () => Promise<T | null>,
|
|
20
|
+
maxAttempts = 3,
|
|
21
|
+
): Promise<T | null> {
|
|
22
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
23
|
+
try {
|
|
24
|
+
const result = await attempt();
|
|
25
|
+
if (result !== null) return result;
|
|
26
|
+
} catch {
|
|
27
|
+
// Treat a throw like an unusable result and retry. The provider layer has
|
|
28
|
+
// already backed off transient errors, so there is nothing to wait for.
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
* `assignPages`, and `invalidateLanes` without process-global module mocks.
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
import { isAssistantFeatureFlagEnabled } from "
|
|
29
|
-
import type { AssistantConfig } from "
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
28
|
+
import { isAssistantFeatureFlagEnabled } from "../../../config/assistant-feature-flags.js";
|
|
29
|
+
import type { AssistantConfig } from "../../../config/types.js";
|
|
30
|
+
import { getMemoryCheckpoint, setMemoryCheckpoint } from "../../../memory/checkpoints.js";
|
|
31
|
+
import type { MemoryJob } from "../../../memory/jobs-store.js";
|
|
32
|
+
import { getPageIndex } from "../../../memory/v2/page-index.js";
|
|
33
|
+
import { listPages, readPage, writePage } from "../../../memory/v2/page-store.js";
|
|
34
|
+
import { getLogger } from "../../../util/logger.js";
|
|
35
|
+
import { getWorkspaceDir } from "../../../util/platform.js";
|
|
36
36
|
import { assignPages as realAssignPages } from "./assign.js";
|
|
37
37
|
import { invalidateLanes as realInvalidateLanes } from "./shadow-plugin.js";
|
|
38
38
|
import { loadLeafTree as realLoadLeafTree, resolveDataDir } from "./tree.js";
|
|
@@ -13,11 +13,16 @@
|
|
|
13
13
|
* then dedup by slug (a page assigned to multiple opened leaves comes back
|
|
14
14
|
* once per leaf) ORing the pinned flag so a page pinned anywhere stays
|
|
15
15
|
* pinned.
|
|
16
|
-
* 4.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
16
|
+
* 4. Age the carry-forward working set to this turn (evict core slugs, stale
|
|
17
|
+
* non-pinned entries, then the cap) and snapshot it — the pages carried in
|
|
18
|
+
* from EARLIER turns.
|
|
19
|
+
* 5. Final injection = unique union of this turn's selected slugs and that
|
|
20
|
+
* carried-forward set, so pages selected on earlier turns carry forward
|
|
21
|
+
* even when this turn does not re-select them.
|
|
22
|
+
* 6. Record this turn's selections into the working set for LATER turns. This
|
|
23
|
+
* runs AFTER the snapshot so the cap is spent on genuinely carried pages,
|
|
24
|
+
* not on this turn's selections (which are injected directly) — otherwise a
|
|
25
|
+
* turn selecting more pages than the cap would evict the entire carry.
|
|
21
26
|
*/
|
|
22
27
|
|
|
23
28
|
import type { NeedleIndex } from "./needle.js";
|
|
@@ -48,7 +53,8 @@ export interface OrchestrateResult {
|
|
|
48
53
|
openedLeaves: LeafPath[];
|
|
49
54
|
/** This turn's L2 selections, deduped by slug (pinned flags ORed). */
|
|
50
55
|
currentSelections: SelectedPage[];
|
|
51
|
-
/**
|
|
56
|
+
/** The carried-forward set: selections from EARLIER turns, aged to this turn
|
|
57
|
+
* (snapshotted before this turn's selections are recorded). */
|
|
52
58
|
workingSetUnion: Set<Slug>;
|
|
53
59
|
/** Slugs to inject: this turn's selections ∪ the carried-forward working set. */
|
|
54
60
|
finalInjection: Slug[];
|
|
@@ -95,20 +101,26 @@ export async function orchestrate(
|
|
|
95
101
|
}
|
|
96
102
|
const currentSelections = [...bySlug.values()];
|
|
97
103
|
|
|
98
|
-
// Step 4:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// Step 5: evict. Core slugs are owned by core, not the working set.
|
|
104
|
+
// Step 4: age the carry-forward set to this turn (drop core slugs, stale
|
|
105
|
+
// non-pinned entries, then the cap) and snapshot it. This is the set carried
|
|
106
|
+
// in from EARLIER turns; recording this turn happens afterward (step 6) so the
|
|
107
|
+
// cap is spent on genuinely carried pages, not on this turn's selections
|
|
108
|
+
// (which are injected directly anyway).
|
|
104
109
|
deps.workingSet.evict(turn.turnNumber, coreSlugs(deps.tree, deps.core));
|
|
105
|
-
|
|
106
|
-
// Step 6: final injection = this turn's selections ∪ carried-forward set.
|
|
107
110
|
const workingSetUnion = deps.workingSet.union();
|
|
111
|
+
|
|
112
|
+
// Step 5: final injection = this turn's selections ∪ the carried-forward set,
|
|
113
|
+
// so pages selected on earlier turns carry forward even when this turn does
|
|
114
|
+
// not re-select them.
|
|
108
115
|
const finalInjection = unique<Slug>([
|
|
109
116
|
...currentSelections.map((s) => s.slug),
|
|
110
117
|
...workingSetUnion,
|
|
111
118
|
]);
|
|
112
119
|
|
|
120
|
+
// Step 6: record this turn's selections so they carry forward to LATER turns.
|
|
121
|
+
for (const sel of currentSelections) {
|
|
122
|
+
deps.workingSet.recordSelection(sel.slug, turn.turnNumber, sel.pinned);
|
|
123
|
+
}
|
|
124
|
+
|
|
113
125
|
return { openedLeaves, currentSelections, workingSetUnion, finalInjection };
|
|
114
126
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "default-
|
|
2
|
+
"name": "default-memory-v3-shadow",
|
|
3
3
|
"version": "1.0.0",
|
|
4
|
-
"description": "First-party default plugin
|
|
4
|
+
"description": "First-party default plugin housing the memory-v3 shadow/live orchestration engine and its injector.",
|
|
5
5
|
"private": true,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { readPage, renderPageContent } from "../../../memory/v2/page-store.js";
|
|
2
|
+
import { getWorkspaceDir } from "../../../util/platform.js";
|
|
3
3
|
import { renderCapabilityContent } from "./capabilities.js";
|
|
4
4
|
import type { Slug } from "./types.js";
|
|
5
5
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ContentBlock } from "../../../providers/types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Text content block carrying a `cache_control` breakpoint with a 1-hour TTL.
|
|
5
|
+
* Shared by the v3 router (the static leaf-tree block) and selector (each
|
|
6
|
+
* leaf's static `<pages>` block): these prefixes are stable across turns — the
|
|
7
|
+
* leaf tree is byte-identical every turn, and a leaf's pages block changes only
|
|
8
|
+
* when its pages/summaries do — while v3 turns are frequently more than the
|
|
9
|
+
* default 5-minute cache window apart. A 1h TTL keeps the prefix warm across
|
|
10
|
+
* those gaps so it is read from cache rather than re-created every turn; the
|
|
11
|
+
* volatile current-message block is rendered after this one and left un-cached.
|
|
12
|
+
* Haiku does not support the extended-cache-ttl beta, so the Anthropic provider
|
|
13
|
+
* strips this `ttl` for Haiku models.
|
|
14
|
+
*
|
|
15
|
+
* Our internal `TextContent` type omits `cache_control` (only the Anthropic
|
|
16
|
+
* provider transforms it onto the wire), so we reach through a `Record` cast to
|
|
17
|
+
* keep the core types provider-agnostic.
|
|
18
|
+
*/
|
|
19
|
+
export function cachedTextBlock(text: string): ContentBlock {
|
|
20
|
+
const block: ContentBlock = { type: "text", text };
|
|
21
|
+
(block as unknown as Record<string, unknown>).cache_control = {
|
|
22
|
+
type: "ephemeral",
|
|
23
|
+
ttl: "1h",
|
|
24
|
+
};
|
|
25
|
+
return block;
|
|
26
|
+
}
|
|
@@ -38,9 +38,9 @@ import { join, relative, sep } from "node:path";
|
|
|
38
38
|
|
|
39
39
|
import { parse as parseYaml } from "yaml";
|
|
40
40
|
|
|
41
|
-
import
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
41
|
+
import { listPages, readPage, writePage } from "../../../memory/v2/page-store.js";
|
|
42
|
+
import type { Provider } from "../../../providers/types.js";
|
|
43
|
+
import { getLogger } from "../../../util/logger.js";
|
|
44
44
|
import { assignPages } from "./assign.js";
|
|
45
45
|
import { loadCore } from "./core.js";
|
|
46
46
|
import { invalidateLanes } from "./shadow-plugin.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `memory-v3-shadow` plugin.
|
|
3
|
+
*
|
|
4
|
+
* Houses the memory-v3 shadow/live orchestration engine (this directory) and
|
|
5
|
+
* its injector (`./injector.ts`). The injector is still consumed by the static
|
|
6
|
+
* chain in `memory-retrieval/injector-chain.ts`; the `user-prompt-submit` /
|
|
7
|
+
* `post-compact` hooks below are no-op scaffolding for the eventual
|
|
8
|
+
* convergence, when v3 injection moves off the loop-driven chain and into these
|
|
9
|
+
* lifecycle hooks. See each hook file for the convergence note.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { type Plugin } from "../../types.js";
|
|
13
|
+
import postCompact from "./hooks/post-compact.js";
|
|
14
|
+
import userPromptSubmit from "./hooks/user-prompt-submit.js";
|
|
15
|
+
import pkg from "./package.json" with { type: "json" };
|
|
16
|
+
|
|
17
|
+
export const memoryV3ShadowPlugin: Plugin = {
|
|
18
|
+
manifest: {
|
|
19
|
+
name: pkg.name,
|
|
20
|
+
version: pkg.version,
|
|
21
|
+
},
|
|
22
|
+
hooks: {
|
|
23
|
+
"user-prompt-submit": userPromptSubmit,
|
|
24
|
+
"post-compact": postCompact,
|
|
25
|
+
},
|
|
26
|
+
};
|