@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
@@ -680,7 +680,14 @@ export function handleListMessages({
680
680
  // assistant message has tool_use blocks but its matching user tool_result
681
681
  // is left visible, the result will render as a standalone orphan because
682
682
  // `mergeToolResultsIntoAssistantMessages` has nothing to merge it into.
683
- const visibleFilter = (m: MessageRow) => !isHiddenMessage(m.metadata);
683
+ //
684
+ // Only renderable roles reach this UI-facing transcript. `system` rows (a
685
+ // permitted `MessageRole`, e.g. skill-authored context) are agent-context
686
+ // scaffolding, never a displayed turn, so they are dropped here at the
687
+ // source rather than narrowed away per-client.
688
+ const visibleFilter = (m: MessageRow) =>
689
+ !isHiddenMessage(m.metadata) &&
690
+ (m.role === "user" || m.role === "assistant");
684
691
 
685
692
  if (isPaginated) {
686
693
  const result = getMessagesPaginated(
@@ -772,14 +779,21 @@ export function handleListMessages({
772
779
  },
773
780
  );
774
781
 
782
+ // `visibleFilter` has already dropped every non-renderable role, so the
783
+ // only values reaching here are `user` and `assistant`; narrow the raw DB
784
+ // `string` to the wire union.
785
+ const role: "user" | "assistant" =
786
+ msg.role === "assistant" ? "assistant" : "user";
787
+
775
788
  return {
776
789
  id: msg.id,
777
- role: msg.role,
790
+ role,
778
791
  content,
779
792
  createdAt: msg.createdAt,
780
793
  sentAt,
781
794
  subagentNotification,
782
795
  slackMessage,
796
+ clientMessageId: msg.clientMessageId ?? undefined,
783
797
  };
784
798
  });
785
799
 
@@ -916,6 +930,7 @@ export function handleListMessages({
916
930
  return {
917
931
  id: m.id ?? "",
918
932
  ...(mergedMessageIds.length > 0 ? { mergedMessageIds } : {}),
933
+ ...(m.clientMessageId ? { clientMessageId: m.clientMessageId } : {}),
919
934
  role: m.role,
920
935
  // Flat plain-text body the legacy Swift client reads directly; see the
921
936
  // `content` field on ConversationMessageSchema for why this must stay.
@@ -1354,6 +1369,11 @@ export async function handleSendMessage(
1354
1369
  mapping.conversationId,
1355
1370
  requestedInferenceProfile,
1356
1371
  );
1372
+ conversation.applyInferenceProfileState({
1373
+ profile: requestedInferenceProfile,
1374
+ sessionId: null,
1375
+ expiresAt: null,
1376
+ });
1357
1377
  }
1358
1378
 
1359
1379
  // Store pre-chat onboarding context on the conversation when this is the
@@ -1721,6 +1741,7 @@ export async function handleSendMessage(
1721
1741
  ...(body.automated === true ? { automated: true } : {}),
1722
1742
  },
1723
1743
  isInteractive,
1744
+ sourceActorPrincipalId,
1724
1745
  transport,
1725
1746
  clientMessageId,
1726
1747
  });
@@ -1822,6 +1843,7 @@ export async function handleSendMessage(
1822
1843
  userMessageInterface: sourceInterface,
1823
1844
  assistantMessageInterface: sourceInterface,
1824
1845
  });
1846
+ conversation.currentTurnSourceActorPrincipalId = sourceActorPrincipalId;
1825
1847
 
1826
1848
  await conversation.ensureActorScopedHistory();
1827
1849
 
@@ -2657,6 +2679,12 @@ export const ROUTES: RouteDefinition[] = [
2657
2679
  conversationType: z.string().optional(),
2658
2680
  slashCommand: z.string().optional(),
2659
2681
  clientTimezone: z.string().optional(),
2682
+ clientMessageId: z
2683
+ .string()
2684
+ .describe(
2685
+ "Client-generated idempotency nonce. Persisted on the row and echoed back on the message_echo event and the messages snapshot so the client can correlate its optimistic row by identity. Duplicate sends for the same (conversation, clientMessageId) are deduplicated server-side.",
2686
+ )
2687
+ .optional(),
2660
2688
  inferenceProfile: z.string().nullable().optional(),
2661
2689
  riskThreshold: z.enum(VALID_RISK_THRESHOLDS).optional(),
2662
2690
  onboarding: z
@@ -11,6 +11,7 @@ import { z } from "zod";
11
11
  import {
12
12
  checkpointKey,
13
13
  CK_ITEM_COUNT,
14
+ CK_LAST_ATTEMPT_AT,
14
15
  CK_LAST_GEN_AT,
15
16
  countActiveMemoryNodes,
16
17
  getCheckpointValue,
@@ -42,10 +43,11 @@ const starterItemSchema = z.object({
42
43
 
43
44
  type StarterItem = z.infer<typeof starterItemSchema>;
44
45
 
45
- export const CONVERSATION_STARTERS_STALE_TTL_MS = 24 * 60 * 60 * 1000;
46
+ export const CONVERSATION_STARTERS_STALE_TTL_MS = 4 * 60 * 60 * 1000;
46
47
 
47
- /** Minimum interval between re-enqueue attempts triggered by invalid items. */
48
- const REFRESH_COOLDOWN_MS = 60_000;
48
+ /** Minimum interval between re-enqueue attempts (prevents tight retry loops
49
+ * when generation repeatedly fails or produces 0 valid starters). */
50
+ const REFRESH_COOLDOWN_MS = 5 * 60 * 1000;
49
51
 
50
52
  function hasActiveConversationStarterJob(
51
53
  db: ReturnType<typeof getDb>,
@@ -199,12 +201,16 @@ function handleListConversationStarters({
199
201
  Date.now() - lastGenAt >= CONVERSATION_STARTERS_STALE_TTL_MS;
200
202
  const checkpointAhead = lastCount != null && totalActive < lastCount;
201
203
  let hasActiveJob = hasActiveConversationStarterJob(db, scopeId);
204
+ const lastAttemptAt = parseCheckpointInt(
205
+ getCheckpointValue(checkpointKey(CK_LAST_ATTEMPT_AT, scopeId)),
206
+ );
202
207
  const withinCooldown =
203
- lastGenAt != null && Date.now() - lastGenAt < REFRESH_COOLDOWN_MS;
208
+ lastAttemptAt != null && Date.now() - lastAttemptAt < REFRESH_COOLDOWN_MS;
204
209
  const shouldRefresh =
205
- staleByAge ||
206
- checkpointAhead ||
207
- (invalidItemCount > 0 && totalActive > 0 && !withinCooldown);
210
+ !withinCooldown &&
211
+ (staleByAge ||
212
+ checkpointAhead ||
213
+ (invalidItemCount > 0 && totalActive > 0));
208
214
 
209
215
  if (shouldRefresh && !hasActiveJob && isMemoryEnabled()) {
210
216
  enqueueMemoryJob("generate_conversation_starters", { scopeId });
@@ -46,7 +46,10 @@ interface ImportPayload {
46
46
 
47
47
  // -- Helpers (ported from CLI) --
48
48
 
49
- function resolveTimestamps(conv: ImportConversation): {
49
+ function resolveTimestamps(
50
+ conv: ImportConversation,
51
+ messages: ImportMessage[],
52
+ ): {
50
53
  convCreatedAt: number;
51
54
  convUpdatedAt: number;
52
55
  messageTimestamps: number[];
@@ -54,13 +57,23 @@ function resolveTimestamps(conv: ImportConversation): {
54
57
  const now = Date.now();
55
58
  const convCreatedAt = conv.createdAt ?? now;
56
59
  const convUpdatedAt = conv.updatedAt ?? conv.createdAt ?? now;
57
- const messageTimestamps = conv.messages.map((msg, i) => {
60
+ const messageTimestamps = messages.map((msg, i) => {
58
61
  if (msg.createdAt != null) return msg.createdAt;
59
62
  return convCreatedAt + i;
60
63
  });
61
64
  return { convCreatedAt, convUpdatedAt, messageTimestamps };
62
65
  }
63
66
 
67
+ /**
68
+ * The messages store is UI-facing (`ConversationMessage`), so only renderable
69
+ * turns are persisted. Non-renderable roles (e.g. agent-context `system`
70
+ * rows an export might carry) are dropped here rather than imported — the
71
+ * import still succeeds with the displayable turns.
72
+ */
73
+ function isRenderableRole(role: string): role is "user" | "assistant" {
74
+ return role === "user" || role === "assistant";
75
+ }
76
+
64
77
  // -- Handler --
65
78
 
66
79
  async function handleConversationsImport({ body }: RouteHandlerArgs) {
@@ -99,12 +112,16 @@ async function handleConversationsImport({ body }: RouteHandlerArgs) {
99
112
  }
100
113
  }
101
114
 
115
+ const messages = conv.messages.filter((msg) =>
116
+ isRenderableRole(msg.role),
117
+ );
118
+
102
119
  const { convCreatedAt, convUpdatedAt, messageTimestamps } =
103
- resolveTimestamps(conv);
120
+ resolveTimestamps(conv, messages);
104
121
 
105
122
  const conversation = createConversation(conv.title);
106
123
 
107
- for (const msg of conv.messages) {
124
+ for (const msg of messages) {
108
125
  const contentStr =
109
126
  typeof msg.content === "string"
110
127
  ? msg.content
@@ -144,8 +161,8 @@ async function handleConversationsImport({ body }: RouteHandlerArgs) {
144
161
  }
145
162
 
146
163
  // Index messages
147
- for (let i = 0; i < dbMessages.length && i < conv.messages.length; i++) {
148
- const msg = conv.messages[i];
164
+ for (let i = 0; i < dbMessages.length && i < messages.length; i++) {
165
+ const msg = messages[i];
149
166
  const contentStr =
150
167
  typeof msg.content === "string"
151
168
  ? msg.content
@@ -176,7 +193,7 @@ async function handleConversationsImport({ body }: RouteHandlerArgs) {
176
193
  }
177
194
 
178
195
  imported++;
179
- totalMessages += conv.messages.length;
196
+ totalMessages += messages.length;
180
197
  } catch (err) {
181
198
  errors.push({
182
199
  index: idx,
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { z } from "zod";
16
16
 
17
- import { findConversation } from "../../daemon/conversation-store.js";
17
+ import { findConversation } from "../../daemon/conversation-registry.js";
18
18
  import type {
19
19
  HostAppControlResultPayload,
20
20
  HostAppControlState,
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { z } from "zod";
8
8
 
9
- import { findConversation } from "../../daemon/conversation-store.js";
9
+ import { findConversation } from "../../daemon/conversation-registry.js";
10
10
  import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
11
11
  import {
12
12
  enforceSameActorOrThrow,
@@ -33,6 +33,7 @@ import { NotFoundError } from "./errors.js";
33
33
  import {
34
34
  getCachedIntro,
35
35
  readWorkspaceGreetings,
36
+ readWorkspaceIdentityIntro,
36
37
  setCachedIntro,
37
38
  } from "./identity-intro-cache.js";
38
39
  import type { RouteDefinition } from "./types.js";
@@ -455,16 +456,30 @@ function getIdentityIntro(): IdentityIntroResponse {
455
456
  return identityIntroResponse(FALLBACK_GREETINGS, "fallback");
456
457
  }
457
458
 
458
- // 2. Cached LLM-generated greetings
459
+ // 2. Cached LLM-generated greetings (populated by background refresh)
459
460
  const cached = getCachedIntro();
460
461
  if (cached) {
461
462
  return identityIntroResponse(cached.greetings, "cache");
462
463
  }
463
464
 
464
- // 3. Trigger fresh generation without blocking the empty-state UI.
465
+ // 3. Identity intro tagline from `## Identity Intro` in IDENTITY.md
466
+ // (written during onboarding by BOOTSTRAP.md instructions)
467
+ const identityIntro = readWorkspaceIdentityIntro();
468
+ if (identityIntro) {
469
+ // Still trigger background generation so the next request gets
470
+ // LLM-generated greetings instead of the static tagline.
471
+ const refreshing = triggerEmptyStateGreetingGeneration();
472
+ return identityIntroResponse(
473
+ [identityIntro, ...FALLBACK_GREETINGS],
474
+ "workspace",
475
+ refreshing,
476
+ );
477
+ }
478
+
479
+ // 4. Trigger fresh generation without blocking the empty-state UI.
465
480
  const refreshing = triggerEmptyStateGreetingGeneration();
466
481
 
467
- // 4. Generic fallback only when generation is unavailable.
482
+ // 5. Generic fallback only when generation is unavailable.
468
483
  return identityIntroResponse(FALLBACK_GREETINGS, "fallback", refreshing);
469
484
  }
470
485
 
@@ -20,7 +20,7 @@ import {
20
20
  createApprovalConversationGenerator,
21
21
  createApprovalCopyGenerator,
22
22
  } from "../../daemon/approval-generators.js";
23
- import { findConversation } from "../../daemon/conversation-store.js";
23
+ import { findConversation } from "../../daemon/conversation-registry.js";
24
24
  import {
25
25
  canonicalizeTimeZone,
26
26
  resolveTurnTimezoneContext,
@@ -23,7 +23,7 @@ import {
23
23
  findByInviteCodeHash,
24
24
  findByInviteCodeHashAnyChannel,
25
25
  } from "../../../memory/invite-store.js";
26
- import { MESSAGE_PREVIEW_MAX_LENGTH } from "../../../notifications/copy-composer.js";
26
+ import { MESSAGE_PREVIEW_MAX_LENGTH } from "../../../notifications/access-request-copy.js";
27
27
  import { resolveGuardianName } from "../../../prompts/user-reference.js";
28
28
  import { getLogger } from "../../../util/logger.js";
29
29
  import { truncate } from "../../../util/truncate.js";
@@ -332,12 +332,12 @@ export async function enforceIngressAcl(
332
332
 
333
333
  return {
334
334
  resolvedMember: null,
335
- earlyResponse: ({
335
+ earlyResponse: {
336
336
  accepted: true,
337
337
  denied: true,
338
338
  reason: "verification_challenge_sent",
339
339
  verificationSessionId: slackVerifyResult.sessionId,
340
- }),
340
+ },
341
341
  };
342
342
  }
343
343
  }
@@ -375,12 +375,12 @@ export async function enforceIngressAcl(
375
375
 
376
376
  return {
377
377
  resolvedMember: null,
378
- earlyResponse: ({
378
+ earlyResponse: {
379
379
  accepted: true,
380
380
  denied: true,
381
381
  reason: "verification_challenge_sent",
382
382
  verificationSessionId: emailVerifyResult.sessionId,
383
- }),
383
+ },
384
384
  };
385
385
  }
386
386
  }
@@ -438,14 +438,14 @@ export async function enforceIngressAcl(
438
438
 
439
439
  return {
440
440
  resolvedMember: null,
441
- earlyResponse: ({
441
+ earlyResponse: {
442
442
  accepted: true,
443
443
  denied: true,
444
444
  reason: "not_a_member",
445
445
  // Include reply text so the gateway can deliver directly when
446
446
  // callback delivery failed (e.g. signing-key mismatch → 401).
447
447
  ...(!replyDelivered && { replyText }),
448
- }),
448
+ },
449
449
  };
450
450
  }
451
451
  }
@@ -610,12 +610,12 @@ export async function enforceIngressAcl(
610
610
 
611
611
  return {
612
612
  resolvedMember,
613
- earlyResponse: ({
613
+ earlyResponse: {
614
614
  accepted: true,
615
615
  denied: true,
616
616
  reason: "verification_challenge_sent",
617
617
  verificationSessionId: slackVerifyResult.sessionId,
618
- }),
618
+ },
619
619
  };
620
620
  }
621
621
  }
@@ -682,12 +682,12 @@ export async function enforceIngressAcl(
682
682
  }
683
683
  return {
684
684
  resolvedMember,
685
- earlyResponse: ({
685
+ earlyResponse: {
686
686
  accepted: true,
687
687
  denied: true,
688
688
  reason: `member_${channelStatusToMemberStatus(resolvedMember.channel.status)}`,
689
689
  ...(!inactiveReplyDelivered && { replyText: inactiveReplyText }),
690
- }),
690
+ },
691
691
  };
692
692
  }
693
693
  }
@@ -722,15 +722,14 @@ export async function enforceIngressAcl(
722
722
  }
723
723
  return {
724
724
  resolvedMember,
725
- earlyResponse: ({
725
+ earlyResponse: {
726
726
  accepted: true,
727
727
  denied: true,
728
728
  reason: "policy_deny",
729
729
  ...(!denyReplyDelivered && { replyText: denyReplyText }),
730
- }),
730
+ },
731
731
  };
732
732
  }
733
-
734
733
  }
735
734
  }
736
735
 
@@ -786,11 +785,11 @@ async function handleInviteTokenIntercept(params: {
786
785
  );
787
786
 
788
787
  if (dedupResult.duplicate) {
789
- return ({
788
+ return {
790
789
  accepted: true,
791
790
  duplicate: true,
792
791
  eventId: dedupResult.eventId,
793
- });
792
+ };
794
793
  }
795
794
 
796
795
  const outcome = redeemInvite({
@@ -835,11 +834,11 @@ async function handleInviteTokenIntercept(params: {
835
834
  }
836
835
  }
837
836
  markProcessed(dedupResult.eventId);
838
- return ({
837
+ return {
839
838
  accepted: true,
840
839
  eventId: dedupResult.eventId,
841
840
  inviteRedemption: "already_member",
842
- });
841
+ };
843
842
  }
844
843
 
845
844
  const replyText = getInviteRedemptionReply(outcome);
@@ -861,22 +860,22 @@ async function handleInviteTokenIntercept(params: {
861
860
 
862
861
  if (outcome.ok && outcome.type === "redeemed") {
863
862
  markProcessed(dedupResult.eventId);
864
- return ({
863
+ return {
865
864
  accepted: true,
866
865
  eventId: dedupResult.eventId,
867
866
  inviteRedemption: "redeemed",
868
867
  memberId: outcome.memberId,
869
- });
868
+ };
870
869
  }
871
870
 
872
871
  // Failed redemption — inform the user and deny
873
872
  markProcessed(dedupResult.eventId);
874
- return ({
873
+ return {
875
874
  accepted: true,
876
875
  eventId: dedupResult.eventId,
877
876
  denied: true,
878
877
  inviteRedemption: outcome.reason,
879
- });
878
+ };
880
879
  }
881
880
 
882
881
  // ---------------------------------------------------------------------------
@@ -942,11 +941,11 @@ async function handleInviteCodeIntercept(params: {
942
941
  );
943
942
 
944
943
  if (dedupResult.duplicate) {
945
- return ({
944
+ return {
946
945
  accepted: true,
947
946
  duplicate: true,
948
947
  eventId: dedupResult.eventId,
949
- });
948
+ };
950
949
  }
951
950
 
952
951
  const mismatchReply = "This invite is not valid for this channel.";
@@ -965,12 +964,12 @@ async function handleInviteCodeIntercept(params: {
965
964
  }
966
965
  }
967
966
  markProcessed(dedupResult.eventId);
968
- return ({
967
+ return {
969
968
  accepted: true,
970
969
  eventId: dedupResult.eventId,
971
970
  denied: true,
972
971
  inviteRedemption: "channel_mismatch",
973
- });
972
+ };
974
973
  }
975
974
  return null;
976
975
  }
@@ -988,11 +987,11 @@ async function handleInviteCodeIntercept(params: {
988
987
  );
989
988
 
990
989
  if (dedupResult.duplicate) {
991
- return ({
990
+ return {
992
991
  accepted: true,
993
992
  duplicate: true,
994
993
  eventId: dedupResult.eventId,
995
- });
994
+ };
996
995
  }
997
996
 
998
997
  let outcome: ReturnType<typeof redeemInviteByCode>;
@@ -1046,11 +1045,11 @@ async function handleInviteCodeIntercept(params: {
1046
1045
  }
1047
1046
  }
1048
1047
  markProcessed(dedupResult.eventId);
1049
- return ({
1048
+ return {
1050
1049
  accepted: true,
1051
1050
  eventId: dedupResult.eventId,
1052
1051
  inviteRedemption: "already_member",
1053
- });
1052
+ };
1054
1053
  }
1055
1054
 
1056
1055
  const replyText = getInviteRedemptionReply(outcome);
@@ -1072,22 +1071,22 @@ async function handleInviteCodeIntercept(params: {
1072
1071
 
1073
1072
  if (outcome.ok && outcome.type === "redeemed") {
1074
1073
  markProcessed(dedupResult.eventId);
1075
- return ({
1074
+ return {
1076
1075
  accepted: true,
1077
1076
  eventId: dedupResult.eventId,
1078
1077
  inviteRedemption: "redeemed",
1079
1078
  memberId: outcome.memberId,
1080
- });
1079
+ };
1081
1080
  }
1082
1081
 
1083
1082
  // Failed redemption (expired, revoked, etc.) — inform and deny
1084
1083
  markProcessed(dedupResult.eventId);
1085
- return ({
1084
+ return {
1086
1085
  accepted: true,
1087
1086
  eventId: dedupResult.eventId,
1088
1087
  denied: true,
1089
1088
  inviteRedemption: !outcome.ok ? outcome.reason : undefined,
1090
- });
1089
+ };
1091
1090
  }
1092
1091
 
1093
1092
  // ---------------------------------------------------------------------------
@@ -15,6 +15,7 @@
15
15
  import { randomUUID } from "node:crypto";
16
16
 
17
17
  import { loadConfig } from "../../config/loader.js";
18
+ import { findConversation } from "../../daemon/conversation-registry.js";
18
19
  import {
19
20
  getConversation,
20
21
  listActiveInferenceProfileSessions,
@@ -118,6 +119,11 @@ export async function setInferenceProfileSession({
118
119
  };
119
120
  }
120
121
  setConversationInferenceProfileSession(resolvedId, null, null, null);
122
+ findConversation(resolvedId)?.applyInferenceProfileState({
123
+ profile: null,
124
+ sessionId: null,
125
+ expiresAt: null,
126
+ });
121
127
  publishConversationInferenceProfileChanged(
122
128
  {
123
129
  conversationId: resolvedId,
@@ -188,6 +194,11 @@ export async function setInferenceProfileSession({
188
194
  newSessionId ?? null,
189
195
  newExpiresAt ?? null,
190
196
  );
197
+ findConversation(resolvedId)?.applyInferenceProfileState({
198
+ profile,
199
+ sessionId: newSessionId ?? null,
200
+ expiresAt: newExpiresAt ?? null,
201
+ });
191
202
 
192
203
  publishConversationInferenceProfileChanged(
193
204
  {
@@ -11,6 +11,7 @@
11
11
  * background sweeps in `http-server.ts`.
12
12
  */
13
13
 
14
+ import { findConversation } from "../../daemon/conversation-registry.js";
14
15
  import { clearExpiredInferenceProfiles } from "../../memory/conversation-crud.js";
15
16
  import { getLogger } from "../../util/logger.js";
16
17
  import { publishConversationInferenceProfileChanged } from "../sync/resource-sync-events.js";
@@ -37,6 +38,11 @@ export function tickInferenceProfileReaper(): void {
37
38
  const now = Date.now();
38
39
  const cleared = clearExpiredInferenceProfiles(now);
39
40
  for (const { conversationId } of cleared) {
41
+ findConversation(conversationId)?.applyInferenceProfileState({
42
+ profile: null,
43
+ sessionId: null,
44
+ expiresAt: null,
45
+ });
40
46
  publishConversationInferenceProfileChanged({
41
47
  conversationId,
42
48
  profile: null,