@vellumai/assistant 0.8.7 → 0.8.8-dev.202606052332.17fc8ea
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +20 -4
- package/bun.lock +2 -2
- package/docker-entrypoint.sh +4 -2
- package/docker-init-apt-root.sh +3 -1
- package/docker-kata-apt-env.sh +3 -1
- package/docker-kata-runtime-family.sh +12 -0
- package/docs/architecture/memory.md +1 -1
- package/examples/plugins/echo/README.md +61 -66
- package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
- package/examples/plugins/echo/hooks/stop.ts +16 -0
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
- package/examples/plugins/echo/package.json +1 -2
- package/examples/plugins/echo/src/emit.ts +19 -0
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
- package/openapi.yaml +3378 -335
- package/package.json +2 -2
- package/scripts/generate-openapi.ts +68 -41
- package/src/__tests__/agent-loop-exit-reason.test.ts +35 -93
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +37 -87
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -3
- package/src/__tests__/anthropic-provider.test.ts +95 -2
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/assistant-event-hub.test.ts +25 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
- package/src/__tests__/{conversation-stream-state.test.ts → assistant-stream-state.test.ts} +252 -91
- package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
- package/src/__tests__/btw-routes.test.ts +62 -3
- package/src/__tests__/build-persisted-content.test.ts +184 -0
- package/src/__tests__/catalog-files.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/clawhub-files.test.ts +1 -1
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction.benchmark.test.ts +0 -30
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +57 -19
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +6 -5
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -7
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +316 -1143
- package/src/__tests__/conversation-agent-loop.test.ts +638 -1655
- package/src/__tests__/conversation-analysis-routes.test.ts +6 -0
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-history-web-search.test.ts +11 -1
- package/src/__tests__/conversation-pairing.test.ts +4 -31
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +6 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -10
- package/src/__tests__/conversation-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +6 -5
- package/src/__tests__/conversation-runtime-assembly.test.ts +310 -300
- package/src/__tests__/conversation-runtime-workspace.test.ts +105 -45
- package/src/__tests__/conversation-slash-commands.test.ts +8 -42
- package/src/__tests__/conversation-slash-queue.test.ts +6 -1
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +84 -0
- package/src/__tests__/conversation-sync-tags.test.ts +27 -15
- package/src/__tests__/conversation-title-service.test.ts +135 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +17 -16
- package/src/__tests__/conversation-workspace-injection.test.ts +67 -2
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +7 -6
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/cross-provider-web-search.test.ts +214 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +5 -0
- package/src/__tests__/dm-persistence.test.ts +5 -1
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +304 -0
- package/src/__tests__/feature-flag-test-helpers.ts +2 -2
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +12 -2
- package/src/__tests__/gemini-image-service.test.ts +13 -0
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/mock-provider.ts +110 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
- package/src/__tests__/history-repair-hook.test.ts +1 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/identity-intro-cache.test.ts +12 -100
- package/src/__tests__/identity-routes.test.ts +248 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +5 -1
- package/src/__tests__/injector-background-turn.test.ts +3 -9
- package/src/__tests__/injector-chain.test.ts +139 -275
- package/src/__tests__/injector-disk-pressure.test.ts +75 -41
- package/src/__tests__/injector-document-comments.test.ts +3 -3
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
- package/src/__tests__/injector-v3-suppression.test.ts +31 -37
- package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/list-messages-page-latest.test.ts +60 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +20 -0
- package/src/__tests__/llm-usage-store.test.ts +223 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
- package/src/__tests__/native-web-search.test.ts +191 -0
- package/src/__tests__/onboarding-template-contract.test.ts +2 -0
- package/src/__tests__/openai-image-service.test.ts +17 -0
- package/src/__tests__/openai-provider.test.ts +31 -1
- package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -284
- package/src/__tests__/persist-unsendable-image.test.ts +215 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +1 -0
- package/src/__tests__/pkb-autoinject.test.ts +2 -5
- package/src/__tests__/plugin-api-shim.test.ts +3 -6
- package/src/__tests__/plugin-bootstrap.test.ts +14 -40
- package/src/__tests__/plugin-registry.test.ts +3 -76
- package/src/__tests__/plugin-types.test.ts +0 -193
- package/src/__tests__/process-message-display-content.test.ts +6 -2
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
- package/src/__tests__/resolve-trust-class.test.ts +4 -4
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +60 -23
- package/src/__tests__/schedule-routes.test.ts +603 -2
- package/src/__tests__/schedule-store.test.ts +41 -0
- package/src/__tests__/schedule-tools.test.ts +35 -0
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/server-history-render.test.ts +314 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
- package/src/__tests__/skillssh-files.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/system-prompt.test.ts +20 -0
- package/src/__tests__/task-scheduler.test.ts +162 -1
- package/src/__tests__/terminal-tools.test.ts +6 -1
- package/src/__tests__/title-generate-hook.test.ts +319 -0
- package/src/__tests__/tool-error-hook.test.ts +278 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +468 -5
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -2
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
- package/src/__tests__/ui-work-result-surface.test.ts +159 -0
- package/src/__tests__/usage-routes.test.ts +285 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/voice-session-bridge.test.ts +6 -3
- package/src/__tests__/web-search-backend-failure.test.ts +166 -0
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +137 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +736 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +196 -0
- package/src/acp/auto-install.ts +177 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +83 -29
- package/src/acp/resolve-agent.test.ts +320 -7
- package/src/acp/resolve-agent.ts +182 -18
- package/src/acp/resume-hint.ts +25 -0
- package/src/acp/session-manager.ts +495 -73
- package/src/acp/types.ts +8 -0
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +362 -485
- package/src/api/events/assistant-thinking-delta.ts +33 -0
- package/src/api/events/tool-output-chunk.ts +45 -0
- package/src/api/events/tool-use-preview-start.ts +32 -0
- package/src/api/events/trace-event.ts +69 -0
- package/src/api/index.ts +48 -13
- package/src/api/responses/conversation-message.ts +374 -0
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/avatar/__tests__/avatar-store.test.ts +34 -29
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/notifications.test.ts +58 -14
- package/src/cli/commands/notifications.ts +112 -60
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +6 -0
- package/src/config/assistant-feature-flags.ts +22 -11
- package/src/config/bundled-skills/acp/SKILL.md +83 -31
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -398
- package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
- package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
- package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
- package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +0 -7
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/feature-flag-cache.ts +3 -3
- package/src/config/feature-flag-registry.json +48 -7
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-v2.ts +8 -0
- package/src/config/schemas/memory-v3.ts +8 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills.ts +13 -0
- package/src/context/compactor.ts +1 -1
- package/src/context/strip-injections.ts +128 -0
- package/src/context/token-estimator.ts +23 -0
- package/src/context/tool-result-truncation.ts +0 -23
- package/src/context/window-manager.ts +5 -7
- package/src/credential-execution/executable-discovery.ts +16 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
- package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/config-watcher.ts +2 -2
- package/src/daemon/context-overflow-reducer.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +594 -153
- package/src/daemon/conversation-agent-loop.ts +301 -997
- package/src/daemon/conversation-history.ts +5 -4
- package/src/daemon/conversation-lifecycle.ts +3 -4
- package/src/daemon/conversation-messaging.ts +7 -6
- package/src/daemon/conversation-process.ts +11 -16
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +218 -398
- package/src/daemon/conversation-slash.ts +6 -25
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +222 -4
- package/src/daemon/conversation-tool-setup.ts +2 -29
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +32 -20
- package/src/daemon/external-plugins-bootstrap.ts +17 -18
- package/src/daemon/handlers/config-a2a.ts +51 -36
- package/src/daemon/handlers/config-slack-channel.ts +20 -14
- package/src/daemon/handlers/config-telegram.ts +16 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/shared.ts +156 -84
- package/src/daemon/handlers/skills.ts +42 -10
- package/src/daemon/lifecycle.ts +25 -0
- package/src/daemon/message-types/apps.ts +1 -29
- package/src/daemon/message-types/messages.ts +9 -57
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +136 -3
- package/src/daemon/now-scratchpad.ts +21 -0
- package/src/daemon/orphan-reaper.test.ts +210 -0
- package/src/daemon/orphan-reaper.ts +240 -0
- package/src/daemon/overflow-reduction-loop.ts +230 -0
- package/src/daemon/persist-unsendable-image.ts +117 -0
- package/src/daemon/process-message.ts +1 -3
- package/src/daemon/server.ts +2 -0
- package/src/daemon/trace-emitter.ts +6 -4
- package/src/daemon/trust-context.ts +19 -0
- package/src/daemon/wake-target-adapter.ts +3 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
- package/src/heartbeat/heartbeat-run-store.ts +23 -1
- package/src/heartbeat/heartbeat-service.ts +26 -0
- package/src/home/home-greeting-cache.ts +24 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/gateway-client.test.ts +2 -2
- package/src/ipc/gateway-client.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
- package/src/ipc/skill-routes/memory.ts +4 -2
- package/src/media/gemini-image-service.ts +15 -0
- package/src/media/openai-image-service.ts +14 -0
- package/src/media/types.ts +34 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
- package/src/memory/auth-fallback-events-store.ts +94 -0
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/conversation-title-service.ts +65 -41
- package/src/memory/db-init.ts +6 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
- package/src/memory/graph/conversation-graph-memory.ts +65 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs-store.ts +33 -0
- package/src/memory/jobs-worker.ts +32 -5
- package/src/memory/llm-usage-store.ts +224 -50
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
- package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
- package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/pkb/autoinject.ts +61 -0
- package/src/memory/pkb/context.ts +50 -0
- package/src/memory/pkb/types.ts +14 -0
- package/src/memory/schedule-attribution-sql.ts +104 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +16 -0
- package/src/memory/usage-grouped-buckets.ts +6 -1
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -4
- package/src/memory/v2/consolidation-job.ts +14 -5
- package/src/notifications/conversation-pairing.ts +8 -15
- package/src/notifications/decision-engine.ts +6 -3
- package/src/notifications/home-feed-side-effect.ts +12 -1
- package/src/permissions/prompter.ts +4 -0
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +7 -5
- package/src/plugin-api/types.ts +151 -1
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/plugins/defaults/compaction/package.json +1 -1
- package/src/plugins/defaults/compaction/register.ts +8 -19
- package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
- package/src/plugins/defaults/empty-response/register.ts +8 -13
- package/src/plugins/defaults/index.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +288 -81
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +16 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +48 -12
- package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +104 -32
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +96 -30
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +34 -16
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
- package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +26 -14
- package/src/plugins/defaults/{llm-call → memory-v3-shadow}/package.json +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +3 -3
- package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +51 -45
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +61 -46
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +69 -99
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +8 -0
- package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/title-generate/package.json +1 -1
- package/src/plugins/defaults/title-generate/register.ts +18 -18
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
- package/src/plugins/defaults/tool-error/package.json +1 -1
- package/src/plugins/defaults/tool-error/register.ts +9 -21
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +10 -21
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +37 -18
- package/src/plugins/external-api.ts +2 -2
- package/src/plugins/pipeline.ts +6 -305
- package/src/plugins/registry.ts +10 -55
- package/src/plugins/types.ts +62 -797
- package/src/plugins/user-loader.ts +30 -127
- package/src/proactive-artifact/aux-message-injector.ts +4 -4
- package/src/proactive-artifact/job.test.ts +8 -13
- package/src/prompts/__tests__/system-prompt.test.ts +42 -0
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
- package/src/prompts/templates/BOOTSTRAP.md +2 -2
- package/src/prompts/templates/system-sections.ts +15 -0
- package/src/providers/anthropic/client.ts +37 -29
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -0
- package/src/providers/openrouter/client.ts +1 -0
- package/src/providers/placeholder-sentinels.ts +35 -0
- package/src/runtime/__tests__/agent-wake.test.ts +10 -6
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +2 -5
- package/src/runtime/assistant-event-hub.ts +37 -7
- package/src/runtime/{conversation-stream-state.ts → assistant-stream-state.ts} +132 -58
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/http-router.ts +16 -21
- package/src/runtime/http-types.ts +16 -70
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +283 -55
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.test.ts +89 -25
- package/src/runtime/routes/acp-routes.ts +81 -29
- package/src/runtime/routes/app-management-routes.ts +6 -117
- package/src/runtime/routes/app-routes.ts +13 -15
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/attachment-routes.ts +26 -15
- package/src/runtime/routes/avatar-routes.ts +26 -0
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/btw-routes.ts +29 -23
- package/src/runtime/routes/consolidation-routes.ts +120 -20
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +3 -1
- package/src/runtime/routes/conversation-routes.ts +372 -185
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- package/src/runtime/routes/documents-routes.ts +4 -0
- package/src/runtime/routes/domain-routes.ts +51 -37
- package/src/runtime/routes/epoch-millis-range.ts +34 -0
- package/src/runtime/routes/events-routes.ts +28 -34
- package/src/runtime/routes/gateway-log-routes.ts +26 -4
- package/src/runtime/routes/heartbeat-routes.ts +32 -12
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-intro-cache.ts +11 -34
- package/src/runtime/routes/identity-routes.ts +224 -18
- package/src/runtime/routes/image-generation-routes.ts +40 -2
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/a2a.ts +12 -10
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
- package/src/runtime/routes/integrations/slack/channel.ts +4 -0
- package/src/runtime/routes/integrations/slack/share.ts +27 -6
- package/src/runtime/routes/integrations/telegram.ts +6 -0
- package/src/runtime/routes/integrations/twilio.ts +42 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
- package/src/runtime/routes/log-export-routes.ts +8 -0
- package/src/runtime/routes/memory-v2-routes.ts +15 -8
- package/src/runtime/routes/memory-v3-routes.ts +66 -34
- package/src/runtime/routes/oauth-apps.ts +66 -12
- package/src/runtime/routes/oauth-providers.ts +44 -5
- package/src/runtime/routes/platform-routes.ts +81 -5
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +6 -4
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/schedule-routes.ts +152 -42
- package/src/runtime/routes/secret-routes.ts +14 -2
- package/src/runtime/routes/skills-routes.ts +43 -14
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
- package/src/runtime/routes/trust-rules-routes.ts +26 -2
- package/src/runtime/routes/tts-routes.ts +35 -0
- package/src/runtime/routes/types.ts +66 -8
- package/src/runtime/routes/usage-routes.ts +47 -39
- package/src/runtime/routes/webhook-routes.ts +41 -2
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +4 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +6 -0
- package/src/runtime/services/analyze-conversation.ts +2 -2
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/schedule/schedule-store.ts +20 -1
- package/src/schedule/schedule-usage-store.ts +83 -0
- package/src/schedule/scheduler.ts +12 -5
- package/src/signals/cancel.ts +2 -4
- package/src/skills/catalog-files.ts +2 -2
- package/src/skills/catalog-install.ts +3 -0
- package/src/skills/categories-cache.ts +118 -0
- package/src/skills/clawhub-files.ts +1 -2
- package/src/skills/skillssh-files.ts +1 -2
- package/src/subagent/manager.ts +17 -5
- package/src/telemetry/types.ts +29 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +112 -3
- package/src/telemetry/usage-telemetry-reporter.ts +57 -2
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +7 -1
- package/src/tools/acp/spawn.test.ts +158 -55
- package/src/tools/acp/spawn.ts +47 -72
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +13 -8
- package/src/tools/executor.ts +1 -53
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
- package/src/tools/network/__tests__/web-search.test.ts +11 -3
- package/src/tools/network/web-search-error.test.ts +248 -0
- package/src/tools/network/web-search-error.ts +267 -0
- package/src/tools/network/web-search.ts +207 -48
- package/src/tools/schedule/create.ts +2 -0
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/terminal/safe-env.ts +10 -1
- package/src/tools/ui-surface/definitions.ts +34 -5
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
- package/src/tts/provider-catalog.ts +76 -1
- package/src/util/mutex.ts +47 -0
- package/src/workspace/git-service.ts +1 -42
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
- package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/docs/plugins.md +0 -836
- package/examples/plugins/echo/register.ts +0 -184
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
- package/src/__tests__/empty-response-pipeline.test.ts +0 -423
- package/src/__tests__/llm-call-pipeline.test.ts +0 -287
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
- package/src/__tests__/persistence-pipeline.test.ts +0 -503
- package/src/__tests__/pipeline-runner.test.ts +0 -564
- package/src/__tests__/title-generate-pipeline.test.ts +0 -211
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -479
- package/src/__tests__/tool-error-pipeline.test.ts +0 -241
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -341
- package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
- package/src/gallery/default-gallery.ts +0 -1359
- package/src/gallery/gallery-manifest.ts +0 -28
- package/src/home/feature-gate.ts +0 -22
- package/src/memory/v3/provider-blocks.ts +0 -16
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
- package/src/plugins/defaults/circuit-breaker/package.json +0 -15
- package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +0 -22
- package/src/plugins/defaults/empty-response/terminal.ts +0 -106
- package/src/plugins/defaults/injectors/package.json +0 -15
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +0 -17
- package/src/plugins/defaults/llm-call/register.ts +0 -45
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +0 -17
- package/src/plugins/defaults/memory-retrieval/package.json +0 -15
- package/src/plugins/defaults/memory-retrieval/register.ts +0 -181
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
- package/src/plugins/defaults/overflow-reduce/package.json +0 -15
- package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +0 -19
- package/src/plugins/defaults/persistence/package.json +0 -15
- package/src/plugins/defaults/persistence/register.ts +0 -38
- package/src/plugins/defaults/persistence/terminal.ts +0 -83
- package/src/plugins/defaults/title-generate/terminal.ts +0 -31
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +0 -23
- package/src/plugins/defaults/token-estimate/package.json +0 -15
- package/src/plugins/defaults/token-estimate/register.ts +0 -34
- package/src/plugins/defaults/token-estimate/terminal.ts +0 -40
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +0 -21
- package/src/plugins/defaults/tool-error/terminal.ts +0 -47
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +0 -23
- package/src/plugins/defaults/tool-execute/package.json +0 -15
- package/src/plugins/defaults/tool-execute/register.ts +0 -49
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/types.ts +0 -22
- package/src/skills/category-inference.ts +0 -111
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Unit tests for
|
|
2
|
+
* Unit tests for `runOverflowReductionLoop` — the direct-call overflow
|
|
3
|
+
* reducer driver.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* 2. A user-registered spy middleware observes **every** reduction attempt
|
|
12
|
-
* when wrapped around the default. This covers the onion-composition
|
|
13
|
-
* contract: the spy sees each call from the outside and can count
|
|
14
|
-
* iterations without changing reducer behavior.
|
|
15
|
-
*
|
|
16
|
-
* The test creates its own plugin registry via
|
|
17
|
-
* `resetPluginRegistryForTests()` and re-registers the default before each
|
|
18
|
-
* case so the registry is deterministic across runs.
|
|
5
|
+
* The default loop produces results **identical** to the historical inline
|
|
6
|
+
* tier loop for a golden set of over-budget histories. We exercise this by
|
|
7
|
+
* running the same inputs through two paths — `runOverflowReductionLoop` and
|
|
8
|
+
* a faithful re-implementation of the original inline loop — and asserting
|
|
9
|
+
* the final `(messages, runMessages, injectionMode, reducerState,
|
|
10
|
+
* reducerCompacted, attempts)` tuple matches byte-for-byte. Additional cases
|
|
11
|
+
* cover the two abort gates and the `reinjectForMode` two-flag semantics.
|
|
19
12
|
*/
|
|
20
13
|
|
|
21
|
-
import {
|
|
14
|
+
import { describe, expect, test } from "bun:test";
|
|
22
15
|
|
|
23
16
|
import { estimatePromptTokens } from "../context/token-estimator.js";
|
|
24
17
|
import type {
|
|
@@ -32,22 +25,10 @@ import {
|
|
|
32
25
|
type ReducerState,
|
|
33
26
|
} from "../daemon/context-overflow-reducer.js";
|
|
34
27
|
import type { InjectionMode } from "../daemon/conversation-runtime-assembly.js";
|
|
35
|
-
import type { TrustContext } from "../daemon/trust-context.js";
|
|
36
|
-
import defaultOverflowReduceMiddleware from "../plugins/defaults/overflow-reduce/middlewares/overflowReduce.js";
|
|
37
|
-
import { defaultOverflowReducePlugin } from "../plugins/defaults/overflow-reduce/register.js";
|
|
38
|
-
import { runPipeline } from "../plugins/pipeline.js";
|
|
39
28
|
import {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
} from "../plugins/registry.js";
|
|
44
|
-
import type {
|
|
45
|
-
Middleware,
|
|
46
|
-
OverflowReduceArgs,
|
|
47
|
-
OverflowReduceResult,
|
|
48
|
-
Plugin,
|
|
49
|
-
TurnContext,
|
|
50
|
-
} from "../plugins/types.js";
|
|
29
|
+
type OverflowReduceArgs,
|
|
30
|
+
runOverflowReductionLoop,
|
|
31
|
+
} from "../daemon/overflow-reduction-loop.js";
|
|
51
32
|
import type { Message } from "../providers/types.js";
|
|
52
33
|
|
|
53
34
|
// ── Fixtures ────────────────────────────────────────────────────────────────
|
|
@@ -87,21 +68,6 @@ const CONTEXT_WINDOW = {
|
|
|
87
68
|
},
|
|
88
69
|
};
|
|
89
70
|
|
|
90
|
-
const TRUST: TrustContext = {
|
|
91
|
-
sourceChannel: "vellum",
|
|
92
|
-
trustClass: "guardian",
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
function makeTurnContext(overrides: Partial<TurnContext> = {}): TurnContext {
|
|
96
|
-
return {
|
|
97
|
-
requestId: "req-overflow-test",
|
|
98
|
-
conversationId: "conv-overflow-test",
|
|
99
|
-
turnIndex: 0,
|
|
100
|
-
trust: TRUST,
|
|
101
|
-
...overrides,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
71
|
/**
|
|
106
72
|
* Minimal compaction stub — always compacts to a one-message summary so the
|
|
107
73
|
* reducer's forced-compaction tier succeeds. Mirrors `makeCompactFn` from
|
|
@@ -146,9 +112,9 @@ function makeCompactFn(
|
|
|
146
112
|
}
|
|
147
113
|
|
|
148
114
|
/**
|
|
149
|
-
* Faithful re-implementation of the
|
|
115
|
+
* Faithful re-implementation of the original inline tier loop — lives in
|
|
150
116
|
* this test file rather than the production module so we have an immutable
|
|
151
|
-
* baseline
|
|
117
|
+
* baseline `runOverflowReductionLoop` can be diffed against. If either
|
|
152
118
|
* implementation drifts, the golden-output cases below fail.
|
|
153
119
|
*
|
|
154
120
|
* The function intentionally avoids any side effects on external state — no
|
|
@@ -267,9 +233,9 @@ function buildArgs(messages: Message[]): {
|
|
|
267
233
|
|
|
268
234
|
// Identity reinject: the test harness does not exercise the full
|
|
269
235
|
// `applyRuntimeInjections` pipeline; it simply tracks how many times the
|
|
270
|
-
// orchestrator would have been asked to rebuild `runMessages
|
|
271
|
-
//
|
|
272
|
-
//
|
|
236
|
+
// orchestrator would have been asked to rebuild `runMessages`. Returns the
|
|
237
|
+
// reducer's latest `messages` untouched — real orchestrator code re-injects
|
|
238
|
+
// runtime blocks.
|
|
273
239
|
const reinjectForMode = async (
|
|
274
240
|
reducedMessages: Message[],
|
|
275
241
|
mode: InjectionMode,
|
|
@@ -295,7 +261,7 @@ function buildArgs(messages: Message[]): {
|
|
|
295
261
|
toolTokenBudget: 0,
|
|
296
262
|
maxAttempts: CONTEXT_WINDOW.overflowRecovery.maxAttempts,
|
|
297
263
|
// `OverflowReduceArgs.compactFn` types `options` as `unknown` to avoid
|
|
298
|
-
// leaking the `ContextWindowCompactOptions` shape into the
|
|
264
|
+
// leaking the `ContextWindowCompactOptions` shape into the loop's args
|
|
299
265
|
// surface. The test helper produces a real `ContextWindowCompactOptions`
|
|
300
266
|
// signature, so we trampoline through a widened wrapper.
|
|
301
267
|
compactFn: (msgs, signal, opts) =>
|
|
@@ -315,14 +281,10 @@ function buildArgs(messages: Message[]): {
|
|
|
315
281
|
|
|
316
282
|
// ── Test suite ──────────────────────────────────────────────────────────────
|
|
317
283
|
|
|
318
|
-
describe("
|
|
319
|
-
|
|
320
|
-
resetPluginRegistryForTests();
|
|
321
|
-
registerPlugin(defaultOverflowReducePlugin);
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
describe("default middleware matches historical inline loop", () => {
|
|
284
|
+
describe("runOverflowReductionLoop", () => {
|
|
285
|
+
describe("matches historical inline loop", () => {
|
|
325
286
|
test("large tool-result history — identical reduced output", async () => {
|
|
287
|
+
// GIVEN an over-budget history dominated by a large tool result.
|
|
326
288
|
const longToolResult = "r".repeat(8000);
|
|
327
289
|
const goldenHistory: Message[] = [
|
|
328
290
|
msg("user", "Start"),
|
|
@@ -332,27 +294,13 @@ describe("overflow-reduce pipeline", () => {
|
|
|
332
294
|
msg("user", "Next"),
|
|
333
295
|
];
|
|
334
296
|
|
|
335
|
-
|
|
297
|
+
// AND two independently-built arg sets over the SAME fixture so the
|
|
298
|
+
// direct call and the inline baseline never share a `compactFn`.
|
|
299
|
+
const directBuild = buildArgs(goldenHistory);
|
|
336
300
|
const inlineBuild = buildArgs(goldenHistory);
|
|
337
301
|
|
|
338
|
-
//
|
|
339
|
-
|
|
340
|
-
const pipelineResult = await runPipeline<
|
|
341
|
-
OverflowReduceArgs,
|
|
342
|
-
OverflowReduceResult
|
|
343
|
-
>(
|
|
344
|
-
"overflowReduce",
|
|
345
|
-
getMiddlewaresFor("overflowReduce"),
|
|
346
|
-
// Sentinel terminal — the default middleware doesn't call next,
|
|
347
|
-
// so this must never fire. Assert that invariant here.
|
|
348
|
-
async () => {
|
|
349
|
-
throw new Error("terminal unexpectedly reached");
|
|
350
|
-
},
|
|
351
|
-
pipelineBuild.args,
|
|
352
|
-
makeTurnContext(),
|
|
353
|
-
30000,
|
|
354
|
-
);
|
|
355
|
-
|
|
302
|
+
// WHEN we reduce via the direct loop and the inline baseline.
|
|
303
|
+
const directResult = await runOverflowReductionLoop(directBuild.args);
|
|
356
304
|
const inlineResult = await runInlineBaseline({
|
|
357
305
|
messages: goldenHistory,
|
|
358
306
|
runMessages: goldenHistory,
|
|
@@ -367,41 +315,27 @@ describe("overflow-reduce pipeline", () => {
|
|
|
367
315
|
estimatePostInjection: inlineBuild.args.estimatePostInjection,
|
|
368
316
|
});
|
|
369
317
|
|
|
370
|
-
//
|
|
371
|
-
expect(
|
|
372
|
-
expect(
|
|
373
|
-
expect(
|
|
374
|
-
expect(
|
|
375
|
-
expect(
|
|
376
|
-
|
|
377
|
-
);
|
|
378
|
-
expect(pipelineResult.attempts).toBe(inlineResult.attempts);
|
|
318
|
+
// THEN every field the orchestrator relies on matches byte-for-byte.
|
|
319
|
+
expect(directResult.messages).toEqual(inlineResult.messages);
|
|
320
|
+
expect(directResult.runMessages).toEqual(inlineResult.runMessages);
|
|
321
|
+
expect(directResult.injectionMode).toBe(inlineResult.injectionMode);
|
|
322
|
+
expect(directResult.reducerState).toEqual(inlineResult.reducerState);
|
|
323
|
+
expect(directResult.reducerCompacted).toBe(inlineResult.reducerCompacted);
|
|
324
|
+
expect(directResult.attempts).toBe(inlineResult.attempts);
|
|
379
325
|
});
|
|
380
326
|
|
|
381
327
|
test("small conversation that fits after first reduction — single attempt", async () => {
|
|
382
|
-
//
|
|
383
|
-
// brings us under — the loop must exit without iterating further.
|
|
328
|
+
// GIVEN a history that the first forced compaction brings under budget.
|
|
384
329
|
const smallHistory: Message[] = [
|
|
385
330
|
msg("user", "Hello"),
|
|
386
331
|
msg("assistant", "Hi there — how can I help?"),
|
|
387
332
|
];
|
|
388
333
|
|
|
389
|
-
const
|
|
334
|
+
const directBuild = buildArgs(smallHistory);
|
|
390
335
|
const inlineBuild = buildArgs(smallHistory);
|
|
391
336
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
OverflowReduceResult
|
|
395
|
-
>(
|
|
396
|
-
"overflowReduce",
|
|
397
|
-
getMiddlewaresFor("overflowReduce"),
|
|
398
|
-
async () => {
|
|
399
|
-
throw new Error("terminal unexpectedly reached");
|
|
400
|
-
},
|
|
401
|
-
pipelineBuild.args,
|
|
402
|
-
makeTurnContext(),
|
|
403
|
-
30000,
|
|
404
|
-
);
|
|
337
|
+
// WHEN we reduce via the direct loop and the inline baseline.
|
|
338
|
+
const directResult = await runOverflowReductionLoop(directBuild.args);
|
|
405
339
|
const inlineResult = await runInlineBaseline({
|
|
406
340
|
messages: smallHistory,
|
|
407
341
|
runMessages: smallHistory,
|
|
@@ -416,149 +350,17 @@ describe("overflow-reduce pipeline", () => {
|
|
|
416
350
|
estimatePostInjection: inlineBuild.args.estimatePostInjection,
|
|
417
351
|
});
|
|
418
352
|
|
|
419
|
-
|
|
420
|
-
expect(
|
|
421
|
-
expect(
|
|
422
|
-
expect(
|
|
423
|
-
|
|
424
|
-
);
|
|
425
|
-
});
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
describe("spy middleware observes each reduction attempt", () => {
|
|
429
|
-
test("spy sees one invocation when the default converges in one step", async () => {
|
|
430
|
-
const history: Message[] = [msg("user", "Hello"), msg("assistant", "Hi")];
|
|
431
|
-
|
|
432
|
-
// Spy tracks the args passed into its layer. It must forward via
|
|
433
|
-
// `next` so the default still fires.
|
|
434
|
-
const spyCalls: Array<{
|
|
435
|
-
hadMessages: number;
|
|
436
|
-
budget: number;
|
|
437
|
-
attempts: number;
|
|
438
|
-
}> = [];
|
|
439
|
-
const spy: Middleware<OverflowReduceArgs, OverflowReduceResult> =
|
|
440
|
-
async function spyMiddleware(args, next, _ctx) {
|
|
441
|
-
spyCalls.push({
|
|
442
|
-
hadMessages: args.messages.length,
|
|
443
|
-
budget: args.preflightBudget,
|
|
444
|
-
attempts: 0, // populated after next() from the result
|
|
445
|
-
});
|
|
446
|
-
const result = await next(args);
|
|
447
|
-
spyCalls[spyCalls.length - 1]!.attempts = result.attempts;
|
|
448
|
-
return result;
|
|
449
|
-
};
|
|
450
|
-
const spyPlugin: Plugin = {
|
|
451
|
-
manifest: {
|
|
452
|
-
name: "spy-overflow",
|
|
453
|
-
version: "0.0.1",
|
|
454
|
-
},
|
|
455
|
-
middleware: { overflowReduce: spy },
|
|
456
|
-
};
|
|
457
|
-
// Register spy first so it wraps the default (registration order =
|
|
458
|
-
// outer→inner). The default therefore runs as the spy's downstream.
|
|
459
|
-
resetPluginRegistryForTests();
|
|
460
|
-
registerPlugin(spyPlugin);
|
|
461
|
-
registerPlugin(defaultOverflowReducePlugin);
|
|
462
|
-
|
|
463
|
-
const { args } = buildArgs(history);
|
|
464
|
-
const result = await runPipeline<
|
|
465
|
-
OverflowReduceArgs,
|
|
466
|
-
OverflowReduceResult
|
|
467
|
-
>(
|
|
468
|
-
"overflowReduce",
|
|
469
|
-
getMiddlewaresFor("overflowReduce"),
|
|
470
|
-
async () => {
|
|
471
|
-
throw new Error("terminal unexpectedly reached");
|
|
472
|
-
},
|
|
473
|
-
args,
|
|
474
|
-
makeTurnContext(),
|
|
475
|
-
30000,
|
|
476
|
-
);
|
|
477
|
-
|
|
478
|
-
// Spy was called exactly once — the pipeline invokes each middleware
|
|
479
|
-
// once per pipeline call, not once per reducer iteration. Iteration
|
|
480
|
-
// count shows up in the result.attempts field.
|
|
481
|
-
expect(spyCalls).toHaveLength(1);
|
|
482
|
-
expect(spyCalls[0]?.hadMessages).toBe(2);
|
|
483
|
-
expect(spyCalls[0]?.budget).toBe(1000);
|
|
484
|
-
expect(spyCalls[0]?.attempts).toBe(result.attempts);
|
|
485
|
-
expect(result.attempts).toBeGreaterThanOrEqual(1);
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
test("spy can short-circuit the default by not calling next", async () => {
|
|
489
|
-
const history: Message[] = [msg("user", "Hi")];
|
|
490
|
-
|
|
491
|
-
const shortCircuit: Middleware<OverflowReduceArgs, OverflowReduceResult> =
|
|
492
|
-
async function shortCircuitMiddleware(args, _next, _ctx) {
|
|
493
|
-
// Returns a synthetic "no-op" result — the default is never invoked.
|
|
494
|
-
return {
|
|
495
|
-
messages: args.messages,
|
|
496
|
-
runMessages: args.runMessages,
|
|
497
|
-
injectionMode: "minimal",
|
|
498
|
-
reducerState: {
|
|
499
|
-
appliedTiers: ["injection_downgrade"],
|
|
500
|
-
injectionMode: "minimal",
|
|
501
|
-
exhausted: true,
|
|
502
|
-
},
|
|
503
|
-
reducerCompacted: false,
|
|
504
|
-
attempts: 0,
|
|
505
|
-
};
|
|
506
|
-
};
|
|
507
|
-
resetPluginRegistryForTests();
|
|
508
|
-
registerPlugin({
|
|
509
|
-
manifest: {
|
|
510
|
-
name: "short-circuit-overflow",
|
|
511
|
-
version: "0.0.1",
|
|
512
|
-
},
|
|
513
|
-
middleware: { overflowReduce: shortCircuit },
|
|
514
|
-
});
|
|
515
|
-
registerPlugin(defaultOverflowReducePlugin);
|
|
516
|
-
|
|
517
|
-
const { args, compactionResults, reinjectCalls } = buildArgs(history);
|
|
518
|
-
const result = await runPipeline<
|
|
519
|
-
OverflowReduceArgs,
|
|
520
|
-
OverflowReduceResult
|
|
521
|
-
>(
|
|
522
|
-
"overflowReduce",
|
|
523
|
-
getMiddlewaresFor("overflowReduce"),
|
|
524
|
-
async () => {
|
|
525
|
-
throw new Error("terminal unexpectedly reached");
|
|
526
|
-
},
|
|
527
|
-
args,
|
|
528
|
-
makeTurnContext(),
|
|
529
|
-
30000,
|
|
530
|
-
);
|
|
531
|
-
|
|
532
|
-
// Because the outer middleware short-circuited, the default never
|
|
533
|
-
// ran — no compactFn invocations, no reinject callbacks.
|
|
534
|
-
expect(result.injectionMode).toBe("minimal");
|
|
535
|
-
expect(result.attempts).toBe(0);
|
|
536
|
-
expect(compactionResults).toHaveLength(0);
|
|
537
|
-
expect(reinjectCalls).toHaveLength(0);
|
|
538
|
-
});
|
|
539
|
-
});
|
|
540
|
-
|
|
541
|
-
describe("direct middleware invocation", () => {
|
|
542
|
-
test("default middleware without the pipeline runner still executes the tier loop", async () => {
|
|
543
|
-
const history: Message[] = [msg("user", "Hi")];
|
|
544
|
-
const { args } = buildArgs(history);
|
|
545
|
-
|
|
546
|
-
const result = await defaultOverflowReduceMiddleware(
|
|
547
|
-
args,
|
|
548
|
-
async () => {
|
|
549
|
-
throw new Error("next should not be invoked by the default");
|
|
550
|
-
},
|
|
551
|
-
makeTurnContext(),
|
|
552
|
-
);
|
|
553
|
-
|
|
554
|
-
expect(result.attempts).toBeGreaterThanOrEqual(1);
|
|
555
|
-
expect(result.reducerState.appliedTiers.length).toBeGreaterThanOrEqual(1);
|
|
353
|
+
// THEN both paths converge in the same single attempt with equal output.
|
|
354
|
+
expect(directResult.attempts).toBe(inlineResult.attempts);
|
|
355
|
+
expect(directResult.attempts).toBeGreaterThanOrEqual(1);
|
|
356
|
+
expect(directResult.messages).toEqual(inlineResult.messages);
|
|
357
|
+
expect(directResult.reducerCompacted).toBe(inlineResult.reducerCompacted);
|
|
556
358
|
});
|
|
557
359
|
});
|
|
558
360
|
|
|
559
361
|
describe("abort signal propagation", () => {
|
|
560
|
-
test("
|
|
561
|
-
//
|
|
362
|
+
test("bails between iterations when abortSignal fires", async () => {
|
|
363
|
+
// GIVEN a history that won't converge in one step (multiple iterations).
|
|
562
364
|
const longToolResult = "r".repeat(8000);
|
|
563
365
|
const history: Message[] = [
|
|
564
366
|
msg("user", "Start"),
|
|
@@ -569,9 +371,8 @@ describe("overflow-reduce pipeline", () => {
|
|
|
569
371
|
|
|
570
372
|
const controller = new AbortController();
|
|
571
373
|
const build = buildArgs(history);
|
|
572
|
-
//
|
|
573
|
-
//
|
|
574
|
-
// must see the signal and throw rather than starting another round.
|
|
374
|
+
// AND an estimator that aborts on its first call while reporting
|
|
375
|
+
// over-budget — so without the abort gate another iteration would run.
|
|
575
376
|
let estimateCalls = 0;
|
|
576
377
|
const aborting: OverflowReduceArgs = {
|
|
577
378
|
...build.args,
|
|
@@ -579,26 +380,18 @@ describe("overflow-reduce pipeline", () => {
|
|
|
579
380
|
estimatePostInjection: () => {
|
|
580
381
|
estimateCalls++;
|
|
581
382
|
if (estimateCalls === 1) controller.abort();
|
|
582
|
-
// Return a value that guarantees another iteration would fire
|
|
583
|
-
// without the abort gate.
|
|
584
383
|
return build.args.preflightBudget + 1_000_000;
|
|
585
384
|
},
|
|
586
385
|
};
|
|
587
386
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
async () => {
|
|
592
|
-
throw new Error("next should not be invoked");
|
|
593
|
-
},
|
|
594
|
-
makeTurnContext(),
|
|
595
|
-
),
|
|
596
|
-
).rejects.toThrow();
|
|
597
|
-
// Exactly one iteration ran; the abort gate stopped the next round.
|
|
387
|
+
// WHEN the loop runs THEN it throws on the post-side-effect abort gate.
|
|
388
|
+
await expect(runOverflowReductionLoop(aborting)).rejects.toThrow();
|
|
389
|
+
// AND exactly one iteration ran; the gate stopped the next round.
|
|
598
390
|
expect(estimateCalls).toBe(1);
|
|
599
391
|
});
|
|
600
392
|
|
|
601
|
-
test("
|
|
393
|
+
test("refuses to start when abortSignal is already aborted", async () => {
|
|
394
|
+
// GIVEN an already-aborted signal.
|
|
602
395
|
const history: Message[] = [msg("user", "Hi")];
|
|
603
396
|
const controller = new AbortController();
|
|
604
397
|
controller.abort();
|
|
@@ -608,16 +401,9 @@ describe("overflow-reduce pipeline", () => {
|
|
|
608
401
|
abortSignal: controller.signal,
|
|
609
402
|
};
|
|
610
403
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
async () => {
|
|
615
|
-
throw new Error("next should not be invoked");
|
|
616
|
-
},
|
|
617
|
-
makeTurnContext(),
|
|
618
|
-
),
|
|
619
|
-
).rejects.toThrow();
|
|
620
|
-
// Reducer never ran — zero compaction and reinject callbacks observed.
|
|
404
|
+
// WHEN the loop runs THEN it throws before the reducer ever runs.
|
|
405
|
+
await expect(runOverflowReductionLoop(args)).rejects.toThrow();
|
|
406
|
+
// AND no compaction or reinject callbacks were observed.
|
|
621
407
|
expect(build.compactionResults).toHaveLength(0);
|
|
622
408
|
expect(build.reinjectCalls).toHaveLength(0);
|
|
623
409
|
});
|
|
@@ -625,10 +411,10 @@ describe("overflow-reduce pipeline", () => {
|
|
|
625
411
|
|
|
626
412
|
describe("reinjectForMode two-flag semantics", () => {
|
|
627
413
|
test("stepCompacted reflects current iteration; accumulatedCompacted stays sticky", async () => {
|
|
628
|
-
//
|
|
629
|
-
//
|
|
630
|
-
//
|
|
631
|
-
//
|
|
414
|
+
// GIVEN a history that stays over-budget so the loop runs every tier:
|
|
415
|
+
// the first iteration compacts (stepCompacted=true), later iterations
|
|
416
|
+
// run other tiers (stepCompacted=false), but accumulatedCompacted must
|
|
417
|
+
// remain true for slack suppression.
|
|
632
418
|
const longToolResult = "r".repeat(8000);
|
|
633
419
|
const history: Message[] = [
|
|
634
420
|
msg("user", "Start"),
|
|
@@ -642,19 +428,13 @@ describe("overflow-reduce pipeline", () => {
|
|
|
642
428
|
estimatePostInjection: () => build.args.preflightBudget + 1_000_000,
|
|
643
429
|
};
|
|
644
430
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
async () => {
|
|
648
|
-
throw new Error("next should not be invoked");
|
|
649
|
-
},
|
|
650
|
-
makeTurnContext(),
|
|
651
|
-
);
|
|
431
|
+
// WHEN the loop runs to exhaustion / maxAttempts.
|
|
432
|
+
await runOverflowReductionLoop(overBudget);
|
|
652
433
|
|
|
653
|
-
//
|
|
434
|
+
// THEN at least one compaction iteration happened.
|
|
654
435
|
expect(build.reinjectCalls.length).toBeGreaterThanOrEqual(1);
|
|
655
|
-
//
|
|
656
|
-
//
|
|
657
|
-
// that iteration's own step did NOT compact.
|
|
436
|
+
// AND once an iteration compacted, accumulatedCompacted stays true for
|
|
437
|
+
// every subsequent iteration even when that step did not compact.
|
|
658
438
|
const firstCompactedAt = build.reinjectCalls.findIndex(
|
|
659
439
|
(c) => c.stepCompacted,
|
|
660
440
|
);
|