@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091853.fbaa2ae

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) 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 +263 -121
  12. package/package.json +2 -2
  13. package/src/__tests__/activation-early-marking.test.ts +120 -0
  14. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  15. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  16. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  17. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  18. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  19. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  20. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  21. package/src/__tests__/agent-loop.test.ts +441 -96
  22. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  23. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  24. package/src/__tests__/anthropic-provider.test.ts +23 -8
  25. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  26. package/src/__tests__/app-control-flow.test.ts +1 -1
  27. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  28. package/src/__tests__/app-executors.test.ts +132 -0
  29. package/src/__tests__/approval-cascade.test.ts +6 -5
  30. package/src/__tests__/approval-routes-http.test.ts +4 -1
  31. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  32. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  33. package/src/__tests__/channel-approvals.test.ts +1 -1
  34. package/src/__tests__/compaction-circuit.test.ts +258 -0
  35. package/src/__tests__/compaction-direct.test.ts +146 -0
  36. package/src/__tests__/compaction-events.test.ts +7 -7
  37. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  38. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  39. package/src/__tests__/context-overflow-reducer.test.ts +265 -125
  40. package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
  41. package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
  42. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  43. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  44. package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
  45. package/src/__tests__/conversation-agent-loop.test.ts +342 -623
  46. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  47. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
  48. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  49. package/src/__tests__/conversation-error.test.ts +15 -1
  50. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  51. package/src/__tests__/conversation-media-retry.test.ts +1 -1
  52. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
  53. package/src/__tests__/conversation-process-callsite.test.ts +15 -15
  54. package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
  55. package/src/__tests__/conversation-queue.test.ts +10 -10
  56. package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
  57. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  58. package/src/__tests__/conversation-slash-queue.test.ts +7 -5
  59. package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
  60. package/src/__tests__/conversation-speed-override.test.ts +11 -10
  61. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  62. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
  63. package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
  64. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
  65. package/src/__tests__/conversation-undo.test.ts +2 -2
  66. package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
  67. package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
  68. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
  69. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  70. package/src/__tests__/corrected-target.test.ts +93 -0
  71. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  72. package/src/__tests__/cu-unified-flow.test.ts +36 -0
  73. package/src/__tests__/db-acp-history.test.ts +101 -0
  74. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  75. package/src/__tests__/empty-response-hook.test.ts +1 -1
  76. package/src/__tests__/file-write-tool.test.ts +63 -0
  77. package/src/__tests__/gateway-only-guard.test.ts +17 -2
  78. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  79. package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
  80. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  81. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  82. package/src/__tests__/heartbeat-service.test.ts +1 -0
  83. package/src/__tests__/history-repair-hook.test.ts +5 -1
  84. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  85. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  86. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  87. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  88. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  89. package/src/__tests__/injector-background-turn.test.ts +13 -23
  90. package/src/__tests__/injector-chain.test.ts +268 -44
  91. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  92. package/src/__tests__/injector-document-comments.test.ts +97 -114
  93. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  94. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  95. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  96. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  97. package/src/__tests__/llm-resolver.test.ts +73 -0
  98. package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
  99. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  100. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  101. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  102. package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
  103. package/src/__tests__/persist-unsendable-image.test.ts +97 -1
  104. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  105. package/src/__tests__/plugin-bootstrap.test.ts +91 -81
  106. package/src/__tests__/plugin-registry.test.ts +3 -49
  107. package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
  108. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  109. package/src/__tests__/plugin-types.test.ts +0 -70
  110. package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
  111. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  112. package/src/__tests__/published-app-updater.test.ts +138 -0
  113. package/src/__tests__/reaction-persistence.test.ts +1 -1
  114. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  115. package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
  116. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  117. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  118. package/src/__tests__/subagent-detail.test.ts +25 -7
  119. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  120. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  121. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  122. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  123. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  124. package/src/__tests__/title-generate-hook.test.ts +5 -1
  125. package/src/__tests__/tool-error-hook.test.ts +1 -1
  126. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  127. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  128. package/src/__tests__/web-fetch.test.ts +45 -0
  129. package/src/acp/__tests__/agent-process.test.ts +161 -0
  130. package/src/acp/__tests__/client-handler.test.ts +40 -0
  131. package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
  132. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  133. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  134. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  135. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  136. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  137. package/src/acp/agent-process.ts +61 -1
  138. package/src/acp/auto-install.test.ts +280 -0
  139. package/src/acp/auto-install.ts +232 -0
  140. package/src/acp/client-handler.ts +31 -0
  141. package/src/acp/prepare-agent-env.ts +80 -27
  142. package/src/acp/resolve-agent.test.ts +188 -28
  143. package/src/acp/resolve-agent.ts +119 -42
  144. package/src/acp/resume-hint.ts +23 -0
  145. package/src/acp/session-manager.ts +507 -73
  146. package/src/agent/compaction-circuit.ts +60 -102
  147. package/src/agent/loop.ts +403 -251
  148. package/src/api/responses/conversation-message.ts +22 -2
  149. package/src/api/responses/memory-v3-selection-log.ts +19 -10
  150. package/src/approvals/guardian-request-resolvers.ts +27 -1
  151. package/src/background-wake/next-wake.ts +1 -0
  152. package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
  153. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  154. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  155. package/src/cli/commands/memory-v3.ts +57 -199
  156. package/src/cli/commands/plugins.ts +43 -37
  157. package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
  158. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  159. package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
  160. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
  161. package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
  162. package/src/cli/lib/install-from-github.ts +797 -60
  163. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  164. package/src/cli/lib/plugin-details.ts +416 -0
  165. package/src/cli/lib/plugin-marketplace.ts +215 -0
  166. package/src/cli/lib/search-plugins.ts +201 -29
  167. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  168. package/src/config/acp-defaults.test.ts +10 -0
  169. package/src/config/acp-defaults.ts +9 -3
  170. package/src/config/acp-schema.ts +1 -7
  171. package/src/config/bundled-skills/acp/SKILL.md +80 -41
  172. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  173. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  174. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  175. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  176. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  177. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  178. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  179. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  180. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  181. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  182. package/src/config/bundled-tool-registry.ts +4 -0
  183. package/src/config/call-site-defaults.ts +0 -3
  184. package/src/config/feature-flag-registry.json +10 -16
  185. package/src/config/llm-resolver.ts +39 -7
  186. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
  187. package/src/config/schemas/call-site-catalog.ts +0 -21
  188. package/src/config/schemas/heartbeat.ts +9 -0
  189. package/src/config/schemas/llm.ts +17 -3
  190. package/src/config/schemas/memory-v3.ts +58 -8
  191. package/src/config/seed-inference-profiles.ts +18 -0
  192. package/src/context/compactor.ts +22 -4
  193. package/src/context/post-turn-tool-result-truncation.ts +39 -1
  194. package/src/context/strip-injections.ts +8 -2
  195. package/src/daemon/conversation-agent-loop-handlers.ts +18 -36
  196. package/src/daemon/conversation-agent-loop.ts +308 -1297
  197. package/src/daemon/conversation-error.ts +31 -4
  198. package/src/daemon/conversation-history.ts +1 -1
  199. package/src/daemon/conversation-lifecycle.ts +11 -255
  200. package/src/daemon/conversation-media-retry.ts +19 -6
  201. package/src/daemon/conversation-messaging.ts +17 -0
  202. package/src/daemon/conversation-process.ts +22 -141
  203. package/src/daemon/conversation-queue-manager.ts +8 -0
  204. package/src/daemon/conversation-registry.ts +159 -0
  205. package/src/daemon/conversation-runtime-assembly.ts +361 -393
  206. package/src/daemon/conversation-store.ts +9 -90
  207. package/src/daemon/conversation-surfaces.ts +165 -11
  208. package/src/daemon/conversation-workspace.ts +17 -0
  209. package/src/daemon/conversation.ts +444 -62
  210. package/src/daemon/disk-pressure-policy.ts +0 -1
  211. package/src/daemon/external-plugins-bootstrap.ts +36 -46
  212. package/src/daemon/handlers/config-channels.ts +11 -2
  213. package/src/daemon/handlers/conversations.ts +3 -1
  214. package/src/daemon/handlers/skills.ts +4 -1
  215. package/src/daemon/host-app-control-proxy.ts +72 -57
  216. package/src/daemon/host-proxy-preactivation.ts +1 -3
  217. package/src/daemon/lifecycle.ts +21 -7
  218. package/src/daemon/persist-unsendable-image.ts +62 -25
  219. package/src/daemon/process-message.ts +1 -1
  220. package/src/daemon/server.ts +2 -0
  221. package/src/daemon/tool-side-effects.ts +15 -0
  222. package/src/daemon/wake-conversation-ops.ts +269 -0
  223. package/src/embedded/plugin-api.ts +2 -2
  224. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  225. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  226. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  227. package/src/heartbeat/heartbeat-service.ts +26 -0
  228. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  229. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  230. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  231. package/src/ipc/skill-routes/memory.ts +4 -2
  232. package/src/memory/__tests__/activation-session-store.test.ts +41 -0
  233. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  234. package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
  235. package/src/memory/activation-session-store.ts +43 -0
  236. package/src/memory/conversation-crud.ts +29 -19
  237. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  238. package/src/memory/db-init.ts +6 -0
  239. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  240. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  241. package/src/memory/jobs-worker.ts +25 -1
  242. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  243. package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
  244. package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
  245. package/src/memory/migrations/index.ts +3 -0
  246. package/src/memory/onboarding-events-store.ts +66 -18
  247. package/src/memory/schema/acp.ts +4 -0
  248. package/src/memory/schema/infrastructure.ts +13 -0
  249. package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
  250. package/src/memory/v2/__tests__/page-store.test.ts +22 -0
  251. package/src/memory/v2/consolidation-job.ts +2 -63
  252. package/src/memory/v2/types.ts +5 -0
  253. package/src/messaging/providers/telegram-bot/api.ts +14 -5
  254. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  255. package/src/notifications/access-request-copy.ts +298 -0
  256. package/src/notifications/adapters/slack.ts +3 -3
  257. package/src/notifications/adapters/telegram.ts +9 -2
  258. package/src/notifications/copy-composer.ts +49 -267
  259. package/src/notifications/decision-engine.ts +16 -35
  260. package/src/notifications/home-feed-side-effect.ts +1 -6
  261. package/src/plugin-api/constants.ts +4 -0
  262. package/src/plugin-api/index.ts +40 -11
  263. package/src/plugin-api/types.ts +108 -0
  264. package/src/plugins/defaults/compaction/compact.ts +106 -0
  265. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
  266. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  267. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  268. package/src/plugins/defaults/compaction/package.json +1 -2
  269. package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
  270. package/src/plugins/defaults/empty-response/package.json +0 -1
  271. package/src/plugins/defaults/history-repair/package.json +0 -1
  272. package/src/plugins/defaults/index.ts +156 -26
  273. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  274. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
  275. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  276. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  277. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  278. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  279. package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
  280. package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
  281. package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
  282. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
  283. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
  284. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
  285. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
  286. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
  287. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
  288. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
  289. package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
  290. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
  291. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
  292. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
  293. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
  294. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
  295. package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
  296. package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
  297. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  298. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  299. package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
  300. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
  301. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
  302. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  303. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
  304. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
  305. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
  306. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
  307. package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
  308. package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
  309. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
  310. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
  311. package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
  312. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
  313. package/src/plugins/defaults/title-generate/package.json +0 -1
  314. package/src/plugins/defaults/tool-error/package.json +0 -1
  315. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  316. package/src/plugins/external-api.ts +12 -2
  317. package/src/plugins/pipeline.ts +6 -293
  318. package/src/plugins/registry.ts +9 -37
  319. package/src/plugins/types.ts +76 -381
  320. package/src/plugins/user-loader.ts +30 -127
  321. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  322. package/src/prompts/system-prompt.ts +61 -10
  323. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
  324. package/src/providers/anthropic/client.ts +9 -10
  325. package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
  326. package/src/providers/inference/logit-bias.ts +55 -0
  327. package/src/providers/model-catalog.ts +34 -0
  328. package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
  329. package/src/providers/openai/chat-completions-provider.ts +44 -1
  330. package/src/providers/retry.ts +22 -0
  331. package/src/providers/types.ts +6 -0
  332. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  333. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  334. package/src/runtime/agent-wake.ts +108 -209
  335. package/src/runtime/assistant-event-hub.ts +1 -1
  336. package/src/runtime/channel-approvals.ts +1 -1
  337. package/src/runtime/interactive-ui.ts +1 -1
  338. package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
  339. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  340. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  341. package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
  342. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  343. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  344. package/src/runtime/routes/acp-routes.test.ts +185 -32
  345. package/src/runtime/routes/acp-routes.ts +328 -30
  346. package/src/runtime/routes/app-management-routes.ts +3 -0
  347. package/src/runtime/routes/approval-routes.ts +1 -1
  348. package/src/runtime/routes/browser-routes.ts +1 -1
  349. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  350. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  351. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  352. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  353. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  354. package/src/runtime/routes/conversation-routes.ts +30 -2
  355. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  356. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  357. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  358. package/src/runtime/routes/host-cu-routes.ts +1 -1
  359. package/src/runtime/routes/identity-routes.ts +18 -3
  360. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  361. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  362. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  363. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  364. package/src/runtime/routes/memory-v3-routes.ts +65 -305
  365. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
  366. package/src/runtime/routes/playground/helpers.ts +1 -1
  367. package/src/runtime/routes/plugins-routes.ts +337 -35
  368. package/src/runtime/routes/stt-routes.ts +45 -12
  369. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  370. package/src/runtime/routes/work-items-routes.ts +2 -4
  371. package/src/runtime/routes/workspace-routes.ts +50 -15
  372. package/src/runtime/services/conversation-serializer.ts +1 -1
  373. package/src/runtime/verification-outbound-actions.ts +147 -2
  374. package/src/runtime/verification-templates.ts +29 -3
  375. package/src/services/published-app-updater.ts +30 -8
  376. package/src/signals/cancel.ts +2 -4
  377. package/src/subagent/manager.ts +21 -5
  378. package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
  379. package/src/telemetry/activation-funnel.ts +167 -0
  380. package/src/telemetry/types.ts +13 -0
  381. package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
  382. package/src/telemetry/usage-telemetry-reporter.ts +26 -1
  383. package/src/tools/acp/context.ts +20 -0
  384. package/src/tools/acp/list-agents.test.ts +9 -19
  385. package/src/tools/acp/list-agents.ts +3 -15
  386. package/src/tools/acp/spawn.test.ts +173 -202
  387. package/src/tools/acp/spawn.ts +37 -172
  388. package/src/tools/acp/steer.test.ts +105 -8
  389. package/src/tools/acp/steer.ts +48 -17
  390. package/src/tools/apps/executors.ts +166 -50
  391. package/src/tools/browser/browser-execution.ts +12 -2
  392. package/src/tools/filesystem/write.ts +34 -0
  393. package/src/tools/network/web-fetch.ts +65 -24
  394. package/src/tools/skills/load.ts +1 -1
  395. package/src/tools/subagent/spawn.ts +2 -4
  396. package/src/tools/ui-surface/definitions.ts +32 -5
  397. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  398. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  399. package/docs/plugins.md +0 -832
  400. package/examples/plugins/echo/register.ts +0 -143
  401. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  402. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  403. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  404. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  405. package/src/__tests__/pipeline-runner.test.ts +0 -554
  406. package/src/daemon/wake-target-adapter.ts +0 -253
  407. package/src/memory/v3/__tests__/assign.test.ts +0 -242
  408. package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
  409. package/src/memory/v3/__tests__/core.test.ts +0 -39
  410. package/src/memory/v3/__tests__/health.test.ts +0 -219
  411. package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
  412. package/src/memory/v3/__tests__/needle.test.ts +0 -107
  413. package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
  414. package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
  415. package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
  416. package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
  417. package/src/memory/v3/__tests__/router.test.ts +0 -332
  418. package/src/memory/v3/__tests__/selector.test.ts +0 -470
  419. package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
  420. package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
  421. package/src/memory/v3/__tests__/tree.test.ts +0 -192
  422. package/src/memory/v3/assign.ts +0 -268
  423. package/src/memory/v3/capabilities.ts +0 -124
  424. package/src/memory/v3/core.ts +0 -26
  425. package/src/memory/v3/health.ts +0 -0
  426. package/src/memory/v3/maintain-job.ts +0 -314
  427. package/src/memory/v3/needle.ts +0 -115
  428. package/src/memory/v3/orchestrate.ts +0 -126
  429. package/src/memory/v3/page-content.ts +0 -34
  430. package/src/memory/v3/provider-blocks.ts +0 -26
  431. package/src/memory/v3/reconcile.ts +0 -523
  432. package/src/memory/v3/router.ts +0 -190
  433. package/src/memory/v3/selection-log-store.ts +0 -84
  434. package/src/memory/v3/selector.ts +0 -226
  435. package/src/memory/v3/shadow-plugin.ts +0 -411
  436. package/src/memory/v3/snapshot.ts +0 -209
  437. package/src/memory/v3/tree.ts +0 -174
  438. package/src/memory/v3/types.ts +0 -59
  439. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  440. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  441. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  442. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  443. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  444. package/src/plugins/defaults/compaction/register.ts +0 -35
  445. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  446. package/src/plugins/defaults/empty-response/register.ts +0 -23
  447. package/src/plugins/defaults/history-repair/register.ts +0 -24
  448. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
  449. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  450. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  451. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  452. package/src/plugins/defaults/title-generate/register.ts +0 -35
  453. package/src/plugins/defaults/tool-error/register.ts +0 -23
  454. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  455. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  456. package/src/proactive-artifact/decision.test.ts +0 -226
  457. package/src/proactive-artifact/decision.ts +0 -165
  458. package/src/proactive-artifact/index.ts +0 -7
  459. package/src/proactive-artifact/job.test.ts +0 -962
  460. package/src/proactive-artifact/job.ts +0 -372
  461. package/src/proactive-artifact/message-copy.ts +0 -58
  462. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  463. package/src/proactive-artifact/trigger-state.ts +0 -123
  464. package/src/util/map-limit.ts +0 -27
  465. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  466. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  467. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  468. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  469. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  470. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  471. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  472. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  473. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  474. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  475. /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
  },