@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091853.fbaa2ae
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +6 -6
- package/bun.lock +2 -2
- package/docs/activation-funnel-telemetry.md +310 -0
- package/examples/plugins/echo/README.md +61 -60
- package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
- package/examples/plugins/echo/hooks/stop.ts +16 -0
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
- package/examples/plugins/echo/package.json +1 -2
- package/examples/plugins/echo/src/emit.ts +19 -0
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
- package/openapi.yaml +263 -121
- package/package.json +2 -2
- package/src/__tests__/activation-early-marking.test.ts +120 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
- package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
- package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
- package/src/__tests__/agent-loop-thinking.test.ts +36 -20
- package/src/__tests__/agent-loop.test.ts +441 -96
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
- package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
- package/src/__tests__/anthropic-provider.test.ts +23 -8
- package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +132 -0
- package/src/__tests__/approval-cascade.test.ts +6 -5
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +146 -0
- package/src/__tests__/compaction-events.test.ts +7 -7
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
- package/src/__tests__/context-overflow-reducer.test.ts +265 -125
- package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
- package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
- package/src/__tests__/conversation-agent-loop.test.ts +342 -623
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
- package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-history-web-search.test.ts +6 -1
- package/src/__tests__/conversation-media-retry.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
- package/src/__tests__/conversation-process-callsite.test.ts +15 -15
- package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
- package/src/__tests__/conversation-queue.test.ts +10 -10
- package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
- package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
- package/src/__tests__/conversation-slash-queue.test.ts +7 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
- package/src/__tests__/conversation-speed-override.test.ts +11 -10
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
- package/src/__tests__/conversation-undo.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
- package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +36 -0
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +1 -1
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +17 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/history-repair-hook.test.ts +5 -1
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/inference-profile-reaper.test.ts +62 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
- package/src/__tests__/injector-background-turn.test.ts +13 -23
- package/src/__tests__/injector-chain.test.ts +268 -44
- package/src/__tests__/injector-disk-pressure.test.ts +210 -52
- package/src/__tests__/injector-document-comments.test.ts +97 -114
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-v3-suppression.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/llm-resolver.test.ts +73 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
- package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
- package/src/__tests__/persist-unsendable-image.test.ts +97 -1
- package/src/__tests__/plugin-api-shim.test.ts +6 -9
- package/src/__tests__/plugin-bootstrap.test.ts +91 -81
- package/src/__tests__/plugin-registry.test.ts +3 -49
- package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -70
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
- package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
- package/src/__tests__/published-app-updater.test.ts +138 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
- package/src/__tests__/steer-tool-repair.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-detail.test.ts +25 -7
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +5 -1
- package/src/__tests__/tool-error-hook.test.ts +1 -1
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/web-fetch.test.ts +45 -0
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +280 -0
- package/src/acp/auto-install.ts +232 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/prepare-agent-env.ts +80 -27
- package/src/acp/resolve-agent.test.ts +188 -28
- package/src/acp/resolve-agent.ts +119 -42
- package/src/acp/resume-hint.ts +23 -0
- package/src/acp/session-manager.ts +507 -73
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +403 -251
- package/src/api/responses/conversation-message.ts +22 -2
- package/src/api/responses/memory-v3-selection-log.ts +19 -10
- package/src/approvals/guardian-request-resolvers.ts +27 -1
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
- package/src/cli/commands/memory-v3.ts +57 -199
- package/src/cli/commands/plugins.ts +43 -37
- package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
- package/src/cli/lib/install-from-github.ts +797 -60
- package/src/cli/lib/plugin-catalog-cache.ts +84 -0
- package/src/cli/lib/plugin-details.ts +416 -0
- package/src/cli/lib/plugin-marketplace.ts +215 -0
- package/src/cli/lib/search-plugins.ts +201 -29
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +9 -3
- package/src/config/acp-schema.ts +1 -7
- package/src/config/bundled-skills/acp/SKILL.md +80 -41
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
- package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-tool-registry.ts +4 -0
- package/src/config/call-site-defaults.ts +0 -3
- package/src/config/feature-flag-registry.json +10 -16
- package/src/config/llm-resolver.ts +39 -7
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
- package/src/config/schemas/call-site-catalog.ts +0 -21
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +17 -3
- package/src/config/schemas/memory-v3.ts +58 -8
- package/src/config/seed-inference-profiles.ts +18 -0
- package/src/context/compactor.ts +22 -4
- package/src/context/post-turn-tool-result-truncation.ts +39 -1
- package/src/context/strip-injections.ts +8 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +18 -36
- package/src/daemon/conversation-agent-loop.ts +308 -1297
- package/src/daemon/conversation-error.ts +31 -4
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +11 -255
- package/src/daemon/conversation-media-retry.ts +19 -6
- package/src/daemon/conversation-messaging.ts +17 -0
- package/src/daemon/conversation-process.ts +22 -141
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +361 -393
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +165 -11
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +444 -62
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/external-plugins-bootstrap.ts +36 -46
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-proxy-preactivation.ts +1 -3
- package/src/daemon/lifecycle.ts +21 -7
- package/src/daemon/persist-unsendable-image.ts +62 -25
- package/src/daemon/process-message.ts +1 -1
- package/src/daemon/server.ts +2 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/wake-conversation-ops.ts +269 -0
- package/src/embedded/plugin-api.ts +2 -2
- package/src/export/__tests__/transcript-formatter.test.ts +5 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
- package/src/heartbeat/heartbeat-run-store.ts +23 -1
- package/src/heartbeat/heartbeat-service.ts +26 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
- package/src/ipc/skill-routes/memory.ts +4 -2
- package/src/memory/__tests__/activation-session-store.test.ts +41 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
- package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
- package/src/memory/activation-session-store.ts +43 -0
- package/src/memory/conversation-crud.ts +29 -19
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/db-init.ts +6 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
- package/src/memory/jobs-worker.ts +25 -1
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
- package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/onboarding-events-store.ts +66 -18
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
- package/src/memory/v2/__tests__/page-store.test.ts +22 -0
- package/src/memory/v2/consolidation-job.ts +2 -63
- package/src/memory/v2/types.ts +5 -0
- package/src/messaging/providers/telegram-bot/api.ts +14 -5
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +9 -2
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +40 -11
- package/src/plugin-api/types.ts +108 -0
- package/src/plugins/defaults/compaction/compact.ts +106 -0
- package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/plugins/defaults/compaction/manager-store.ts +57 -0
- package/src/plugins/defaults/compaction/package.json +1 -2
- package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
- package/src/plugins/defaults/empty-response/package.json +0 -1
- package/src/plugins/defaults/history-repair/package.json +0 -1
- package/src/plugins/defaults/index.ts +156 -26
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
- package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
- package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
- package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
- package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
- package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
- package/src/plugins/defaults/title-generate/package.json +0 -1
- package/src/plugins/defaults/tool-error/package.json +0 -1
- package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
- package/src/plugins/external-api.ts +12 -2
- package/src/plugins/pipeline.ts +6 -293
- package/src/plugins/registry.ts +9 -37
- package/src/plugins/types.ts +76 -381
- package/src/plugins/user-loader.ts +30 -127
- package/src/prompts/__tests__/system-prompt.test.ts +6 -0
- package/src/prompts/system-prompt.ts +61 -10
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
- package/src/providers/anthropic/client.ts +9 -10
- package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
- package/src/providers/inference/logit-bias.ts +55 -0
- package/src/providers/model-catalog.ts +34 -0
- package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -1
- package/src/providers/retry.ts +22 -0
- package/src/providers/types.ts +6 -0
- package/src/runtime/__tests__/agent-wake.test.ts +555 -691
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +108 -209
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
- package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/acp-routes.test.ts +185 -32
- package/src/runtime/routes/acp-routes.ts +328 -30
- package/src/runtime/routes/app-management-routes.ts +3 -0
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +1 -1
- package/src/runtime/routes/conversation-routes.ts +30 -2
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +18 -3
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
- package/src/runtime/routes/memory-v3-routes.ts +65 -305
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +337 -35
- package/src/runtime/routes/stt-routes.ts +45 -12
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +50 -15
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/services/published-app-updater.ts +30 -8
- package/src/signals/cancel.ts +2 -4
- package/src/subagent/manager.ts +21 -5
- package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
- package/src/telemetry/activation-funnel.ts +167 -0
- package/src/telemetry/types.ts +13 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
- package/src/telemetry/usage-telemetry-reporter.ts +26 -1
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +9 -19
- package/src/tools/acp/list-agents.ts +3 -15
- package/src/tools/acp/spawn.test.ts +173 -202
- package/src/tools/acp/spawn.ts +37 -172
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +166 -50
- package/src/tools/browser/browser-execution.ts +12 -2
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/web-fetch.ts +65 -24
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/ui-surface/definitions.ts +32 -5
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
- package/docs/plugins.md +0 -832
- package/examples/plugins/echo/register.ts +0 -143
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
- package/src/__tests__/pipeline-runner.test.ts +0 -554
- package/src/daemon/wake-target-adapter.ts +0 -253
- package/src/memory/v3/__tests__/assign.test.ts +0 -242
- package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
- package/src/memory/v3/__tests__/core.test.ts +0 -39
- package/src/memory/v3/__tests__/health.test.ts +0 -219
- package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
- package/src/memory/v3/__tests__/needle.test.ts +0 -107
- package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
- package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
- package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
- package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
- package/src/memory/v3/__tests__/router.test.ts +0 -332
- package/src/memory/v3/__tests__/selector.test.ts +0 -470
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
- package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
- package/src/memory/v3/__tests__/tree.test.ts +0 -192
- package/src/memory/v3/assign.ts +0 -268
- package/src/memory/v3/capabilities.ts +0 -124
- package/src/memory/v3/core.ts +0 -26
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +0 -314
- package/src/memory/v3/needle.ts +0 -115
- package/src/memory/v3/orchestrate.ts +0 -126
- package/src/memory/v3/page-content.ts +0 -34
- package/src/memory/v3/provider-blocks.ts +0 -26
- package/src/memory/v3/reconcile.ts +0 -523
- package/src/memory/v3/router.ts +0 -190
- package/src/memory/v3/selection-log-store.ts +0 -84
- package/src/memory/v3/selector.ts +0 -226
- package/src/memory/v3/shadow-plugin.ts +0 -411
- package/src/memory/v3/snapshot.ts +0 -209
- package/src/memory/v3/tree.ts +0 -174
- package/src/memory/v3/types.ts +0 -59
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
- package/src/plugins/defaults/circuit-breaker/package.json +0 -15
- package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
- package/src/plugins/defaults/compaction/register.ts +0 -35
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/register.ts +0 -23
- package/src/plugins/defaults/history-repair/register.ts +0 -24
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
- package/src/plugins/defaults/overflow-reduce/package.json +0 -15
- package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
- package/src/plugins/defaults/title-generate/register.ts +0 -35
- package/src/plugins/defaults/tool-error/register.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
- package/src/proactive-artifact/aux-message-injector.ts +0 -97
- package/src/proactive-artifact/decision.test.ts +0 -226
- package/src/proactive-artifact/decision.ts +0 -165
- package/src/proactive-artifact/index.ts +0 -7
- package/src/proactive-artifact/job.test.ts +0 -962
- package/src/proactive-artifact/job.ts +0 -372
- package/src/proactive-artifact/message-copy.ts +0 -58
- package/src/proactive-artifact/trigger-state.test.ts +0 -286
- package/src/proactive-artifact/trigger-state.ts +0 -123
- package/src/util/map-limit.ts +0 -27
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
|
@@ -120,7 +120,7 @@ describe("stripInjectionsForCompaction preserves history shape", () => {
|
|
|
120
120
|
expect(out[3]).toEqual(messages[3]);
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
-
test("leaves <turn_context
|
|
123
|
+
test("strips <workspace> but leaves <turn_context> and <memory __injected> alone", () => {
|
|
124
124
|
const messages: Message[] = [
|
|
125
125
|
{
|
|
126
126
|
role: "user",
|
|
@@ -132,6 +132,9 @@ describe("stripInjectionsForCompaction preserves history shape", () => {
|
|
|
132
132
|
},
|
|
133
133
|
];
|
|
134
134
|
const out = stripInjectionsForCompaction(messages);
|
|
135
|
-
expect(out[0].content).toEqual(
|
|
135
|
+
expect(out[0].content).toEqual([
|
|
136
|
+
{ type: "text", text: "<turn_context>\nnow\n</turn_context>" },
|
|
137
|
+
{ type: "text", text: "<memory __injected>\nrecent\n</memory>" },
|
|
138
|
+
]);
|
|
136
139
|
});
|
|
137
140
|
});
|
|
@@ -164,9 +164,10 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
164
164
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
165
165
|
}));
|
|
166
166
|
|
|
167
|
-
mock.module("../
|
|
167
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
168
168
|
ContextWindowManager: class {
|
|
169
169
|
constructor() {}
|
|
170
|
+
updateConfig() {}
|
|
170
171
|
shouldCompact() {
|
|
171
172
|
return { needed: false, estimatedTokens: 0 };
|
|
172
173
|
}
|
|
@@ -199,10 +200,10 @@ mock.module("../agent/loop.js", () => ({
|
|
|
199
200
|
getActiveModel() {
|
|
200
201
|
return undefined;
|
|
201
202
|
}
|
|
202
|
-
async run(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
): Promise<Message[]> {
|
|
203
|
+
async run(_options: {
|
|
204
|
+
messages: Message[];
|
|
205
|
+
onEvent: (event: AgentEvent) => void;
|
|
206
|
+
}): Promise<Message[]> {
|
|
206
207
|
return [];
|
|
207
208
|
}
|
|
208
209
|
},
|
|
@@ -9,7 +9,7 @@ mock.module("../util/logger.js", () => ({
|
|
|
9
9
|
import {
|
|
10
10
|
createConversation,
|
|
11
11
|
getConversation,
|
|
12
|
-
|
|
12
|
+
resolveOverrideProfile,
|
|
13
13
|
setConversationInferenceProfile,
|
|
14
14
|
setConversationInferenceProfileSession,
|
|
15
15
|
} from "../memory/conversation-crud.js";
|
|
@@ -55,7 +55,7 @@ describe("setConversationInferenceProfile", () => {
|
|
|
55
55
|
});
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
describe("
|
|
58
|
+
describe("resolveOverrideProfile — lazy expiry check", () => {
|
|
59
59
|
beforeEach(() => {
|
|
60
60
|
const db = getDb();
|
|
61
61
|
db.run(`DELETE FROM messages`);
|
|
@@ -73,7 +73,7 @@ describe("getConversationOverrideProfileFromRow — lazy expiry check", () => {
|
|
|
73
73
|
);
|
|
74
74
|
const row = getConversation(conv.id);
|
|
75
75
|
expect(row).not.toBeNull();
|
|
76
|
-
expect(
|
|
76
|
+
expect(resolveOverrideProfile(row)).toBeUndefined();
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
test("returns the profile when inferenceProfileExpiresAt is in the future", () => {
|
|
@@ -86,7 +86,7 @@ describe("getConversationOverrideProfileFromRow — lazy expiry check", () => {
|
|
|
86
86
|
);
|
|
87
87
|
const row = getConversation(conv.id);
|
|
88
88
|
expect(row).not.toBeNull();
|
|
89
|
-
expect(
|
|
89
|
+
expect(resolveOverrideProfile(row)).toBe("balanced");
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
test("returns undefined at the exact-expiry boundary (expiresAt === now)", () => {
|
|
@@ -110,7 +110,7 @@ describe("getConversationOverrideProfileFromRow — lazy expiry check", () => {
|
|
|
110
110
|
const realNow = Date.now;
|
|
111
111
|
Date.now = () => now;
|
|
112
112
|
try {
|
|
113
|
-
expect(
|
|
113
|
+
expect(resolveOverrideProfile(row)).toBeUndefined();
|
|
114
114
|
} finally {
|
|
115
115
|
Date.now = realNow;
|
|
116
116
|
}
|
|
@@ -126,9 +126,7 @@ describe("getConversationOverrideProfileFromRow — lazy expiry check", () => {
|
|
|
126
126
|
);
|
|
127
127
|
const row = getConversation(conv.id);
|
|
128
128
|
expect(row).not.toBeNull();
|
|
129
|
-
expect(
|
|
130
|
-
"quality-optimized",
|
|
131
|
-
);
|
|
129
|
+
expect(resolveOverrideProfile(row)).toBe("quality-optimized");
|
|
132
130
|
});
|
|
133
131
|
|
|
134
132
|
test.each<"background" | "scheduled">(["background", "scheduled"])(
|
|
@@ -148,7 +146,7 @@ describe("getConversationOverrideProfileFromRow — lazy expiry check", () => {
|
|
|
148
146
|
expect(row).not.toBeNull();
|
|
149
147
|
expect(row?.conversationType).toBe(conversationType);
|
|
150
148
|
expect(row?.inferenceProfile).toBe("quality-optimized");
|
|
151
|
-
expect(
|
|
149
|
+
expect(resolveOverrideProfile(row)).toBeUndefined();
|
|
152
150
|
},
|
|
153
151
|
);
|
|
154
152
|
});
|
|
@@ -319,7 +319,6 @@ describe("classifyConversationError", () => {
|
|
|
319
319
|
expect(result.errorCategory).toBe("image_dimensions_too_large");
|
|
320
320
|
expect(result.retryable).toBe(false);
|
|
321
321
|
expect(result.userMessage).toContain("image");
|
|
322
|
-
expect(result.userMessage).toContain("8000");
|
|
323
322
|
});
|
|
324
323
|
|
|
325
324
|
it("matches the singular 'image dimension exceeds' phrasing as well", () => {
|
|
@@ -333,6 +332,21 @@ describe("classifyConversationError", () => {
|
|
|
333
332
|
expect(result.retryable).toBe(false);
|
|
334
333
|
});
|
|
335
334
|
|
|
335
|
+
it("classifies the base64 payload 'exceeds 5 MB maximum' variant as IMAGE_TOO_LARGE (JARVIS-1041)", () => {
|
|
336
|
+
// This is the exact shape that wedged the reporting user: an oversized
|
|
337
|
+
// image nested in a tool_result. It must route to IMAGE_TOO_LARGE so the
|
|
338
|
+
// recovery path fires, not to a retryable PROVIDER_API loop.
|
|
339
|
+
const err = new ProviderError(
|
|
340
|
+
'Anthropic API error (400): 400 {"type":"error","error":{"type":"invalid_request_error","message":"messages.28.content.1.tool_result.content.1.image.source.base64: image exceeds 5 MB maximum: 7465044 bytes > 5242880 bytes"},"request_id":"req_011CbbFqvxBmDQdhVlqxtAfW"}',
|
|
341
|
+
"anthropic",
|
|
342
|
+
400,
|
|
343
|
+
);
|
|
344
|
+
const result = classifyConversationError(err, baseCtx);
|
|
345
|
+
expect(result.code).toBe("IMAGE_TOO_LARGE");
|
|
346
|
+
expect(result.errorCategory).toBe("image_dimensions_too_large");
|
|
347
|
+
expect(result.retryable).toBe(false);
|
|
348
|
+
});
|
|
349
|
+
|
|
336
350
|
it("does not steal generic 400s that happen to mention 'image'", () => {
|
|
337
351
|
const err = new ProviderError(
|
|
338
352
|
"invalid request: image source is missing",
|
|
@@ -807,7 +807,12 @@ describe("web_search_tool_result structural guard", () => {
|
|
|
807
807
|
// Media token counting iterates tool_result.contentBlocks for nested
|
|
808
808
|
// image/file blocks. web_search_tool_result has opaque content with no
|
|
809
809
|
// contentBlocks property, so it cannot contain nested media.
|
|
810
|
-
"
|
|
810
|
+
"plugins/defaults/compaction/context-overflow-reducer.ts",
|
|
811
|
+
|
|
812
|
+
// Downgrades permanently-unsendable images nested in tool_result.contentBlocks
|
|
813
|
+
// (e.g. an oversized browser screenshot). web_search_tool_result has opaque
|
|
814
|
+
// content with no contentBlocks property, so it cannot hold such an image.
|
|
815
|
+
"daemon/persist-unsendable-image.ts",
|
|
811
816
|
|
|
812
817
|
// Final orphan-pair safety pass in the Slack transcript renderer.
|
|
813
818
|
// Server-side block types (`server_tool_use`, `web_search_tool_result`)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import { createContextSummaryMessage } from "../context/window-manager.js";
|
|
4
3
|
import { stripMediaPayloadsForRetry } from "../daemon/conversation-media-retry.js";
|
|
4
|
+
import { createContextSummaryMessage } from "../plugins/defaults/compaction/window-manager.js";
|
|
5
5
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
@@ -92,7 +92,7 @@ mock.module("../daemon/conversation-messaging.js", () => ({
|
|
|
92
92
|
// ---------------------------------------------------------------------------
|
|
93
93
|
|
|
94
94
|
import type { TurnInterfaceContext } from "../channels/types.js";
|
|
95
|
-
import type {
|
|
95
|
+
import type { Conversation } from "../daemon/conversation.js";
|
|
96
96
|
import { drainQueue } from "../daemon/conversation-process.js";
|
|
97
97
|
import {
|
|
98
98
|
MessageQueue,
|
|
@@ -102,7 +102,7 @@ import { TraceEmitter } from "../daemon/trace-emitter.js";
|
|
|
102
102
|
|
|
103
103
|
// ---------------------------------------------------------------------------
|
|
104
104
|
// Fake context — captures preactivation calls, satisfies the bare minimum
|
|
105
|
-
// of `
|
|
105
|
+
// of `Conversation`. `runAgentLoop` resolves immediately so
|
|
106
106
|
// the drain-chain does not recurse forever.
|
|
107
107
|
// ---------------------------------------------------------------------------
|
|
108
108
|
|
|
@@ -113,7 +113,7 @@ interface FakeRecord {
|
|
|
113
113
|
function makeFakeContext(opts: {
|
|
114
114
|
queue: MessageQueue;
|
|
115
115
|
turnInterfaceContext?: TurnInterfaceContext;
|
|
116
|
-
}):
|
|
116
|
+
}): Conversation & FakeRecord {
|
|
117
117
|
const calls: string[] = [];
|
|
118
118
|
let preactivatedSkillIds: string[] | undefined = undefined;
|
|
119
119
|
const ctx = {
|
|
@@ -177,7 +177,7 @@ function makeFakeContext(opts: {
|
|
|
177
177
|
setTransportHints() {},
|
|
178
178
|
applyHostEnvFromTransport() {},
|
|
179
179
|
ensureHostProxiesForTurn() {},
|
|
180
|
-
} as unknown as
|
|
180
|
+
} as unknown as Conversation & FakeRecord;
|
|
181
181
|
return ctx;
|
|
182
182
|
}
|
|
183
183
|
|
|
@@ -185,6 +185,7 @@ function makeQueuedMessage(opts: {
|
|
|
185
185
|
requestId: string;
|
|
186
186
|
content?: string;
|
|
187
187
|
turnInterfaceContext?: TurnInterfaceContext;
|
|
188
|
+
sourceActorPrincipalId?: string;
|
|
188
189
|
}): QueuedMessage {
|
|
189
190
|
return {
|
|
190
191
|
content: opts.content ?? "follow up",
|
|
@@ -194,6 +195,10 @@ function makeQueuedMessage(opts: {
|
|
|
194
195
|
metadata: {},
|
|
195
196
|
sentAt: Date.now(),
|
|
196
197
|
turnInterfaceContext: opts.turnInterfaceContext,
|
|
198
|
+
sourceActorPrincipalId: opts.sourceActorPrincipalId,
|
|
199
|
+
authContext: opts.sourceActorPrincipalId
|
|
200
|
+
? ({ actorPrincipalId: opts.sourceActorPrincipalId } as never)
|
|
201
|
+
: undefined,
|
|
197
202
|
};
|
|
198
203
|
}
|
|
199
204
|
|
|
@@ -332,6 +337,7 @@ describe("drainQueue preactivation re-add for host-proxy interfaces", () => {
|
|
|
332
337
|
makeQueuedMessage({
|
|
333
338
|
requestId: "req-web-1",
|
|
334
339
|
turnInterfaceContext: ifCtx,
|
|
340
|
+
sourceActorPrincipalId: "user-1",
|
|
335
341
|
}),
|
|
336
342
|
);
|
|
337
343
|
const ctx = makeFakeContext({ queue, turnInterfaceContext: ifCtx });
|
|
@@ -346,6 +352,39 @@ describe("drainQueue preactivation re-add for host-proxy interfaces", () => {
|
|
|
346
352
|
expect(ctx.preactivatedSkillIdCalls).toContain("computer-use");
|
|
347
353
|
});
|
|
348
354
|
|
|
355
|
+
test("drainSingleMessage filters cross-client preactivation by the queued requester, not guardian owner", async () => {
|
|
356
|
+
mockCapabilityClients = [
|
|
357
|
+
{ clientId: "owner-macos-client", actorPrincipalId: "owner-user" },
|
|
358
|
+
];
|
|
359
|
+
const queue = new MessageQueue();
|
|
360
|
+
const ifCtx: TurnInterfaceContext = {
|
|
361
|
+
userMessageInterface: "web",
|
|
362
|
+
assistantMessageInterface: "web",
|
|
363
|
+
};
|
|
364
|
+
queue.push(
|
|
365
|
+
makeQueuedMessage({
|
|
366
|
+
requestId: "req-web-attacker",
|
|
367
|
+
turnInterfaceContext: ifCtx,
|
|
368
|
+
sourceActorPrincipalId: "trusted-contact-user",
|
|
369
|
+
}),
|
|
370
|
+
);
|
|
371
|
+
const ctx = makeFakeContext({ queue, turnInterfaceContext: ifCtx });
|
|
372
|
+
ctx.trustContext = {
|
|
373
|
+
trustClass: "trusted_contact",
|
|
374
|
+
guardianPrincipalId: "owner-user",
|
|
375
|
+
sourceChannel: "vellum",
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
await drainQueue(ctx);
|
|
379
|
+
|
|
380
|
+
expect(ctx.preactivatedSkillIdCalls).not.toContain("computer-use");
|
|
381
|
+
expect(ctx.preactivatedSkillIdCalls).not.toContain("app-control");
|
|
382
|
+
expect(ctx.currentTurnAuthContext?.actorPrincipalId).toBe(
|
|
383
|
+
"trusted-contact-user",
|
|
384
|
+
);
|
|
385
|
+
expect(ctx.currentTurnSourceActorPrincipalId).toBe("trusted-contact-user");
|
|
386
|
+
});
|
|
387
|
+
|
|
349
388
|
test("drainSingleMessage does NOT re-add 'app-control' for web-sourced message when no capable client is connected", async () => {
|
|
350
389
|
// mockCapabilityClients remains [] (reset by afterEach from prior test)
|
|
351
390
|
const queue = new MessageQueue();
|
|
@@ -380,6 +419,7 @@ describe("drainQueue preactivation re-add for host-proxy interfaces", () => {
|
|
|
380
419
|
makeQueuedMessage({
|
|
381
420
|
requestId: "req-web-3",
|
|
382
421
|
turnInterfaceContext: ifCtx,
|
|
422
|
+
sourceActorPrincipalId: "user-1",
|
|
383
423
|
}),
|
|
384
424
|
);
|
|
385
425
|
const ctx = makeFakeContext({ queue, turnInterfaceContext: ifCtx });
|
|
@@ -208,14 +208,12 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
208
208
|
mock.module("../agent/loop.js", () => ({
|
|
209
209
|
AgentLoop: class {
|
|
210
210
|
compactionCircuit = new CompactionCircuit("test-conv");
|
|
211
|
-
constructor(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
},
|
|
218
|
-
) {
|
|
211
|
+
constructor(options?: {
|
|
212
|
+
provider?: unknown;
|
|
213
|
+
systemPrompt?: string;
|
|
214
|
+
config?: Record<string, unknown>;
|
|
215
|
+
resolveSystemPrompt?: (history: Message[]) => Record<string, unknown>;
|
|
216
|
+
}) {
|
|
219
217
|
captured.constructorMaxTokens = options?.config?.maxTokens;
|
|
220
218
|
const resolved = options?.resolveSystemPrompt?.([]);
|
|
221
219
|
captured.resolvedMaxTokens = resolved?.maxTokens;
|
|
@@ -229,12 +227,13 @@ mock.module("../agent/loop.js", () => ({
|
|
|
229
227
|
getResolvedTools() {
|
|
230
228
|
return [];
|
|
231
229
|
}
|
|
232
|
-
async run(
|
|
233
|
-
messages: Message[]
|
|
234
|
-
onEvent: (event: Record<string, unknown>) => void
|
|
235
|
-
|
|
236
|
-
): Promise<Message[]> {
|
|
237
|
-
|
|
230
|
+
async run(options: {
|
|
231
|
+
messages: Message[];
|
|
232
|
+
onEvent: (event: Record<string, unknown>) => void;
|
|
233
|
+
callSite?: string;
|
|
234
|
+
}): Promise<Message[]> {
|
|
235
|
+
const { messages, onEvent } = options;
|
|
236
|
+
captured.callSite = options.callSite;
|
|
238
237
|
onEvent({
|
|
239
238
|
type: "usage",
|
|
240
239
|
inputTokens: 0,
|
|
@@ -250,9 +249,10 @@ mock.module("../agent/loop.js", () => ({
|
|
|
250
249
|
},
|
|
251
250
|
}));
|
|
252
251
|
|
|
253
|
-
mock.module("../
|
|
252
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
254
253
|
ContextWindowManager: class {
|
|
255
254
|
constructor() {}
|
|
255
|
+
updateConfig() {}
|
|
256
256
|
shouldCompact() {
|
|
257
257
|
return { needed: false, estimatedTokens: 0 };
|
|
258
258
|
}
|
|
@@ -98,58 +98,57 @@ mock.module("../context/token-estimator.js", () => ({
|
|
|
98
98
|
|
|
99
99
|
// Overflow recovery module mocks — the convergence loop delegates to these
|
|
100
100
|
// but these tests exercise the Conversation-level flow, not the reducer internals.
|
|
101
|
-
// The reducer mock
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
) =>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const cr = await compactFn(msgs, signal, { force: true });
|
|
101
|
+
// The reducer mock runs the forced-compaction tier through defaultCompact, which
|
|
102
|
+
// resolves the conversation's ContextWindowManager from the store — mirroring the
|
|
103
|
+
// real reducer's Tier 1.
|
|
104
|
+
mock.module(
|
|
105
|
+
"../plugins/defaults/compaction/context-overflow-reducer.js",
|
|
106
|
+
() => ({
|
|
107
|
+
createInitialReducerState: () => ({
|
|
108
|
+
appliedTiers: [],
|
|
109
|
+
injectionMode: "full" as const,
|
|
110
|
+
exhausted: false,
|
|
111
|
+
}),
|
|
112
|
+
reduceContextOverflow: async (
|
|
113
|
+
msgs: Message[],
|
|
114
|
+
cfg: { conversationId: string },
|
|
115
|
+
_state: unknown,
|
|
116
|
+
signal?: AbortSignal,
|
|
117
|
+
) => {
|
|
118
|
+
const { defaultCompact } =
|
|
119
|
+
await import("../plugins/defaults/compaction/compact.js");
|
|
120
|
+
const cr = await defaultCompact({
|
|
121
|
+
conversationId: cfg.conversationId,
|
|
122
|
+
messages: msgs,
|
|
123
|
+
signal,
|
|
124
|
+
force: true,
|
|
125
|
+
minKeepRecentUserTurns: 0,
|
|
126
|
+
});
|
|
127
|
+
let resultMessages = msgs;
|
|
128
|
+
let compactionResult;
|
|
130
129
|
if (cr.compacted) {
|
|
131
130
|
resultMessages = cr.messages;
|
|
132
131
|
compactionResult = cr;
|
|
133
132
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
|
|
133
|
+
return {
|
|
134
|
+
messages: resultMessages,
|
|
135
|
+
tier: "forced_compaction",
|
|
136
|
+
state: {
|
|
137
|
+
appliedTiers: [
|
|
138
|
+
"forced_compaction",
|
|
139
|
+
"tool_result_truncation",
|
|
140
|
+
"media_stubbing",
|
|
141
|
+
"injection_downgrade",
|
|
142
|
+
],
|
|
143
|
+
injectionMode: "full",
|
|
144
|
+
exhausted: true,
|
|
145
|
+
},
|
|
146
|
+
estimatedTokens: 1000,
|
|
147
|
+
compactionResult,
|
|
148
|
+
};
|
|
149
|
+
},
|
|
150
|
+
}),
|
|
151
|
+
);
|
|
153
152
|
|
|
154
153
|
mock.module("../daemon/context-overflow-policy.js", () => ({
|
|
155
154
|
resolveOverflowAction: () => "fail_gracefully",
|
|
@@ -218,9 +217,10 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
218
217
|
let maybeCompactCalls: Array<{ force: boolean }> = [];
|
|
219
218
|
let forceCompactionEnabled = false;
|
|
220
219
|
|
|
221
|
-
mock.module("../
|
|
220
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
222
221
|
ContextWindowManager: class {
|
|
223
222
|
constructor() {}
|
|
223
|
+
updateConfig() {}
|
|
224
224
|
shouldCompact() {
|
|
225
225
|
return { needed: false, estimatedTokens: 0 };
|
|
226
226
|
}
|
|
@@ -280,10 +280,11 @@ mock.module("../agent/loop.js", () => ({
|
|
|
280
280
|
getActiveModel() {
|
|
281
281
|
return undefined;
|
|
282
282
|
}
|
|
283
|
-
async run(
|
|
284
|
-
messages: Message[]
|
|
285
|
-
onEvent: (event: AgentEvent) => void
|
|
286
|
-
): Promise<AgentLoopRunResult> {
|
|
283
|
+
async run(options: {
|
|
284
|
+
messages: Message[];
|
|
285
|
+
onEvent: (event: AgentEvent) => void;
|
|
286
|
+
}): Promise<AgentLoopRunResult> {
|
|
287
|
+
const { messages, onEvent } = options;
|
|
287
288
|
// Prime the assistant row anchor — production code emits this from
|
|
288
289
|
// `AgentLoop.run` just before `provider.sendMessage`.
|
|
289
290
|
await onEvent({ type: "llm_call_started" });
|
|
@@ -486,11 +487,10 @@ describe("provider ordering error retry", () => {
|
|
|
486
487
|
firstRunErrorMode = "ordering";
|
|
487
488
|
maybeCompactCalls = [];
|
|
488
489
|
forceCompactionEnabled = false;
|
|
489
|
-
//
|
|
490
|
-
//
|
|
491
|
-
//
|
|
492
|
-
//
|
|
493
|
-
// delegates go through the mocked implementations.
|
|
490
|
+
// The compaction pipeline runs through the plugin registry; re-register
|
|
491
|
+
// every default so it has a middleware to dispatch to. Collaborators are
|
|
492
|
+
// mocked above, so the default plugins' delegates go through the mocked
|
|
493
|
+
// implementations.
|
|
494
494
|
resetPluginRegistryAndRegisterDefaults();
|
|
495
495
|
});
|
|
496
496
|
|
|
@@ -570,7 +570,7 @@ describe("provider ordering error retry", () => {
|
|
|
570
570
|
});
|
|
571
571
|
|
|
572
572
|
expect(agentLoopRunCount).toBe(2);
|
|
573
|
-
expect(maybeCompactCalls).toEqual([{ force:
|
|
573
|
+
expect(maybeCompactCalls).toEqual([{ force: true }]);
|
|
574
574
|
expect(events.some((e) => e.type === "message_complete")).toBe(true);
|
|
575
575
|
expect(events.some((e) => e.type === "conversation_error")).toBe(false);
|
|
576
576
|
});
|
|
@@ -595,9 +595,10 @@ describe("provider ordering error retry", () => {
|
|
|
595
595
|
// (forceCompactionEnabled=false), the second run also fails with
|
|
596
596
|
// context_too_large. The overflow policy (fail_gracefully) surfaces error.
|
|
597
597
|
expect(agentLoopRunCount).toBe(2);
|
|
598
|
-
//
|
|
599
|
-
//
|
|
600
|
-
|
|
598
|
+
// One maybeCompact call: the reducer's compactFn (force:true). The
|
|
599
|
+
// orchestrator's start-of-turn auto-compact no longer runs — the loop's
|
|
600
|
+
// pre-call budget gate owns turn-start compaction and doesn't trip here.
|
|
601
|
+
expect(maybeCompactCalls).toEqual([{ force: true }]);
|
|
601
602
|
|
|
602
603
|
expect(events.some((e) => e.type === "conversation_error")).toBe(true);
|
|
603
604
|
});
|
|
@@ -618,7 +619,7 @@ describe("provider ordering error retry", () => {
|
|
|
618
619
|
|
|
619
620
|
// Same as above — convergence loop re-runs agent loop, which also fails.
|
|
620
621
|
expect(agentLoopRunCount).toBe(2);
|
|
621
|
-
expect(maybeCompactCalls).toEqual([{ force:
|
|
622
|
+
expect(maybeCompactCalls).toEqual([{ force: true }]);
|
|
622
623
|
expect(events.some((e) => e.type === "conversation_error")).toBe(true);
|
|
623
624
|
});
|
|
624
625
|
|
|
@@ -637,7 +638,7 @@ describe("provider ordering error retry", () => {
|
|
|
637
638
|
});
|
|
638
639
|
|
|
639
640
|
expect(agentLoopRunCount).toBe(2);
|
|
640
|
-
expect(maybeCompactCalls).toEqual([{ force:
|
|
641
|
+
expect(maybeCompactCalls).toEqual([{ force: true }]);
|
|
641
642
|
expect(events.some((e) => e.type === "message_complete")).toBe(true);
|
|
642
643
|
expect(events.some((e) => e.type === "conversation_error")).toBe(false);
|
|
643
644
|
});
|
|
@@ -660,7 +661,7 @@ describe("provider ordering error retry", () => {
|
|
|
660
661
|
// the regex patterns, but classifyConversationError recognizes statusCode 413
|
|
661
662
|
// as CONTEXT_TOO_LARGE and sets contextTooLargeDetected = true.
|
|
662
663
|
expect(agentLoopRunCount).toBe(2);
|
|
663
|
-
expect(maybeCompactCalls).toEqual([{ force:
|
|
664
|
+
expect(maybeCompactCalls).toEqual([{ force: true }]);
|
|
664
665
|
expect(events.some((e) => e.type === "message_complete")).toBe(true);
|
|
665
666
|
expect(events.some((e) => e.type === "conversation_error")).toBe(false);
|
|
666
667
|
});
|
|
@@ -262,9 +262,10 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
262
262
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
263
263
|
}));
|
|
264
264
|
|
|
265
|
-
mock.module("../
|
|
265
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
266
266
|
ContextWindowManager: class {
|
|
267
267
|
constructor() {}
|
|
268
|
+
updateConfig() {}
|
|
268
269
|
shouldCompact() {
|
|
269
270
|
return { needed: false, estimatedTokens: 0 };
|
|
270
271
|
}
|
|
@@ -353,15 +354,14 @@ mock.module("../agent/loop.js", () => ({
|
|
|
353
354
|
getActiveModel() {
|
|
354
355
|
return undefined;
|
|
355
356
|
}
|
|
356
|
-
async run(
|
|
357
|
-
messages: Message[]
|
|
358
|
-
onEvent: (event: AgentEvent) => void | Promise<void
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
): Promise<AgentLoopRunResult> {
|
|
357
|
+
async run(options: {
|
|
358
|
+
messages: Message[];
|
|
359
|
+
onEvent: (event: AgentEvent) => void | Promise<void>;
|
|
360
|
+
onCheckpoint?: (
|
|
361
|
+
checkpoint: CheckpointInfo,
|
|
362
|
+
) => CheckpointDecision | Promise<CheckpointDecision>;
|
|
363
|
+
}): Promise<AgentLoopRunResult> {
|
|
364
|
+
const { messages, onEvent } = options;
|
|
365
365
|
return new Promise<AgentLoopRunResult>((resolveResult, reject) => {
|
|
366
366
|
const pending: PendingRun = {
|
|
367
367
|
resolve: (history: Message[]) =>
|