@vellumai/assistant 0.8.8 → 0.8.9-staging.2
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/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 +235 -6
- package/package.json +2 -2
- 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 +1 -1
- 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 +5 -4
- 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 +132 -0
- package/src/__tests__/compaction-events.test.ts +5 -5
- package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
- package/src/__tests__/context-overflow-reducer.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
- 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 +142 -218
- package/src/__tests__/conversation-agent-loop.test.ts +297 -586
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
- package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +14 -14
- package/src/__tests__/conversation-provider-retry-repair.test.ts +70 -65
- package/src/__tests__/conversation-queue.test.ts +9 -9
- package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
- package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
- package/src/__tests__/conversation-slash-queue.test.ts +6 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
- package/src/__tests__/conversation-speed-override.test.ts +10 -9
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
- package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- 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 +12 -2
- 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__/history-repair-hook.test.ts +1 -1
- 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__/memory-retrieval-hook.test.ts +131 -26
- package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
- package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
- package/src/__tests__/plugin-api-shim.test.ts +6 -9
- package/src/__tests__/plugin-bootstrap.test.ts +12 -23
- package/src/__tests__/plugin-registry.test.ts +3 -49
- package/src/__tests__/plugin-types.test.ts +0 -70
- package/src/__tests__/pre-model-call-sanitize.test.ts +109 -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 +33 -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 +1 -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/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 +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/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +80 -27
- package/src/acp/resolve-agent.test.ts +225 -9
- package/src/acp/resolve-agent.ts +122 -17
- 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 +414 -248
- package/src/api/responses/conversation-message.ts +14 -1
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
- package/src/cli/commands/plugins.ts +43 -37
- package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
- package/src/cli/lib/install-from-github.ts +464 -55
- package/src/cli/lib/plugin-catalog-cache.ts +84 -0
- package/src/cli/lib/plugin-details.ts +409 -0
- package/src/cli/lib/plugin-marketplace.ts +197 -0
- package/src/cli/lib/search-plugins.ts +195 -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 +6 -0
- package/src/config/bundled-skills/acp/SKILL.md +85 -33
- 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 -2
- package/src/config/feature-flag-registry.json +15 -6
- package/src/config/schemas/call-site-catalog.ts +0 -14
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +0 -2
- package/src/context/compactor.ts +22 -4
- package/src/context/strip-injections.ts +8 -2
- package/src/context/window-manager.ts +27 -13
- package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
- package/src/daemon/conversation-agent-loop.ts +175 -1055
- package/src/daemon/conversation-lifecycle.ts +11 -255
- package/src/daemon/conversation-process.ts +8 -136
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +293 -392
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +24 -8
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +404 -57
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/external-plugins-bootstrap.ts +14 -19
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-proxy-preactivation.ts +1 -3
- package/src/daemon/lifecycle.ts +21 -7
- package/src/daemon/server.ts +2 -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__/jobs-worker-v2-schedule.test.ts +87 -0
- package/src/memory/conversation-crud.ts +29 -19
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/db-init.ts +2 -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/index.ts +1 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
- package/src/memory/v2/consolidation-job.ts +13 -4
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +6 -5
- package/src/plugin-api/types.ts +75 -0
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +7 -7
- package/src/plugins/defaults/compaction/manager-store.ts +57 -0
- package/src/plugins/defaults/compaction/package.json +1 -2
- 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 +135 -26
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +184 -74
- 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/unified-turn-context.ts +223 -0
- 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__/live-integration.test.ts +9 -6
- 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 +8 -5
- 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 +10 -5
- 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 +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
- 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/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
- 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 +5 -5
- 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 +7 -7
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -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/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/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
- 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 +315 -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__/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 +89 -25
- package/src/runtime/routes/acp-routes.ts +81 -29
- 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/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 +28 -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/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 +16 -6
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +337 -35
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/signals/cancel.ts +2 -4
- package/src/subagent/manager.ts +21 -5
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +8 -2
- package/src/tools/acp/spawn.test.ts +176 -195
- 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/filesystem/write.ts +34 -0
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/ui-surface/definitions.ts +25 -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/__tests__/plugin-external-api.test.ts +0 -68
- package/src/daemon/wake-target-adapter.ts +0 -253
- 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/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/plugins/external-api.ts +0 -104
- 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/{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__/health.test.ts +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__/provider-blocks.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__/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}/health.ts +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}/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
|
@@ -13,17 +13,22 @@
|
|
|
13
13
|
* Sites not exercised here (`aborted_via_error`) require deeper provider
|
|
14
14
|
* fakery and are best covered by integration tests.
|
|
15
15
|
*/
|
|
16
|
-
import { describe, expect,
|
|
16
|
+
import { afterEach, describe, expect, mock, test } from "bun:test";
|
|
17
17
|
|
|
18
18
|
import type {
|
|
19
19
|
AgentEvent,
|
|
20
20
|
CheckpointDecision,
|
|
21
21
|
CheckpointInfo,
|
|
22
|
-
MidLoopCompaction,
|
|
23
22
|
} from "../agent/loop.js";
|
|
24
23
|
import { AgentLoop, isMaxTokensStopReason } from "../agent/loop.js";
|
|
25
|
-
import type {
|
|
26
|
-
import {
|
|
24
|
+
import type { ContextWindowConfig } from "../config/types.js";
|
|
25
|
+
import type { TrustContext } from "../daemon/trust-context.js";
|
|
26
|
+
import {
|
|
27
|
+
createContextWindowManager,
|
|
28
|
+
disposeContextWindowManager,
|
|
29
|
+
getContextWindowManager,
|
|
30
|
+
} from "../plugins/defaults/compaction/manager-store.js";
|
|
31
|
+
import type { PostCompactContext } from "../plugins/defaults/memory-retrieval/hooks/post-compact.js";
|
|
27
32
|
import type {
|
|
28
33
|
Message,
|
|
29
34
|
Provider,
|
|
@@ -32,6 +37,23 @@ import type {
|
|
|
32
37
|
ToolDefinition,
|
|
33
38
|
} from "../providers/types.js";
|
|
34
39
|
|
|
40
|
+
// The agent loop invokes the default post-compaction re-injection hook directly
|
|
41
|
+
// when it compacts in place. Stub it so these unit tests can drive the
|
|
42
|
+
// re-injection result without the daemon-level injector chain. Tests assign
|
|
43
|
+
// `postCompactImpl` to observe the call or force a failure; when unset
|
|
44
|
+
// the hook is a no-op that returns the history it was handed.
|
|
45
|
+
let postCompactImpl:
|
|
46
|
+
| ((input: PostCompactContext) => Promise<Message[]>)
|
|
47
|
+
| null = null;
|
|
48
|
+
mock.module(
|
|
49
|
+
"../plugins/defaults/memory-retrieval/hooks/post-compact.js",
|
|
50
|
+
() => ({
|
|
51
|
+
default: async (input: PostCompactContext) => ({
|
|
52
|
+
messages: postCompactImpl ? await postCompactImpl(input) : input.history,
|
|
53
|
+
}),
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
|
|
35
57
|
// ---------------------------------------------------------------------------
|
|
36
58
|
// Helpers (mirrored from agent-loop.test.ts so this file is self-contained)
|
|
37
59
|
// ---------------------------------------------------------------------------
|
|
@@ -101,38 +123,26 @@ const userMessage: Message = {
|
|
|
101
123
|
content: [{ type: "text", text: "Hello" }],
|
|
102
124
|
};
|
|
103
125
|
|
|
104
|
-
//
|
|
105
|
-
// result
|
|
106
|
-
// orchestrator machinery.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
function timeoutCompactionTurnContext(): TurnContext {
|
|
125
|
-
return {
|
|
126
|
-
requestId: "req-compact",
|
|
127
|
-
conversationId: "conv-compact",
|
|
128
|
-
turnIndex: 0,
|
|
129
|
-
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
130
|
-
contextWindowManager: {
|
|
131
|
-
maybeCompact: async () => {
|
|
132
|
-
throw new PluginTimeoutError("compaction", "default-compaction", 1);
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
} as unknown as TurnContext;
|
|
126
|
+
// Register a context-window manager whose `maybeCompact` returns a canned
|
|
127
|
+
// result in the compaction store the loop resolves from, so the loop's
|
|
128
|
+
// compaction call runs without the real orchestrator machinery. Returns the
|
|
129
|
+
// trust snapshot the loop also needs as a run option.
|
|
130
|
+
function fakeCompaction(
|
|
131
|
+
conversationId: string,
|
|
132
|
+
result: { compacted: boolean; exhausted: boolean },
|
|
133
|
+
): { trust: TrustContext } {
|
|
134
|
+
createContextWindowManager({
|
|
135
|
+
provider: { name: "mock-provider" } as unknown as Provider,
|
|
136
|
+
systemPrompt: "system",
|
|
137
|
+
config: {} as unknown as ContextWindowConfig,
|
|
138
|
+
conversationId,
|
|
139
|
+
});
|
|
140
|
+
const manager = getContextWindowManager(conversationId);
|
|
141
|
+
if (manager) {
|
|
142
|
+
manager.maybeCompact = (async () =>
|
|
143
|
+
result) as unknown as typeof manager.maybeCompact;
|
|
144
|
+
}
|
|
145
|
+
return { trust: { sourceChannel: "vellum", trustClass: "unknown" } };
|
|
136
146
|
}
|
|
137
147
|
|
|
138
148
|
function lastExitEvent(
|
|
@@ -153,6 +163,10 @@ function countExitEvents(events: AgentEvent[]): number {
|
|
|
153
163
|
// ---------------------------------------------------------------------------
|
|
154
164
|
|
|
155
165
|
describe("AgentLoop exit-reason instrumentation", () => {
|
|
166
|
+
afterEach(() => {
|
|
167
|
+
disposeContextWindowManager("test-conversation");
|
|
168
|
+
});
|
|
169
|
+
|
|
156
170
|
test("recognizes provider output-token stop reasons", () => {
|
|
157
171
|
expect(isMaxTokensStopReason("max_tokens")).toBe(true);
|
|
158
172
|
expect(isMaxTokensStopReason("MAX_TOKENS")).toBe(true);
|
|
@@ -164,11 +178,19 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
164
178
|
|
|
165
179
|
test("emits exit event exactly once with 'no_tool_calls' on plain text response", async () => {
|
|
166
180
|
const { provider } = createMockProvider([textResponse("Hi there!")]);
|
|
167
|
-
const loop = new AgentLoop(
|
|
181
|
+
const loop = new AgentLoop({
|
|
182
|
+
provider: provider,
|
|
183
|
+
systemPrompt: "system prompt",
|
|
184
|
+
conversationId: "test-conversation",
|
|
185
|
+
});
|
|
168
186
|
|
|
169
187
|
const events: AgentEvent[] = [];
|
|
170
|
-
await loop.run(
|
|
171
|
-
|
|
188
|
+
await loop.run({
|
|
189
|
+
messages: [userMessage],
|
|
190
|
+
onEvent: (e) => {
|
|
191
|
+
events.push(e);
|
|
192
|
+
},
|
|
193
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
172
194
|
});
|
|
173
195
|
|
|
174
196
|
expect(countExitEvents(events)).toBe(1);
|
|
@@ -178,11 +200,19 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
178
200
|
|
|
179
201
|
test("agent_loop_exit is the last event emitted", async () => {
|
|
180
202
|
const { provider } = createMockProvider([textResponse("Hi there!")]);
|
|
181
|
-
const loop = new AgentLoop(
|
|
203
|
+
const loop = new AgentLoop({
|
|
204
|
+
provider: provider,
|
|
205
|
+
systemPrompt: "system prompt",
|
|
206
|
+
conversationId: "test-conversation",
|
|
207
|
+
});
|
|
182
208
|
|
|
183
209
|
const events: AgentEvent[] = [];
|
|
184
|
-
await loop.run(
|
|
185
|
-
|
|
210
|
+
await loop.run({
|
|
211
|
+
messages: [userMessage],
|
|
212
|
+
onEvent: (e) => {
|
|
213
|
+
events.push(e);
|
|
214
|
+
},
|
|
215
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
186
216
|
});
|
|
187
217
|
|
|
188
218
|
expect(events.length).toBeGreaterThan(0);
|
|
@@ -193,11 +223,19 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
193
223
|
const { provider } = createMockProvider([
|
|
194
224
|
maxTokensResponse("Partial answer"),
|
|
195
225
|
]);
|
|
196
|
-
const loop = new AgentLoop(
|
|
226
|
+
const loop = new AgentLoop({
|
|
227
|
+
provider: provider,
|
|
228
|
+
systemPrompt: "system prompt",
|
|
229
|
+
conversationId: "test-conversation",
|
|
230
|
+
});
|
|
197
231
|
|
|
198
232
|
const events: AgentEvent[] = [];
|
|
199
|
-
await loop.run(
|
|
200
|
-
|
|
233
|
+
await loop.run({
|
|
234
|
+
messages: [userMessage],
|
|
235
|
+
onEvent: (e) => {
|
|
236
|
+
events.push(e);
|
|
237
|
+
},
|
|
238
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
201
239
|
});
|
|
202
240
|
|
|
203
241
|
expect(events.map((e) => e.type)).toEqual([
|
|
@@ -228,13 +266,20 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
228
266
|
stopReason: "max_tokens",
|
|
229
267
|
},
|
|
230
268
|
]);
|
|
231
|
-
const loop = new AgentLoop(
|
|
269
|
+
const loop = new AgentLoop({
|
|
270
|
+
provider: provider,
|
|
271
|
+
systemPrompt: "system prompt",
|
|
272
|
+
conversationId: "test-conversation",
|
|
232
273
|
tools: dummyTools,
|
|
233
274
|
});
|
|
234
275
|
|
|
235
276
|
const events: AgentEvent[] = [];
|
|
236
|
-
const { history: result } = await loop.run(
|
|
237
|
-
|
|
277
|
+
const { history: result } = await loop.run({
|
|
278
|
+
messages: [userMessage],
|
|
279
|
+
onEvent: (e) => {
|
|
280
|
+
events.push(e);
|
|
281
|
+
},
|
|
282
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
238
283
|
});
|
|
239
284
|
|
|
240
285
|
expect(events.some((e) => e.type === "tool_use")).toBe(false);
|
|
@@ -246,19 +291,24 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
246
291
|
|
|
247
292
|
test("emits 'aborted_pre_call' when signal is already aborted at run start", async () => {
|
|
248
293
|
const { provider } = createMockProvider([textResponse("never sent")]);
|
|
249
|
-
const loop = new AgentLoop(
|
|
294
|
+
const loop = new AgentLoop({
|
|
295
|
+
provider: provider,
|
|
296
|
+
systemPrompt: "system prompt",
|
|
297
|
+
conversationId: "test-conversation",
|
|
298
|
+
});
|
|
250
299
|
|
|
251
300
|
const controller = new AbortController();
|
|
252
301
|
controller.abort();
|
|
253
302
|
|
|
254
303
|
const events: AgentEvent[] = [];
|
|
255
|
-
await loop.run(
|
|
256
|
-
[userMessage],
|
|
257
|
-
(e) => {
|
|
304
|
+
await loop.run({
|
|
305
|
+
messages: [userMessage],
|
|
306
|
+
onEvent: (e) => {
|
|
258
307
|
events.push(e);
|
|
259
308
|
},
|
|
260
|
-
{
|
|
261
|
-
|
|
309
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
310
|
+
signal: controller.signal,
|
|
311
|
+
});
|
|
262
312
|
|
|
263
313
|
expect(countExitEvents(events)).toBe(1);
|
|
264
314
|
expect(lastExitEvent(events)?.reason).toBe("aborted_pre_call");
|
|
@@ -273,14 +323,21 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
273
323
|
isError: false,
|
|
274
324
|
yieldToUser: true,
|
|
275
325
|
});
|
|
276
|
-
const loop = new AgentLoop(
|
|
326
|
+
const loop = new AgentLoop({
|
|
327
|
+
provider: provider,
|
|
328
|
+
systemPrompt: "system",
|
|
329
|
+
conversationId: "test-conversation",
|
|
277
330
|
tools: dummyTools,
|
|
278
331
|
toolExecutor: toolExecutor,
|
|
279
332
|
});
|
|
280
333
|
|
|
281
334
|
const events: AgentEvent[] = [];
|
|
282
|
-
await loop.run(
|
|
283
|
-
|
|
335
|
+
await loop.run({
|
|
336
|
+
messages: [userMessage],
|
|
337
|
+
onEvent: (e) => {
|
|
338
|
+
events.push(e);
|
|
339
|
+
},
|
|
340
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
284
341
|
});
|
|
285
342
|
|
|
286
343
|
expect(countExitEvents(events)).toBe(1);
|
|
@@ -293,7 +350,10 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
293
350
|
textResponse("never reached"),
|
|
294
351
|
]);
|
|
295
352
|
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
296
|
-
const loop = new AgentLoop(
|
|
353
|
+
const loop = new AgentLoop({
|
|
354
|
+
provider: provider,
|
|
355
|
+
systemPrompt: "system",
|
|
356
|
+
conversationId: "test-conversation",
|
|
297
357
|
tools: dummyTools,
|
|
298
358
|
toolExecutor: toolExecutor,
|
|
299
359
|
});
|
|
@@ -302,13 +362,14 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
302
362
|
"budget";
|
|
303
363
|
|
|
304
364
|
const events: AgentEvent[] = [];
|
|
305
|
-
await loop.run(
|
|
306
|
-
[userMessage],
|
|
307
|
-
(e) => {
|
|
365
|
+
await loop.run({
|
|
366
|
+
messages: [userMessage],
|
|
367
|
+
onEvent: (e) => {
|
|
308
368
|
events.push(e);
|
|
309
369
|
},
|
|
310
|
-
{
|
|
311
|
-
|
|
370
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
371
|
+
onCheckpoint,
|
|
372
|
+
});
|
|
312
373
|
|
|
313
374
|
expect(countExitEvents(events)).toBe(0);
|
|
314
375
|
});
|
|
@@ -321,7 +382,10 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
321
382
|
textResponse("never reached"),
|
|
322
383
|
]);
|
|
323
384
|
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
324
|
-
const loop = new AgentLoop(
|
|
385
|
+
const loop = new AgentLoop({
|
|
386
|
+
provider: provider,
|
|
387
|
+
systemPrompt: "system",
|
|
388
|
+
conversationId: "test-conversation",
|
|
325
389
|
tools: dummyTools,
|
|
326
390
|
toolExecutor: toolExecutor,
|
|
327
391
|
});
|
|
@@ -329,7 +393,10 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
329
393
|
// AND an effective context window so small that any real token estimate
|
|
330
394
|
// of the running history exceeds the mid-loop threshold.
|
|
331
395
|
// WHEN the loop checkpoints after the tool results land
|
|
332
|
-
const result = await loop.run(
|
|
396
|
+
const result = await loop.run({
|
|
397
|
+
messages: [userMessage],
|
|
398
|
+
onEvent: () => {},
|
|
399
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
333
400
|
resolveContextWindow: () => ({
|
|
334
401
|
maxInputTokens: 10,
|
|
335
402
|
overflowRecovery: { enabled: true, safetyMarginRatio: 0 },
|
|
@@ -348,13 +415,19 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
348
415
|
textResponse("done"),
|
|
349
416
|
]);
|
|
350
417
|
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
351
|
-
const loop = new AgentLoop(
|
|
418
|
+
const loop = new AgentLoop({
|
|
419
|
+
provider: provider,
|
|
420
|
+
systemPrompt: "system",
|
|
421
|
+
conversationId: "test-conversation",
|
|
352
422
|
tools: dummyTools,
|
|
353
423
|
toolExecutor: toolExecutor,
|
|
354
424
|
});
|
|
355
425
|
|
|
356
426
|
// WHEN the loop runs to completion
|
|
357
|
-
const result = await loop.run(
|
|
427
|
+
const result = await loop.run({
|
|
428
|
+
messages: [userMessage],
|
|
429
|
+
onEvent: () => {},
|
|
430
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
358
431
|
resolveContextWindow: () => ({
|
|
359
432
|
maxInputTokens: 10,
|
|
360
433
|
overflowRecovery: { enabled: false, safetyMarginRatio: 0 },
|
|
@@ -373,38 +446,37 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
373
446
|
textResponse("done after compaction"),
|
|
374
447
|
]);
|
|
375
448
|
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
376
|
-
const loop = new AgentLoop(
|
|
449
|
+
const loop = new AgentLoop({
|
|
450
|
+
provider: provider,
|
|
451
|
+
systemPrompt: "system",
|
|
452
|
+
conversationId: "test-conversation",
|
|
377
453
|
tools: dummyTools,
|
|
378
454
|
toolExecutor: toolExecutor,
|
|
379
455
|
});
|
|
380
456
|
|
|
381
457
|
let reinjected = false;
|
|
382
458
|
const events: AgentEvent[] = [];
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
return [userMessage];
|
|
387
|
-
},
|
|
459
|
+
postCompactImpl = async () => {
|
|
460
|
+
reinjected = true;
|
|
461
|
+
return [userMessage];
|
|
388
462
|
};
|
|
389
463
|
|
|
390
464
|
// WHEN the in-loop budget gate trips at the checkpoint
|
|
391
|
-
const result = await loop.run(
|
|
392
|
-
[userMessage],
|
|
393
|
-
(event) => {
|
|
465
|
+
const result = await loop.run({
|
|
466
|
+
messages: [userMessage],
|
|
467
|
+
onEvent: (event) => {
|
|
394
468
|
events.push(event);
|
|
395
469
|
},
|
|
396
|
-
{
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
},
|
|
407
|
-
);
|
|
470
|
+
resolveContextWindow: () => ({
|
|
471
|
+
maxInputTokens: 10,
|
|
472
|
+
overflowRecovery: { enabled: true, safetyMarginRatio: 0 },
|
|
473
|
+
}),
|
|
474
|
+
compactInPlace: true,
|
|
475
|
+
...fakeCompaction("test-conversation", {
|
|
476
|
+
compacted: true,
|
|
477
|
+
exhausted: false,
|
|
478
|
+
}),
|
|
479
|
+
});
|
|
408
480
|
|
|
409
481
|
// THEN the loop runs the compaction ceremony in place and continues to a
|
|
410
482
|
// clean exit instead of yielding for budget. The durable commit is
|
|
@@ -416,67 +488,36 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
416
488
|
expect(result.exitReason).not.toBe("budget");
|
|
417
489
|
});
|
|
418
490
|
|
|
419
|
-
test("yields 'budget' when inline compaction times out", async () => {
|
|
420
|
-
const { provider } = createMockProvider([
|
|
421
|
-
toolUseResponse("t1", "read_file", { path: "/a.txt" }),
|
|
422
|
-
textResponse("never reached"),
|
|
423
|
-
]);
|
|
424
|
-
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
425
|
-
const loop = new AgentLoop(provider, "system", {
|
|
426
|
-
tools: dummyTools,
|
|
427
|
-
toolExecutor: toolExecutor,
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
const compaction: MidLoopCompaction = {
|
|
431
|
-
postCompactionHook: async () => {
|
|
432
|
-
throw new Error("postCompactionHook must not run after a timeout");
|
|
433
|
-
},
|
|
434
|
-
};
|
|
435
|
-
const recordOutcomeSpy = spyOn(loop.compactionCircuit, "recordOutcome");
|
|
436
|
-
|
|
437
|
-
// WHEN the compaction pipeline throws a PluginTimeoutError
|
|
438
|
-
const result = await loop.run([userMessage], () => {}, {
|
|
439
|
-
resolveContextWindow: () => ({
|
|
440
|
-
maxInputTokens: 10,
|
|
441
|
-
overflowRecovery: { enabled: true, safetyMarginRatio: 0 },
|
|
442
|
-
}),
|
|
443
|
-
compaction,
|
|
444
|
-
turnContext: timeoutCompactionTurnContext(),
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
// THEN the loop records the timeout as a compaction failure against its
|
|
448
|
-
// own circuit breaker, and yields for budget so the orchestrator can
|
|
449
|
-
// escalate.
|
|
450
|
-
expect(recordOutcomeSpy).toHaveBeenCalledTimes(1);
|
|
451
|
-
expect(recordOutcomeSpy.mock.calls[0]?.[1]).toBe(true);
|
|
452
|
-
expect(result.exitReason).toBe("budget");
|
|
453
|
-
});
|
|
454
|
-
|
|
455
491
|
test("yields 'budget' when inline compaction reports exhausted", async () => {
|
|
456
492
|
const { provider } = createMockProvider([
|
|
457
493
|
toolUseResponse("t1", "read_file", { path: "/a.txt" }),
|
|
458
494
|
textResponse("never reached"),
|
|
459
495
|
]);
|
|
460
496
|
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
461
|
-
const loop = new AgentLoop(
|
|
497
|
+
const loop = new AgentLoop({
|
|
498
|
+
provider: provider,
|
|
499
|
+
systemPrompt: "system",
|
|
500
|
+
conversationId: "test-conversation",
|
|
462
501
|
tools: dummyTools,
|
|
463
502
|
toolExecutor: toolExecutor,
|
|
464
503
|
});
|
|
465
504
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
505
|
+
postCompactImpl = async () => {
|
|
506
|
+
throw new Error(
|
|
507
|
+
"post-compaction re-injection must not run when exhausted",
|
|
508
|
+
);
|
|
470
509
|
};
|
|
471
510
|
|
|
472
511
|
// WHEN compaction exhausts its retry budget
|
|
473
|
-
const result = await loop.run(
|
|
512
|
+
const result = await loop.run({
|
|
513
|
+
messages: [userMessage],
|
|
514
|
+
onEvent: () => {},
|
|
474
515
|
resolveContextWindow: () => ({
|
|
475
516
|
maxInputTokens: 10,
|
|
476
517
|
overflowRecovery: { enabled: true, safetyMarginRatio: 0 },
|
|
477
518
|
}),
|
|
478
|
-
|
|
479
|
-
|
|
519
|
+
compactInPlace: true,
|
|
520
|
+
...fakeCompaction("test-conversation", {
|
|
480
521
|
compacted: false,
|
|
481
522
|
exhausted: true,
|
|
482
523
|
}),
|
|
@@ -493,11 +534,19 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
493
534
|
throw new Error("provider exploded");
|
|
494
535
|
},
|
|
495
536
|
};
|
|
496
|
-
const loop = new AgentLoop(
|
|
537
|
+
const loop = new AgentLoop({
|
|
538
|
+
provider: provider,
|
|
539
|
+
systemPrompt: "system prompt",
|
|
540
|
+
conversationId: "test-conversation",
|
|
541
|
+
});
|
|
497
542
|
|
|
498
543
|
const events: AgentEvent[] = [];
|
|
499
|
-
await loop.run(
|
|
500
|
-
|
|
544
|
+
await loop.run({
|
|
545
|
+
messages: [userMessage],
|
|
546
|
+
onEvent: (e) => {
|
|
547
|
+
events.push(e);
|
|
548
|
+
},
|
|
549
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
501
550
|
});
|
|
502
551
|
|
|
503
552
|
expect(countExitEvents(events)).toBe(1);
|
|
@@ -516,14 +565,21 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
516
565
|
isError: false,
|
|
517
566
|
yieldToUser: true,
|
|
518
567
|
});
|
|
519
|
-
const loop = new AgentLoop(
|
|
568
|
+
const loop = new AgentLoop({
|
|
569
|
+
provider: provider,
|
|
570
|
+
systemPrompt: "system",
|
|
571
|
+
conversationId: "test-conversation",
|
|
520
572
|
tools: dummyTools,
|
|
521
573
|
toolExecutor: toolExecutor,
|
|
522
574
|
});
|
|
523
575
|
|
|
524
576
|
const events: AgentEvent[] = [];
|
|
525
|
-
await loop.run(
|
|
526
|
-
|
|
577
|
+
await loop.run({
|
|
578
|
+
messages: [userMessage],
|
|
579
|
+
onEvent: (e) => {
|
|
580
|
+
events.push(e);
|
|
581
|
+
},
|
|
582
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
527
583
|
});
|
|
528
584
|
|
|
529
585
|
expect(countExitEvents(events)).toBe(1);
|
|
@@ -540,19 +596,23 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
540
596
|
controller.abort();
|
|
541
597
|
return { content: "ok", isError: false };
|
|
542
598
|
};
|
|
543
|
-
const loop = new AgentLoop(
|
|
599
|
+
const loop = new AgentLoop({
|
|
600
|
+
provider: provider,
|
|
601
|
+
systemPrompt: "system",
|
|
602
|
+
conversationId: "test-conversation",
|
|
544
603
|
tools: dummyTools,
|
|
545
604
|
toolExecutor: toolExecutor,
|
|
546
605
|
});
|
|
547
606
|
|
|
548
607
|
const events: AgentEvent[] = [];
|
|
549
|
-
await loop.run(
|
|
550
|
-
[userMessage],
|
|
551
|
-
(e) => {
|
|
608
|
+
await loop.run({
|
|
609
|
+
messages: [userMessage],
|
|
610
|
+
onEvent: (e) => {
|
|
552
611
|
events.push(e);
|
|
553
612
|
},
|
|
554
|
-
{
|
|
555
|
-
|
|
613
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
614
|
+
signal: controller.signal,
|
|
615
|
+
});
|
|
556
616
|
|
|
557
617
|
expect(countExitEvents(events)).toBe(1);
|
|
558
618
|
expect(lastExitEvent(events)?.reason).toBe("aborted_during_tools");
|