@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091926.ebb2d62

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.
Files changed (490) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/docs/activation-funnel-telemetry.md +310 -0
  4. package/examples/plugins/echo/README.md +61 -60
  5. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  6. package/examples/plugins/echo/hooks/stop.ts +16 -0
  7. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  8. package/examples/plugins/echo/package.json +1 -2
  9. package/examples/plugins/echo/src/emit.ts +19 -0
  10. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  11. package/openapi.yaml +273 -121
  12. package/package.json +2 -2
  13. package/scripts/sync-llm-catalog.ts +2 -0
  14. package/src/__tests__/activation-early-marking.test.ts +120 -0
  15. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  16. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  17. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  18. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  19. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  20. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  21. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  22. package/src/__tests__/agent-loop.test.ts +441 -96
  23. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  24. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  25. package/src/__tests__/anthropic-provider.test.ts +23 -8
  26. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  27. package/src/__tests__/app-control-flow.test.ts +1 -1
  28. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  29. package/src/__tests__/app-executors.test.ts +132 -0
  30. package/src/__tests__/approval-cascade.test.ts +6 -5
  31. package/src/__tests__/approval-routes-http.test.ts +4 -1
  32. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  33. package/src/__tests__/build-persisted-content.test.ts +75 -1
  34. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  35. package/src/__tests__/channel-approvals.test.ts +1 -1
  36. package/src/__tests__/compaction-circuit.test.ts +258 -0
  37. package/src/__tests__/compaction-direct.test.ts +146 -0
  38. package/src/__tests__/compaction-events.test.ts +7 -7
  39. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  40. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  41. package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
  42. package/src/__tests__/context-overflow-reducer.test.ts +265 -125
  43. package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
  44. package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
  45. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  46. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  47. package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
  48. package/src/__tests__/conversation-agent-loop.test.ts +342 -623
  49. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  50. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
  51. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  52. package/src/__tests__/conversation-error.test.ts +15 -1
  53. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  54. package/src/__tests__/conversation-media-retry.test.ts +1 -1
  55. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
  56. package/src/__tests__/conversation-process-callsite.test.ts +15 -15
  57. package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
  58. package/src/__tests__/conversation-queue.test.ts +10 -10
  59. package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
  60. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  61. package/src/__tests__/conversation-slash-queue.test.ts +7 -5
  62. package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
  63. package/src/__tests__/conversation-speed-override.test.ts +11 -10
  64. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  65. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
  66. package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
  67. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
  68. package/src/__tests__/conversation-undo.test.ts +2 -2
  69. package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
  70. package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
  71. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
  72. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  73. package/src/__tests__/corrected-target.test.ts +93 -0
  74. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -4
  75. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  76. package/src/__tests__/cu-unified-flow.test.ts +36 -0
  77. package/src/__tests__/db-acp-history.test.ts +101 -0
  78. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  79. package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
  80. package/src/__tests__/empty-response-hook.test.ts +1 -1
  81. package/src/__tests__/file-write-tool.test.ts +63 -0
  82. package/src/__tests__/gateway-only-guard.test.ts +17 -2
  83. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  84. package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
  85. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  86. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  87. package/src/__tests__/heartbeat-service.test.ts +1 -0
  88. package/src/__tests__/history-repair-hook.test.ts +5 -1
  89. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  90. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  91. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  92. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  93. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  94. package/src/__tests__/injector-background-turn.test.ts +13 -23
  95. package/src/__tests__/injector-chain.test.ts +268 -44
  96. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  97. package/src/__tests__/injector-document-comments.test.ts +97 -114
  98. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  99. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  100. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  101. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  102. package/src/__tests__/llm-catalog-parity.test.ts +4 -0
  103. package/src/__tests__/llm-resolver.test.ts +73 -0
  104. package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
  105. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  106. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  107. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  108. package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
  109. package/src/__tests__/persist-unsendable-image.test.ts +97 -1
  110. package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
  111. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  112. package/src/__tests__/plugin-bootstrap.test.ts +91 -81
  113. package/src/__tests__/plugin-registry.test.ts +3 -49
  114. package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
  115. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  116. package/src/__tests__/plugin-types.test.ts +0 -70
  117. package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
  118. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  119. package/src/__tests__/published-app-updater.test.ts +138 -0
  120. package/src/__tests__/reaction-persistence.test.ts +1 -1
  121. package/src/__tests__/retry-thinking-adaptive-only.test.ts +245 -0
  122. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  123. package/src/__tests__/server-history-render.test.ts +39 -0
  124. package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
  125. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  126. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  127. package/src/__tests__/subagent-detail.test.ts +25 -7
  128. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  129. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  130. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  131. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  132. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  133. package/src/__tests__/title-generate-hook.test.ts +5 -1
  134. package/src/__tests__/tool-error-hook.test.ts +1 -1
  135. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  136. package/src/__tests__/tool-start-timestamp.test.ts +218 -0
  137. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  138. package/src/__tests__/web-fetch.test.ts +45 -0
  139. package/src/acp/__tests__/agent-process.test.ts +161 -0
  140. package/src/acp/__tests__/client-handler.test.ts +40 -0
  141. package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
  142. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  143. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  144. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  145. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  146. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  147. package/src/acp/agent-process.ts +61 -1
  148. package/src/acp/auto-install.test.ts +280 -0
  149. package/src/acp/auto-install.ts +232 -0
  150. package/src/acp/client-handler.ts +31 -0
  151. package/src/acp/prepare-agent-env.ts +80 -27
  152. package/src/acp/resolve-agent.test.ts +188 -28
  153. package/src/acp/resolve-agent.ts +119 -42
  154. package/src/acp/resume-hint.ts +23 -0
  155. package/src/acp/session-manager.ts +507 -73
  156. package/src/agent/compaction-circuit.ts +60 -102
  157. package/src/agent/loop.ts +403 -251
  158. package/src/api/events/tool-result.ts +9 -0
  159. package/src/api/events/tool-use-start.ts +7 -0
  160. package/src/api/responses/conversation-message.ts +72 -13
  161. package/src/api/responses/memory-v3-selection-log.ts +19 -10
  162. package/src/approvals/guardian-request-resolvers.ts +27 -1
  163. package/src/background-wake/next-wake.ts +1 -0
  164. package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
  165. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  166. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  167. package/src/cli/commands/memory-v3.ts +57 -199
  168. package/src/cli/commands/plugins.ts +43 -37
  169. package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
  170. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  171. package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
  172. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
  173. package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
  174. package/src/cli/lib/install-from-github.ts +797 -60
  175. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  176. package/src/cli/lib/plugin-details.ts +416 -0
  177. package/src/cli/lib/plugin-marketplace.ts +215 -0
  178. package/src/cli/lib/search-plugins.ts +201 -29
  179. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  180. package/src/config/acp-defaults.test.ts +10 -0
  181. package/src/config/acp-defaults.ts +9 -3
  182. package/src/config/acp-schema.ts +1 -7
  183. package/src/config/bundled-skills/acp/SKILL.md +80 -41
  184. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  185. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  186. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  187. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  188. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  189. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  190. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  191. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  192. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  193. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  194. package/src/config/bundled-tool-registry.ts +4 -0
  195. package/src/config/call-site-defaults.ts +0 -3
  196. package/src/config/feature-flag-registry.json +10 -56
  197. package/src/config/llm-resolver.ts +39 -7
  198. package/src/config/loader.ts +5 -22
  199. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
  200. package/src/config/schemas/call-site-catalog.ts +0 -21
  201. package/src/config/schemas/heartbeat.ts +9 -0
  202. package/src/config/schemas/llm.ts +17 -3
  203. package/src/config/schemas/memory-v3.ts +58 -8
  204. package/src/config/seed-inference-profiles.ts +18 -0
  205. package/src/context/compactor.ts +22 -4
  206. package/src/context/post-turn-tool-result-truncation.ts +39 -1
  207. package/src/context/strip-injections.ts +8 -2
  208. package/src/daemon/conversation-agent-loop-handlers.ts +120 -42
  209. package/src/daemon/conversation-agent-loop.ts +308 -1297
  210. package/src/daemon/conversation-error.ts +31 -4
  211. package/src/daemon/conversation-history.ts +1 -1
  212. package/src/daemon/conversation-lifecycle.ts +11 -255
  213. package/src/daemon/conversation-media-retry.ts +19 -6
  214. package/src/daemon/conversation-messaging.ts +17 -0
  215. package/src/daemon/conversation-process.ts +22 -141
  216. package/src/daemon/conversation-queue-manager.ts +8 -0
  217. package/src/daemon/conversation-registry.ts +159 -0
  218. package/src/daemon/conversation-runtime-assembly.ts +361 -393
  219. package/src/daemon/conversation-store.ts +9 -90
  220. package/src/daemon/conversation-surfaces.ts +165 -11
  221. package/src/daemon/conversation-workspace.ts +17 -0
  222. package/src/daemon/conversation.ts +444 -62
  223. package/src/daemon/disk-pressure-policy.ts +0 -1
  224. package/src/daemon/external-plugins-bootstrap.ts +36 -46
  225. package/src/daemon/handlers/config-channels.ts +11 -2
  226. package/src/daemon/handlers/conversations.ts +3 -1
  227. package/src/daemon/handlers/shared.ts +9 -1
  228. package/src/daemon/handlers/skills.ts +4 -1
  229. package/src/daemon/host-app-control-proxy.ts +72 -57
  230. package/src/daemon/host-proxy-preactivation.ts +1 -3
  231. package/src/daemon/lifecycle.ts +21 -7
  232. package/src/daemon/persist-unsendable-image.ts +62 -25
  233. package/src/daemon/process-message.ts +1 -1
  234. package/src/daemon/server.ts +2 -0
  235. package/src/daemon/tool-side-effects.ts +15 -0
  236. package/src/daemon/wake-conversation-ops.ts +269 -0
  237. package/src/embedded/plugin-api.ts +2 -2
  238. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  239. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  240. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  241. package/src/heartbeat/heartbeat-service.ts +26 -0
  242. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  243. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  244. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  245. package/src/ipc/skill-routes/memory.ts +4 -2
  246. package/src/memory/__tests__/activation-session-store.test.ts +41 -0
  247. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  248. package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
  249. package/src/memory/activation-session-store.ts +43 -0
  250. package/src/memory/conversation-crud.ts +29 -19
  251. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  252. package/src/memory/db-init.ts +6 -0
  253. package/src/memory/embedding-backend.ts +5 -22
  254. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  255. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  256. package/src/memory/jobs-worker.ts +25 -1
  257. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  258. package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
  259. package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
  260. package/src/memory/migrations/index.ts +3 -0
  261. package/src/memory/onboarding-events-store.ts +66 -18
  262. package/src/memory/schema/acp.ts +4 -0
  263. package/src/memory/schema/infrastructure.ts +13 -0
  264. package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
  265. package/src/memory/v2/__tests__/page-store.test.ts +22 -0
  266. package/src/memory/v2/consolidation-job.ts +2 -63
  267. package/src/memory/v2/types.ts +5 -0
  268. package/src/messaging/providers/telegram-bot/api.ts +14 -5
  269. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  270. package/src/notifications/access-request-copy.ts +298 -0
  271. package/src/notifications/adapters/slack.ts +3 -3
  272. package/src/notifications/adapters/telegram.ts +9 -2
  273. package/src/notifications/copy-composer.ts +49 -267
  274. package/src/notifications/decision-engine.ts +16 -35
  275. package/src/notifications/home-feed-side-effect.ts +1 -6
  276. package/src/plugin-api/constants.ts +4 -0
  277. package/src/plugin-api/index.ts +40 -11
  278. package/src/plugin-api/types.ts +108 -0
  279. package/src/plugins/defaults/compaction/compact.ts +106 -0
  280. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
  281. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  282. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  283. package/src/plugins/defaults/compaction/package.json +1 -2
  284. package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
  285. package/src/plugins/defaults/empty-response/package.json +0 -1
  286. package/src/plugins/defaults/history-repair/package.json +0 -1
  287. package/src/plugins/defaults/index.ts +156 -26
  288. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  289. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
  290. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  291. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  292. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  293. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  294. package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
  295. package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
  296. package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
  297. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
  298. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
  299. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
  300. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
  301. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
  302. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
  303. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
  304. package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
  305. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
  306. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
  307. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
  308. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
  309. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
  310. package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
  311. package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
  312. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  313. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  314. package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
  315. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
  316. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
  317. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  318. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
  319. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
  320. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
  321. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
  322. package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
  323. package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
  324. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
  325. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
  326. package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
  327. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
  328. package/src/plugins/defaults/title-generate/package.json +0 -1
  329. package/src/plugins/defaults/tool-error/package.json +0 -1
  330. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  331. package/src/plugins/external-api.ts +12 -2
  332. package/src/plugins/pipeline.ts +6 -293
  333. package/src/plugins/registry.ts +9 -37
  334. package/src/plugins/types.ts +76 -381
  335. package/src/plugins/user-loader.ts +30 -127
  336. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  337. package/src/prompts/system-prompt.ts +61 -10
  338. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
  339. package/src/providers/anthropic/client.ts +9 -10
  340. package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
  341. package/src/providers/inference/logit-bias.ts +55 -0
  342. package/src/providers/model-catalog.ts +57 -0
  343. package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
  344. package/src/providers/openai/chat-completions-provider.ts +44 -1
  345. package/src/providers/retry.ts +57 -7
  346. package/src/providers/types.ts +6 -0
  347. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  348. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  349. package/src/runtime/agent-wake.ts +108 -209
  350. package/src/runtime/assistant-event-hub.ts +1 -1
  351. package/src/runtime/channel-approvals.ts +1 -1
  352. package/src/runtime/interactive-ui.ts +1 -1
  353. package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
  354. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  355. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  356. package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
  357. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  358. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  359. package/src/runtime/routes/acp-routes.test.ts +185 -32
  360. package/src/runtime/routes/acp-routes.ts +328 -30
  361. package/src/runtime/routes/app-management-routes.ts +3 -0
  362. package/src/runtime/routes/approval-routes.ts +1 -1
  363. package/src/runtime/routes/browser-routes.ts +1 -1
  364. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  365. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  366. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  367. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  368. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  369. package/src/runtime/routes/conversation-routes.ts +30 -2
  370. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  371. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  372. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  373. package/src/runtime/routes/host-cu-routes.ts +1 -1
  374. package/src/runtime/routes/identity-routes.ts +18 -3
  375. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  376. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  377. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  378. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  379. package/src/runtime/routes/memory-v3-routes.ts +65 -305
  380. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
  381. package/src/runtime/routes/playground/helpers.ts +1 -1
  382. package/src/runtime/routes/plugins-routes.ts +337 -35
  383. package/src/runtime/routes/stt-routes.ts +45 -12
  384. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  385. package/src/runtime/routes/work-items-routes.ts +2 -4
  386. package/src/runtime/routes/workspace-routes.ts +50 -15
  387. package/src/runtime/services/conversation-serializer.ts +1 -1
  388. package/src/runtime/verification-outbound-actions.ts +147 -2
  389. package/src/runtime/verification-templates.ts +29 -3
  390. package/src/services/published-app-updater.ts +30 -8
  391. package/src/signals/cancel.ts +2 -4
  392. package/src/subagent/manager.ts +21 -5
  393. package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
  394. package/src/telemetry/activation-funnel.ts +167 -0
  395. package/src/telemetry/types.ts +13 -0
  396. package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
  397. package/src/telemetry/usage-telemetry-reporter.ts +26 -1
  398. package/src/tools/acp/context.ts +20 -0
  399. package/src/tools/acp/list-agents.test.ts +9 -19
  400. package/src/tools/acp/list-agents.ts +3 -15
  401. package/src/tools/acp/spawn.test.ts +173 -202
  402. package/src/tools/acp/spawn.ts +37 -172
  403. package/src/tools/acp/steer.test.ts +105 -8
  404. package/src/tools/acp/steer.ts +48 -17
  405. package/src/tools/apps/executors.ts +166 -50
  406. package/src/tools/browser/browser-execution.ts +12 -2
  407. package/src/tools/filesystem/write.ts +34 -0
  408. package/src/tools/network/web-fetch.ts +65 -24
  409. package/src/tools/skills/load.ts +1 -1
  410. package/src/tools/subagent/spawn.ts +2 -4
  411. package/src/tools/ui-surface/definitions.ts +32 -5
  412. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  413. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  414. package/docs/plugins.md +0 -832
  415. package/examples/plugins/echo/register.ts +0 -143
  416. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  417. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  418. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  419. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  420. package/src/__tests__/pipeline-runner.test.ts +0 -554
  421. package/src/daemon/wake-target-adapter.ts +0 -253
  422. package/src/memory/v3/__tests__/assign.test.ts +0 -242
  423. package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
  424. package/src/memory/v3/__tests__/core.test.ts +0 -39
  425. package/src/memory/v3/__tests__/health.test.ts +0 -219
  426. package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
  427. package/src/memory/v3/__tests__/needle.test.ts +0 -107
  428. package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
  429. package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
  430. package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
  431. package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
  432. package/src/memory/v3/__tests__/router.test.ts +0 -332
  433. package/src/memory/v3/__tests__/selector.test.ts +0 -470
  434. package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
  435. package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
  436. package/src/memory/v3/__tests__/tree.test.ts +0 -192
  437. package/src/memory/v3/assign.ts +0 -268
  438. package/src/memory/v3/capabilities.ts +0 -124
  439. package/src/memory/v3/core.ts +0 -26
  440. package/src/memory/v3/health.ts +0 -0
  441. package/src/memory/v3/maintain-job.ts +0 -314
  442. package/src/memory/v3/needle.ts +0 -115
  443. package/src/memory/v3/orchestrate.ts +0 -126
  444. package/src/memory/v3/page-content.ts +0 -34
  445. package/src/memory/v3/provider-blocks.ts +0 -26
  446. package/src/memory/v3/reconcile.ts +0 -523
  447. package/src/memory/v3/router.ts +0 -190
  448. package/src/memory/v3/selection-log-store.ts +0 -84
  449. package/src/memory/v3/selector.ts +0 -226
  450. package/src/memory/v3/shadow-plugin.ts +0 -411
  451. package/src/memory/v3/snapshot.ts +0 -209
  452. package/src/memory/v3/tree.ts +0 -174
  453. package/src/memory/v3/types.ts +0 -59
  454. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  455. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  456. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  457. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  458. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  459. package/src/plugins/defaults/compaction/register.ts +0 -35
  460. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  461. package/src/plugins/defaults/empty-response/register.ts +0 -23
  462. package/src/plugins/defaults/history-repair/register.ts +0 -24
  463. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
  464. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  465. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  466. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  467. package/src/plugins/defaults/title-generate/register.ts +0 -35
  468. package/src/plugins/defaults/tool-error/register.ts +0 -23
  469. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  470. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  471. package/src/proactive-artifact/decision.test.ts +0 -226
  472. package/src/proactive-artifact/decision.ts +0 -165
  473. package/src/proactive-artifact/index.ts +0 -7
  474. package/src/proactive-artifact/job.test.ts +0 -962
  475. package/src/proactive-artifact/job.ts +0 -372
  476. package/src/proactive-artifact/message-copy.ts +0 -58
  477. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  478. package/src/proactive-artifact/trigger-state.ts +0 -123
  479. package/src/util/map-limit.ts +0 -27
  480. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  481. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  482. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  483. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  484. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  485. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  486. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  487. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  488. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  489. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  490. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
@@ -9,39 +9,67 @@
9
9
  * messages is a no-op. Tiers are ordered so that less destructive
10
10
  * transformations are tried first.
11
11
  *
12
- * Tier progression:
13
- * 1. Forced compaction (emergency keep-boundary options)
12
+ * Rung progression:
13
+ * 0. Emergency summarize-around-last-tool-pair (preserves the most recent
14
+ * tool call/result while aggressively compressing earlier history)
15
+ * 1. Forced full-history compaction (emergency keep-boundary options)
14
16
  * 2. Aggressive tool-result text truncation across retained history
15
17
  * 3. Media/file payload stubbing (replace images/files with text stubs)
16
18
  * 4. Runtime injection downgrade to minimal mode
19
+ * terminal. Auto-compress the latest turn (policy-gated by the caller)
20
+ *
21
+ * Rungs 1–4 are the "middle tiers" and are bounded by `maxMiddleTierAttempts`.
22
+ * The emergency rung always runs first; the auto-compress rung runs last and
23
+ * only when the caller permits it. The caller invokes the reducer repeatedly,
24
+ * re-running the agent loop after each rung, until either the context fits or
25
+ * `state.exhausted` is true.
17
26
  */
18
27
 
19
- import type { ContextWindowConfig } from "../config/types.js";
28
+ import type { ContextWindowConfig } from "../../../config/types.js";
20
29
  import {
21
30
  estimateContentBlockTokens,
22
31
  estimatePromptTokens,
23
- } from "../context/token-estimator.js";
24
- import { truncateToolResultsAcrossHistory } from "../context/tool-result-truncation.js";
25
- import type {
26
- ContextWindowCompactOptions,
27
- ContextWindowResult,
28
- } from "../context/window-manager.js";
29
- import type { Message } from "../providers/types.js";
32
+ } from "../../../context/token-estimator.js";
33
+ import { truncateToolResultsAcrossHistory } from "../../../context/tool-result-truncation.js";
30
34
  import {
31
35
  countMediaBlocks,
32
36
  estimateUnconditionalStubTokens,
33
37
  stripMediaPayloadsForRetry,
34
- } from "./conversation-media-retry.js";
35
- import type { InjectionMode } from "./conversation-runtime-assembly.js";
38
+ } from "../../../daemon/conversation-media-retry.js";
39
+ import type { InjectionMode } from "../../../daemon/conversation-runtime-assembly.js";
40
+ import type { Message } from "../../../providers/types.js";
41
+ import type { TrustClass } from "../../../runtime/actor-trust-resolver.js";
42
+ import { getLogger } from "../../../util/logger.js";
43
+ import { defaultCompact, defaultEmergencyCompact } from "./compact.js";
44
+ import type {
45
+ ContextWindowCompactOptions,
46
+ ContextWindowResult,
47
+ } from "./window-manager.js";
48
+
49
+ const log = getLogger("context-overflow-reducer");
36
50
 
37
51
  /**
38
52
  * Identifies which reduction tier was applied in a given step.
39
53
  */
40
54
  export type ReducerTier =
55
+ | "emergency_compaction"
41
56
  | "forced_compaction"
42
57
  | "tool_result_truncation"
43
58
  | "media_stubbing"
44
- | "injection_downgrade";
59
+ | "injection_downgrade"
60
+ | "auto_compress_latest_turn";
61
+
62
+ /**
63
+ * The "middle tiers" — the rungs bounded by `maxMiddleTierAttempts`. The
64
+ * emergency and auto-compress rungs are intentionally excluded so they remain
65
+ * reachable regardless of how small the middle-tier budget is.
66
+ */
67
+ const MIDDLE_TIERS: readonly ReducerTier[] = [
68
+ "forced_compaction",
69
+ "tool_result_truncation",
70
+ "media_stubbing",
71
+ "injection_downgrade",
72
+ ];
45
73
 
46
74
  /**
47
75
  * Tracks the cumulative state of the reducer across successive calls.
@@ -94,18 +122,35 @@ export interface ReducerConfig {
94
122
  targetTokens: number;
95
123
  /** Pre-computed tool token budget to include in estimations. */
96
124
  toolTokenBudget?: number;
125
+ /**
126
+ * Conversation whose {@link ContextWindowManager} the compaction rungs
127
+ * resolve from the compaction store to run the summary call.
128
+ */
129
+ conversationId: string;
130
+ /** Per-conversation inference-profile override for the summary call. */
131
+ overrideProfile?: string | null;
132
+ /** Trust class of the actor whose turn triggered overflow recovery. */
133
+ actorTrustClass?: TrustClass;
134
+ /**
135
+ * The provider-reported estimate at the overflow that triggered recovery.
136
+ * Sizes the emergency summarize-around-last-tool-pair cut.
137
+ */
138
+ previousEstimatedInputTokens: number;
139
+ /**
140
+ * Maximum number of middle-tier reductions (forced compaction, tool-result
141
+ * truncation, media stubbing, injection downgrade) to apply before
142
+ * escalating to the terminal auto-compress rung. The emergency and
143
+ * auto-compress rungs are not counted against this budget.
144
+ */
145
+ maxMiddleTierAttempts: number;
146
+ /**
147
+ * Whether the terminal auto-compress-latest-turn rung is permitted. The
148
+ * caller resolves this from the overflow policy; when false, the ladder ends
149
+ * once the middle tiers are exhausted.
150
+ */
151
+ allowAutoCompressLatestTurn: boolean;
97
152
  }
98
153
 
99
- /**
100
- * Compaction callback — the reducer does not own the ContextWindowManager
101
- * instance, so the caller provides a function that performs compaction.
102
- */
103
- export type CompactFn = (
104
- messages: Message[],
105
- signal: AbortSignal | undefined,
106
- options: ContextWindowCompactOptions,
107
- ) => Promise<ContextWindowResult>;
108
-
109
154
  // Aggressive truncation cap for tool results during overflow recovery.
110
155
  // Much tighter than the normal per-result budget.
111
156
  const OVERFLOW_TOOL_RESULT_MAX_CHARS = 4_000;
@@ -121,53 +166,163 @@ export async function reduceContextOverflow(
121
166
  messages: Message[],
122
167
  config: ReducerConfig,
123
168
  state: ReducerState | undefined,
124
- compactFn: CompactFn,
125
169
  signal?: AbortSignal,
126
170
  ): Promise<ReducerStepResult> {
127
171
  const applied = state?.appliedTiers ?? [];
172
+ const step = await selectNextRung(messages, config, state, applied, signal);
128
173
 
129
- // Tier 1: forced compaction
130
- if (!applied.includes("forced_compaction")) {
131
- return applyForcedCompaction(messages, config, applied, compactFn, signal);
132
- }
174
+ // Exhaustion is decided centrally from the rungs applied so far so the last
175
+ // rung that actually runs sets `exhausted`, avoiding a wasted no-op rerun.
176
+ step.state.exhausted = isLadderExhausted(step.state.appliedTiers, config);
177
+ return step;
178
+ }
133
179
 
134
- // Tier 2: aggressive tool-result truncation
135
- if (!applied.includes("tool_result_truncation")) {
136
- return applyToolResultTruncation(messages, config, applied, state);
180
+ async function selectNextRung(
181
+ messages: Message[],
182
+ config: ReducerConfig,
183
+ state: ReducerState | undefined,
184
+ applied: ReducerTier[],
185
+ signal?: AbortSignal,
186
+ ): Promise<ReducerStepResult> {
187
+ // Rung 0: emergency summarize-around-last-tool-pair (uncounted, runs first).
188
+ if (!applied.includes("emergency_compaction")) {
189
+ return applyEmergencyCompaction(messages, config, applied, signal);
137
190
  }
138
191
 
139
- // Tier 3: media/file payload stubbing
140
- if (!applied.includes("media_stubbing")) {
141
- return applyMediaStubbing(messages, config, applied, state);
192
+ // Middle tiers (rungs 1–4), bounded by the configured attempt budget.
193
+ const middleApplied = applied.filter((t) => MIDDLE_TIERS.includes(t)).length;
194
+ if (
195
+ middleApplied < config.maxMiddleTierAttempts &&
196
+ hasUnappliedMiddleTier(applied)
197
+ ) {
198
+ if (!applied.includes("forced_compaction")) {
199
+ return applyForcedCompaction(messages, config, applied, signal);
200
+ }
201
+ if (!applied.includes("tool_result_truncation")) {
202
+ return applyToolResultTruncation(messages, config, applied, state);
203
+ }
204
+ if (!applied.includes("media_stubbing")) {
205
+ return applyMediaStubbing(messages, config, applied, state);
206
+ }
207
+ return applyInjectionDowngrade(messages, config, applied, state);
142
208
  }
143
209
 
144
- // Tier 4: injection downgrade
145
- if (!applied.includes("injection_downgrade")) {
146
- return applyInjectionDowngrade(messages, config, applied, state);
210
+ // Terminal rung: auto-compress the latest turn (uncounted, policy-gated).
211
+ if (
212
+ config.allowAutoCompressLatestTurn &&
213
+ !applied.includes("auto_compress_latest_turn")
214
+ ) {
215
+ return applyAutoCompressLatestTurn(
216
+ messages,
217
+ config,
218
+ applied,
219
+ state,
220
+ signal,
221
+ );
147
222
  }
148
223
 
149
- // All tiers exhausted
224
+ // No rung left to apply — return a no-op step. `reduceContextOverflow`
225
+ // marks it exhausted via `isLadderExhausted`.
150
226
  const estimatedTokens = estimatePromptTokens(messages, config.systemPrompt, {
151
227
  providerName: config.providerName,
152
228
  toolTokenBudget: config.toolTokenBudget,
153
229
  });
154
230
  return {
155
231
  messages,
156
- tier: "injection_downgrade",
232
+ tier: applied[applied.length - 1] ?? "forced_compaction",
157
233
  state: {
158
234
  appliedTiers: [...applied],
159
235
  injectionMode: state?.injectionMode ?? "minimal",
236
+ toolResultMaxChars: state?.toolResultMaxChars,
237
+ compactionOptions: state?.compactionOptions,
160
238
  exhausted: true,
161
239
  },
162
240
  estimatedTokens,
163
241
  };
164
242
  }
165
243
 
244
+ /** Whether any middle tier remains unapplied. */
245
+ function hasUnappliedMiddleTier(applied: ReducerTier[]): boolean {
246
+ return MIDDLE_TIERS.some((tier) => !applied.includes(tier));
247
+ }
248
+
249
+ /**
250
+ * Decide whether the ladder has nothing more to try after the given rungs.
251
+ * The terminal auto-compress rung is the last; before it, the middle tiers
252
+ * are exhausted once the attempt budget is spent or every middle tier ran.
253
+ */
254
+ function isLadderExhausted(
255
+ applied: ReducerTier[],
256
+ config: ReducerConfig,
257
+ ): boolean {
258
+ if (applied.includes("auto_compress_latest_turn")) {
259
+ return true;
260
+ }
261
+ const middleApplied = applied.filter((t) => MIDDLE_TIERS.includes(t)).length;
262
+ const middleExhausted =
263
+ middleApplied >= config.maxMiddleTierAttempts ||
264
+ !hasUnappliedMiddleTier(applied);
265
+ if (!middleExhausted) {
266
+ return false;
267
+ }
268
+ // Middle tiers are done — the ladder continues only if the terminal
269
+ // auto-compress rung is permitted and has not run yet.
270
+ return !config.allowAutoCompressLatestTurn;
271
+ }
272
+
273
+ async function applyEmergencyCompaction(
274
+ messages: Message[],
275
+ config: ReducerConfig,
276
+ applied: ReducerTier[],
277
+ signal?: AbortSignal,
278
+ ): Promise<ReducerStepResult> {
279
+ let result: ContextWindowResult | null = null;
280
+ try {
281
+ result = await defaultEmergencyCompact({
282
+ conversationId: config.conversationId,
283
+ messages,
284
+ previousEstimatedInputTokens: config.previousEstimatedInputTokens,
285
+ overrideProfile: config.overrideProfile ?? null,
286
+ signal,
287
+ });
288
+ } catch (err) {
289
+ // No tool pair to split on, an unparseable summary, or a provider error.
290
+ // Fall through to forced compaction below rather than failing recovery.
291
+ log.warn(
292
+ { err },
293
+ "Emergency mid-turn compaction failed; falling through to forced compaction",
294
+ );
295
+ }
296
+
297
+ if (result?.compacted) {
298
+ return {
299
+ messages: result.messages,
300
+ tier: "emergency_compaction",
301
+ state: {
302
+ appliedTiers: [...applied, "emergency_compaction"],
303
+ injectionMode: "full",
304
+ exhausted: false,
305
+ },
306
+ estimatedTokens: result.estimatedInputTokens,
307
+ compactionResult: result,
308
+ };
309
+ }
310
+
311
+ // Emergency compaction produced no reduction; continue straight to forced
312
+ // compaction in the same step so the caller does not waste a provider rerun
313
+ // on unchanged messages.
314
+ return applyForcedCompaction(
315
+ messages,
316
+ config,
317
+ [...applied, "emergency_compaction"],
318
+ signal,
319
+ );
320
+ }
321
+
166
322
  async function applyForcedCompaction(
167
323
  messages: Message[],
168
324
  config: ReducerConfig,
169
325
  applied: ReducerTier[],
170
- compactFn: CompactFn,
171
326
  signal?: AbortSignal,
172
327
  ): Promise<ReducerStepResult> {
173
328
  const compactionOptions: ContextWindowCompactOptions = {
@@ -175,7 +330,14 @@ async function applyForcedCompaction(
175
330
  minKeepRecentUserTurns: 0,
176
331
  };
177
332
 
178
- const result = await compactFn(messages, signal, compactionOptions);
333
+ const result = await defaultCompact({
334
+ conversationId: config.conversationId,
335
+ messages,
336
+ signal,
337
+ ...compactionOptions,
338
+ overrideProfile: config.overrideProfile ?? null,
339
+ actorTrustClass: config.actorTrustClass,
340
+ });
179
341
  const nextMessages = result.compacted ? result.messages : messages;
180
342
  const estimatedTokens = result.compacted
181
343
  ? result.estimatedInputTokens
@@ -339,9 +501,55 @@ function applyInjectionDowngrade(
339
501
  injectionMode: "minimal",
340
502
  toolResultMaxChars: prevState?.toolResultMaxChars,
341
503
  compactionOptions: prevState?.compactionOptions,
342
- exhausted: true,
504
+ exhausted: false,
505
+ },
506
+ estimatedTokens,
507
+ };
508
+ }
509
+
510
+ async function applyAutoCompressLatestTurn(
511
+ messages: Message[],
512
+ config: ReducerConfig,
513
+ applied: ReducerTier[],
514
+ prevState: ReducerState | undefined,
515
+ signal?: AbortSignal,
516
+ ): Promise<ReducerStepResult> {
517
+ // Force-compress the latest turn as a last resort. Shares the forced
518
+ // compaction options, but runs after the middle tiers have been spent.
519
+ const compactionOptions: ContextWindowCompactOptions = {
520
+ force: true,
521
+ minKeepRecentUserTurns: 0,
522
+ };
523
+
524
+ const result = await defaultCompact({
525
+ conversationId: config.conversationId,
526
+ messages,
527
+ signal,
528
+ ...compactionOptions,
529
+ overrideProfile: config.overrideProfile ?? null,
530
+ actorTrustClass: config.actorTrustClass,
531
+ });
532
+ const nextMessages = result.compacted ? result.messages : messages;
533
+ const estimatedTokens = result.compacted
534
+ ? result.estimatedInputTokens
535
+ : estimatePromptTokens(nextMessages, config.systemPrompt, {
536
+ providerName: config.providerName,
537
+ toolTokenBudget: config.toolTokenBudget,
538
+ });
539
+
540
+ const nextApplied: ReducerTier[] = [...applied, "auto_compress_latest_turn"];
541
+ return {
542
+ messages: nextMessages,
543
+ tier: "auto_compress_latest_turn",
544
+ state: {
545
+ appliedTiers: nextApplied,
546
+ injectionMode: prevState?.injectionMode ?? "full",
547
+ toolResultMaxChars: prevState?.toolResultMaxChars,
548
+ compactionOptions,
549
+ exhausted: false,
343
550
  },
344
551
  estimatedTokens,
552
+ compactionResult: result,
345
553
  };
346
554
  }
347
555
 
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Corrected compaction target for reactive context-overflow recovery.
3
+ *
4
+ * When the provider rejects a request as context-too-large, the rejection
5
+ * reveals the *actual* token count it measured (e.g. "242201 tokens > 200000").
6
+ * The local estimator that gated the call may have significantly under-counted,
7
+ * so compacting to the nominal preflight budget would still overshoot the
8
+ * provider's real limit and re-reject. Scaling the preflight budget down by the
9
+ * observed estimator error yields a target that, once the estimator re-measures
10
+ * the reduced history, lands under the provider's true ceiling.
11
+ */
12
+
13
+ /** The compaction target plus the estimator-error context used to derive it. */
14
+ export interface CorrectedOverflowTarget {
15
+ /**
16
+ * Token budget the reducer should compact below. Equal to `preflightBudget`
17
+ * when the estimator did not under-count, and lower otherwise.
18
+ */
19
+ targetTokens: number;
20
+ /**
21
+ * The provider-actual / estimator ratio when the estimator under-counted
22
+ * (> 1), otherwise `null`. Exposed so callers can log the adjustment without
23
+ * recomputing it.
24
+ */
25
+ estimationErrorRatio: number | null;
26
+ }
27
+
28
+ /**
29
+ * Compute the compaction target for an overflow rejection, lowering the
30
+ * preflight budget in proportion to how badly the estimator under-counted.
31
+ *
32
+ * @param preflightBudget The nominal target the estimator gates against.
33
+ * @param actualTokens Provider-reported token count from the rejection, or
34
+ * `null` when it could not be parsed.
35
+ * @param estimatedTokens The estimator's count for the same history at overflow.
36
+ */
37
+ export function computeCorrectedOverflowTarget(params: {
38
+ preflightBudget: number;
39
+ actualTokens: number | null;
40
+ estimatedTokens: number;
41
+ }): CorrectedOverflowTarget {
42
+ const { preflightBudget, actualTokens, estimatedTokens } = params;
43
+ if (actualTokens != null && actualTokens > 0 && estimatedTokens > 0) {
44
+ const estimationErrorRatio = actualTokens / estimatedTokens;
45
+ if (estimationErrorRatio > 1.0) {
46
+ return {
47
+ targetTokens: Math.floor(preflightBudget / estimationErrorRatio),
48
+ estimationErrorRatio,
49
+ };
50
+ }
51
+ }
52
+ return { targetTokens: preflightBudget, estimationErrorRatio: null };
53
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Per-conversation {@link ContextWindowManager} ownership for the default
3
+ * compaction module.
4
+ *
5
+ * Construction of the manager lives here rather than in the conversation so the
6
+ * compaction surface owns the manager's lifetime: {@link createContextWindowManager}
7
+ * builds the instance and records it in a per-conversation store, and
8
+ * {@link disposeContextWindowManager} drops it when the conversation is torn
9
+ * down so the store doesn't grow unbounded.
10
+ *
11
+ * This module is side-effect free: importing it only initializes an empty
12
+ * store and registers no plugin.
13
+ */
14
+
15
+ import {
16
+ ContextWindowManager,
17
+ type ContextWindowManagerOptions,
18
+ } from "./window-manager.js";
19
+
20
+ /** Live managers keyed by conversation id. */
21
+ const managersByConversation = new Map<string, ContextWindowManager>();
22
+
23
+ /**
24
+ * Build the conversation's {@link ContextWindowManager} and register it under
25
+ * its conversation id. Construction is owned by the compaction module; the
26
+ * conversation supplies the provider, prompt/tool resolvers, and initial
27
+ * config. Replaces any prior manager for the same conversation so each
28
+ * construction yields a fresh instance, matching a direct `new` call.
29
+ */
30
+ export function createContextWindowManager(
31
+ options: ContextWindowManagerOptions & { conversationId: string },
32
+ ): ContextWindowManager {
33
+ const manager = new ContextWindowManager(options);
34
+ managersByConversation.set(options.conversationId, manager);
35
+ return manager;
36
+ }
37
+
38
+ /**
39
+ * Resolve the manager registered for a conversation, or `undefined` when none
40
+ * is registered (the conversation was never constructed or has been torn
41
+ * down). The store is the single owner of the instance; the conversation, its
42
+ * agent loop, and the compaction surface all read through this lookup rather
43
+ * than holding their own handle.
44
+ */
45
+ export function getContextWindowManager(
46
+ conversationId: string,
47
+ ): ContextWindowManager | undefined {
48
+ return managersByConversation.get(conversationId);
49
+ }
50
+
51
+ /**
52
+ * Release the manager registered for a conversation. Called from conversation
53
+ * teardown so the store releases the instance once the conversation is gone.
54
+ */
55
+ export function disposeContextWindowManager(conversationId: string): void {
56
+ managersByConversation.delete(conversationId);
57
+ }
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "default-compaction",
3
3
  "version": "1.0.0",
4
- "description": "First-party default plugin wrapping the assistant's built-in compaction pipeline with a passthrough implementation.",
4
+ "description": "First-party default plugin providing the assistant's built-in conversation-history compaction.",
5
5
  "private": true,
6
6
  "license": "MIT",
7
7
  "type": "module",
8
- "main": "./register.ts",
9
8
  "engines": {
10
9
  "node": ">=20.12.0"
11
10
  },