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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/docs/activation-funnel-telemetry.md +310 -0
  4. package/examples/plugins/echo/README.md +61 -60
  5. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  6. package/examples/plugins/echo/hooks/stop.ts +16 -0
  7. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  8. package/examples/plugins/echo/package.json +1 -2
  9. package/examples/plugins/echo/src/emit.ts +19 -0
  10. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  11. package/openapi.yaml +273 -121
  12. package/package.json +2 -2
  13. package/scripts/sync-llm-catalog.ts +2 -0
  14. package/src/__tests__/activation-early-marking.test.ts +120 -0
  15. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  16. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  17. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  18. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  19. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  20. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  21. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  22. package/src/__tests__/agent-loop.test.ts +441 -96
  23. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  24. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  25. package/src/__tests__/anthropic-provider.test.ts +23 -8
  26. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  27. package/src/__tests__/app-control-flow.test.ts +1 -1
  28. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  29. package/src/__tests__/app-executors.test.ts +132 -0
  30. package/src/__tests__/approval-cascade.test.ts +6 -5
  31. package/src/__tests__/approval-routes-http.test.ts +4 -1
  32. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  33. package/src/__tests__/build-persisted-content.test.ts +75 -1
  34. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  35. package/src/__tests__/channel-approvals.test.ts +1 -1
  36. package/src/__tests__/compaction-circuit.test.ts +258 -0
  37. package/src/__tests__/compaction-direct.test.ts +146 -0
  38. package/src/__tests__/compaction-events.test.ts +7 -7
  39. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  40. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  41. package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
  42. package/src/__tests__/context-overflow-reducer.test.ts +265 -125
  43. package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
  44. package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
  45. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  46. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  47. package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
  48. package/src/__tests__/conversation-agent-loop.test.ts +342 -623
  49. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  50. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
  51. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  52. package/src/__tests__/conversation-error.test.ts +15 -1
  53. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  54. package/src/__tests__/conversation-media-retry.test.ts +1 -1
  55. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
  56. package/src/__tests__/conversation-process-callsite.test.ts +15 -15
  57. package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
  58. package/src/__tests__/conversation-queue.test.ts +10 -10
  59. package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
  60. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  61. package/src/__tests__/conversation-slash-queue.test.ts +7 -5
  62. package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
  63. package/src/__tests__/conversation-speed-override.test.ts +11 -10
  64. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  65. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
  66. package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
  67. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
  68. package/src/__tests__/conversation-undo.test.ts +2 -2
  69. package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
  70. package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
  71. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
  72. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  73. package/src/__tests__/corrected-target.test.ts +93 -0
  74. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -4
  75. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  76. package/src/__tests__/cu-unified-flow.test.ts +36 -0
  77. package/src/__tests__/db-acp-history.test.ts +101 -0
  78. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  79. package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
  80. package/src/__tests__/empty-response-hook.test.ts +1 -1
  81. package/src/__tests__/file-write-tool.test.ts +63 -0
  82. package/src/__tests__/gateway-only-guard.test.ts +17 -2
  83. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  84. package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
  85. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  86. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  87. package/src/__tests__/heartbeat-service.test.ts +1 -0
  88. package/src/__tests__/history-repair-hook.test.ts +5 -1
  89. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  90. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  91. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  92. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  93. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  94. package/src/__tests__/injector-background-turn.test.ts +13 -23
  95. package/src/__tests__/injector-chain.test.ts +268 -44
  96. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  97. package/src/__tests__/injector-document-comments.test.ts +97 -114
  98. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  99. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  100. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  101. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  102. package/src/__tests__/llm-catalog-parity.test.ts +4 -0
  103. package/src/__tests__/llm-resolver.test.ts +73 -0
  104. package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
  105. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  106. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  107. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  108. package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
  109. package/src/__tests__/persist-unsendable-image.test.ts +97 -1
  110. package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
  111. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  112. package/src/__tests__/plugin-bootstrap.test.ts +91 -81
  113. package/src/__tests__/plugin-registry.test.ts +3 -49
  114. package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
  115. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  116. package/src/__tests__/plugin-types.test.ts +0 -70
  117. package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
  118. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  119. package/src/__tests__/published-app-updater.test.ts +138 -0
  120. package/src/__tests__/reaction-persistence.test.ts +1 -1
  121. package/src/__tests__/retry-thinking-adaptive-only.test.ts +245 -0
  122. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  123. package/src/__tests__/server-history-render.test.ts +39 -0
  124. package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
  125. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  126. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  127. package/src/__tests__/subagent-detail.test.ts +25 -7
  128. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  129. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  130. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  131. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  132. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  133. package/src/__tests__/title-generate-hook.test.ts +5 -1
  134. package/src/__tests__/tool-error-hook.test.ts +1 -1
  135. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  136. package/src/__tests__/tool-start-timestamp.test.ts +218 -0
  137. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  138. package/src/__tests__/web-fetch.test.ts +45 -0
  139. package/src/acp/__tests__/agent-process.test.ts +161 -0
  140. package/src/acp/__tests__/client-handler.test.ts +40 -0
  141. package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
  142. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  143. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  144. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  145. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  146. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  147. package/src/acp/agent-process.ts +61 -1
  148. package/src/acp/auto-install.test.ts +280 -0
  149. package/src/acp/auto-install.ts +232 -0
  150. package/src/acp/client-handler.ts +31 -0
  151. package/src/acp/prepare-agent-env.ts +80 -27
  152. package/src/acp/resolve-agent.test.ts +188 -28
  153. package/src/acp/resolve-agent.ts +119 -42
  154. package/src/acp/resume-hint.ts +23 -0
  155. package/src/acp/session-manager.ts +507 -73
  156. package/src/agent/compaction-circuit.ts +60 -102
  157. package/src/agent/loop.ts +403 -251
  158. package/src/api/events/tool-result.ts +9 -0
  159. package/src/api/events/tool-use-start.ts +7 -0
  160. package/src/api/responses/conversation-message.ts +72 -13
  161. package/src/api/responses/memory-v3-selection-log.ts +19 -10
  162. package/src/approvals/guardian-request-resolvers.ts +27 -1
  163. package/src/background-wake/next-wake.ts +1 -0
  164. package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
  165. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  166. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  167. package/src/cli/commands/memory-v3.ts +57 -199
  168. package/src/cli/commands/plugins.ts +43 -37
  169. package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
  170. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  171. package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
  172. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
  173. package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
  174. package/src/cli/lib/install-from-github.ts +797 -60
  175. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  176. package/src/cli/lib/plugin-details.ts +416 -0
  177. package/src/cli/lib/plugin-marketplace.ts +215 -0
  178. package/src/cli/lib/search-plugins.ts +201 -29
  179. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  180. package/src/config/acp-defaults.test.ts +10 -0
  181. package/src/config/acp-defaults.ts +9 -3
  182. package/src/config/acp-schema.ts +1 -7
  183. package/src/config/bundled-skills/acp/SKILL.md +80 -41
  184. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  185. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  186. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  187. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  188. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  189. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  190. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  191. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  192. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  193. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  194. package/src/config/bundled-tool-registry.ts +4 -0
  195. package/src/config/call-site-defaults.ts +0 -3
  196. package/src/config/feature-flag-registry.json +10 -56
  197. package/src/config/llm-resolver.ts +39 -7
  198. package/src/config/loader.ts +5 -22
  199. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
  200. package/src/config/schemas/call-site-catalog.ts +0 -21
  201. package/src/config/schemas/heartbeat.ts +9 -0
  202. package/src/config/schemas/llm.ts +17 -3
  203. package/src/config/schemas/memory-v3.ts +58 -8
  204. package/src/config/seed-inference-profiles.ts +18 -0
  205. package/src/context/compactor.ts +22 -4
  206. package/src/context/post-turn-tool-result-truncation.ts +39 -1
  207. package/src/context/strip-injections.ts +8 -2
  208. package/src/daemon/conversation-agent-loop-handlers.ts +120 -42
  209. package/src/daemon/conversation-agent-loop.ts +308 -1297
  210. package/src/daemon/conversation-error.ts +31 -4
  211. package/src/daemon/conversation-history.ts +1 -1
  212. package/src/daemon/conversation-lifecycle.ts +11 -255
  213. package/src/daemon/conversation-media-retry.ts +19 -6
  214. package/src/daemon/conversation-messaging.ts +17 -0
  215. package/src/daemon/conversation-process.ts +22 -141
  216. package/src/daemon/conversation-queue-manager.ts +8 -0
  217. package/src/daemon/conversation-registry.ts +159 -0
  218. package/src/daemon/conversation-runtime-assembly.ts +361 -393
  219. package/src/daemon/conversation-store.ts +9 -90
  220. package/src/daemon/conversation-surfaces.ts +165 -11
  221. package/src/daemon/conversation-workspace.ts +17 -0
  222. package/src/daemon/conversation.ts +444 -62
  223. package/src/daemon/disk-pressure-policy.ts +0 -1
  224. package/src/daemon/external-plugins-bootstrap.ts +36 -46
  225. package/src/daemon/handlers/config-channels.ts +11 -2
  226. package/src/daemon/handlers/conversations.ts +3 -1
  227. package/src/daemon/handlers/shared.ts +9 -1
  228. package/src/daemon/handlers/skills.ts +4 -1
  229. package/src/daemon/host-app-control-proxy.ts +72 -57
  230. package/src/daemon/host-proxy-preactivation.ts +1 -3
  231. package/src/daemon/lifecycle.ts +21 -7
  232. package/src/daemon/persist-unsendable-image.ts +62 -25
  233. package/src/daemon/process-message.ts +1 -1
  234. package/src/daemon/server.ts +2 -0
  235. package/src/daemon/tool-side-effects.ts +15 -0
  236. package/src/daemon/wake-conversation-ops.ts +269 -0
  237. package/src/embedded/plugin-api.ts +2 -2
  238. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  239. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  240. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  241. package/src/heartbeat/heartbeat-service.ts +26 -0
  242. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  243. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  244. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  245. package/src/ipc/skill-routes/memory.ts +4 -2
  246. package/src/memory/__tests__/activation-session-store.test.ts +41 -0
  247. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  248. package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
  249. package/src/memory/activation-session-store.ts +43 -0
  250. package/src/memory/conversation-crud.ts +29 -19
  251. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  252. package/src/memory/db-init.ts +6 -0
  253. package/src/memory/embedding-backend.ts +5 -22
  254. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  255. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  256. package/src/memory/jobs-worker.ts +25 -1
  257. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  258. package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
  259. package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
  260. package/src/memory/migrations/index.ts +3 -0
  261. package/src/memory/onboarding-events-store.ts +66 -18
  262. package/src/memory/schema/acp.ts +4 -0
  263. package/src/memory/schema/infrastructure.ts +13 -0
  264. package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
  265. package/src/memory/v2/__tests__/page-store.test.ts +22 -0
  266. package/src/memory/v2/consolidation-job.ts +2 -63
  267. package/src/memory/v2/types.ts +5 -0
  268. package/src/messaging/providers/telegram-bot/api.ts +14 -5
  269. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  270. package/src/notifications/access-request-copy.ts +298 -0
  271. package/src/notifications/adapters/slack.ts +3 -3
  272. package/src/notifications/adapters/telegram.ts +9 -2
  273. package/src/notifications/copy-composer.ts +49 -267
  274. package/src/notifications/decision-engine.ts +16 -35
  275. package/src/notifications/home-feed-side-effect.ts +1 -6
  276. package/src/plugin-api/constants.ts +4 -0
  277. package/src/plugin-api/index.ts +40 -11
  278. package/src/plugin-api/types.ts +108 -0
  279. package/src/plugins/defaults/compaction/compact.ts +106 -0
  280. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
  281. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  282. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  283. package/src/plugins/defaults/compaction/package.json +1 -2
  284. package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
  285. package/src/plugins/defaults/empty-response/package.json +0 -1
  286. package/src/plugins/defaults/history-repair/package.json +0 -1
  287. package/src/plugins/defaults/index.ts +156 -26
  288. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  289. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
  290. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  291. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  292. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  293. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  294. package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
  295. package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
  296. package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
  297. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
  298. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
  299. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
  300. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
  301. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
  302. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
  303. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
  304. package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
  305. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
  306. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
  307. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
  308. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
  309. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
  310. package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
  311. package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
  312. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  313. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  314. package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
  315. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
  316. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
  317. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  318. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
  319. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
  320. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
  321. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
  322. package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
  323. package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
  324. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
  325. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
  326. package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
  327. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
  328. package/src/plugins/defaults/title-generate/package.json +0 -1
  329. package/src/plugins/defaults/tool-error/package.json +0 -1
  330. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  331. package/src/plugins/external-api.ts +12 -2
  332. package/src/plugins/pipeline.ts +6 -293
  333. package/src/plugins/registry.ts +9 -37
  334. package/src/plugins/types.ts +76 -381
  335. package/src/plugins/user-loader.ts +30 -127
  336. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  337. package/src/prompts/system-prompt.ts +61 -10
  338. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
  339. package/src/providers/anthropic/client.ts +9 -10
  340. package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
  341. package/src/providers/inference/logit-bias.ts +55 -0
  342. package/src/providers/model-catalog.ts +57 -0
  343. package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
  344. package/src/providers/openai/chat-completions-provider.ts +44 -1
  345. package/src/providers/retry.ts +57 -7
  346. package/src/providers/types.ts +6 -0
  347. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  348. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  349. package/src/runtime/agent-wake.ts +108 -209
  350. package/src/runtime/assistant-event-hub.ts +1 -1
  351. package/src/runtime/channel-approvals.ts +1 -1
  352. package/src/runtime/interactive-ui.ts +1 -1
  353. package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
  354. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  355. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  356. package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
  357. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  358. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  359. package/src/runtime/routes/acp-routes.test.ts +185 -32
  360. package/src/runtime/routes/acp-routes.ts +328 -30
  361. package/src/runtime/routes/app-management-routes.ts +3 -0
  362. package/src/runtime/routes/approval-routes.ts +1 -1
  363. package/src/runtime/routes/browser-routes.ts +1 -1
  364. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  365. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  366. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  367. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  368. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  369. package/src/runtime/routes/conversation-routes.ts +30 -2
  370. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  371. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  372. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  373. package/src/runtime/routes/host-cu-routes.ts +1 -1
  374. package/src/runtime/routes/identity-routes.ts +18 -3
  375. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  376. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  377. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  378. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  379. package/src/runtime/routes/memory-v3-routes.ts +65 -305
  380. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
  381. package/src/runtime/routes/playground/helpers.ts +1 -1
  382. package/src/runtime/routes/plugins-routes.ts +337 -35
  383. package/src/runtime/routes/stt-routes.ts +45 -12
  384. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  385. package/src/runtime/routes/work-items-routes.ts +2 -4
  386. package/src/runtime/routes/workspace-routes.ts +50 -15
  387. package/src/runtime/services/conversation-serializer.ts +1 -1
  388. package/src/runtime/verification-outbound-actions.ts +147 -2
  389. package/src/runtime/verification-templates.ts +29 -3
  390. package/src/services/published-app-updater.ts +30 -8
  391. package/src/signals/cancel.ts +2 -4
  392. package/src/subagent/manager.ts +21 -5
  393. package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
  394. package/src/telemetry/activation-funnel.ts +167 -0
  395. package/src/telemetry/types.ts +13 -0
  396. package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
  397. package/src/telemetry/usage-telemetry-reporter.ts +26 -1
  398. package/src/tools/acp/context.ts +20 -0
  399. package/src/tools/acp/list-agents.test.ts +9 -19
  400. package/src/tools/acp/list-agents.ts +3 -15
  401. package/src/tools/acp/spawn.test.ts +173 -202
  402. package/src/tools/acp/spawn.ts +37 -172
  403. package/src/tools/acp/steer.test.ts +105 -8
  404. package/src/tools/acp/steer.ts +48 -17
  405. package/src/tools/apps/executors.ts +166 -50
  406. package/src/tools/browser/browser-execution.ts +12 -2
  407. package/src/tools/filesystem/write.ts +34 -0
  408. package/src/tools/network/web-fetch.ts +65 -24
  409. package/src/tools/skills/load.ts +1 -1
  410. package/src/tools/subagent/spawn.ts +2 -4
  411. package/src/tools/ui-surface/definitions.ts +32 -5
  412. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  413. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  414. package/docs/plugins.md +0 -832
  415. package/examples/plugins/echo/register.ts +0 -143
  416. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  417. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  418. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  419. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  420. package/src/__tests__/pipeline-runner.test.ts +0 -554
  421. package/src/daemon/wake-target-adapter.ts +0 -253
  422. package/src/memory/v3/__tests__/assign.test.ts +0 -242
  423. package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
  424. package/src/memory/v3/__tests__/core.test.ts +0 -39
  425. package/src/memory/v3/__tests__/health.test.ts +0 -219
  426. package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
  427. package/src/memory/v3/__tests__/needle.test.ts +0 -107
  428. package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
  429. package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
  430. package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
  431. package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
  432. package/src/memory/v3/__tests__/router.test.ts +0 -332
  433. package/src/memory/v3/__tests__/selector.test.ts +0 -470
  434. package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
  435. package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
  436. package/src/memory/v3/__tests__/tree.test.ts +0 -192
  437. package/src/memory/v3/assign.ts +0 -268
  438. package/src/memory/v3/capabilities.ts +0 -124
  439. package/src/memory/v3/core.ts +0 -26
  440. package/src/memory/v3/health.ts +0 -0
  441. package/src/memory/v3/maintain-job.ts +0 -314
  442. package/src/memory/v3/needle.ts +0 -115
  443. package/src/memory/v3/orchestrate.ts +0 -126
  444. package/src/memory/v3/page-content.ts +0 -34
  445. package/src/memory/v3/provider-blocks.ts +0 -26
  446. package/src/memory/v3/reconcile.ts +0 -523
  447. package/src/memory/v3/router.ts +0 -190
  448. package/src/memory/v3/selection-log-store.ts +0 -84
  449. package/src/memory/v3/selector.ts +0 -226
  450. package/src/memory/v3/shadow-plugin.ts +0 -411
  451. package/src/memory/v3/snapshot.ts +0 -209
  452. package/src/memory/v3/tree.ts +0 -174
  453. package/src/memory/v3/types.ts +0 -59
  454. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  455. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  456. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  457. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  458. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  459. package/src/plugins/defaults/compaction/register.ts +0 -35
  460. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  461. package/src/plugins/defaults/empty-response/register.ts +0 -23
  462. package/src/plugins/defaults/history-repair/register.ts +0 -24
  463. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
  464. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  465. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  466. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  467. package/src/plugins/defaults/title-generate/register.ts +0 -35
  468. package/src/plugins/defaults/tool-error/register.ts +0 -23
  469. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  470. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  471. package/src/proactive-artifact/decision.test.ts +0 -226
  472. package/src/proactive-artifact/decision.ts +0 -165
  473. package/src/proactive-artifact/index.ts +0 -7
  474. package/src/proactive-artifact/job.test.ts +0 -962
  475. package/src/proactive-artifact/job.ts +0 -372
  476. package/src/proactive-artifact/message-copy.ts +0 -58
  477. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  478. package/src/proactive-artifact/trigger-state.ts +0 -123
  479. package/src/util/map-limit.ts +0 -27
  480. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  481. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  482. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  483. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  484. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  485. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  486. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  487. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  488. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  489. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  490. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
@@ -27,99 +27,18 @@ import { ProviderNotConfiguredError } from "../util/errors.js";
27
27
  import { getSandboxWorkingDir } from "../util/platform.js";
28
28
  import { Conversation } from "./conversation.js";
29
29
  import type { ConversationEvictor } from "./conversation-evictor.js";
30
+ import {
31
+ allConversations,
32
+ clearConversations,
33
+ conversationCount,
34
+ conversationIds,
35
+ deleteConversation,
36
+ findConversation,
37
+ setConversation,
38
+ } from "./conversation-registry.js";
30
39
  import type { ConversationCreateOptions } from "./handlers/shared.js";
31
40
  import { buildTransportHints } from "./transport-hints.js";
32
41
 
33
- // ── Private store ──────────────────────────────────────────────────
34
-
35
- const conversations = new Map<string, Conversation>();
36
-
37
- // ── Read helpers ───────────────────────────────────────────────────
38
-
39
- export function findConversation(
40
- conversationId: string,
41
- ): Conversation | undefined {
42
- return conversations.get(conversationId);
43
- }
44
-
45
- export function findConversationBySurfaceId(
46
- surfaceId: string,
47
- ): Conversation | undefined {
48
- // Fast path: exact surfaceId match in surfaceState
49
- for (const c of conversations.values()) {
50
- if (c.surfaceState.has(surfaceId)) return c;
51
- }
52
-
53
- // Fallback: standalone app surfaces use "app-open-{appId}" IDs that
54
- // were never part of any conversation. Extract the appId and find
55
- // a conversation whose surfaceState has a surface for that app.
56
- const appOpenPrefix = "app-open-";
57
- if (surfaceId.startsWith(appOpenPrefix)) {
58
- const appId = surfaceId.slice(appOpenPrefix.length);
59
- for (const c of conversations.values()) {
60
- for (const [, state] of c.surfaceState.entries()) {
61
- const data = state.data as unknown as Record<string, unknown>;
62
- if (data?.appId === appId) {
63
- // Register this surfaceId so subsequent lookups are O(1)
64
- c.surfaceState.set(surfaceId, state);
65
- return c;
66
- }
67
- }
68
- }
69
- }
70
-
71
- return undefined;
72
- }
73
-
74
- function conversationCount(): number {
75
- return conversations.size;
76
- }
77
-
78
- /** Iterate over all active conversations. */
79
- export function allConversations(): IterableIterator<Conversation> {
80
- return conversations.values();
81
- }
82
-
83
- /** Iterate over all [id, conversation] entries. */
84
- export function conversationEntries(): IterableIterator<
85
- [string, Conversation]
86
- > {
87
- return conversations.entries();
88
- }
89
-
90
- /** Iterate over all active conversation IDs. */
91
- function conversationIds(): IterableIterator<string> {
92
- return conversations.keys();
93
- }
94
-
95
- // ── Write helpers ──────────────────────────────────────────────────
96
-
97
- export function setConversation(
98
- conversationId: string,
99
- conversation: Conversation,
100
- ): void {
101
- conversations.set(conversationId, conversation);
102
- }
103
-
104
- export function deleteConversation(conversationId: string): boolean {
105
- return conversations.delete(conversationId);
106
- }
107
-
108
- export function clearConversations(): void {
109
- conversations.clear();
110
- }
111
-
112
- // ── Underlying Map (for the evictor, which takes a mutable ref) ───
113
-
114
- /**
115
- * Expose the raw Map for the {@link ConversationEvictor}, which needs
116
- * a mutable reference to delete entries during sweeps. No other code
117
- * should use this — prefer the named helpers above.
118
- */
119
- export function getConversationMap(): Map<string, Conversation> {
120
- return conversations;
121
- }
122
-
123
42
  // ── Per-conversation persistent options ────────────────────────────
124
43
 
125
44
  const conversationOptions = new Map<string, ConversationCreateOptions>();
@@ -1,5 +1,6 @@
1
1
  import { v4 as uuid } from "uuid";
2
2
 
3
+ import { isActivationSession } from "../memory/activation-session-store.js";
3
4
  import {
4
5
  addAppConversationId,
5
6
  getApp,
@@ -14,6 +15,7 @@ import {
14
15
  getMessages,
15
16
  updateMessageContent,
16
17
  } from "../memory/conversation-crud.js";
18
+ import { recordActivationEvent } from "../memory/onboarding-events-store.js";
17
19
  import {
18
20
  assistantEventHub,
19
21
  broadcastMessage,
@@ -23,10 +25,17 @@ import {
23
25
  enforceSameActorOrErrorResult,
24
26
  pickSameUserAutoResolve,
25
27
  } from "../runtime/auth/same-actor.js";
28
+ import type { AuthContext } from "../runtime/auth/types.js";
26
29
  import type {
27
30
  InteractiveUiRequest,
28
31
  InteractiveUiResult,
29
32
  } from "../runtime/interactive-ui-types.js";
33
+ import {
34
+ activationMomentEmitsAtShow,
35
+ type ActivationMomentParam,
36
+ activationStepNameForMomentParam,
37
+ isActivationMomentParam,
38
+ } from "../telemetry/activation-funnel.js";
30
39
  import type { ToolExecutionResult } from "../tools/types.js";
31
40
  import { getLogger } from "../util/logger.js";
32
41
  import { isPlainObject } from "../util/object.js";
@@ -544,6 +553,12 @@ export interface SurfaceConversationContext {
544
553
  readonly assistantId?: string;
545
554
  /** Inherited to spawned conversations in the `launch_conversation` action path. */
546
555
  readonly trustContext?: TrustContext;
556
+ /** Verified requester auth context for the active turn. */
557
+ readonly authContext?: AuthContext;
558
+ /** Per-turn auth snapshot, preferred for tool dispatch authorization. */
559
+ readonly currentTurnAuthContext?: AuthContext;
560
+ /** JWT-verified requester principal for the active turn. */
561
+ readonly currentTurnSourceActorPrincipalId?: string;
547
562
  readonly channelCapabilities?: {
548
563
  channel: string;
549
564
  supportsDynamicUi: boolean;
@@ -569,6 +584,14 @@ export interface SurfaceConversationContext {
569
584
  style?: string;
570
585
  data?: Record<string, unknown>;
571
586
  }>;
587
+ /**
588
+ * Activation-rail telemetry tag (daemon-only). When the model tags a
589
+ * `ui_show` surface as an activation funnel moment, the token is captured
590
+ * here so the milestone can be recorded deterministically when the user
591
+ * commits the surface (`handleSurfaceAction`). Never forwarded to the
592
+ * client.
593
+ */
594
+ activationMoment?: ActivationMomentParam;
572
595
  }
573
596
  >;
574
597
  surfaceUndoStacks: Map<string, string[]>;
@@ -613,6 +636,12 @@ export interface SurfaceConversationContext {
613
636
  display?: string;
614
637
  persistent?: boolean;
615
638
  toolCallId?: string;
639
+ /**
640
+ * Commit-timing activation-rail tag (daemon-only). Carried through to the
641
+ * persisted `ui_surface` history block so it survives a reload — never sent
642
+ * to the client.
643
+ */
644
+ activationMoment?: ActivationMomentParam;
616
645
  }>;
617
646
  /** Optional proxy for delegating computer-use actions to a connected desktop client. */
618
647
  hostCuProxy?: HostCuProxy;
@@ -1250,6 +1279,60 @@ function getRequestedSurfaceCompletionSummary(
1250
1279
  return summary || "Completed";
1251
1280
  }
1252
1281
 
1282
+ /**
1283
+ * Best-effort recorder for a single activation-funnel moment. Gated on the
1284
+ * conversation being a marked activation-rail session. Fire-and-forget: never
1285
+ * throws, never blocks or alters the surface-action flow (a failure is logged
1286
+ * and swallowed). Shared by the show-time path (`first_wow_executed`, recorded
1287
+ * when the surface renders) and the commit-time path (the other moments,
1288
+ * recorded when the user commits the surface).
1289
+ */
1290
+ function recordActivationMoment(
1291
+ ctx: SurfaceConversationContext,
1292
+ moment: ActivationMomentParam,
1293
+ ): void {
1294
+ try {
1295
+ if (!isActivationSession(ctx.conversationId)) return;
1296
+ recordActivationEvent({
1297
+ stepName: activationStepNameForMomentParam(moment),
1298
+ sessionId: ctx.conversationId,
1299
+ });
1300
+ } catch (err) {
1301
+ log.warn(
1302
+ { err, conversationId: ctx.conversationId, moment },
1303
+ "Failed to record activation moment",
1304
+ );
1305
+ }
1306
+ }
1307
+
1308
+ /**
1309
+ * Best-effort activation-funnel emission on a user surface commit.
1310
+ *
1311
+ * When the committed surface carries a commit-timing `activationMoment` tag,
1312
+ * record the corresponding funnel milestone. Show-timing moments
1313
+ * (`first_wow_executed`) are recorded at render time in `surfaceProxyResolver`
1314
+ * and are NOT stored on `surfaceState`, so they never reach this path. The tag
1315
+ * is cleared after the first record so re-entrant or repeated commits on the
1316
+ * same surface do not double-emit (and the deterministic `daemon_event_id`
1317
+ * collapses any cross-surface duplicate downstream anyway).
1318
+ *
1319
+ * Must be called only from terminal-commit paths (user clicked an action /
1320
+ * submitted / selected-and-committed), NOT from intermediate non-terminal
1321
+ * events (`selection_changed` / `content_changed` / `state_update`).
1322
+ */
1323
+ function maybeEmitActivationMoment(
1324
+ ctx: SurfaceConversationContext,
1325
+ surfaceId: string,
1326
+ ): void {
1327
+ const stored = ctx.surfaceState.get(surfaceId);
1328
+ const moment = stored?.activationMoment;
1329
+ if (!moment) return;
1330
+ // Clear the tag first so this can fire at most once per surface even if the
1331
+ // commit path is re-entered.
1332
+ stored.activationMoment = undefined;
1333
+ recordActivationMoment(ctx, moment);
1334
+ }
1335
+
1253
1336
  function completeSurfaceFromAction(
1254
1337
  ctx: SurfaceConversationContext,
1255
1338
  surfaceId: string,
@@ -1317,6 +1400,13 @@ export async function handleSurfaceAction(
1317
1400
  });
1318
1401
  markSurfaceCompleted(ctx, surfaceId, summary);
1319
1402
 
1403
+ // Terminal user commit on a standalone surface (submit, not cancel/dismiss)
1404
+ // — record an activation milestone if tagged. Must run before
1405
+ // `cleanupStandaloneSurface` clears the surface state.
1406
+ if (!isCancellation) {
1407
+ maybeEmitActivationMoment(ctx, surfaceId);
1408
+ }
1409
+
1320
1410
  // Cleanup and resolve — order matters: cleanup clears the timer
1321
1411
  // before resolve() unblocks the caller.
1322
1412
  cleanupStandaloneSurface(ctx, surfaceId);
@@ -1403,6 +1493,10 @@ export async function handleSurfaceAction(
1403
1493
  { originConversationId: ctx.conversationId, conversationId, surfaceId },
1404
1494
  "launch_conversation dispatched inline from surface action",
1405
1495
  );
1496
+ // Launching a child conversation is a terminal user commit — record an
1497
+ // activation milestone if tagged. The helper clears the tag after firing,
1498
+ // so the other commit-path call sites below can't double-emit.
1499
+ maybeEmitActivationMoment(ctx, surfaceId);
1406
1500
  return { accepted: true, conversationId };
1407
1501
  }
1408
1502
 
@@ -1557,6 +1651,12 @@ export async function handleSurfaceAction(
1557
1651
  return;
1558
1652
  }
1559
1653
 
1654
+ // Terminal user commit accepted — record the activation milestone if this
1655
+ // surface was tagged (best-effort, no-op otherwise). Deferred until after
1656
+ // the rejection check so a queue-full click doesn't over-report a moment
1657
+ // (and the one-shot tag stays intact for the user's retry).
1658
+ maybeEmitActivationMoment(ctx, surfaceId);
1659
+
1560
1660
  const requestedCompletionSummary =
1561
1661
  getRequestedSurfaceCompletionSummary(mergedData);
1562
1662
  if (requestedCompletionSummary) {
@@ -1796,6 +1896,12 @@ export async function handleSurfaceAction(
1796
1896
  return;
1797
1897
  }
1798
1898
 
1899
+ // Terminal user commit accepted — record the activation milestone if this
1900
+ // surface was tagged (best-effort, no-op otherwise). Deferred until after the
1901
+ // rejection check so a queue-full click doesn't over-report a moment (and the
1902
+ // one-shot tag stays intact for the user's retry).
1903
+ maybeEmitActivationMoment(ctx, surfaceId);
1904
+
1799
1905
  const requestedCompletionSummary =
1800
1906
  getRequestedSurfaceCompletionSummary(mergedData);
1801
1907
 
@@ -1960,6 +2066,15 @@ export function refreshSurfacesForApp(
1960
2066
  return refreshed;
1961
2067
  }
1962
2068
 
2069
+ /**
2070
+ * Strip a leading "Connect "/"Connected " verb from an OAuth provider label so
2071
+ * a supplied displayName like "Connect Gmail" doesn't double the verb when
2072
+ * prefixed (e.g. avoids "Connected Connect Gmail").
2073
+ */
2074
+ function stripConnectVerb(label: string): string {
2075
+ return label.replace(/^connect(?:ed)?\s+/i, "");
2076
+ }
2077
+
1963
2078
  export function buildCompletionSummary(
1964
2079
  surfaceType: string | undefined,
1965
2080
  actionId: string,
@@ -2026,20 +2141,24 @@ export function buildCompletionSummary(
2026
2141
  : typeof data?.providerKey === "string"
2027
2142
  ? data.providerKey
2028
2143
  : "OAuth";
2144
+ // Strip the verb once so every branch (connected/cancelled/failed/
2145
+ // fallback) is normalized — a displayName like "Connect Gmail" must not
2146
+ // produce "Cancelled Connect Gmail connection".
2147
+ const label = stripConnectVerb(providerLabel);
2029
2148
  const accountLabel =
2030
2149
  typeof data?.accountLabel === "string" ? data.accountLabel : undefined;
2031
2150
  if (actionId === "connect" || data?.status === "connected") {
2032
2151
  return accountLabel
2033
- ? `Connected ${providerLabel}: ${accountLabel}`
2034
- : `Connected ${providerLabel}`;
2152
+ ? `Connected ${label}: ${accountLabel}`
2153
+ : `Connected ${label}`;
2035
2154
  }
2036
2155
  if (actionId === "cancel" || data?.status === "cancelled") {
2037
- return `Cancelled ${providerLabel} connection`;
2156
+ return `Cancelled ${label} connection`;
2038
2157
  }
2039
2158
  if (data?.status === "error") {
2040
- return `${providerLabel} connection failed`;
2159
+ return `${label} connection failed`;
2041
2160
  }
2042
- return `${providerLabel} connection ${actionId}`;
2161
+ return `${label} connection ${actionId}`;
2043
2162
  }
2044
2163
  if (surfaceType === "list" && data) {
2045
2164
  const selectedIds = data.selectedIds as string[] | undefined;
@@ -2120,18 +2239,21 @@ function buildUserFacingLabel(
2120
2239
  : typeof data?.providerKey === "string"
2121
2240
  ? data.providerKey
2122
2241
  : "OAuth";
2242
+ // Strip the verb once so every branch is normalized (e.g. a displayName
2243
+ // like "Connect Gmail" must not produce "Connect Gmail connection failed").
2244
+ const label = stripConnectVerb(providerLabel);
2123
2245
  const accountLabel =
2124
2246
  typeof data?.accountLabel === "string" ? data.accountLabel : undefined;
2125
2247
  if (actionId === "connect" || data?.status === "connected") {
2126
2248
  return accountLabel
2127
- ? `Connected ${providerLabel}: ${accountLabel}`
2128
- : `Connected ${providerLabel}`;
2249
+ ? `Connected ${label}: ${accountLabel}`
2250
+ : `Connected ${label}`;
2129
2251
  }
2130
2252
  if (actionId === "cancel" || data?.status === "cancelled") {
2131
2253
  return "Cancelled";
2132
2254
  }
2133
2255
  if (data?.status === "error") {
2134
- return `${providerLabel} connection failed`;
2256
+ return `${label} connection failed`;
2135
2257
  }
2136
2258
  return `Selected: ${actionId}`;
2137
2259
  }
@@ -2199,7 +2321,10 @@ export async function surfaceProxyResolver(
2199
2321
  // validate at the tool-resolution layer for the same reason. The proxy
2200
2322
  // re-checks same-user (single authoritative gate); using the shared
2201
2323
  // helper keeps log payload and error wording identical at both layers.
2202
- const sourceActorPrincipalId = ctx.trustContext?.guardianPrincipalId;
2324
+ const sourceActorPrincipalId =
2325
+ ctx.currentTurnSourceActorPrincipalId ??
2326
+ ctx.currentTurnAuthContext?.actorPrincipalId ??
2327
+ ctx.authContext?.actorPrincipalId;
2203
2328
  if (targetClientId != null) {
2204
2329
  const client = assistantEventHub.getClientById(targetClientId);
2205
2330
  if (!client) {
@@ -2305,7 +2430,10 @@ export async function surfaceProxyResolver(
2305
2430
  ? input.target_client_id
2306
2431
  : undefined;
2307
2432
 
2308
- const sourceActorPrincipalId = ctx.trustContext?.guardianPrincipalId;
2433
+ const sourceActorPrincipalId =
2434
+ ctx.currentTurnSourceActorPrincipalId ??
2435
+ ctx.currentTurnAuthContext?.actorPrincipalId ??
2436
+ ctx.authContext?.actorPrincipalId;
2309
2437
  if (targetClientId != null) {
2310
2438
  const client = assistantEventHub.getClientById(targetClientId);
2311
2439
  if (!client) {
@@ -2488,6 +2616,24 @@ export async function surfaceProxyResolver(
2488
2616
  ...(a.data ? { data: a.data } : {}),
2489
2617
  }));
2490
2618
 
2619
+ // Optional activation-rail telemetry tag. Daemon-only metadata: validated
2620
+ // and ignored if invalid; never forwarded to the client.
2621
+ const activationMoment =
2622
+ typeof input.activation_moment === "string" &&
2623
+ isActivationMomentParam(input.activation_moment)
2624
+ ? input.activation_moment
2625
+ : undefined;
2626
+
2627
+ // Show-timing moments (`first_wow_executed`) record the instant the surface
2628
+ // renders — a display-only result/`work_result` card may never be committed,
2629
+ // so a commit-time emit would never fire. We record now and do NOT store the
2630
+ // tag, so the commit path won't double-emit. Commit-timing moments are
2631
+ // stored and recorded when the user commits the surface (see
2632
+ // `handleSurfaceAction` → `maybeEmitActivationMoment`).
2633
+ const storeTagForCommit =
2634
+ activationMoment !== undefined &&
2635
+ !activationMomentEmitsAtShow(activationMoment);
2636
+
2491
2637
  // Track surface state for ui_update merging (includes actions so we can
2492
2638
  // look up per-action data payloads when the client sends an action back).
2493
2639
  ctx.surfaceState.set(surfaceId, {
@@ -2495,8 +2641,13 @@ export async function surfaceProxyResolver(
2495
2641
  data,
2496
2642
  title,
2497
2643
  actions: mappedActions,
2644
+ ...(storeTagForCommit ? { activationMoment } : {}),
2498
2645
  });
2499
2646
 
2647
+ if (activationMoment !== undefined && !storeTagForCommit) {
2648
+ recordActivationMoment(ctx, activationMoment);
2649
+ }
2650
+
2500
2651
  log.info(
2501
2652
  {
2502
2653
  surfaceId,
@@ -2524,7 +2675,9 @@ export async function surfaceProxyResolver(
2524
2675
  ...(toolUseId ? { toolCallId: toolUseId } : {}),
2525
2676
  } as unknown as UiSurfaceShow);
2526
2677
 
2527
- // Track surface for persistence with the message
2678
+ // Track surface for persistence with the message. The commit-timing
2679
+ // activation tag rides along (daemon-only) so it survives history restore;
2680
+ // show-timing moments aren't stored here (already recorded at render).
2528
2681
  ctx.currentTurnSurfaces.push({
2529
2682
  surfaceId,
2530
2683
  surfaceType,
@@ -2534,6 +2687,7 @@ export async function surfaceProxyResolver(
2534
2687
  display,
2535
2688
  ...(persistent ? { persistent: true } : {}),
2536
2689
  ...(toolUseId ? { toolCallId: toolUseId } : {}),
2690
+ ...(storeTagForCommit ? { activationMoment } : {}),
2537
2691
  });
2538
2692
 
2539
2693
  if (awaitAction) {
@@ -4,6 +4,7 @@ import { getConversation } from "../memory/conversation-crud.js";
4
4
  import { resolveConversationDirectoryPaths } from "../memory/conversation-directories.js";
5
5
  import { renderWorkspaceTopLevelContext } from "../workspace/top-level-renderer.js";
6
6
  import { scanTopLevelDirectories } from "../workspace/top-level-scanner.js";
7
+ import { findConversationOrSubagent } from "./conversation-registry.js";
7
8
 
8
9
  /**
9
10
  * Subset of Conversation state that workspace context helpers need.
@@ -25,6 +26,22 @@ export interface WorkspaceConversationContext {
25
26
  hostUsername?: string;
26
27
  }
27
28
 
29
+ /**
30
+ * Resolve the live workspace top-level block for a conversation, refreshing
31
+ * the dirty-guarded cache first so a workspace-mutating tool's
32
+ * `markWorkspaceTopLevelDirty` from the prior turn is picked up. Returns `null`
33
+ * when no live conversation is found (no active conversation, or a context with
34
+ * no conversation id) or when the rendered context is empty.
35
+ */
36
+ export function resolveWorkspaceTopLevelContext(
37
+ conversationId: string | undefined,
38
+ ): string | null {
39
+ const conversation = findConversationOrSubagent(conversationId);
40
+ if (!conversation) return null;
41
+ refreshWorkspaceTopLevelContextIfNeeded(conversation);
42
+ return conversation.workspaceTopLevelContext;
43
+ }
44
+
28
45
  /** Refresh workspace top-level directory context if needed. */
29
46
  export function refreshWorkspaceTopLevelContextIfNeeded(
30
47
  ctx: WorkspaceConversationContext,