@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
@@ -12,14 +12,12 @@ import {
12
12
  createUserMessage,
13
13
  } from "../agent/message-types.js";
14
14
  import {
15
- type InterfaceId,
16
15
  parseChannelId,
17
16
  parseInterfaceId,
18
17
  type TurnChannelContext,
19
18
  type TurnInterfaceContext,
20
19
  } from "../channels/types.js";
21
20
  import type { LLMCallSite } from "../config/schemas/llm.js";
22
- import type { ContextWindowResult } from "../context/window-manager.js";
23
21
  import { listPendingRequestsByConversationScope } from "../memory/canonical-guardian-store.js";
24
22
  import {
25
23
  addMessage,
@@ -29,22 +27,19 @@ import {
29
27
  } from "../memory/conversation-crud.js";
30
28
  import { extractPreferences } from "../notifications/preference-extractor.js";
31
29
  import { createPreference } from "../notifications/preferences-store.js";
32
- import type { Message } from "../providers/types.js";
30
+ import type { ContextWindowResult } from "../plugins/defaults/compaction/window-manager.js";
33
31
  import { routeGuardianReply } from "../runtime/guardian-reply-router.js";
34
32
  import { publishConversationMessagesChanged } from "../runtime/sync/resource-sync-events.js";
35
33
  import { getLogger } from "../util/logger.js";
36
- import type { CleanResult } from "./conversation.js";
37
- import type { PersistMessageOptions } from "./conversation-messaging.js";
34
+ import type { CleanResult, Conversation } from "./conversation.js";
38
35
  import {
39
36
  persistQueuedMessageBody,
40
37
  serializePersistedUserMessageContent,
41
38
  } from "./conversation-messaging.js";
42
39
  import type {
43
- MessageQueue,
44
40
  QueuedMessage,
45
41
  QueueDrainReason,
46
42
  } from "./conversation-queue-manager.js";
47
- import type { ChannelCapabilities } from "./conversation-runtime-assembly.js";
48
43
  import {
49
44
  buildSlashContextForContent,
50
45
  classifySlash,
@@ -55,13 +50,9 @@ import { getModelInfo } from "./handlers/config-model.js";
55
50
  import { preactivateHostProxySkills } from "./host-proxy-preactivation.js";
56
51
  import type {
57
52
  ServerMessage,
58
- UsageStats,
59
53
  UserMessageAttachment,
60
54
  } from "./message-protocol.js";
61
- import type { ConversationTransportMetadata } from "./message-types/conversations.js";
62
- import type { TraceEmitter } from "./trace-emitter.js";
63
55
  import { buildTransportHints } from "./transport-hints.js";
64
- import type { TrustContext } from "./trust-context.js";
65
56
  import { resolveVerificationSessionIntent } from "./verification-session-intent.js";
66
57
 
67
58
  const log = getLogger("conversation-process");
@@ -117,123 +108,6 @@ export function isModelSlashCommand(content: string): boolean {
117
108
  return content.trim() === "/models";
118
109
  }
119
110
 
120
- // ── Context Interface ────────────────────────────────────────────────
121
-
122
- /**
123
- * Subset of Conversation state that drainQueue / processMessage need access to.
124
- * The Conversation class implements this interface so its instances can be
125
- * passed directly to the extracted functions.
126
- */
127
- export interface ProcessConversationContext {
128
- readonly conversationId: string;
129
- messages: Message[];
130
- isProcessing(): boolean;
131
- setProcessing(value: boolean): void;
132
- abortController: AbortController | null;
133
- currentRequestId?: string;
134
- readonly queue: MessageQueue;
135
- readonly traceEmitter: TraceEmitter;
136
- /**
137
- * Set of requestIds created by surface-action responses. Used to
138
- * distinguish surface-action turns from regular user turns (e.g. for
139
- * stale-surface auto-dismiss guards and batched-drain exclusion).
140
- */
141
- readonly surfaceActionRequestIds: Set<string>;
142
- currentActiveSurfaceId?: string;
143
- currentPage?: string;
144
- /** When true, the drain path should inject synthetic tool_result messages
145
- * for any pending tool_use blocks abandoned by a steered abort. */
146
- pendingSteerRepair?: boolean;
147
- /** Cumulative token usage stats for the conversation. */
148
- readonly usageStats: UsageStats;
149
- /** Request-scoped skill IDs preactivated via config or programmatic injection. */
150
- preactivatedSkillIds?: string[];
151
- /** Add a skill ID to the preactivated set without replacing existing entries. */
152
- addPreactivatedSkillId(id: string): void;
153
- /** Assistant identity — used for scoping notification preferences. */
154
- readonly assistantId?: string;
155
- trustContext?: TrustContext;
156
- channelCapabilities?: ChannelCapabilities;
157
- /** Per-turn snapshot of trustContext, frozen at message-processing start. */
158
- currentTurnTrustContext?: TrustContext;
159
- /** Per-turn snapshot of channelCapabilities, frozen at message-processing start. */
160
- currentTurnChannelCapabilities?: ChannelCapabilities;
161
- ensureActorScopedHistory(): Promise<void>;
162
- persistUserMessage(
163
- options: PersistMessageOptions,
164
- ): Promise<{ id: string; deduplicated: boolean }>;
165
- runAgentLoop(
166
- content: string,
167
- userMessageId: string,
168
- options?: {
169
- onEvent?: (msg: ServerMessage) => void;
170
- isInteractive?: boolean;
171
- isUserMessage?: boolean;
172
- titleText?: string;
173
- callSite?: LLMCallSite;
174
- },
175
- ): Promise<void>;
176
- getTurnChannelContext(): TurnChannelContext | null;
177
- setTurnChannelContext(ctx: TurnChannelContext): void;
178
- getTurnInterfaceContext(): TurnInterfaceContext | null;
179
- setTurnInterfaceContext(ctx: TurnInterfaceContext): void;
180
- emitActivityState(
181
- phase:
182
- | "idle"
183
- | "thinking"
184
- | "streaming"
185
- | "tool_running"
186
- | "awaiting_confirmation",
187
- reason:
188
- | "message_dequeued"
189
- | "thinking_delta"
190
- | "first_text_delta"
191
- | "tool_use_start"
192
- | "tool_result_received"
193
- | "confirmation_requested"
194
- | "confirmation_resolved"
195
- | "message_complete"
196
- | "generation_cancelled"
197
- | "error_terminal"
198
- | "preview_start"
199
- | "context_compacting",
200
- options?: {
201
- anchor?: "assistant_turn" | "user_turn" | "global";
202
- requestId?: string;
203
- statusText?: string;
204
- },
205
- ): void;
206
- /** Force context compaction regardless of threshold/cooldown. */
207
- forceCompact(): Promise<ContextWindowResult>;
208
- /** Strip runtime injections and reset memory-injection state. */
209
- forceClean(): Promise<CleanResult>;
210
- /** Set transport-derived hints for the conversation. */
211
- setTransportHints(hints: string[] | undefined): void;
212
- /** IANA timezone reported by the active client for the current turn. */
213
- clientTimezone?: string;
214
- /**
215
- * Apply client-reported host env (home dir, username) from transport
216
- * metadata, gating on `supportsHostProxy` so non-host-proxy interfaces
217
- * clear any stale values. Shared between the create/reuse path in
218
- * `DaemonServer.applyTransportMetadata` and the queue-drain path below.
219
- */
220
- applyHostEnvFromTransport(transport: ConversationTransportMetadata): void;
221
- /** Apply the per-turn client timezone reported by transport metadata. */
222
- applyClientTimezoneFromTransport(
223
- transport: ConversationTransportMetadata,
224
- ): void;
225
- /**
226
- * Instantiate host proxies for capabilities that have become reachable
227
- * mid-queue (e.g. a macOS client connected after a web turn was enqueued
228
- * without a proxy). Called from drain paths before preactivation so skills
229
- * are only activated when the proxy that services them is present.
230
- */
231
- ensureHostProxiesForTurn(
232
- sourceInterface: InterfaceId | undefined,
233
- sourceActorPrincipalId?: string,
234
- ): void;
235
- }
236
-
237
111
  function resolveQueuedTurnContext(
238
112
  queued: {
239
113
  turnChannelContext?: TurnChannelContext;
@@ -281,7 +155,7 @@ function resolveQueuedTurnInterfaceContext(
281
155
  /** Build a SlashContext from the current conversation state and config. */
282
156
  function buildSlashContext(
283
157
  content: string,
284
- conversation: ProcessConversationContext,
158
+ conversation: Conversation,
285
159
  ): SlashContext | undefined {
286
160
  const turnInterface = conversation.getTurnInterfaceContext();
287
161
  return buildSlashContextForContent(content, {
@@ -306,7 +180,7 @@ function buildSlashContext(
306
180
  * accounting centralized in `MessageQueue` rather than mutating mid-walk.
307
181
  */
308
182
  async function buildPassthroughBatch(
309
- conversation: ProcessConversationContext,
183
+ conversation: Conversation,
310
184
  ): Promise<QueuedMessage[]> {
311
185
  const head = conversation.queue.peek(0);
312
186
  if (head === undefined) return [];
@@ -348,6 +222,8 @@ async function buildPassthroughBatch(
348
222
  // otherwise diverge.
349
223
  if (candIf?.userMessageInterface !== headInterface?.userMessageInterface)
350
224
  break;
225
+ if (candidate.sourceActorPrincipalId !== head.sourceActorPrincipalId)
226
+ break;
351
227
  if (classifySlash(candidate.content) !== "passthrough") break;
352
228
  if (
353
229
  resolveVerificationSessionIntent(candidate.content).kind ===
@@ -379,9 +255,7 @@ async function buildPassthroughBatch(
379
255
  * history and injects synthetic error `tool_result` messages for any
380
256
  * unmatched `tool_use` blocks.
381
257
  */
382
- function repairPendingToolUseBlocks(
383
- conversation: ProcessConversationContext,
384
- ): void {
258
+ function repairPendingToolUseBlocks(conversation: Conversation): void {
385
259
  if (!conversation.pendingSteerRepair) return;
386
260
  conversation.pendingSteerRepair = false;
387
261
 
@@ -452,7 +326,7 @@ function repairPendingToolUseBlocks(
452
326
  * remaining queued messages would be stranded.
453
327
  */
454
328
  export async function drainQueue(
455
- conversation: ProcessConversationContext,
329
+ conversation: Conversation,
456
330
  reason: QueueDrainReason = "loop_complete",
457
331
  ): Promise<void> {
458
332
  // After a steer, drain only the promoted head message — don't batch
@@ -485,7 +359,7 @@ export async function drainQueue(
485
359
  }
486
360
 
487
361
  async function drainSingleMessage(
488
- conversation: ProcessConversationContext,
362
+ conversation: Conversation,
489
363
  next: QueuedMessage,
490
364
  reason: QueueDrainReason,
491
365
  ): Promise<void> {
@@ -550,6 +424,9 @@ async function drainSingleMessage(
550
424
  conversation.applyClientTimezoneFromTransport(next.transport);
551
425
  }
552
426
 
427
+ conversation.currentTurnAuthContext = next.authContext;
428
+ conversation.currentTurnSourceActorPrincipalId = next.sourceActorPrincipalId;
429
+
553
430
  // Re-attach and re-preactivate host-proxy skills for interactive turns.
554
431
  // The dequeue path reset `preactivatedSkillIds` above; without these
555
432
  // re-adds the relevant skill tools won't be projected to the LLM for
@@ -561,8 +438,7 @@ async function drainSingleMessage(
561
438
  const interfaceCtx =
562
439
  queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
563
440
  const sourceInterface = interfaceCtx?.userMessageInterface;
564
- const sourceActorPrincipalId =
565
- conversation.trustContext?.guardianPrincipalId;
441
+ const sourceActorPrincipalId = next.sourceActorPrincipalId;
566
442
  conversation.ensureHostProxiesForTurn(
567
443
  sourceInterface,
568
444
  sourceActorPrincipalId,
@@ -1059,7 +935,7 @@ async function drainSingleMessage(
1059
935
  // runAgentLoop run. Per-message dequeue events and DB persistence are
1060
936
  // preserved; the agent reply fans out to every batched client.
1061
937
  async function drainBatch(
1062
- conversation: ProcessConversationContext,
938
+ conversation: Conversation,
1063
939
  batch: QueuedMessage[],
1064
940
  reason: QueueDrainReason,
1065
941
  ): Promise<void> {
@@ -1107,14 +983,16 @@ async function drainBatch(
1107
983
  conversation.applyClientTimezoneFromTransport(head.transport);
1108
984
  }
1109
985
 
986
+ conversation.currentTurnAuthContext = head.authContext;
987
+ conversation.currentTurnSourceActorPrincipalId = head.sourceActorPrincipalId;
988
+
1110
989
  // Re-attach and re-preactivate host-proxy skills for interactive turns.
1111
990
  // Mirrors the single-message path exactly — sourced from `head`.
1112
991
  if (head.isInteractive !== false) {
1113
992
  const interfaceCtx =
1114
993
  queuedInterfaceCtx ?? conversation.getTurnInterfaceContext();
1115
994
  const sourceInterface = interfaceCtx?.userMessageInterface;
1116
- const sourceActorPrincipalId =
1117
- conversation.trustContext?.guardianPrincipalId;
995
+ const sourceActorPrincipalId = head.sourceActorPrincipalId;
1118
996
  conversation.ensureHostProxiesForTurn(
1119
997
  sourceInterface,
1120
998
  sourceActorPrincipalId,
@@ -1490,7 +1368,7 @@ export interface ProcessMessageOptions {
1490
1368
  * in a single call. Used by the message-handler path where blocking is expected.
1491
1369
  */
1492
1370
  export async function processMessage(
1493
- conversation: ProcessConversationContext,
1371
+ conversation: Conversation,
1494
1372
  options: ProcessMessageOptions,
1495
1373
  ): Promise<string> {
1496
1374
  const {
@@ -1508,6 +1386,9 @@ export async function processMessage(
1508
1386
  // Snapshot persona context at turn start so later tool turns can't pick up
1509
1387
  // a different actor's context if a concurrent request mutates the live fields.
1510
1388
  conversation.currentTurnTrustContext = conversation.trustContext;
1389
+ conversation.currentTurnAuthContext = conversation.authContext;
1390
+ conversation.currentTurnSourceActorPrincipalId =
1391
+ conversation.authContext?.actorPrincipalId;
1511
1392
  conversation.currentTurnChannelCapabilities =
1512
1393
  conversation.channelCapabilities;
1513
1394
  conversation.currentActiveSurfaceId = activeSurfaceId;
@@ -9,6 +9,7 @@ import type {
9
9
  TurnChannelContext,
10
10
  TurnInterfaceContext,
11
11
  } from "../channels/types.js";
12
+ import type { AuthContext } from "../runtime/auth/types.js";
12
13
  import { getLogger } from "../util/logger.js";
13
14
  import type {
14
15
  ServerMessage,
@@ -30,6 +31,10 @@ export interface QueuedMessage {
30
31
  turnInterfaceContext?: TurnInterfaceContext;
31
32
  /** When false, the turn has no interactive user and should skip clarification prompts. */
32
33
  isInteractive?: boolean;
34
+ /** Requester identity captured from the verified auth context at enqueue time. */
35
+ sourceActorPrincipalId?: string;
36
+ /** Full auth snapshot captured at enqueue time for turn-scoped authorization decisions. */
37
+ authContext?: AuthContext;
33
38
  /** Transport metadata snapshot captured at enqueue time, applied when this message becomes active. */
34
39
  transport?: ConversationTransportMetadata;
35
40
  /** Original user message text to persist to DB when recording intent stripping produced a different `content`. */
@@ -204,6 +209,9 @@ function estimateItemBytes(item: QueuedMessage): number {
204
209
  if (item.transport) {
205
210
  bytes += JSON.stringify(item.transport).length * 2;
206
211
  }
212
+ if (item.sourceActorPrincipalId) {
213
+ bytes += item.sourceActorPrincipalId.length * 2;
214
+ }
207
215
  // Small fixed overhead for metadata, pointers, etc. (not worth
208
216
  // measuring precisely — the content/attachment data dominates).
209
217
  bytes += 512;
@@ -0,0 +1,159 @@
1
+ /**
2
+ * In-memory registry of active {@link Conversation} instances, keyed by
3
+ * conversation ID, plus the read/write accessors over it.
4
+ *
5
+ * This is a leaf module: it imports `Conversation` as a type only, so any
6
+ * layer — including the memory-retrieval plugin's injectors, which only know a
7
+ * conversation id — can look up the live conversation and read its state
8
+ * without pulling in the daemon-core creation graph (providers, system-prompt
9
+ * assembly, the `Conversation` class value) that `getOrCreateConversation` in
10
+ * `conversation-store` depends on. Keeping the registry free of those value
11
+ * imports is what lets the injector chain consume it without forming an import
12
+ * cycle (`injectors → store → conversation → agent-loop → runtime-assembly →
13
+ * injector-chain → injectors`).
14
+ *
15
+ * `conversation-store` owns the creation/reuse lifecycle and writes top-level
16
+ * conversations into this map via {@link setConversation}.
17
+ */
18
+
19
+ import type { Conversation } from "./conversation.js";
20
+
21
+ const conversations = new Map<string, Conversation>();
22
+
23
+ // ── Read helpers ───────────────────────────────────────────────────
24
+
25
+ export function findConversation(
26
+ conversationId: string | undefined,
27
+ ): Conversation | undefined {
28
+ if (!conversationId) return undefined;
29
+ return conversations.get(conversationId);
30
+ }
31
+
32
+ export function findConversationBySurfaceId(
33
+ surfaceId: string,
34
+ ): Conversation | undefined {
35
+ // Fast path: exact surfaceId match in surfaceState
36
+ for (const c of conversations.values()) {
37
+ if (c.surfaceState.has(surfaceId)) return c;
38
+ }
39
+
40
+ // Fallback: standalone app surfaces use "app-open-{appId}" IDs that
41
+ // were never part of any conversation. Extract the appId and find
42
+ // a conversation whose surfaceState has a surface for that app.
43
+ const appOpenPrefix = "app-open-";
44
+ if (surfaceId.startsWith(appOpenPrefix)) {
45
+ const appId = surfaceId.slice(appOpenPrefix.length);
46
+ for (const c of conversations.values()) {
47
+ for (const [, state] of c.surfaceState.entries()) {
48
+ const data = state.data as unknown as Record<string, unknown>;
49
+ if (data?.appId === appId) {
50
+ // Register this surfaceId so subsequent lookups are O(1)
51
+ c.surfaceState.set(surfaceId, state);
52
+ return c;
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ return undefined;
59
+ }
60
+
61
+ export function conversationCount(): number {
62
+ return conversations.size;
63
+ }
64
+
65
+ /** Iterate over all active conversations. */
66
+ export function allConversations(): IterableIterator<Conversation> {
67
+ return conversations.values();
68
+ }
69
+
70
+ /** Iterate over all [id, conversation] entries. */
71
+ export function conversationEntries(): IterableIterator<
72
+ [string, Conversation]
73
+ > {
74
+ return conversations.entries();
75
+ }
76
+
77
+ /** Iterate over all active conversation IDs. */
78
+ export function conversationIds(): IterableIterator<string> {
79
+ return conversations.keys();
80
+ }
81
+
82
+ // ── Write helpers ──────────────────────────────────────────────────
83
+
84
+ export function setConversation(
85
+ conversationId: string,
86
+ conversation: Conversation,
87
+ ): void {
88
+ conversations.set(conversationId, conversation);
89
+ }
90
+
91
+ export function deleteConversation(conversationId: string): boolean {
92
+ return conversations.delete(conversationId);
93
+ }
94
+
95
+ export function clearConversations(): void {
96
+ conversations.clear();
97
+ }
98
+
99
+ // ── Underlying Map (for the evictor, which takes a mutable ref) ───
100
+
101
+ /**
102
+ * Expose the raw Map for the {@link ConversationEvictor}, which needs
103
+ * a mutable reference to delete entries during sweeps. No other code
104
+ * should use this — prefer the named helpers above.
105
+ */
106
+ export function getConversationMap(): Map<string, Conversation> {
107
+ return conversations;
108
+ }
109
+
110
+ // ── Subagent live-conversation index ───────────────────────────────
111
+ //
112
+ // Subagents run their own agent loop — and therefore the injector chain — but
113
+ // are owned by the `SubagentManager` rather than the daemon's eviction-managed
114
+ // store, so they are deliberately absent from `conversations` above. This
115
+ // point-lookup index lets the per-conversation injectors (workspace context,
116
+ // disk-pressure warning) resolve a subagent's live `Conversation` by id and
117
+ // read state off it. It is intentionally excluded from the iteration accessors
118
+ // and the evictor map so subagent lifecycle stays solely with the manager.
119
+
120
+ const subagentConversations = new Map<string, Conversation>();
121
+
122
+ /** Register a subagent's live conversation for point lookups. */
123
+ export function setSubagentConversation(
124
+ conversationId: string,
125
+ conversation: Conversation,
126
+ ): void {
127
+ subagentConversations.set(conversationId, conversation);
128
+ }
129
+
130
+ /**
131
+ * Remove a subagent's conversation from the index. Guards against clobbering a
132
+ * newer registration for the same id by only deleting when the stored entry
133
+ * still points at this instance.
134
+ */
135
+ export function removeSubagentConversation(
136
+ conversationId: string,
137
+ conversation: Conversation,
138
+ ): void {
139
+ if (subagentConversations.get(conversationId) === conversation) {
140
+ subagentConversations.delete(conversationId);
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Resolve a live `Conversation` by id, including subagent conversations.
146
+ * Top-level conversations are checked first, then subagents. Used by the
147
+ * per-conversation injectors, which run for subagent turns too; other callers
148
+ * should use {@link findConversation}, which is scoped to the eviction-managed
149
+ * top-level conversations.
150
+ */
151
+ export function findConversationOrSubagent(
152
+ conversationId: string | undefined,
153
+ ): Conversation | undefined {
154
+ if (!conversationId) return undefined;
155
+ return (
156
+ conversations.get(conversationId) ??
157
+ subagentConversations.get(conversationId)
158
+ );
159
+ }