@vellumai/assistant 0.8.10 → 0.8.11-staging.1
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/bun.lock +62 -1
- package/docs/workspace-tools.md +196 -0
- package/examples/plugins/echo/README.md +3 -3
- package/knip.json +1 -0
- package/openapi.yaml +460 -128
- package/package.json +2 -1
- package/scripts/build-plugin-api.ts +299 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
- package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
- package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
- package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
- package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
- package/src/__tests__/agent-loop-thinking.test.ts +4 -0
- package/src/__tests__/agent-loop.test.ts +578 -5
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -1
- package/src/__tests__/catalog-install-normalize.test.ts +141 -0
- package/src/__tests__/ces-startup-timeout.test.ts +60 -0
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +264 -124
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
- package/src/__tests__/conversation-agent-loop.test.ts +131 -551
- package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-fork-crud.test.ts +259 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +257 -1
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
- package/src/__tests__/conversation-queue.test.ts +1 -39
- package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
- package/src/__tests__/conversation-skill-tools.test.ts +491 -5
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +74 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
- package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
- package/src/__tests__/credential-execution-tools.test.ts +23 -11
- package/src/__tests__/credential-security-invariants.test.ts +6 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
- package/src/__tests__/device-id.test.ts +70 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- package/src/__tests__/empty-response-hook.test.ts +242 -66
- package/src/__tests__/external-plugin-loader.test.ts +0 -31
- package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
- package/src/__tests__/history-repair-hook.test.ts +228 -3
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-browser-proxy.test.ts +254 -9
- package/src/__tests__/identity-routes.test.ts +1 -0
- package/src/__tests__/image-recovery-hook.test.ts +387 -0
- package/src/__tests__/injector-chain.test.ts +5 -4
- package/src/__tests__/injector-v3-suppression.test.ts +373 -47
- package/src/__tests__/intent-routing.test.ts +7 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/oauth-store.test.ts +0 -85
- package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
- package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
- package/src/__tests__/persist-unsendable-image.test.ts +4 -4
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-bootstrap.test.ts +82 -73
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -8
- package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
- package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
- package/src/__tests__/registry.test.ts +240 -1
- package/src/__tests__/require-fresh-approval.test.ts +3 -0
- package/src/__tests__/schedule-routes.test.ts +116 -1
- package/src/__tests__/schedule-store.test.ts +28 -0
- package/src/__tests__/schedule-tools.test.ts +94 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
- package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
- package/src/__tests__/skills.test.ts +202 -0
- package/src/__tests__/slim-skill-category.test.ts +195 -0
- package/src/__tests__/strip-memory-injections.test.ts +33 -39
- package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
- package/src/__tests__/title-generate-hook.test.ts +9 -7
- package/src/__tests__/tool-audit-listener.test.ts +264 -1
- package/src/__tests__/tool-error-hook.test.ts +4 -3
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/tools-get-route.test.ts +202 -0
- package/src/__tests__/workspace-tool-loader.test.ts +319 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +569 -319
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/index.ts +10 -0
- package/src/api/responses/conversation-message.ts +135 -27
- package/src/api/responses/memory-v3-selection-log.ts +4 -4
- package/src/approvals/guardian-request-resolvers.ts +26 -0
- package/src/browser-session/backends/host-bridge.ts +29 -0
- package/src/browser-session/index.ts +1 -0
- package/src/browser-session/types.ts +5 -1
- package/src/cli/commands/__tests__/schedules.test.ts +62 -4
- package/src/cli/commands/__tests__/skills.test.ts +53 -0
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/inference-providers.ts +0 -8
- package/src/cli/commands/plugins.ts +2 -2
- package/src/cli/commands/schedules.ts +27 -4
- package/src/cli/commands/skills.ts +187 -146
- package/src/cli/commands/tools.ts +106 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
- package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
- package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
- package/src/cli/lib/install-from-github.ts +187 -117
- package/src/cli/lib/plugin-catalog-cache.ts +9 -9
- package/src/cli/lib/plugin-details.ts +38 -68
- package/src/cli/lib/plugin-marketplace.ts +42 -14
- package/src/cli/lib/search-plugins.ts +29 -129
- package/src/cli/program.ts +2 -0
- package/src/config/bundled-skills/acp/SKILL.md +1 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
- package/src/config/bundled-skills/app-control/SKILL.md +1 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
- package/src/config/bundled-skills/contacts/SKILL.md +1 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
- package/src/config/bundled-skills/followups/SKILL.md +1 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
- package/src/config/bundled-skills/messaging/SKILL.md +1 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
- package/src/config/bundled-skills/sequences/SKILL.md +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +1 -0
- package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
- package/src/config/bundled-skills/subagent/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
- package/src/config/env-registry.ts +23 -0
- package/src/config/feature-flag-registry.json +17 -81
- package/src/config/loader.ts +5 -22
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
- package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
- package/src/config/schemas/compaction-logs.ts +79 -0
- package/src/config/schemas/memory-v2.ts +0 -8
- package/src/config/schemas/memory-v3.ts +104 -33
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/config/skills.ts +117 -47
- package/src/context/compactor.ts +11 -0
- package/src/context/strip-injections.ts +38 -4
- package/src/credential-execution/feature-gates.ts +0 -21
- package/src/credential-execution/startup-timeout.ts +32 -4
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
- package/src/daemon/conversation-agent-loop.ts +123 -658
- package/src/daemon/conversation-error.ts +6 -33
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-runtime-assembly.ts +183 -22
- package/src/daemon/conversation-skill-tools.ts +137 -8
- package/src/daemon/conversation-slash.ts +0 -14
- package/src/daemon/conversation-store.ts +2 -19
- package/src/daemon/conversation-tool-setup.ts +87 -1
- package/src/daemon/conversation.ts +119 -50
- package/src/daemon/external-plugins-bootstrap.ts +36 -95
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +10 -4
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-browser-proxy.ts +117 -22
- package/src/daemon/lifecycle.ts +34 -5
- package/src/daemon/message-protocol.ts +0 -7
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/skills.ts +17 -0
- package/src/daemon/providers-setup.ts +3 -0
- package/src/daemon/server.ts +3 -3
- package/src/daemon/tool-setup-types.ts +9 -3
- package/src/daemon/trust-context.ts +23 -0
- package/src/daemon/workspace-tools-watcher.ts +324 -0
- package/src/events/tool-audit-listener.ts +78 -16
- package/src/events/tool-metrics-listener.ts +2 -5
- package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
- package/src/memory/__tests__/conversation-queries.test.ts +176 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
- package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
- package/src/memory/conversation-crud.ts +134 -3
- package/src/memory/conversation-queries.ts +64 -7
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.test.ts +130 -1
- package/src/memory/embedding-backend.ts +79 -106
- package/src/memory/embedding-gemini.ts +5 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
- package/src/memory/graph/conversation-graph-memory.ts +36 -25
- package/src/memory/graph/tool-handlers.ts +3 -0
- package/src/memory/job-handlers/cleanup.ts +3 -1
- package/src/memory/jobs-store.ts +0 -28
- package/src/memory/jobs-worker.ts +10 -22
- package/src/memory/memory-marker.ts +29 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
- package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
- package/src/memory/migrations/270-schedule-description.ts +36 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
- package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
- package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
- package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
- package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
- package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +16 -0
- package/src/memory/schema/infrastructure.ts +26 -0
- package/src/memory/skill-loaded-events-store.test.ts +160 -0
- package/src/memory/skill-loaded-events-store.ts +95 -0
- package/src/memory/tool-executed-events-store.test.ts +219 -0
- package/src/memory/tool-executed-events-store.ts +102 -0
- package/src/memory/tool-usage-store.ts +15 -3
- package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
- package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
- package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
- package/src/memory/v2/__tests__/page-store.test.ts +33 -0
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
- package/src/memory/v2/activation-store.ts +50 -1
- package/src/memory/v2/consolidation-job.ts +113 -29
- package/src/memory/v2/injected-block-slugs.ts +79 -0
- package/src/memory/v2/injection.ts +6 -1
- package/src/memory/v2/prompts/consolidation.ts +414 -13
- package/src/memory/v2/router.ts +2 -28
- package/src/memory/v2/static-context.ts +1 -1
- package/src/memory/v2/types.ts +16 -0
- 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 +2 -1
- 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/oauth/oauth-store.ts +0 -9
- package/src/permissions/checker.test.ts +83 -1
- package/src/permissions/checker.ts +25 -2
- package/src/permissions/gateway-threshold-reader.test.ts +182 -0
- package/src/permissions/gateway-threshold-reader.ts +80 -0
- package/src/platform/client.ts +1 -3
- package/src/platform/feature-gate.ts +3 -12
- package/src/plugin-api/constants.ts +4 -2
- package/src/plugin-api/index.ts +63 -11
- package/src/plugin-api/types.ts +236 -71
- package/src/plugins/defaults/compaction/compact.ts +66 -2
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +303 -1
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
- package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
- package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
- package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
- package/src/plugins/defaults/history-repair/terminal.ts +39 -2
- package/src/plugins/defaults/image-recovery/detect.ts +25 -0
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
- package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
- package/src/plugins/defaults/image-recovery/package.json +14 -0
- package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
- package/src/plugins/defaults/index.ts +71 -5
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
- package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
- package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
- package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
- package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
- package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
- package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
- package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
- package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
- package/src/plugins/pipeline.ts +8 -5
- package/src/plugins/types.ts +5 -51
- package/src/providers/cache-control.ts +26 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
- package/src/providers/model-catalog.ts +13 -1
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
- package/src/providers/openai/chat-completions-provider.ts +46 -0
- package/src/providers/openai/responses-provider.ts +45 -0
- package/src/providers/registry.ts +0 -8
- package/src/runtime/__tests__/agent-wake.test.ts +0 -1
- package/src/runtime/agent-wake.ts +13 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
- package/src/runtime/routes/acp-routes.test.ts +106 -0
- package/src/runtime/routes/acp-routes.ts +248 -2
- package/src/runtime/routes/browser-tabs-routes.ts +1 -1
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
- package/src/runtime/routes/consolidation-routes.ts +6 -82
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +71 -0
- package/src/runtime/routes/identity-routes.ts +8 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
- package/src/runtime/routes/plugins-routes.ts +34 -45
- package/src/runtime/routes/schedule-routes.ts +43 -5
- package/src/runtime/routes/settings-routes.ts +140 -15
- package/src/runtime/routes/skills-routes.ts +18 -6
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
- package/src/runtime/services/conversation-serializer.ts +38 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/schedule/schedule-store.ts +19 -0
- package/src/skills/catalog-install.ts +77 -13
- package/src/tasks/task-scheduler.ts +1 -0
- package/src/telemetry/types.ts +66 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
- package/src/telemetry/usage-telemetry-reporter.ts +213 -20
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
- package/src/tools/browser/browser-execution.ts +27 -9
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
- package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
- package/src/tools/browser/cdp-client/factory.ts +217 -17
- package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
- package/src/tools/browser/cdp-client/types.ts +22 -2
- package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
- package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
- package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
- package/src/tools/executor.ts +39 -7
- package/src/tools/registry.ts +387 -5
- package/src/tools/schedule/create.ts +16 -0
- package/src/tools/schedule/list.ts +12 -4
- package/src/tools/schedule/update.ts +12 -0
- package/src/tools/skills/load.ts +11 -6
- package/src/tools/terminal/safe-env.ts +2 -0
- package/src/tools/types.ts +65 -9
- package/src/tools/workspace-tools/loader.ts +673 -0
- package/src/usage/attribution.ts +28 -0
- package/src/util/device-id.ts +17 -3
- package/src/util/platform.ts +16 -0
- package/tsconfig.plugin-api.json +13 -0
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
- package/src/daemon/message-types/browser.ts +0 -10
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
- package/src/plugins/external-api.ts +0 -114
- package/src/plugins/plugin-skill-contributions.ts +0 -292
|
@@ -1,18 +1,47 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
1
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import { estimatePromptTokens } from "../context/token-estimator.js";
|
|
4
|
+
import type {
|
|
5
|
+
CompactionContext,
|
|
6
|
+
EmergencyCompactionContext,
|
|
7
|
+
} from "../plugins/defaults/compaction/compact.js";
|
|
8
|
+
import type { Message } from "../providers/types.js";
|
|
9
|
+
|
|
10
|
+
const SYSTEM_PROMPT = "You are a helpful assistant.";
|
|
11
|
+
|
|
12
|
+
// The reducer's compaction rungs call `defaultCompact` /
|
|
13
|
+
// `defaultEmergencyCompact`, which resolve the conversation's
|
|
14
|
+
// ContextWindowManager from the compaction store. Tests drive these impls to
|
|
15
|
+
// exercise rung progression without a live manager.
|
|
16
|
+
let compactImpl: (context: CompactionContext) => Promise<ContextWindowResult>;
|
|
17
|
+
let emergencyImpl: (
|
|
18
|
+
context: EmergencyCompactionContext,
|
|
19
|
+
) => Promise<ContextWindowResult>;
|
|
20
|
+
|
|
21
|
+
mock.module("../plugins/defaults/compaction/compact.js", () => ({
|
|
22
|
+
defaultCompact: (context: CompactionContext) => compactImpl(context),
|
|
23
|
+
defaultEmergencyCompact: (context: EmergencyCompactionContext) =>
|
|
24
|
+
emergencyImpl(context),
|
|
25
|
+
}));
|
|
26
|
+
|
|
4
27
|
import {
|
|
5
28
|
createInitialReducerState,
|
|
6
29
|
reduceContextOverflow,
|
|
7
30
|
type ReducerConfig,
|
|
8
31
|
type ReducerState,
|
|
9
32
|
} from "../plugins/defaults/compaction/context-overflow-reducer.js";
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
33
|
+
import {
|
|
34
|
+
type ContextWindowResult,
|
|
35
|
+
createContextSummaryMessage,
|
|
13
36
|
} from "../plugins/defaults/compaction/window-manager.js";
|
|
14
|
-
|
|
15
|
-
|
|
37
|
+
|
|
38
|
+
// The emergency rung (rung 0) runs first on every reduction step. Default it
|
|
39
|
+
// to a no-op so the ladder falls straight through to forced compaction — the
|
|
40
|
+
// rungs most tests exercise. Tests covering the emergency rung override
|
|
41
|
+
// `emergencyImpl` via useEmergencyCompacting().
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
emergencyImpl = async ({ messages }) => noOpResult(messages);
|
|
44
|
+
});
|
|
16
45
|
|
|
17
46
|
function msg(role: "user" | "assistant", text: string): Message {
|
|
18
47
|
return { role, content: [{ type: "text", text }] };
|
|
@@ -48,8 +77,6 @@ function imageMsg(): Message {
|
|
|
48
77
|
};
|
|
49
78
|
}
|
|
50
79
|
|
|
51
|
-
const SYSTEM_PROMPT = "You are a helpful assistant.";
|
|
52
|
-
|
|
53
80
|
function makeConfig(overrides?: Partial<ReducerConfig>): ReducerConfig {
|
|
54
81
|
return {
|
|
55
82
|
providerName: "mock",
|
|
@@ -69,80 +96,97 @@ function makeConfig(overrides?: Partial<ReducerConfig>): ReducerConfig {
|
|
|
69
96
|
},
|
|
70
97
|
},
|
|
71
98
|
targetTokens: 1000,
|
|
99
|
+
conversationId: "conv-overflow-test",
|
|
100
|
+
previousEstimatedInputTokens: 2000,
|
|
101
|
+
maxMiddleTierAttempts: 4,
|
|
102
|
+
allowAutoCompressLatestTurn: false,
|
|
72
103
|
...overrides,
|
|
73
104
|
};
|
|
74
105
|
}
|
|
75
106
|
|
|
76
|
-
/**
|
|
77
|
-
|
|
78
|
-
*/
|
|
79
|
-
function makeCompactFn(
|
|
80
|
-
summaryText = "## Goals\n- compacted summary",
|
|
81
|
-
): (
|
|
107
|
+
/** A compaction result that replaces `messages` with a single summary. */
|
|
108
|
+
function compactedResult(
|
|
82
109
|
messages: Message[],
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
110
|
+
summaryText: string,
|
|
111
|
+
): ContextWindowResult {
|
|
112
|
+
const compactedMessages = [createContextSummaryMessage(summaryText)];
|
|
113
|
+
return {
|
|
114
|
+
messages: compactedMessages,
|
|
115
|
+
compacted: true,
|
|
116
|
+
previousEstimatedInputTokens: estimatePromptTokens(
|
|
117
|
+
messages,
|
|
118
|
+
SYSTEM_PROMPT,
|
|
119
|
+
{
|
|
120
|
+
providerName: "mock",
|
|
121
|
+
},
|
|
122
|
+
),
|
|
123
|
+
estimatedInputTokens: estimatePromptTokens(
|
|
90
124
|
compactedMessages,
|
|
91
125
|
SYSTEM_PROMPT,
|
|
92
|
-
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
126
|
+
{
|
|
127
|
+
providerName: "mock",
|
|
128
|
+
},
|
|
129
|
+
),
|
|
130
|
+
maxInputTokens: 2000,
|
|
131
|
+
thresholdTokens: 1200,
|
|
132
|
+
compactedMessages: messages.length,
|
|
133
|
+
compactedPersistedMessages: messages.length,
|
|
134
|
+
summaryCalls: 1,
|
|
135
|
+
summaryInputTokens: 100,
|
|
136
|
+
summaryOutputTokens: 50,
|
|
137
|
+
summaryModel: "mock-model",
|
|
138
|
+
summaryText,
|
|
139
|
+
} satisfies ContextWindowResult;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** A compaction result that leaves `messages` untouched (no progress). */
|
|
143
|
+
function noOpResult(messages: Message[]): ContextWindowResult {
|
|
144
|
+
const estimatedInputTokens = estimatePromptTokens(messages, SYSTEM_PROMPT, {
|
|
145
|
+
providerName: "mock",
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
messages,
|
|
149
|
+
compacted: false,
|
|
150
|
+
previousEstimatedInputTokens: estimatedInputTokens,
|
|
151
|
+
estimatedInputTokens,
|
|
152
|
+
maxInputTokens: 2000,
|
|
153
|
+
thresholdTokens: 1200,
|
|
154
|
+
compactedMessages: 0,
|
|
155
|
+
compactedPersistedMessages: 0,
|
|
156
|
+
summaryCalls: 0,
|
|
157
|
+
summaryInputTokens: 0,
|
|
158
|
+
summaryOutputTokens: 0,
|
|
159
|
+
summaryModel: "",
|
|
160
|
+
summaryText: "",
|
|
161
|
+
reason: "unable to compact",
|
|
162
|
+
} satisfies ContextWindowResult;
|
|
114
163
|
}
|
|
115
164
|
|
|
116
165
|
/**
|
|
117
|
-
*
|
|
118
|
-
* being unable to reduce further).
|
|
166
|
+
* Install a compaction stub that replaces messages with a summary.
|
|
119
167
|
*/
|
|
120
|
-
function
|
|
121
|
-
messages:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
summaryText: "",
|
|
143
|
-
reason: "unable to compact",
|
|
144
|
-
};
|
|
145
|
-
};
|
|
168
|
+
function useCompacting(summaryText = "## Goals\n- compacted summary"): void {
|
|
169
|
+
compactImpl = async ({ messages }: CompactionContext) =>
|
|
170
|
+
compactedResult(messages, summaryText);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Install a compaction stub that cannot reduce (simulates compaction being
|
|
175
|
+
* unable to make progress).
|
|
176
|
+
*/
|
|
177
|
+
function useNoOpCompacting(): void {
|
|
178
|
+
compactImpl = async ({ messages }: CompactionContext) => noOpResult(messages);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Install an emergency-compaction stub that replaces messages with a summary,
|
|
183
|
+
* letting the emergency rung (rung 0) make progress on the first step.
|
|
184
|
+
*/
|
|
185
|
+
function useEmergencyCompacting(
|
|
186
|
+
summaryText = "## Goals\n- emergency summary",
|
|
187
|
+
): void {
|
|
188
|
+
emergencyImpl = async ({ messages }: EmergencyCompactionContext) =>
|
|
189
|
+
compactedResult(messages, summaryText);
|
|
146
190
|
}
|
|
147
191
|
|
|
148
192
|
describe("context-overflow-reducer", () => {
|
|
@@ -164,7 +208,7 @@ describe("context-overflow-reducer", () => {
|
|
|
164
208
|
];
|
|
165
209
|
|
|
166
210
|
const config = makeConfig();
|
|
167
|
-
|
|
211
|
+
useCompacting();
|
|
168
212
|
|
|
169
213
|
let state: ReducerState | undefined;
|
|
170
214
|
let prevTokens = Infinity;
|
|
@@ -177,7 +221,6 @@ describe("context-overflow-reducer", () => {
|
|
|
177
221
|
currentMessages,
|
|
178
222
|
config,
|
|
179
223
|
state,
|
|
180
|
-
compactFn,
|
|
181
224
|
);
|
|
182
225
|
|
|
183
226
|
// Each step should either reduce tokens or advance tier state
|
|
@@ -210,7 +253,7 @@ describe("context-overflow-reducer", () => {
|
|
|
210
253
|
];
|
|
211
254
|
|
|
212
255
|
const config = makeConfig();
|
|
213
|
-
|
|
256
|
+
useCompacting();
|
|
214
257
|
|
|
215
258
|
let currentMessages = messages;
|
|
216
259
|
let state: ReducerState | undefined;
|
|
@@ -221,7 +264,6 @@ describe("context-overflow-reducer", () => {
|
|
|
221
264
|
currentMessages,
|
|
222
265
|
config,
|
|
223
266
|
state,
|
|
224
|
-
compactFn,
|
|
225
267
|
);
|
|
226
268
|
tokenHistory.push(result.estimatedTokens);
|
|
227
269
|
currentMessages = result.messages;
|
|
@@ -243,7 +285,7 @@ describe("context-overflow-reducer", () => {
|
|
|
243
285
|
];
|
|
244
286
|
|
|
245
287
|
const config = makeConfig();
|
|
246
|
-
|
|
288
|
+
useCompacting();
|
|
247
289
|
|
|
248
290
|
// Exhaust all tiers first
|
|
249
291
|
let currentMessages = messages;
|
|
@@ -253,7 +295,6 @@ describe("context-overflow-reducer", () => {
|
|
|
253
295
|
currentMessages,
|
|
254
296
|
config,
|
|
255
297
|
state,
|
|
256
|
-
compactFn,
|
|
257
298
|
);
|
|
258
299
|
currentMessages = result.messages;
|
|
259
300
|
state = result.state;
|
|
@@ -264,7 +305,6 @@ describe("context-overflow-reducer", () => {
|
|
|
264
305
|
currentMessages,
|
|
265
306
|
config,
|
|
266
307
|
state,
|
|
267
|
-
compactFn,
|
|
268
308
|
);
|
|
269
309
|
|
|
270
310
|
expect(finalResult.state.exhausted).toBe(true);
|
|
@@ -283,14 +323,9 @@ describe("context-overflow-reducer", () => {
|
|
|
283
323
|
];
|
|
284
324
|
|
|
285
325
|
const config = makeConfig();
|
|
286
|
-
|
|
326
|
+
useNoOpCompacting();
|
|
287
327
|
|
|
288
|
-
const result = await reduceContextOverflow(
|
|
289
|
-
messages,
|
|
290
|
-
config,
|
|
291
|
-
undefined,
|
|
292
|
-
noOpCompact,
|
|
293
|
-
);
|
|
328
|
+
const result = await reduceContextOverflow(messages, config, undefined);
|
|
294
329
|
|
|
295
330
|
expect(result.tier).toBe("forced_compaction");
|
|
296
331
|
expect(result.state.appliedTiers).toContain("forced_compaction");
|
|
@@ -311,20 +346,14 @@ describe("context-overflow-reducer", () => {
|
|
|
311
346
|
];
|
|
312
347
|
|
|
313
348
|
const config = makeConfig();
|
|
314
|
-
|
|
349
|
+
useNoOpCompacting();
|
|
315
350
|
|
|
316
351
|
// Skip compaction, apply tool-result truncation
|
|
317
|
-
const step1 = await reduceContextOverflow(
|
|
318
|
-
messages,
|
|
319
|
-
config,
|
|
320
|
-
undefined,
|
|
321
|
-
compactFn,
|
|
322
|
-
);
|
|
352
|
+
const step1 = await reduceContextOverflow(messages, config, undefined);
|
|
323
353
|
const step2 = await reduceContextOverflow(
|
|
324
354
|
step1.messages,
|
|
325
355
|
config,
|
|
326
356
|
step1.state,
|
|
327
|
-
compactFn,
|
|
328
357
|
);
|
|
329
358
|
|
|
330
359
|
expect(step2.tier).toBe("tool_result_truncation");
|
|
@@ -352,7 +381,7 @@ describe("context-overflow-reducer", () => {
|
|
|
352
381
|
];
|
|
353
382
|
|
|
354
383
|
const config = makeConfig();
|
|
355
|
-
|
|
384
|
+
useNoOpCompacting();
|
|
356
385
|
|
|
357
386
|
let currentMessages = messages;
|
|
358
387
|
let state: ReducerState | undefined;
|
|
@@ -361,7 +390,6 @@ describe("context-overflow-reducer", () => {
|
|
|
361
390
|
currentMessages,
|
|
362
391
|
config,
|
|
363
392
|
state,
|
|
364
|
-
compactFn,
|
|
365
393
|
);
|
|
366
394
|
currentMessages = result.messages;
|
|
367
395
|
state = result.state;
|
|
@@ -399,7 +427,7 @@ describe("context-overflow-reducer", () => {
|
|
|
399
427
|
];
|
|
400
428
|
|
|
401
429
|
const config = makeConfig();
|
|
402
|
-
|
|
430
|
+
useCompacting();
|
|
403
431
|
|
|
404
432
|
// Run 1
|
|
405
433
|
const run1Tiers: string[] = [];
|
|
@@ -407,7 +435,7 @@ describe("context-overflow-reducer", () => {
|
|
|
407
435
|
let state1: ReducerState | undefined;
|
|
408
436
|
let msgs1 = messages;
|
|
409
437
|
while (!state1?.exhausted) {
|
|
410
|
-
const r = await reduceContextOverflow(msgs1, config, state1
|
|
438
|
+
const r = await reduceContextOverflow(msgs1, config, state1);
|
|
411
439
|
run1Tiers.push(r.tier);
|
|
412
440
|
run1Tokens.push(r.estimatedTokens);
|
|
413
441
|
msgs1 = r.messages;
|
|
@@ -420,7 +448,7 @@ describe("context-overflow-reducer", () => {
|
|
|
420
448
|
let state2: ReducerState | undefined;
|
|
421
449
|
let msgs2 = messages;
|
|
422
450
|
while (!state2?.exhausted) {
|
|
423
|
-
const r = await reduceContextOverflow(msgs2, config, state2
|
|
451
|
+
const r = await reduceContextOverflow(msgs2, config, state2);
|
|
424
452
|
run2Tiers.push(r.tier);
|
|
425
453
|
run2Tokens.push(r.estimatedTokens);
|
|
426
454
|
msgs2 = r.messages;
|
|
@@ -440,7 +468,7 @@ describe("context-overflow-reducer", () => {
|
|
|
440
468
|
];
|
|
441
469
|
|
|
442
470
|
const config = makeConfig();
|
|
443
|
-
|
|
471
|
+
useCompacting();
|
|
444
472
|
|
|
445
473
|
let state: ReducerState | undefined;
|
|
446
474
|
let currentMessages = messages;
|
|
@@ -451,7 +479,6 @@ describe("context-overflow-reducer", () => {
|
|
|
451
479
|
currentMessages,
|
|
452
480
|
config,
|
|
453
481
|
state,
|
|
454
|
-
compactFn,
|
|
455
482
|
);
|
|
456
483
|
injectionModes.push(result.state.injectionMode);
|
|
457
484
|
currentMessages = result.messages;
|
|
@@ -512,22 +539,16 @@ describe("context-overflow-reducer", () => {
|
|
|
512
539
|
const config = makeConfig({
|
|
513
540
|
targetTokens: 500_000,
|
|
514
541
|
});
|
|
515
|
-
|
|
542
|
+
useNoOpCompacting();
|
|
516
543
|
|
|
517
544
|
// Run through forced_compaction and tool_result_truncation first
|
|
518
|
-
const step1 = await reduceContextOverflow(
|
|
519
|
-
messages,
|
|
520
|
-
config,
|
|
521
|
-
undefined,
|
|
522
|
-
compactFn,
|
|
523
|
-
);
|
|
545
|
+
const step1 = await reduceContextOverflow(messages, config, undefined);
|
|
524
546
|
expect(step1.tier).toBe("forced_compaction");
|
|
525
547
|
|
|
526
548
|
const step2 = await reduceContextOverflow(
|
|
527
549
|
step1.messages,
|
|
528
550
|
config,
|
|
529
551
|
step1.state,
|
|
530
|
-
compactFn,
|
|
531
552
|
);
|
|
532
553
|
expect(step2.tier).toBe("tool_result_truncation");
|
|
533
554
|
|
|
@@ -536,7 +557,6 @@ describe("context-overflow-reducer", () => {
|
|
|
536
557
|
step2.messages,
|
|
537
558
|
config,
|
|
538
559
|
step2.state,
|
|
539
|
-
compactFn,
|
|
540
560
|
);
|
|
541
561
|
expect(step3.tier).toBe("media_stubbing");
|
|
542
562
|
|
|
@@ -570,14 +590,9 @@ describe("context-overflow-reducer", () => {
|
|
|
570
590
|
];
|
|
571
591
|
|
|
572
592
|
const config = makeConfig();
|
|
573
|
-
|
|
593
|
+
useCompacting();
|
|
574
594
|
|
|
575
|
-
const result = await reduceContextOverflow(
|
|
576
|
-
messages,
|
|
577
|
-
config,
|
|
578
|
-
undefined,
|
|
579
|
-
compactFn,
|
|
580
|
-
);
|
|
595
|
+
const result = await reduceContextOverflow(messages, config, undefined);
|
|
581
596
|
|
|
582
597
|
expect(result.tier).toBe("forced_compaction");
|
|
583
598
|
expect(result.compactionResult).toBeDefined();
|
|
@@ -594,24 +609,149 @@ describe("context-overflow-reducer", () => {
|
|
|
594
609
|
];
|
|
595
610
|
|
|
596
611
|
const config = makeConfig();
|
|
597
|
-
|
|
612
|
+
useCompacting();
|
|
598
613
|
|
|
599
614
|
// Skip past compaction tier
|
|
600
|
-
const step1 = await reduceContextOverflow(
|
|
601
|
-
messages,
|
|
602
|
-
config,
|
|
603
|
-
undefined,
|
|
604
|
-
compactFn,
|
|
605
|
-
);
|
|
615
|
+
const step1 = await reduceContextOverflow(messages, config, undefined);
|
|
606
616
|
const step2 = await reduceContextOverflow(
|
|
607
617
|
step1.messages,
|
|
608
618
|
config,
|
|
609
619
|
step1.state,
|
|
610
|
-
compactFn,
|
|
611
620
|
);
|
|
612
621
|
|
|
613
622
|
expect(step2.tier).toBe("tool_result_truncation");
|
|
614
623
|
expect(step2.compactionResult).toBeUndefined();
|
|
615
624
|
});
|
|
616
625
|
});
|
|
626
|
+
|
|
627
|
+
describe("emergency compaction rung", () => {
|
|
628
|
+
test("emergency rung runs first and forwards its compaction result", async () => {
|
|
629
|
+
const messages: Message[] = [
|
|
630
|
+
msg("user", "do something"),
|
|
631
|
+
toolUseMsg("tu_1", "bash"),
|
|
632
|
+
toolResultMsg("tu_1", "x".repeat(8000)),
|
|
633
|
+
];
|
|
634
|
+
|
|
635
|
+
const config = makeConfig();
|
|
636
|
+
useCompacting();
|
|
637
|
+
useEmergencyCompacting();
|
|
638
|
+
|
|
639
|
+
const result = await reduceContextOverflow(messages, config, undefined);
|
|
640
|
+
|
|
641
|
+
expect(result.tier).toBe("emergency_compaction");
|
|
642
|
+
expect(result.state.appliedTiers).toEqual(["emergency_compaction"]);
|
|
643
|
+
expect(result.compactionResult?.compacted).toBe(true);
|
|
644
|
+
expect(result.state.exhausted).toBe(false);
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
test("when emergency cannot reduce, the same step falls through to forced compaction", async () => {
|
|
648
|
+
const messages: Message[] = [
|
|
649
|
+
msg("user", "Hello"),
|
|
650
|
+
msg("assistant", "World"),
|
|
651
|
+
];
|
|
652
|
+
|
|
653
|
+
const config = makeConfig();
|
|
654
|
+
useCompacting();
|
|
655
|
+
|
|
656
|
+
// Default emergency stub is a no-op, so the step falls through.
|
|
657
|
+
const result = await reduceContextOverflow(messages, config, undefined);
|
|
658
|
+
|
|
659
|
+
expect(result.tier).toBe("forced_compaction");
|
|
660
|
+
expect(result.state.appliedTiers).toEqual([
|
|
661
|
+
"emergency_compaction",
|
|
662
|
+
"forced_compaction",
|
|
663
|
+
]);
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
describe("terminal auto-compress rung", () => {
|
|
668
|
+
test("auto-compress runs as the final rung when the policy permits it", async () => {
|
|
669
|
+
const messages: Message[] = [
|
|
670
|
+
msg("user", "Hello"),
|
|
671
|
+
msg("assistant", "World"),
|
|
672
|
+
];
|
|
673
|
+
|
|
674
|
+
const config = makeConfig({ allowAutoCompressLatestTurn: true });
|
|
675
|
+
useCompacting();
|
|
676
|
+
|
|
677
|
+
let state: ReducerState | undefined;
|
|
678
|
+
let currentMessages = messages;
|
|
679
|
+
const tiers: string[] = [];
|
|
680
|
+
while (!state?.exhausted) {
|
|
681
|
+
const result = await reduceContextOverflow(
|
|
682
|
+
currentMessages,
|
|
683
|
+
config,
|
|
684
|
+
state,
|
|
685
|
+
);
|
|
686
|
+
tiers.push(result.tier);
|
|
687
|
+
currentMessages = result.messages;
|
|
688
|
+
state = result.state;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
expect(tiers[tiers.length - 1]).toBe("auto_compress_latest_turn");
|
|
692
|
+
expect(state!.appliedTiers).toContain("auto_compress_latest_turn");
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
test("auto-compress is skipped when the policy disallows it", async () => {
|
|
696
|
+
const messages: Message[] = [
|
|
697
|
+
msg("user", "Hello"),
|
|
698
|
+
msg("assistant", "World"),
|
|
699
|
+
];
|
|
700
|
+
|
|
701
|
+
const config = makeConfig({ allowAutoCompressLatestTurn: false });
|
|
702
|
+
useCompacting();
|
|
703
|
+
|
|
704
|
+
let state: ReducerState | undefined;
|
|
705
|
+
let currentMessages = messages;
|
|
706
|
+
const tiers: string[] = [];
|
|
707
|
+
while (!state?.exhausted) {
|
|
708
|
+
const result = await reduceContextOverflow(
|
|
709
|
+
currentMessages,
|
|
710
|
+
config,
|
|
711
|
+
state,
|
|
712
|
+
);
|
|
713
|
+
tiers.push(result.tier);
|
|
714
|
+
currentMessages = result.messages;
|
|
715
|
+
state = result.state;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
expect(tiers).not.toContain("auto_compress_latest_turn");
|
|
719
|
+
expect(tiers[tiers.length - 1]).toBe("injection_downgrade");
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
describe("middle-tier attempt budget", () => {
|
|
724
|
+
test("the ladder escalates once maxMiddleTierAttempts middle rungs run", async () => {
|
|
725
|
+
const messages: Message[] = [
|
|
726
|
+
msg("user", "Hello"),
|
|
727
|
+
msg("assistant", "World"),
|
|
728
|
+
];
|
|
729
|
+
|
|
730
|
+
const config = makeConfig({
|
|
731
|
+
maxMiddleTierAttempts: 2,
|
|
732
|
+
allowAutoCompressLatestTurn: false,
|
|
733
|
+
});
|
|
734
|
+
useCompacting();
|
|
735
|
+
|
|
736
|
+
let state: ReducerState | undefined;
|
|
737
|
+
let currentMessages = messages;
|
|
738
|
+
const tiers: string[] = [];
|
|
739
|
+
while (!state?.exhausted) {
|
|
740
|
+
const result = await reduceContextOverflow(
|
|
741
|
+
currentMessages,
|
|
742
|
+
config,
|
|
743
|
+
state,
|
|
744
|
+
);
|
|
745
|
+
tiers.push(result.tier);
|
|
746
|
+
currentMessages = result.messages;
|
|
747
|
+
state = result.state;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// Only two middle tiers run before the ladder is exhausted; media
|
|
751
|
+
// stubbing and injection downgrade are never reached.
|
|
752
|
+
expect(tiers).toEqual(["forced_compaction", "tool_result_truncation"]);
|
|
753
|
+
expect(tiers).not.toContain("media_stubbing");
|
|
754
|
+
expect(tiers).not.toContain("injection_downgrade");
|
|
755
|
+
});
|
|
756
|
+
});
|
|
617
757
|
});
|