@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091853.fbaa2ae
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/ARCHITECTURE.md +6 -6
- package/bun.lock +2 -2
- package/docs/activation-funnel-telemetry.md +310 -0
- package/examples/plugins/echo/README.md +61 -60
- 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/skill-host.ts +7 -6
- package/openapi.yaml +263 -121
- package/package.json +2 -2
- package/src/__tests__/activation-early-marking.test.ts +120 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
- package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
- package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
- package/src/__tests__/agent-loop-thinking.test.ts +36 -20
- package/src/__tests__/agent-loop.test.ts +441 -96
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
- package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
- package/src/__tests__/anthropic-provider.test.ts +23 -8
- package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +132 -0
- package/src/__tests__/approval-cascade.test.ts +6 -5
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/background-workers-disk-pressure.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__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +146 -0
- package/src/__tests__/compaction-events.test.ts +7 -7
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
- package/src/__tests__/context-overflow-reducer.test.ts +265 -125
- package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
- package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
- package/src/__tests__/conversation-agent-loop.test.ts +342 -623
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
- package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-history-web-search.test.ts +6 -1
- package/src/__tests__/conversation-media-retry.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
- package/src/__tests__/conversation-process-callsite.test.ts +15 -15
- package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
- package/src/__tests__/conversation-queue.test.ts +10 -10
- package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
- package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
- package/src/__tests__/conversation-slash-queue.test.ts +7 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
- package/src/__tests__/conversation-speed-override.test.ts +11 -10
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
- package/src/__tests__/conversation-undo.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
- package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +36 -0
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +1 -1
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +17 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -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__/history-repair-hook.test.ts +5 -1
- package/src/__tests__/host-app-control-proxy.test.ts +45 -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__/inference-profile-reaper.test.ts +62 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
- package/src/__tests__/injector-background-turn.test.ts +13 -23
- package/src/__tests__/injector-chain.test.ts +268 -44
- package/src/__tests__/injector-disk-pressure.test.ts +210 -52
- package/src/__tests__/injector-document-comments.test.ts +97 -114
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-v3-suppression.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/llm-resolver.test.ts +73 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
- package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
- package/src/__tests__/persist-unsendable-image.test.ts +97 -1
- package/src/__tests__/plugin-api-shim.test.ts +6 -9
- package/src/__tests__/plugin-bootstrap.test.ts +91 -81
- package/src/__tests__/plugin-registry.test.ts +3 -49
- package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -70
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
- package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
- package/src/__tests__/published-app-updater.test.ts +138 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
- package/src/__tests__/steer-tool-repair.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-detail.test.ts +25 -7
- 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__/title-generate-hook.test.ts +5 -1
- package/src/__tests__/tool-error-hook.test.ts +1 -1
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/web-fetch.test.ts +45 -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-config-stub.ts +0 -2
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +280 -0
- package/src/acp/auto-install.ts +232 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/prepare-agent-env.ts +80 -27
- package/src/acp/resolve-agent.test.ts +188 -28
- package/src/acp/resolve-agent.ts +119 -42
- package/src/acp/resume-hint.ts +23 -0
- package/src/acp/session-manager.ts +507 -73
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +403 -251
- package/src/api/responses/conversation-message.ts +22 -2
- package/src/api/responses/memory-v3-selection-log.ts +19 -10
- package/src/approvals/guardian-request-resolvers.ts +27 -1
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
- package/src/cli/commands/memory-v3.ts +57 -199
- package/src/cli/commands/plugins.ts +43 -37
- package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
- package/src/cli/lib/install-from-github.ts +797 -60
- package/src/cli/lib/plugin-catalog-cache.ts +84 -0
- package/src/cli/lib/plugin-details.ts +416 -0
- package/src/cli/lib/plugin-marketplace.ts +215 -0
- package/src/cli/lib/search-plugins.ts +201 -29
- 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 +9 -3
- package/src/config/acp-schema.ts +1 -7
- package/src/config/bundled-skills/acp/SKILL.md +80 -41
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
- package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
- 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/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -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-tool-registry.ts +4 -0
- package/src/config/call-site-defaults.ts +0 -3
- package/src/config/feature-flag-registry.json +10 -16
- package/src/config/llm-resolver.ts +39 -7
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
- package/src/config/schemas/call-site-catalog.ts +0 -21
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +17 -3
- package/src/config/schemas/memory-v3.ts +58 -8
- package/src/config/seed-inference-profiles.ts +18 -0
- package/src/context/compactor.ts +22 -4
- package/src/context/post-turn-tool-result-truncation.ts +39 -1
- package/src/context/strip-injections.ts +8 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +18 -36
- package/src/daemon/conversation-agent-loop.ts +308 -1297
- package/src/daemon/conversation-error.ts +31 -4
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +11 -255
- package/src/daemon/conversation-media-retry.ts +19 -6
- package/src/daemon/conversation-messaging.ts +17 -0
- package/src/daemon/conversation-process.ts +22 -141
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +361 -393
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +165 -11
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +444 -62
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/external-plugins-bootstrap.ts +36 -46
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-proxy-preactivation.ts +1 -3
- package/src/daemon/lifecycle.ts +21 -7
- package/src/daemon/persist-unsendable-image.ts +62 -25
- package/src/daemon/process-message.ts +1 -1
- package/src/daemon/server.ts +2 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/wake-conversation-ops.ts +269 -0
- package/src/embedded/plugin-api.ts +2 -2
- package/src/export/__tests__/transcript-formatter.test.ts +5 -0
- 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/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.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/memory/__tests__/activation-session-store.test.ts +41 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
- package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
- package/src/memory/activation-session-store.ts +43 -0
- package/src/memory/conversation-crud.ts +29 -19
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/db-init.ts +6 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
- package/src/memory/jobs-worker.ts +25 -1
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
- package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/onboarding-events-store.ts +66 -18
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
- package/src/memory/v2/__tests__/page-store.test.ts +22 -0
- package/src/memory/v2/consolidation-job.ts +2 -63
- package/src/memory/v2/types.ts +5 -0
- package/src/messaging/providers/telegram-bot/api.ts +14 -5
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +9 -2
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +40 -11
- package/src/plugin-api/types.ts +108 -0
- package/src/plugins/defaults/compaction/compact.ts +106 -0
- package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/plugins/defaults/compaction/manager-store.ts +57 -0
- package/src/plugins/defaults/compaction/package.json +1 -2
- package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
- package/src/plugins/defaults/empty-response/package.json +0 -1
- package/src/plugins/defaults/history-repair/package.json +0 -1
- package/src/plugins/defaults/index.ts +156 -26
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
- package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -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 +76 -0
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
- package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
- package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
- package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
- package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
- package/src/plugins/defaults/title-generate/package.json +0 -1
- package/src/plugins/defaults/tool-error/package.json +0 -1
- package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
- package/src/plugins/external-api.ts +12 -2
- package/src/plugins/pipeline.ts +6 -293
- package/src/plugins/registry.ts +9 -37
- package/src/plugins/types.ts +76 -381
- package/src/plugins/user-loader.ts +30 -127
- package/src/prompts/__tests__/system-prompt.test.ts +6 -0
- package/src/prompts/system-prompt.ts +61 -10
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
- package/src/providers/anthropic/client.ts +9 -10
- package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
- package/src/providers/inference/logit-bias.ts +55 -0
- package/src/providers/model-catalog.ts +34 -0
- package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -1
- package/src/providers/retry.ts +22 -0
- package/src/providers/types.ts +6 -0
- package/src/runtime/__tests__/agent-wake.test.ts +555 -691
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +108 -209
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
- package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
- 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/acp-routes.test.ts +185 -32
- package/src/runtime/routes/acp-routes.ts +328 -30
- package/src/runtime/routes/app-management-routes.ts +3 -0
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- 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 +1 -1
- package/src/runtime/routes/conversation-routes.ts +30 -2
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- 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-routes.ts +18 -3
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
- package/src/runtime/routes/memory-v3-routes.ts +65 -305
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +337 -35
- package/src/runtime/routes/stt-routes.ts +45 -12
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +50 -15
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/services/published-app-updater.ts +30 -8
- package/src/signals/cancel.ts +2 -4
- package/src/subagent/manager.ts +21 -5
- package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
- package/src/telemetry/activation-funnel.ts +167 -0
- package/src/telemetry/types.ts +13 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
- package/src/telemetry/usage-telemetry-reporter.ts +26 -1
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +9 -19
- package/src/tools/acp/list-agents.ts +3 -15
- package/src/tools/acp/spawn.test.ts +173 -202
- package/src/tools/acp/spawn.ts +37 -172
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +166 -50
- package/src/tools/browser/browser-execution.ts +12 -2
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/web-fetch.ts +65 -24
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/ui-surface/definitions.ts +32 -5
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
- package/docs/plugins.md +0 -832
- package/examples/plugins/echo/register.ts +0 -143
- 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__/overflow-reduce-pipeline.test.ts +0 -667
- package/src/__tests__/pipeline-runner.test.ts +0 -554
- package/src/daemon/wake-target-adapter.ts +0 -253
- package/src/memory/v3/__tests__/assign.test.ts +0 -242
- package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
- package/src/memory/v3/__tests__/core.test.ts +0 -39
- package/src/memory/v3/__tests__/health.test.ts +0 -219
- package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
- package/src/memory/v3/__tests__/needle.test.ts +0 -107
- package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
- package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
- package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
- package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
- package/src/memory/v3/__tests__/router.test.ts +0 -332
- package/src/memory/v3/__tests__/selector.test.ts +0 -470
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
- package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
- package/src/memory/v3/__tests__/tree.test.ts +0 -192
- package/src/memory/v3/assign.ts +0 -268
- package/src/memory/v3/capabilities.ts +0 -124
- package/src/memory/v3/core.ts +0 -26
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +0 -314
- package/src/memory/v3/needle.ts +0 -115
- package/src/memory/v3/orchestrate.ts +0 -126
- package/src/memory/v3/page-content.ts +0 -34
- package/src/memory/v3/provider-blocks.ts +0 -26
- package/src/memory/v3/reconcile.ts +0 -523
- package/src/memory/v3/router.ts +0 -190
- package/src/memory/v3/selection-log-store.ts +0 -84
- package/src/memory/v3/selector.ts +0 -226
- package/src/memory/v3/shadow-plugin.ts +0 -411
- package/src/memory/v3/snapshot.ts +0 -209
- package/src/memory/v3/tree.ts +0 -174
- package/src/memory/v3/types.ts +0 -59
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- 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/register.ts +0 -35
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/register.ts +0 -23
- package/src/plugins/defaults/history-repair/register.ts +0 -24
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
- 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/title-generate/register.ts +0 -35
- package/src/plugins/defaults/tool-error/register.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
- package/src/proactive-artifact/aux-message-injector.ts +0 -97
- package/src/proactive-artifact/decision.test.ts +0 -226
- package/src/proactive-artifact/decision.ts +0 -165
- package/src/proactive-artifact/index.ts +0 -7
- package/src/proactive-artifact/job.test.ts +0 -962
- package/src/proactive-artifact/job.ts +0 -372
- package/src/proactive-artifact/message-copy.ts +0 -58
- package/src/proactive-artifact/trigger-state.test.ts +0 -286
- package/src/proactive-artifact/trigger-state.ts +0 -123
- package/src/util/map-limit.ts +0 -27
- /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__/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}/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}/llm-retry.ts +0 -0
package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts
RENAMED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* SCOPE / ALTITUDE. A full daemon-assembly integration (plugin registry → flag
|
|
5
5
|
* read → runtime assembly → provider call) is too heavy and too mock-fragile
|
|
6
6
|
* for a unit test. Instead this composes the REAL v3 live-path units with a
|
|
7
|
-
* mocked
|
|
7
|
+
* mocked select provider + stubbed dense lane and synthetic fixtures:
|
|
8
8
|
*
|
|
9
|
-
* orchestrate (
|
|
9
|
+
* orchestrate (needle ∪ dense ∪ edge → selectPool over a shared WorkingSet)
|
|
10
10
|
* → renderMemoryBlock (the rendered `<memory>` working-set block)
|
|
11
11
|
* → stripAllMemoryInjections (all-turns history strip)
|
|
12
12
|
*
|
|
@@ -16,108 +16,103 @@
|
|
|
16
16
|
* message so exactly one block exists. Driving these real units across turns
|
|
17
17
|
* exercises carry-forward, eviction, single-source, and strip-all end-to-end at
|
|
18
18
|
* the v3 layer without the daemon. The provider is stubbed (no network).
|
|
19
|
-
*
|
|
20
|
-
* Mock-leak safety: the only `mock.module` here stub the provider + logger,
|
|
21
|
-
* which are pure inputs to orchestrate and carry no real behavior siblings
|
|
22
|
-
* depend on (orchestrate.test.ts installs the identical stubs). No
|
|
23
|
-
* snapshot-real-modules dance is needed because nothing is partially stubbed.
|
|
24
19
|
*/
|
|
25
20
|
|
|
26
|
-
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
21
|
+
import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
27
22
|
|
|
23
|
+
import { stripAllMemoryInjections } from "../../../../memory/graph/conversation-graph-memory.js";
|
|
24
|
+
import type { PageIndexEntry } from "../../../../memory/v2/page-index.js";
|
|
28
25
|
import type {
|
|
29
26
|
ContentBlock,
|
|
30
27
|
Message,
|
|
31
28
|
Provider,
|
|
32
29
|
ProviderResponse,
|
|
33
|
-
} from "
|
|
34
|
-
import {
|
|
35
|
-
import
|
|
36
|
-
import
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
LeafTree,
|
|
40
|
-
Slug,
|
|
41
|
-
TurnContext,
|
|
42
|
-
} from "../types.js";
|
|
43
|
-
import liveTurns from "./fixtures/live-turns.json" with { type: "json" };
|
|
30
|
+
} from "../../../../providers/types.js";
|
|
31
|
+
import type { EdgeGraph } from "../edge.js";
|
|
32
|
+
import { buildEdgeGraph } from "../edge.js";
|
|
33
|
+
import { buildSectionNeedle } from "../section-needle.js";
|
|
34
|
+
import { buildSectionIndex } from "../sections.js";
|
|
35
|
+
import type { MemoryRoutingTurn, SectionIndex, Slug } from "../types.js";
|
|
44
36
|
|
|
45
37
|
// ---------------------------------------------------------------------------
|
|
46
|
-
//
|
|
47
|
-
// selector.ts observe it at load time. Mirrors orchestrate.test.ts.
|
|
38
|
+
// Module stubs installed BEFORE the orchestrator import.
|
|
48
39
|
// ---------------------------------------------------------------------------
|
|
49
40
|
|
|
50
41
|
let providerStub: Provider | null = null;
|
|
51
42
|
|
|
52
|
-
mock.module("
|
|
43
|
+
mock.module("../../../../providers/provider-send-message.js", () => ({
|
|
53
44
|
getConfiguredProvider: async () => providerStub,
|
|
54
45
|
extractToolUse: (response: ProviderResponse) =>
|
|
55
46
|
response.content.find((b) => b.type === "tool_use"),
|
|
56
47
|
}));
|
|
57
48
|
|
|
58
|
-
mock.module("
|
|
49
|
+
mock.module("../../../../util/logger.js", () => ({
|
|
59
50
|
getLogger: () =>
|
|
60
51
|
new Proxy({} as Record<string, unknown>, {
|
|
61
52
|
get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
|
|
62
53
|
}),
|
|
63
54
|
}));
|
|
64
55
|
|
|
56
|
+
// The dense lane never hits in this fixture — the needle drives the pool. The
|
|
57
|
+
// stub DELEGATES to the real `denseLane` unless this file's tests are running
|
|
58
|
+
// (`denseMockActive`), so the process-global `mock.module` cannot leak fake
|
|
59
|
+
// behavior into dense.test.ts (which exercises the real lane).
|
|
60
|
+
const realDense = { ...(await import("../dense.js")) };
|
|
61
|
+
let denseMockActive = false;
|
|
62
|
+
mock.module("../dense.js", () => ({
|
|
63
|
+
...realDense,
|
|
64
|
+
denseLane: async (...args: Parameters<typeof realDense.denseLane>) =>
|
|
65
|
+
denseMockActive ? [] : realDense.denseLane(...args),
|
|
66
|
+
}));
|
|
67
|
+
|
|
65
68
|
const { orchestrate } = await import("../orchestrate.js");
|
|
66
69
|
const { WorkingSet } = await import("../working-set.js");
|
|
67
70
|
const { renderMemoryBlock } = await import("../render-injection.js");
|
|
68
71
|
|
|
69
72
|
// ---------------------------------------------------------------------------
|
|
70
|
-
//
|
|
73
|
+
// Fixtures: a tiny corpus whose section text contains a distinctive term per
|
|
74
|
+
// page so a query selects exactly that page via the needle.
|
|
71
75
|
// ---------------------------------------------------------------------------
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
description: `description for ${path}`,
|
|
90
|
-
members,
|
|
91
|
-
domain: path.split("/")[0],
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Synthetic tree. Sorted leaf order is [domain-a/topic-x, domain-a/topic-y],
|
|
97
|
-
* so L1 id 1 → topic-x, id 2 → topic-y.
|
|
98
|
-
*/
|
|
99
|
-
function makeTree(): LeafTree {
|
|
100
|
-
const leaves: LeafNode[] = [
|
|
101
|
-
makeLeaf("domain-a/topic-x", ["page-a", "page-b"]),
|
|
102
|
-
makeLeaf("domain-a/topic-y", ["page-c"]),
|
|
103
|
-
];
|
|
104
|
-
const byPage = new Map<Slug, LeafPath[]>();
|
|
105
|
-
for (const leaf of leaves) {
|
|
106
|
-
for (const slug of leaf.members) {
|
|
107
|
-
byPage.set(slug, [...(byPage.get(slug) ?? []), leaf.path]);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return { leaves: new Map(leaves.map((n) => [n.path, n])), byPage };
|
|
77
|
+
const PAGES: Record<Slug, string> = {
|
|
78
|
+
"page-a": "lead a\n## Body\napple content for page a",
|
|
79
|
+
"page-b": "lead b\n## Body\nbanana content for page b",
|
|
80
|
+
"page-c": "lead c\n## Body\ncherry content for page c",
|
|
81
|
+
};
|
|
82
|
+
const SLUGS = Object.keys(PAGES);
|
|
83
|
+
|
|
84
|
+
function makeEntries(): PageIndexEntry[] {
|
|
85
|
+
return SLUGS.map((slug, i) => ({
|
|
86
|
+
id: i + 1,
|
|
87
|
+
slug,
|
|
88
|
+
summary: `summary of ${slug}`,
|
|
89
|
+
edges: [],
|
|
90
|
+
leaves: [],
|
|
91
|
+
modifiedAt: 0,
|
|
92
|
+
}));
|
|
111
93
|
}
|
|
112
94
|
|
|
113
|
-
const
|
|
114
|
-
/** Deterministic per-slug body so the rendered `<memory>` block is assertable. */
|
|
95
|
+
const config = {} as never;
|
|
115
96
|
const contentOf = async (slug: Slug): Promise<string> => `body for ${slug}`;
|
|
116
97
|
|
|
117
|
-
|
|
118
|
-
|
|
98
|
+
async function buildLanes(): Promise<{
|
|
99
|
+
sectionIndex: SectionIndex;
|
|
100
|
+
needle: ReturnType<typeof buildSectionNeedle>;
|
|
101
|
+
edgeGraph: EdgeGraph;
|
|
102
|
+
}> {
|
|
103
|
+
const sectionIndex = await buildSectionIndex(SLUGS, async (s) => PAGES[s]!);
|
|
104
|
+
const needle = buildSectionNeedle(sectionIndex);
|
|
105
|
+
const edgeGraph = await buildEdgeGraph(
|
|
106
|
+
makeEntries(),
|
|
107
|
+
async (s) => PAGES[s]!, // no `links:` frontmatter → edge graph is empty
|
|
108
|
+
);
|
|
109
|
+
return { sectionIndex, needle, edgeGraph };
|
|
110
|
+
}
|
|
119
111
|
|
|
120
|
-
function makeTurn(
|
|
112
|
+
function makeTurn(
|
|
113
|
+
turnNumber: number,
|
|
114
|
+
currentMessage: string,
|
|
115
|
+
): MemoryRoutingTurn {
|
|
121
116
|
return {
|
|
122
117
|
conversationId: "conv-xyz",
|
|
123
118
|
turnNumber,
|
|
@@ -126,71 +121,72 @@ function makeTurn(turnNumber: number, currentMessage: string): TurnContext {
|
|
|
126
121
|
};
|
|
127
122
|
}
|
|
128
123
|
|
|
129
|
-
function toolUseResponse(
|
|
130
|
-
name: string,
|
|
131
|
-
input: Record<string, unknown>,
|
|
132
|
-
): ProviderResponse {
|
|
124
|
+
function toolUseResponse(input: Record<string, unknown>): ProviderResponse {
|
|
133
125
|
return {
|
|
134
126
|
model: "stub-model",
|
|
135
127
|
stopReason: "tool_use",
|
|
136
128
|
usage: { inputTokens: 0, outputTokens: 0 },
|
|
137
|
-
content: [{ type: "tool_use", id: "tu-1", name, input }],
|
|
129
|
+
content: [{ type: "tool_use", id: "tu-1", name: "select_pages", input }],
|
|
138
130
|
};
|
|
139
131
|
}
|
|
140
132
|
|
|
141
|
-
/**
|
|
142
|
-
function
|
|
133
|
+
/** Parse the numbered `<candidates>` block into an ordered slug list. */
|
|
134
|
+
function candidateSlugs(messages: Message[]): Slug[] {
|
|
143
135
|
for (const msg of messages) {
|
|
144
136
|
for (const block of msg.content) {
|
|
145
|
-
if (block.type
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
137
|
+
if (block.type !== "text") continue;
|
|
138
|
+
const m = /<candidates>\n([\s\S]*?)\n<\/candidates>/.exec(block.text);
|
|
139
|
+
if (!m) continue;
|
|
140
|
+
return m[1]
|
|
141
|
+
.split("\n")
|
|
142
|
+
.map((line) => /^\[\d+\] (\S+) —/.exec(line)?.[1])
|
|
143
|
+
.filter((s): s is string => !!s);
|
|
149
144
|
}
|
|
150
145
|
}
|
|
151
|
-
return
|
|
146
|
+
return [];
|
|
152
147
|
}
|
|
153
148
|
|
|
154
|
-
/**
|
|
155
|
-
|
|
156
|
-
* `select_pages` call with the per-leaf selection from the fixture turn.
|
|
157
|
-
*/
|
|
158
|
-
function providerForTurn(turn: LiveTurn): Provider {
|
|
149
|
+
/** Provider that selects (and optionally pins) the pooled candidates in `keep`. */
|
|
150
|
+
function selectProvider(keep: Slug[], pin: Slug[] = []): Provider {
|
|
159
151
|
return {
|
|
160
152
|
name: "stub",
|
|
161
|
-
sendMessage: async (messages
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
ids: [],
|
|
169
|
-
pinned_ids: [],
|
|
170
|
-
};
|
|
171
|
-
return toolUseResponse("select_pages", {
|
|
172
|
-
ids: sel.ids,
|
|
173
|
-
pinned_ids: sel.pinned_ids,
|
|
153
|
+
sendMessage: async (messages) => {
|
|
154
|
+
const pool = candidateSlugs(messages);
|
|
155
|
+
const ids: number[] = [];
|
|
156
|
+
const pinned_ids: number[] = [];
|
|
157
|
+
pool.forEach((slug, i) => {
|
|
158
|
+
if (keep.includes(slug)) ids.push(i + 1);
|
|
159
|
+
if (pin.includes(slug)) pinned_ids.push(i + 1);
|
|
174
160
|
});
|
|
161
|
+
return toolUseResponse({ ids, pinned_ids });
|
|
175
162
|
},
|
|
176
163
|
};
|
|
177
164
|
}
|
|
178
165
|
|
|
179
166
|
/** Run one turn through orchestrate over the shared working set + render it. */
|
|
180
167
|
async function runTurn(
|
|
181
|
-
turn: LiveTurn,
|
|
182
168
|
turnNumber: number,
|
|
183
|
-
|
|
169
|
+
query: string,
|
|
170
|
+
keep: Slug[],
|
|
171
|
+
pin: Slug[],
|
|
172
|
+
deps: {
|
|
173
|
+
lanes: Awaited<ReturnType<typeof buildLanes>>;
|
|
174
|
+
workingSet: InstanceType<typeof WorkingSet>;
|
|
175
|
+
},
|
|
184
176
|
) {
|
|
185
|
-
providerStub =
|
|
186
|
-
const result = await orchestrate(makeTurn(turnNumber,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
177
|
+
providerStub = selectProvider(keep, pin);
|
|
178
|
+
const result = await orchestrate(makeTurn(turnNumber, query), {
|
|
179
|
+
sectionIndex: deps.lanes.sectionIndex,
|
|
180
|
+
needle: deps.lanes.needle,
|
|
181
|
+
denseConfig: config,
|
|
182
|
+
edgeGraph: deps.lanes.edgeGraph,
|
|
190
183
|
workingSet: deps.workingSet,
|
|
191
|
-
pageSummary: summaryOf,
|
|
192
184
|
});
|
|
193
|
-
const block = await renderMemoryBlock(
|
|
185
|
+
const block = await renderMemoryBlock(
|
|
186
|
+
result.finalInjection,
|
|
187
|
+
result.sectionBySlug,
|
|
188
|
+
contentOf,
|
|
189
|
+
);
|
|
194
190
|
return { result, block };
|
|
195
191
|
}
|
|
196
192
|
|
|
@@ -200,9 +196,14 @@ function countMemoryBlocks(text: string): number {
|
|
|
200
196
|
}
|
|
201
197
|
|
|
202
198
|
beforeEach(() => {
|
|
199
|
+
denseMockActive = true;
|
|
203
200
|
providerStub = null;
|
|
204
201
|
});
|
|
205
202
|
|
|
203
|
+
afterAll(() => {
|
|
204
|
+
denseMockActive = false;
|
|
205
|
+
});
|
|
206
|
+
|
|
206
207
|
// ---------------------------------------------------------------------------
|
|
207
208
|
// Carry-forward: a page pinned in turn 1 appears in turn 2's injected block
|
|
208
209
|
// WITHOUT being re-selected in turn 2 (same WorkingSet reused across turns).
|
|
@@ -210,20 +211,23 @@ beforeEach(() => {
|
|
|
210
211
|
|
|
211
212
|
describe("memory-v3 live — carry-forward across turns", () => {
|
|
212
213
|
test("a page pinned in turn 1 is injected in turn 2 without re-selection", async () => {
|
|
213
|
-
const
|
|
214
|
+
const lanes = await buildLanes();
|
|
214
215
|
const workingSet = new WorkingSet();
|
|
215
216
|
|
|
216
|
-
const t1 = await runTurn(
|
|
217
|
-
|
|
217
|
+
const t1 = await runTurn(1, "apple", ["page-a"], ["page-a"], {
|
|
218
|
+
lanes,
|
|
219
|
+
workingSet,
|
|
220
|
+
});
|
|
218
221
|
expect(t1.result.currentSelections.map((s) => s.slug)).toContain("page-a");
|
|
219
222
|
expect(t1.block).toContain("body for page-a");
|
|
220
223
|
|
|
221
|
-
const t2 = await runTurn(
|
|
222
|
-
|
|
224
|
+
const t2 = await runTurn(2, "cherry", ["page-c"], [], {
|
|
225
|
+
lanes,
|
|
226
|
+
workingSet,
|
|
227
|
+
});
|
|
223
228
|
expect(t2.result.currentSelections.map((s) => s.slug)).not.toContain(
|
|
224
229
|
"page-a",
|
|
225
230
|
);
|
|
226
|
-
// …yet page-a carries forward into the injected block via the working set.
|
|
227
231
|
expect(t2.result.finalInjection).toContain("page-a");
|
|
228
232
|
expect(t2.block).toContain("body for page-a");
|
|
229
233
|
});
|
|
@@ -236,24 +240,36 @@ describe("memory-v3 live — carry-forward across turns", () => {
|
|
|
236
240
|
|
|
237
241
|
describe("memory-v3 live — eviction reflected in the injected block", () => {
|
|
238
242
|
test("a stale non-pinned page drops out; the pinned page persists", async () => {
|
|
239
|
-
const
|
|
243
|
+
const lanes = await buildLanes();
|
|
240
244
|
// Small window: a non-pinned entry unseen for >2 turns evicts. page-b is
|
|
241
245
|
// selected only in turn 1, so by turn 4 (4-1=3 > 2) it ages out; pinned
|
|
242
246
|
// page-a never evicts; page-c is re-selected every later turn.
|
|
243
247
|
const workingSet = new WorkingSet(150, 2);
|
|
244
248
|
|
|
245
|
-
const t1 = await runTurn(
|
|
249
|
+
const t1 = await runTurn(
|
|
250
|
+
1,
|
|
251
|
+
"apple banana",
|
|
252
|
+
["page-a", "page-b"],
|
|
253
|
+
["page-a"],
|
|
254
|
+
{ lanes, workingSet },
|
|
255
|
+
);
|
|
246
256
|
expect(t1.result.finalInjection).toContain("page-b");
|
|
247
257
|
expect(t1.block).toContain("body for page-b");
|
|
248
258
|
|
|
249
|
-
// Turns 2–3 keep page-b inside the window (3-1=2, not > 2).
|
|
250
|
-
await runTurn(
|
|
251
|
-
const t3 = await runTurn(
|
|
259
|
+
// Turns 2–3 keep page-b inside the window (3-1=2, not > 2); re-select page-c.
|
|
260
|
+
await runTurn(2, "cherry", ["page-c"], [], { lanes, workingSet });
|
|
261
|
+
const t3 = await runTurn(3, "cherry", ["page-c"], [], {
|
|
262
|
+
lanes,
|
|
263
|
+
workingSet,
|
|
264
|
+
});
|
|
252
265
|
expect(t3.result.finalInjection).toContain("page-b");
|
|
253
266
|
|
|
254
267
|
// Turn 4: page-b is now stale (4-1=3 > 2) and must be gone from the block;
|
|
255
268
|
// pinned page-a and freshly-selected page-c remain.
|
|
256
|
-
const t4 = await runTurn(
|
|
269
|
+
const t4 = await runTurn(4, "cherry", ["page-c"], [], {
|
|
270
|
+
lanes,
|
|
271
|
+
workingSet,
|
|
272
|
+
});
|
|
257
273
|
expect(t4.result.finalInjection).not.toContain("page-b");
|
|
258
274
|
expect(t4.block).not.toContain("body for page-b");
|
|
259
275
|
expect(t4.result.finalInjection).toContain("page-a");
|
|
@@ -263,17 +279,20 @@ describe("memory-v3 live — eviction reflected in the injected block", () => {
|
|
|
263
279
|
|
|
264
280
|
// ---------------------------------------------------------------------------
|
|
265
281
|
// Single source: orchestrate → render produces exactly one coherent `<memory>`
|
|
266
|
-
// block per turn.
|
|
267
|
-
// tests; here we assert the v3 producer never emits more than one block.)
|
|
282
|
+
// block per turn.
|
|
268
283
|
// ---------------------------------------------------------------------------
|
|
269
284
|
|
|
270
285
|
describe("memory-v3 live — single memory source", () => {
|
|
271
286
|
test("each turn renders exactly one <memory> block", async () => {
|
|
272
|
-
const
|
|
287
|
+
const lanes = await buildLanes();
|
|
273
288
|
const workingSet = new WorkingSet();
|
|
274
289
|
|
|
275
|
-
|
|
276
|
-
|
|
290
|
+
const queries = ["apple", "banana", "cherry"];
|
|
291
|
+
for (const [i, query] of queries.entries()) {
|
|
292
|
+
const { block } = await runTurn(i + 1, query, [SLUGS[i]!], [], {
|
|
293
|
+
lanes,
|
|
294
|
+
workingSet,
|
|
295
|
+
});
|
|
277
296
|
expect(countMemoryBlocks(block)).toBe(1);
|
|
278
297
|
expect(block.startsWith("<memory>\n")).toBe(true);
|
|
279
298
|
expect(block.endsWith("\n</memory>")).toBe(true);
|
|
@@ -288,10 +307,9 @@ describe("memory-v3 live — single memory source", () => {
|
|
|
288
307
|
|
|
289
308
|
describe("memory-v3 live — all-turns history strip", () => {
|
|
290
309
|
test("historical <memory> blocks strip back to byte-stable user history", async () => {
|
|
291
|
-
const
|
|
310
|
+
const lanes = await buildLanes();
|
|
292
311
|
const workingSet = new WorkingSet();
|
|
293
312
|
|
|
294
|
-
// The canonical (un-injected) user history the strip must converge to.
|
|
295
313
|
const baseHistory: Message[] = [
|
|
296
314
|
{ role: "user", content: [{ type: "text", text: "first user message" }] },
|
|
297
315
|
{ role: "assistant", content: [{ type: "text", text: "ok" }] },
|
|
@@ -303,17 +321,14 @@ describe("memory-v3 live — all-turns history strip", () => {
|
|
|
303
321
|
{ role: "user", content: [{ type: "text", text: "third user message" }] },
|
|
304
322
|
];
|
|
305
323
|
|
|
306
|
-
// Simulate prior turns having injected a v3 `<memory>` block onto EVERY
|
|
307
|
-
// historical user message (prepended, as the live path does).
|
|
308
324
|
const memBlock = (text: string): ContentBlock => ({ type: "text", text });
|
|
325
|
+
const queries = ["apple", "banana", "cherry"];
|
|
309
326
|
let injected: Message[] = baseHistory;
|
|
310
|
-
for (
|
|
311
|
-
const { block } = await runTurn(
|
|
312
|
-
|
|
327
|
+
for (const [i, query] of queries.entries()) {
|
|
328
|
+
const { block } = await runTurn(i + 1, query, [SLUGS[i]!], [], {
|
|
329
|
+
lanes,
|
|
313
330
|
workingSet,
|
|
314
331
|
});
|
|
315
|
-
// Re-inject this turn's freshly-rendered block onto each user message,
|
|
316
|
-
// after stripping the prior turn's block (what the live assembly does).
|
|
317
332
|
const stripped = stripAllMemoryInjections(injected);
|
|
318
333
|
injected = stripped.map((m) =>
|
|
319
334
|
m.role === "user"
|
|
@@ -322,8 +337,6 @@ describe("memory-v3 live — all-turns history strip", () => {
|
|
|
322
337
|
);
|
|
323
338
|
}
|
|
324
339
|
|
|
325
|
-
// After a final all-turns strip, history is byte-identical to the canonical
|
|
326
|
-
// base — every injected block was recognized and removed.
|
|
327
340
|
const finalStripped = stripAllMemoryInjections(injected);
|
|
328
341
|
expect(finalStripped).toEqual(baseHistory);
|
|
329
342
|
});
|