@vellumai/assistant 0.12.2 → 0.12.3-staging.2

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 (772) hide show
  1. package/.env.example +2 -0
  2. package/AGENTS.md +1 -1
  3. package/ARCHITECTURE.md +43 -29
  4. package/Dockerfile +63 -0
  5. package/docs/architecture/integrations.md +7 -0
  6. package/docs/architecture/memory.md +17 -2
  7. package/docs/architecture/security.md +10 -5
  8. package/docs/architecture/turn-actor.md +2 -0
  9. package/docs/credential-execution-service.md +1 -1
  10. package/docs/desktop-browser-cli.md +50 -5
  11. package/docs/live-voice-task-outcomes.md +100 -0
  12. package/docs/mode-sessions.md +183 -0
  13. package/docs/voice-input-diagnostics.md +58 -0
  14. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +2 -1
  15. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
  16. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  17. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
  18. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
  19. package/node_modules/@vellumai/environments/src/shell.test.ts +21 -0
  20. package/node_modules/@vellumai/environments/src/shell.ts +24 -0
  21. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +2 -1
  22. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
  23. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  24. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
  25. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
  26. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -0
  27. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -2
  28. package/node_modules/@vellumai/gateway-client/src/index.ts +4 -1
  29. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +38 -7
  30. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +5 -6
  31. package/node_modules/@vellumai/service-contracts/package.json +2 -1
  32. package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +1 -0
  33. package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  34. package/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
  35. package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +4 -1
  36. package/node_modules/@vellumai/slack-text/src/index.ts +4 -8
  37. package/openapi.yaml +716 -16
  38. package/package.json +1 -1
  39. package/scripts/smoke-desktop-browser-cli.ts +11 -26
  40. package/scripts/smoke-desktop-window-theme.ts +2 -3
  41. package/scripts/sync-llm-catalog.ts +3 -0
  42. package/scripts/voice-ttft-spike.ts +2 -2
  43. package/src/__tests__/agent-loop-output-hooks.test.ts +150 -1
  44. package/src/__tests__/agent-loop-provider-error-recording.test.ts +87 -19
  45. package/src/__tests__/agent-loop.test.ts +259 -0
  46. package/src/__tests__/agent-wake-delegation-prompt.test.ts +64 -2
  47. package/src/__tests__/annotate-activity-metadata.test.ts +3 -1
  48. package/src/__tests__/annotate-risk-options.test.ts +2 -0
  49. package/src/__tests__/answered-question-persistence.test.ts +2 -0
  50. package/src/__tests__/anthropic-gateway-shared.test.ts +22 -0
  51. package/src/__tests__/anthropic-provider.test.ts +55 -0
  52. package/src/__tests__/approval-interception-trust-gates.test.ts +40 -0
  53. package/src/__tests__/approval-message-composer.test.ts +1 -118
  54. package/src/__tests__/approval-routes-http.test.ts +3 -0
  55. package/src/__tests__/assistant-event-hub-connection-history.test.ts +111 -0
  56. package/src/__tests__/assistant-event-hub-targeted.test.ts +50 -0
  57. package/src/__tests__/assistant-event-targeting.test.ts +186 -0
  58. package/src/__tests__/assistant-stream-state.test.ts +29 -9
  59. package/src/__tests__/attachments-store.test.ts +22 -3
  60. package/src/__tests__/browser-fill-credential.test.ts +11 -22
  61. package/src/__tests__/btw-routes.test.ts +4 -1
  62. package/src/__tests__/build-persisted-content.test.ts +1 -1
  63. package/src/__tests__/call-conversation-messages.test.ts +5 -0
  64. package/src/__tests__/call-recovery.test.ts +7 -2
  65. package/src/__tests__/call-routes-http.test.ts +12 -0
  66. package/src/__tests__/call-store.test.ts +7 -2
  67. package/src/__tests__/channel-approval.test.ts +9 -14
  68. package/src/__tests__/channel-reply-delivery.test.ts +56 -0
  69. package/src/__tests__/channel-retry-sweep.test.ts +9 -0
  70. package/src/__tests__/chat-credential-redaction.test.ts +23 -0
  71. package/src/__tests__/chat-reveal-guard-priming.test.ts +2 -0
  72. package/src/__tests__/checker.test.ts +11 -3
  73. package/src/__tests__/client-os-metadata-persistence.test.ts +35 -1
  74. package/src/__tests__/computer-use-screenshot-attachments.test.ts +411 -0
  75. package/src/__tests__/computer-use-screenshot-selection.test.ts +50 -0
  76. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +0 -25
  77. package/src/__tests__/computer-use-tools.test.ts +1 -233
  78. package/src/__tests__/config-model-image-provider.test.ts +39 -0
  79. package/src/__tests__/config-schema.test.ts +16 -0
  80. package/src/__tests__/config-watcher.test.ts +24 -0
  81. package/src/__tests__/context-search-agent-runner.test.ts +260 -1
  82. package/src/__tests__/context-search-fanout.test.ts +1 -1
  83. package/src/__tests__/context-search-types.test.ts +7 -7
  84. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +8 -2
  85. package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +2 -0
  86. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
  87. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -0
  88. package/src/__tests__/conversation-agent-loop.test.ts +797 -16
  89. package/src/__tests__/conversation-app-control-lifecycle.test.ts +53 -1
  90. package/src/__tests__/conversation-attachments.test.ts +106 -0
  91. package/src/__tests__/conversation-evictor.test.ts +62 -37
  92. package/src/__tests__/conversation-fork-crud.test.ts +191 -0
  93. package/src/__tests__/conversation-history-boundary-repair-failure.test.ts +174 -0
  94. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +2 -0
  95. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +2 -0
  96. package/src/__tests__/conversation-rendered-delegation-state.test.ts +276 -0
  97. package/src/__tests__/conversation-retry-route.test.ts +22 -0
  98. package/src/__tests__/conversation-routes-disk-view.test.ts +2 -0
  99. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +2 -0
  100. package/src/__tests__/conversation-routes-guardian-reply.test.ts +10 -0
  101. package/src/__tests__/conversation-routes-hidden-queue.test.ts +2 -0
  102. package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
  103. package/src/__tests__/conversation-runtime-assembly.test.ts +29 -0
  104. package/src/__tests__/conversation-surface-snapshots.test.ts +543 -0
  105. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +151 -0
  106. package/src/__tests__/conversation-surfaces-point-at-budget.test.ts +63 -1
  107. package/src/__tests__/conversation-tool-setup-attribution.test.ts +23 -0
  108. package/src/__tests__/conversation-undo.test.ts +61 -0
  109. package/src/__tests__/credential-execution-client.test.ts +72 -55
  110. package/src/__tests__/credential-prompt-route.test.ts +35 -3
  111. package/src/__tests__/cu-unified-flow.test.ts +82 -1
  112. package/src/__tests__/db-conversation-tool-surface.test.ts +221 -0
  113. package/src/__tests__/db-mode-sessions-migration.test.ts +175 -0
  114. package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -0
  115. package/src/__tests__/dm-backfill.test.ts +91 -1
  116. package/src/__tests__/document-create-route.test.ts +88 -0
  117. package/src/__tests__/document-sync-tags.test.ts +27 -0
  118. package/src/__tests__/emit-signal-routing-intent.test.ts +142 -2
  119. package/src/__tests__/events-tail-route.test.ts +58 -0
  120. package/src/__tests__/evict-conversations-for-reload.test.ts +57 -8
  121. package/src/__tests__/guardian-action-sweep.test.ts +16 -0
  122. package/src/__tests__/guardian-dispatch.test.ts +13 -0
  123. package/src/__tests__/headless-browser-interactions.test.ts +64 -20
  124. package/src/__tests__/heartbeat-service.test.ts +2 -59
  125. package/src/__tests__/helpers/mock-conversation.ts +21 -0
  126. package/src/__tests__/helpers/native-web-search-harness.ts +2 -0
  127. package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +5 -0
  128. package/src/__tests__/history-repair.test.ts +53 -0
  129. package/src/__tests__/host-cu-proxy.test.ts +46 -2
  130. package/src/__tests__/http-user-message-parity.test.ts +2 -0
  131. package/src/__tests__/image-credentials.test.ts +49 -0
  132. package/src/__tests__/image-service-dispatcher.test.ts +45 -0
  133. package/src/__tests__/inference-profile-session-handler.test.ts +26 -0
  134. package/src/__tests__/interrupt-on-send.test.ts +57 -43
  135. package/src/__tests__/interrupt-turn-note.test.ts +5 -6
  136. package/src/__tests__/list-messages-tool-merge.test.ts +85 -1
  137. package/src/__tests__/llm-catalog-parity.test.ts +27 -4
  138. package/src/__tests__/media-generate-image.test.ts +49 -1
  139. package/src/__tests__/message-provenance-contact-id.test.ts +69 -0
  140. package/src/__tests__/migration-export-to-gcs.test.ts +142 -0
  141. package/src/__tests__/mode-session-history.test.ts +245 -0
  142. package/src/__tests__/mode-session-recovery.test.ts +222 -0
  143. package/src/__tests__/mode-session-wire.test.ts +141 -0
  144. package/src/__tests__/notification-guardian-path.test.ts +7 -0
  145. package/src/__tests__/notification-telegram-adapter.test.ts +2 -2
  146. package/src/__tests__/notification-vellum-adapter.test.ts +34 -0
  147. package/src/__tests__/oauth-apps-routes.test.ts +1 -0
  148. package/src/__tests__/oauth-commands-routes.test.ts +114 -101
  149. package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
  150. package/src/__tests__/oauth-provider-serializer.test.ts +13 -0
  151. package/src/__tests__/oauth-providers-routes.test.ts +3 -0
  152. package/src/__tests__/outbound-slack-persistence.test.ts +2 -0
  153. package/src/__tests__/persist-media-references.test.ts +50 -0
  154. package/src/__tests__/persistence-secret-redaction.test.ts +2 -0
  155. package/src/__tests__/plugin-api-provider.test.ts +5 -0
  156. package/src/__tests__/plugin-api-resolve-credential.test.ts +97 -0
  157. package/src/__tests__/plugin-import-boundary-guard.test.ts +9 -1
  158. package/src/__tests__/process-message-display-content.test.ts +56 -0
  159. package/src/__tests__/reaction-persistence.test.ts +5 -0
  160. package/src/__tests__/request-secret-standalone-channel-gate.test.ts +25 -9
  161. package/src/__tests__/run-conversation-turn-persistence.test.ts +138 -1
  162. package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
  163. package/src/__tests__/schedule-routes.test.ts +20 -0
  164. package/src/__tests__/scheduler-result-notification.test.ts +23 -4
  165. package/src/__tests__/script-proxy-certs.test.ts +1 -1
  166. package/src/__tests__/scripted-turn-metadata-persistence.test.ts +73 -0
  167. package/src/__tests__/secret-ingress-http.test.ts +2 -0
  168. package/src/__tests__/secret-routes-platform-proxy.test.ts +86 -31
  169. package/src/__tests__/secret-routes-scrub.test.ts +22 -27
  170. package/src/__tests__/secret-scanner.test.ts +20 -0
  171. package/src/__tests__/secure-keys-managed-failover.test.ts +8 -0
  172. package/src/__tests__/secure-keys.test.ts +50 -4
  173. package/src/__tests__/send-endpoint-busy.test.ts +163 -1
  174. package/src/__tests__/server-history-render.test.ts +91 -1
  175. package/src/__tests__/server-tool-pairing.test.ts +107 -0
  176. package/src/__tests__/settings-routes.test.ts +50 -1
  177. package/src/__tests__/skill-script-runner-sandbox.test.ts +32 -0
  178. package/src/__tests__/skills.test.ts +5 -4
  179. package/src/__tests__/subagent-fork-notifications.test.ts +1 -2
  180. package/src/__tests__/subagent-manager-notify.test.ts +1 -2
  181. package/src/__tests__/subagent-notify-parent.test.ts +146 -39
  182. package/src/__tests__/subagent-notify-stale-rebuild.test.ts +2 -4
  183. package/src/__tests__/subagent-tool-gate-mode.test.ts +226 -0
  184. package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +2 -0
  185. package/src/__tests__/terminal-tools.test.ts +8 -0
  186. package/src/__tests__/thread-backfill.test.ts +53 -0
  187. package/src/__tests__/tool-preview-lifecycle.test.ts +2 -0
  188. package/src/__tests__/tool-result-follow-up.test.ts +99 -0
  189. package/src/__tests__/tool-result-metadata-plumbing.test.ts +66 -1
  190. package/src/__tests__/tool-start-timestamp.test.ts +2 -0
  191. package/src/__tests__/twilio-routes.test.ts +1 -0
  192. package/src/__tests__/unicode.test.ts +36 -0
  193. package/src/__tests__/web-search-backend-failure.test.ts +1 -1
  194. package/src/activation/progress-store.test.ts +12 -7
  195. package/src/agent/loop.ts +136 -53
  196. package/src/agent/tool-result-follow-up.ts +70 -0
  197. package/src/api/attachment-provenance.test.ts +68 -0
  198. package/src/api/computer-use-tool.test.ts +55 -0
  199. package/src/api/computer-use-tool.ts +27 -0
  200. package/src/api/events/assistant-outbound-attachment.ts +3 -0
  201. package/src/api/events/assistant-turn-start.ts +3 -0
  202. package/src/api/events/desktop-activity-changed.ts +10 -0
  203. package/src/api/events/generation-handoff.ts +2 -0
  204. package/src/api/events/message-complete.ts +2 -0
  205. package/src/api/events/notification-conversation-created.ts +14 -16
  206. package/src/api/events/notification-intent.ts +4 -2
  207. package/src/api/events/question-request.ts +1 -0
  208. package/src/api/events/tool-result.ts +85 -0
  209. package/src/api/events/tool-use-start.ts +3 -0
  210. package/src/api/events/user-message-echo.ts +3 -0
  211. package/src/api/index.ts +42 -6
  212. package/src/api/mode-session.test.ts +131 -0
  213. package/src/api/mode-session.ts +148 -0
  214. package/src/api/remember-tool.ts +15 -0
  215. package/src/api/responses/conversation-message.ts +9 -0
  216. package/src/approvals/AGENTS.md +4 -2
  217. package/src/approvals/approval-primitive.ts +5 -2
  218. package/src/approvals/scoped-approval-grants.ts +6 -2
  219. package/src/browser/__tests__/operations.test.ts +29 -0
  220. package/src/browser/operation-meta.ts +2 -1
  221. package/src/browser/operations.ts +29 -0
  222. package/src/browser/virtual-desktop-target.ts +2 -9
  223. package/src/bundler/bundle-signer.ts +1 -3
  224. package/src/calls/__tests__/barge-in-guard.test.ts +3 -0
  225. package/src/calls/__tests__/call-controller.test.ts +94 -0
  226. package/src/calls/__tests__/call-funnel-telemetry.test.ts +204 -0
  227. package/src/calls/__tests__/voice-control-protocol.test.ts +15 -0
  228. package/src/calls/__tests__/voice-escalation-judge.test.ts +209 -0
  229. package/src/calls/__tests__/voice-leg-coordinator.test.ts +168 -0
  230. package/src/{live-voice/__tests__/live-voice-metrics.test.ts → calls/__tests__/voice-metrics.test.ts} +32 -38
  231. package/src/calls/__tests__/voice-session-bridge.test.ts +576 -122
  232. package/src/calls/barge-in-guard.ts +5 -0
  233. package/src/calls/call-controller.ts +196 -1
  234. package/src/calls/call-domain.ts +4 -0
  235. package/src/calls/call-store.ts +87 -2
  236. package/src/calls/guardian-action-sweep.ts +22 -8
  237. package/src/calls/media-stream-audio-transcode.ts +1 -3
  238. package/src/calls/typesafe-noul.ts +156 -0
  239. package/src/calls/voice-control-protocol.ts +6 -0
  240. package/src/calls/voice-escalation-judge.ts +145 -0
  241. package/src/calls/voice-escalation-target.ts +10 -0
  242. package/src/calls/voice-leg-coordinator.ts +121 -3
  243. package/src/{live-voice/live-voice-metrics.ts → calls/voice-metrics.ts} +94 -87
  244. package/src/calls/voice-session-bridge.ts +256 -112
  245. package/src/calls/voice-triage-escalate.ts +7 -0
  246. package/src/cli/__tests__/roadmap-cli.test.ts +4 -41
  247. package/src/cli/commands/__tests__/cli-test-harness.ts +21 -3
  248. package/src/cli/commands/__tests__/notifications.test.ts +35 -10
  249. package/src/cli/commands/__tests__/plugins.test.ts +20 -1
  250. package/src/cli/commands/__tests__/schedules.test.ts +14 -0
  251. package/src/cli/commands/bash.help.ts +4 -3
  252. package/src/cli/commands/browser.help.ts +9 -6
  253. package/src/cli/commands/browser.ts +0 -1
  254. package/src/cli/commands/clients.help.ts +46 -0
  255. package/src/cli/commands/clients.ts +116 -0
  256. package/src/cli/commands/credentials.help.ts +9 -4
  257. package/src/cli/commands/notifications.help.ts +16 -2
  258. package/src/cli/commands/notifications.ts +30 -8
  259. package/src/cli/commands/oauth/index.help.ts +10 -0
  260. package/src/cli/commands/oauth/providers.ts +12 -0
  261. package/src/cli/commands/oauth/request.test.ts +179 -2
  262. package/src/cli/commands/oauth/request.ts +41 -10
  263. package/src/cli/commands/plugins.ts +12 -5
  264. package/src/cli/commands/roadmap.help.ts +18 -21
  265. package/src/cli/commands/roadmap.ts +4 -21
  266. package/src/cli/commands/schedules.ts +2 -0
  267. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  268. package/src/cli/lib/__tests__/install-from-github.test.ts +41 -0
  269. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +5 -2
  270. package/src/cli/lib/__tests__/local-plugin-upgrade.test.ts +133 -51
  271. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +8 -2
  272. package/src/cli/lib/bundled-marketplace.json +906 -1
  273. package/src/cli/lib/bundled-plugin-packages.json +783 -1
  274. package/src/cli/lib/inspect-plugin.ts +11 -4
  275. package/src/cli/lib/plugin-marketplace.ts +8 -0
  276. package/src/cli/lib/publish-plugin.ts +1 -2
  277. package/src/cli/lib/upgrade-plugin.ts +19 -11
  278. package/src/cli/output.ts +18 -4
  279. package/src/config/__tests__/default-provider.test.ts +6 -0
  280. package/src/config/__tests__/memory-retrospective-schema.test.ts +14 -1
  281. package/src/config/bundled-skills/computer-use/SKILL.md +1 -1
  282. package/src/config/bundled-skills/computer-use/TOOLS.json +89 -1
  283. package/src/config/bundled-skills/image-studio/SKILL.md +17 -2
  284. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +7 -11
  285. package/src/config/bundled-skills/schedule/SKILL.md +6 -6
  286. package/src/config/bundled-skills/sequences/TOOLS.json +1 -5
  287. package/src/config/call-site-defaults.ts +9 -0
  288. package/src/config/feature-flag-registry.json +16 -0
  289. package/src/config/loader.ts +9 -17
  290. package/src/config/platform-identity.ts +8 -8
  291. package/src/config/profile-text-generation.test.ts +51 -0
  292. package/src/config/profile-text-generation.ts +51 -0
  293. package/src/config/schemas/__tests__/memory-v3.test.ts +12 -0
  294. package/src/config/schemas/__tests__/tools.test.ts +31 -0
  295. package/src/config/schemas/call-site-catalog.ts +14 -0
  296. package/src/config/schemas/channels.ts +0 -18
  297. package/src/config/schemas/llm.ts +9 -2
  298. package/src/config/schemas/mcp.ts +6 -1
  299. package/src/config/schemas/memory-retrospective.ts +11 -2
  300. package/src/config/schemas/memory-v3.ts +12 -0
  301. package/src/config/schemas/services.ts +15 -6
  302. package/src/config/schemas/tools.ts +10 -0
  303. package/src/config/session-groups-gate.ts +21 -0
  304. package/src/config/skills.ts +2 -6
  305. package/src/conversations/__tests__/message-consolidation.test.ts +149 -0
  306. package/src/conversations/message-consolidation.ts +102 -5
  307. package/src/credential-execution/ces-connect.test.ts +69 -0
  308. package/src/credential-execution/ces-connect.ts +115 -0
  309. package/src/credential-execution/ces-runtime.ts +55 -93
  310. package/src/credential-execution/executable-discovery.ts +34 -142
  311. package/src/credential-execution/process-manager.test.ts +20 -24
  312. package/src/credential-execution/process-manager.ts +24 -19
  313. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +10 -1
  314. package/src/daemon/__tests__/conversation-tool-setup.test.ts +43 -0
  315. package/src/daemon/__tests__/inference-profile-notification.test.ts +2 -0
  316. package/src/daemon/__tests__/turn-tail-deleted-conversation.test.ts +36 -0
  317. package/src/daemon/assistant-attachments.ts +20 -12
  318. package/src/daemon/browser-mode-session.test.ts +402 -0
  319. package/src/daemon/browser-mode-session.ts +186 -0
  320. package/src/daemon/chat-credential-redaction.ts +16 -1
  321. package/src/daemon/computer-use-mode-session.test.ts +210 -0
  322. package/src/daemon/computer-use-mode-session.ts +105 -0
  323. package/src/daemon/config-watcher.ts +10 -0
  324. package/src/daemon/conversation-agent-loop-handlers.ts +132 -13
  325. package/src/daemon/conversation-agent-loop.ts +231 -25
  326. package/src/daemon/conversation-attachments.ts +93 -12
  327. package/src/daemon/conversation-evictor.ts +5 -24
  328. package/src/daemon/conversation-history.ts +10 -0
  329. package/src/daemon/conversation-interrupt-repair.ts +4 -43
  330. package/src/daemon/conversation-interrupt.ts +7 -11
  331. package/src/daemon/conversation-messaging.ts +58 -5
  332. package/src/daemon/conversation-mode-session.test.ts +1667 -0
  333. package/src/daemon/conversation-mode-session.ts +1008 -0
  334. package/src/daemon/conversation-process.ts +5 -0
  335. package/src/daemon/conversation-runtime-assembly.ts +10 -20
  336. package/src/daemon/conversation-skill-tools.ts +1 -0
  337. package/src/daemon/conversation-store.ts +4 -4
  338. package/src/daemon/conversation-surface-snapshots.ts +135 -0
  339. package/src/daemon/conversation-surfaces.ts +113 -5
  340. package/src/daemon/conversation-tool-setup.ts +79 -6
  341. package/src/daemon/conversation-turn-finalize.ts +26 -13
  342. package/src/daemon/conversation.ts +215 -58
  343. package/src/daemon/daemon-control.ts +3 -7
  344. package/src/daemon/handlers/config-model.ts +7 -5
  345. package/src/daemon/handlers/shared.ts +55 -16
  346. package/src/daemon/host-cu-proxy.ts +51 -22
  347. package/src/daemon/lifecycle.ts +30 -13
  348. package/src/daemon/mcp-reload-service.ts +1 -1
  349. package/src/daemon/message-protocol.ts +0 -1
  350. package/src/daemon/message-provenance.ts +28 -4
  351. package/src/daemon/message-types/shared.ts +1 -0
  352. package/src/daemon/mode-session-startup-recovery.ts +23 -0
  353. package/src/daemon/mode-session-tracking.ts +54 -0
  354. package/src/daemon/orphan-reaper.ts +4 -3
  355. package/src/daemon/persist-media-references.ts +20 -3
  356. package/src/daemon/process-message.ts +13 -4
  357. package/src/daemon/tool-setup-types.ts +6 -0
  358. package/src/daemon/virtual-desktop-context.ts +21 -0
  359. package/src/daemon/wake-conversation-ops.ts +50 -15
  360. package/src/desktop/__tests__/fake-desktop.ts +1 -0
  361. package/src/desktop/desktop-accessibility-script.ts +88 -0
  362. package/src/desktop/desktop-accessibility.test.ts +160 -0
  363. package/src/desktop/desktop-accessibility.ts +169 -0
  364. package/src/desktop/desktop-automation-lease.test.ts +302 -64
  365. package/src/desktop/desktop-automation-lease.ts +129 -54
  366. package/src/desktop/desktop-browser-endpoint.ts +4 -0
  367. package/src/desktop/desktop-computer-use-routing.test.ts +330 -0
  368. package/src/desktop/desktop-computer-use.test.ts +449 -0
  369. package/src/desktop/desktop-computer-use.ts +502 -0
  370. package/src/desktop/desktop-dependencies.ts +47 -293
  371. package/src/desktop/desktop-display.ts +2 -2
  372. package/src/desktop/desktop-help.ts +15 -0
  373. package/src/desktop/desktop-panel-config.test.ts +13 -3
  374. package/src/desktop/desktop-panel-config.ts +109 -15
  375. package/src/desktop/desktop-session-manager.test.ts +69 -21
  376. package/src/desktop/desktop-session-manager.ts +76 -22
  377. package/src/desktop/desktop-stream-bridge.test.ts +76 -132
  378. package/src/desktop/desktop-stream-bridge.ts +9 -11
  379. package/src/desktop/desktop-wallpaper-renderer.ts +132 -0
  380. package/src/desktop/desktop-wallpaper-worker.ts +17 -0
  381. package/src/desktop/desktop-wallpaper.test.ts +48 -7
  382. package/src/desktop/desktop-wallpaper.ts +34 -102
  383. package/src/desktop/desktop-window-theme.ts +5 -25
  384. package/src/desktop/virtual-desktop-feature.ts +53 -3
  385. package/src/desktop/virtual-desktop-platform.test.ts +5 -9
  386. package/src/documents/document-store.ts +23 -0
  387. package/src/heartbeat/__tests__/heartbeat-service.test.ts +22 -26
  388. package/src/heartbeat/heartbeat-service.ts +5 -33
  389. package/src/ipc/__tests__/browser-ipc.test.ts +215 -6
  390. package/src/ipc/assistant-server.ts +2 -0
  391. package/src/ipc/routes/__tests__/channel-reply-ipc-routes.test.ts +111 -0
  392. package/src/ipc/routes/channel-reply-ipc-routes.ts +73 -0
  393. package/src/live-voice/__tests__/continuation-judge.test.ts +151 -0
  394. package/src/live-voice/__tests__/live-activity-reporter.test.ts +154 -15
  395. package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +743 -31
  396. package/src/live-voice/__tests__/live-voice-look-follow-up.test.ts +191 -10
  397. package/src/live-voice/__tests__/live-voice-session-groups-gate.test.ts +87 -0
  398. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +5 -1
  399. package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +41 -0
  400. package/src/live-voice/__tests__/live-voice-sight-frame.test.ts +1017 -9
  401. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +224 -1
  402. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +101 -0
  403. package/src/live-voice/__tests__/live-voice-tts.test.ts +44 -0
  404. package/src/live-voice/__tests__/live-voice-vad.test.ts +939 -75
  405. package/src/live-voice/__tests__/microphone-idle-gate.test.ts +87 -0
  406. package/src/live-voice/__tests__/session-controls.test.ts +23 -0
  407. package/src/live-voice/__tests__/task-outcomes.test.ts +117 -0
  408. package/src/live-voice/__tests__/voice-input-diagnostics.test.ts +117 -0
  409. package/src/live-voice/camera-mode-session.test.ts +265 -0
  410. package/src/live-voice/camera-mode-session.ts +277 -0
  411. package/src/live-voice/continuation-judge.ts +123 -0
  412. package/src/live-voice/live-activity-reporter.ts +115 -6
  413. package/src/live-voice/live-voice-manager.ts +36 -1
  414. package/src/live-voice/live-voice-photo.ts +88 -7
  415. package/src/live-voice/live-voice-session-manager.ts +15 -0
  416. package/src/live-voice/live-voice-session.ts +1443 -747
  417. package/src/live-voice/live-voice-tts.ts +22 -4
  418. package/src/live-voice/microphone-idle-gate.ts +56 -0
  419. package/src/live-voice/protocol.ts +171 -4
  420. package/src/live-voice/session-controls.ts +11 -3
  421. package/src/live-voice/task-outcomes.ts +131 -0
  422. package/src/live-voice/voice-input-diagnostics.ts +117 -0
  423. package/src/mcp/__tests__/manager-tool-caps.test.ts +156 -0
  424. package/src/mcp/__tests__/startup.test.ts +30 -7
  425. package/src/mcp/__tests__/tool-caps.test.ts +134 -0
  426. package/src/mcp/manager.ts +171 -101
  427. package/src/mcp/startup.ts +33 -13
  428. package/src/mcp/tool-caps.ts +184 -0
  429. package/src/media/__tests__/image-models.test.ts +58 -0
  430. package/src/media/image-credentials.ts +5 -0
  431. package/src/media/image-models.ts +52 -0
  432. package/src/media/image-service.ts +8 -0
  433. package/src/media/openrouter-image-service.test.ts +133 -0
  434. package/src/media/openrouter-image-service.ts +153 -0
  435. package/src/media/types.ts +1 -1
  436. package/src/messaging/provider-message-metadata.ts +3 -3
  437. package/src/messaging/providers/__tests__/transport-dispatch.test.ts +65 -11
  438. package/src/messaging/providers/discord/send.ts +4 -17
  439. package/src/messaging/providers/discord/transport.ts +2 -2
  440. package/src/messaging/providers/outlook/client.ts +16 -22
  441. package/src/messaging/providers/telegram-bot/send.test.ts +236 -1
  442. package/src/messaging/providers/telegram-bot/send.ts +10 -7
  443. package/src/messaging/providers/telegram-bot/transport.ts +3 -10
  444. package/src/messaging/providers/whatsapp/send.test.ts +169 -4
  445. package/src/monitoring/__tests__/control.test.ts +17 -5
  446. package/src/monitoring/control.ts +15 -5
  447. package/src/notifications/AGENTS.md +1 -1
  448. package/src/notifications/README.md +83 -99
  449. package/src/notifications/__tests__/broadcaster.test.ts +1 -1
  450. package/src/notifications/__tests__/channel-allowlist.test.ts +39 -0
  451. package/src/notifications/__tests__/copy-composer.test.ts +71 -1
  452. package/src/notifications/__tests__/decision-engine.test.ts +79 -2
  453. package/src/notifications/__tests__/deterministic-checks.test.ts +10 -10
  454. package/src/notifications/__tests__/home-feed-side-effect.test.ts +93 -4
  455. package/src/notifications/__tests__/notification-utils.test.ts +18 -0
  456. package/src/notifications/adapters/macos.ts +37 -46
  457. package/src/notifications/broadcaster.ts +5 -6
  458. package/src/notifications/channel-allowlist.ts +44 -0
  459. package/src/notifications/copy-composer.ts +11 -26
  460. package/src/notifications/decision-engine.ts +24 -14
  461. package/src/notifications/deterministic-checks.ts +1 -1
  462. package/src/notifications/emit-signal.ts +123 -37
  463. package/src/notifications/home-feed-side-effect.ts +9 -7
  464. package/src/notifications/notification-utils.ts +19 -0
  465. package/src/notifications/schedule-result-producer.ts +4 -6
  466. package/src/notifications/signal.ts +4 -19
  467. package/src/notifications/types.ts +15 -0
  468. package/src/oauth/AGENTS.md +2 -0
  469. package/src/oauth/__tests__/identity-verifier.test.ts +36 -1
  470. package/src/oauth/connection-resolver.ts +1 -2
  471. package/src/oauth/identity-verifier.ts +24 -0
  472. package/src/oauth/oauth-store.ts +12 -4
  473. package/src/oauth/provider-serializer.ts +8 -0
  474. package/src/oauth/seed-providers.ts +42 -0
  475. package/src/onboarding/onboarding-events-store.ts +99 -12
  476. package/src/permissions/confirmation-guardian-request.test.ts +16 -0
  477. package/src/permissions/confirmation-guardian-request.ts +2 -3
  478. package/src/permissions/question-prompter.test.ts +31 -0
  479. package/src/permissions/question-prompter.ts +2 -0
  480. package/src/persistence/__tests__/client-connection-events-store.test.ts +322 -0
  481. package/src/persistence/attachments-store.ts +84 -44
  482. package/src/persistence/client-connection-events-store.ts +377 -0
  483. package/src/persistence/conversation-crud.ts +166 -26
  484. package/src/persistence/conversation-mode-sessions.test.ts +424 -0
  485. package/src/persistence/conversation-mode-sessions.ts +460 -0
  486. package/src/persistence/conversation-plugin-facade.ts +30 -0
  487. package/src/persistence/conversation-queries.ts +6 -19
  488. package/src/persistence/conversation-tool-surface.ts +135 -0
  489. package/src/persistence/conversation-types.test.ts +32 -0
  490. package/src/persistence/conversation-types.ts +26 -4
  491. package/src/persistence/llm-usage-store.ts +3 -9
  492. package/src/persistence/message-metadata.ts +25 -0
  493. package/src/persistence/migrations/378-create-conversation-tool-surfaces.test.ts +78 -0
  494. package/src/persistence/migrations/378-create-conversation-tool-surfaces.ts +29 -0
  495. package/src/persistence/migrations/379-oauth-providers-response-ok-field.test.ts +92 -0
  496. package/src/persistence/migrations/379-oauth-providers-response-ok-field.ts +32 -0
  497. package/src/persistence/migrations/380-conversation-tool-surfaces-delegate-independent-tasks.test.ts +90 -0
  498. package/src/persistence/migrations/380-conversation-tool-surfaces-delegate-independent-tasks.ts +34 -0
  499. package/src/persistence/migrations/381-create-conversation-mode-sessions.ts +41 -0
  500. package/src/persistence/migrations/382-create-client-connection-events.ts +40 -0
  501. package/src/persistence/migrations/__tests__/382-create-client-connection-events.test.ts +56 -0
  502. package/src/persistence/schema/conversation-tool-surfaces.ts +32 -0
  503. package/src/persistence/schema/conversations.ts +67 -0
  504. package/src/persistence/schema/index.ts +1 -0
  505. package/src/persistence/schema/infrastructure.ts +29 -0
  506. package/src/persistence/schema/oauth.ts +1 -0
  507. package/src/persistence/steps.ts +41 -3
  508. package/src/plugin-api/__tests__/plugin-name-env.test.ts +249 -0
  509. package/src/plugin-api/conversation-turn.ts +31 -7
  510. package/src/plugin-api/effective-context-window.ts +33 -0
  511. package/src/plugin-api/index.ts +35 -6
  512. package/src/plugin-api/plugin-channel-turn-trust.test.ts +133 -0
  513. package/src/plugin-api/plugin-channel-turn-trust.ts +71 -0
  514. package/src/plugin-api/plugin-name-env.ts +125 -0
  515. package/src/plugin-api/resolve-credential.ts +79 -20
  516. package/src/plugin-api/vision-support.test.ts +22 -0
  517. package/src/plugin-api/vision-support.ts +17 -5
  518. package/src/plugins/__tests__/active-plugin-env.test.ts +136 -0
  519. package/src/plugins/active-plugin-env.ts +51 -0
  520. package/src/plugins/defaults/index.ts +24 -0
  521. package/src/plugins/defaults/memory/AGENTS.md +39 -5
  522. package/src/plugins/defaults/memory/__tests__/archive-removal-framing.test.ts +64 -0
  523. package/src/plugins/defaults/memory/__tests__/buffer-file.test.ts +365 -0
  524. package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +43 -0
  525. package/src/plugins/defaults/memory/__tests__/conversation-memory-purge.test.ts +1 -0
  526. package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +2 -0
  527. package/src/plugins/defaults/memory/__tests__/fixtures/buffer-appender.ts +17 -0
  528. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +74 -0
  529. package/src/plugins/defaults/memory/__tests__/memory-run-evidence.test.ts +161 -0
  530. package/src/plugins/defaults/memory/__tests__/relocated-memory-test-rows.ts +10 -0
  531. package/src/plugins/defaults/memory/__tests__/worker-control.test.ts +19 -6
  532. package/src/plugins/defaults/memory/buffer-file.ts +354 -0
  533. package/src/plugins/defaults/memory/buffer-format.ts +40 -0
  534. package/src/plugins/defaults/memory/context-search/agent-protocol.ts +9 -12
  535. package/src/plugins/defaults/memory/context-search/agent-runner.ts +77 -22
  536. package/src/plugins/defaults/memory/context-search/format.ts +53 -8
  537. package/src/plugins/defaults/memory/context-search/limits.ts +10 -12
  538. package/src/plugins/defaults/memory/context-search/recall-input.ts +38 -0
  539. package/src/plugins/defaults/memory/context-search/search.ts +8 -14
  540. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +1 -0
  541. package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +2 -1
  542. package/src/plugins/defaults/memory/context-search/sources/workspace.ts +2 -1
  543. package/src/plugins/defaults/memory/context-search/types.ts +1 -11
  544. package/src/plugins/defaults/memory/conversation-memory-purge.ts +4 -0
  545. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +11 -4
  546. package/src/plugins/defaults/memory/graph/capability-seed.ts +1 -2
  547. package/src/plugins/defaults/memory/graph/tool-handlers.ts +13 -63
  548. package/src/plugins/defaults/memory/graph/tools.ts +35 -64
  549. package/src/plugins/defaults/memory/host-utils.ts +0 -10
  550. package/src/plugins/defaults/memory/injectors.ts +4 -3
  551. package/src/plugins/defaults/memory/memory-retrospective-job.ts +72 -183
  552. package/src/plugins/defaults/memory/memory-run-evidence.ts +213 -0
  553. package/src/plugins/defaults/memory/src/memory-eval-routes.ts +2 -3
  554. package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +6 -1
  555. package/src/plugins/defaults/memory/src/memory-item-routes.ts +2 -1
  556. package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +407 -99
  557. package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +10 -0
  558. package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +107 -7
  559. package/src/plugins/defaults/memory/substrate/consolidation-job.ts +307 -86
  560. package/src/plugins/defaults/memory/substrate/consolidation-tool-surface.ts +34 -0
  561. package/src/plugins/defaults/memory/substrate/page-index.ts +2 -1
  562. package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +91 -51
  563. package/src/plugins/defaults/memory/substrate/sweep-job.ts +1 -1
  564. package/src/plugins/defaults/memory/tools.test.ts +124 -9
  565. package/src/plugins/defaults/memory/tools.ts +38 -11
  566. package/src/plugins/defaults/memory/v1/graph/consolidation.ts +2 -2
  567. package/src/plugins/defaults/memory/v1/graph/extraction.ts +2 -1
  568. package/src/plugins/defaults/memory/v1/graph/retriever.ts +1 -1
  569. package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +5 -0
  570. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +5 -2
  571. package/src/plugins/defaults/memory/v2/reranker.ts +2 -1
  572. package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +81 -1
  573. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +87 -0
  574. package/src/plugins/defaults/memory/v3/__tests__/plugin-schema.test.ts +12 -0
  575. package/src/plugins/defaults/memory/v3/__tests__/pool-log-store.test.ts +332 -15
  576. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +626 -27
  577. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +148 -28
  578. package/src/plugins/defaults/memory/v3/card.ts +2 -1
  579. package/src/plugins/defaults/memory/v3/injector.ts +212 -178
  580. package/src/plugins/defaults/memory/v3/orchestrate.ts +159 -32
  581. package/src/plugins/defaults/memory/v3/plugin-schema.ts +54 -4
  582. package/src/plugins/defaults/memory/v3/pool-log-store.ts +275 -37
  583. package/src/plugins/defaults/memory/v3/pool-select.test.ts +47 -5
  584. package/src/plugins/defaults/memory/v3/pool-select.ts +710 -59
  585. package/src/plugins/defaults/memory/v3/sections.ts +2 -1
  586. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +41 -14
  587. package/src/plugins/defaults/memory/worker-control.ts +15 -5
  588. package/src/plugins/defaults/task-progress/__tests__/registration.test.ts +70 -0
  589. package/src/plugins/defaults/task-progress/__tests__/task-progress-context.test.ts +380 -0
  590. package/src/plugins/defaults/task-progress/hooks/post-compact.ts +19 -0
  591. package/src/plugins/defaults/task-progress/hooks/user-prompt-submit.ts +24 -0
  592. package/src/plugins/defaults/task-progress/package.json +14 -0
  593. package/src/plugins/defaults/task-progress/src/apply-task-progress-context.ts +93 -0
  594. package/src/plugins/defaults/task-progress/src/format-task-progress-context.ts +67 -0
  595. package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +4 -1
  596. package/src/plugins/defaults/tool-result-truncate/terminal.ts +1 -46
  597. package/src/prompts/__tests__/parallel-tasks-section.test.ts +25 -0
  598. package/src/prompts/delegation-gate.ts +57 -0
  599. package/src/prompts/system-prompt.ts +14 -32
  600. package/src/providers/__tests__/context-overflow-error.test.ts +10 -0
  601. package/src/providers/__tests__/search-provider-catalog.test.ts +18 -0
  602. package/src/providers/anthropic/client.ts +10 -1
  603. package/src/providers/anthropic-gateway-shared.ts +6 -0
  604. package/src/providers/fetch-provider-catalog.ts +11 -0
  605. package/src/providers/gemini/client.ts +25 -8
  606. package/src/providers/inference/adapter-factory.ts +6 -0
  607. package/src/providers/jev/client.test.ts +270 -0
  608. package/src/providers/jev/client.ts +534 -0
  609. package/src/providers/model-catalog.ts +59 -3
  610. package/src/providers/openai/__tests__/chat-completions-extra-body.test.ts +94 -1
  611. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +106 -1
  612. package/src/providers/openai/__tests__/chat-template-flatten.test.ts +24 -0
  613. package/src/providers/openai/__tests__/google-thought-signature.test.ts +1 -2
  614. package/src/providers/openai/chat-completions-provider.ts +100 -29
  615. package/src/providers/openai/google-thought-signature.ts +0 -6
  616. package/src/providers/openai/responses-provider.ts +23 -1
  617. package/src/providers/ratelimit.ts +1 -3
  618. package/src/providers/search-provider-catalog.ts +24 -0
  619. package/src/providers/server-tool-pairing.ts +16 -7
  620. package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +24 -0
  621. package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +7 -1
  622. package/src/providers/speech-to-text/__tests__/vellum-managed-realtime.test.ts +50 -1
  623. package/src/providers/speech-to-text/deepgram-flux-frames.ts +11 -0
  624. package/src/providers/speech-to-text/vellum-managed-flux-realtime.ts +13 -0
  625. package/src/providers/types.ts +5 -0
  626. package/src/routes/control.ts +7 -5
  627. package/src/runtime/AGENTS.md +6 -4
  628. package/src/runtime/__tests__/agent-wake.test.ts +94 -1
  629. package/src/runtime/actor-trust-resolver.ts +3 -3
  630. package/src/runtime/agent-wake.ts +32 -5
  631. package/src/runtime/approval-message-composer.ts +3 -69
  632. package/src/runtime/assistant-event-hub.ts +73 -75
  633. package/src/runtime/assistant-event-publish-options.ts +7 -0
  634. package/src/runtime/assistant-event-targeting.ts +79 -0
  635. package/src/runtime/assistant-stream-state.ts +13 -100
  636. package/src/runtime/background-job-runner.ts +5 -5
  637. package/src/runtime/channel-retry-sweep.ts +1 -0
  638. package/src/runtime/guardian-action-message-composer.ts +8 -161
  639. package/src/runtime/guardian-action-service.ts +2 -17
  640. package/src/runtime/guardian-reply-router.ts +29 -40
  641. package/src/runtime/http-server.ts +2 -2
  642. package/src/runtime/http-types.ts +6 -0
  643. package/src/runtime/message-composer-types.ts +3 -61
  644. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +67 -1
  645. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +89 -0
  646. package/src/runtime/migrations/vbundle-builder.ts +24 -1
  647. package/src/runtime/migrations/vbundle-import-analyzer.ts +13 -4
  648. package/src/runtime/migrations/vbundle-import-policy.ts +43 -11
  649. package/src/runtime/migrations/vbundle-importer.ts +4 -1
  650. package/src/runtime/migrations/vbundle-streaming-importer.ts +4 -1
  651. package/src/runtime/migrations/vbundle-validator.ts +1 -0
  652. package/src/runtime/pending-interactions-mode-session.test.ts +62 -0
  653. package/src/runtime/pending-interactions.ts +29 -0
  654. package/src/runtime/routes/__tests__/client-history-routes.test.ts +104 -0
  655. package/src/runtime/routes/__tests__/image-generation-routes.test.ts +97 -0
  656. package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +24 -2
  657. package/src/runtime/routes/__tests__/roadmap-routes.test.ts +29 -6
  658. package/src/runtime/routes/browser-context.ts +31 -11
  659. package/src/runtime/routes/browser-routes.ts +43 -4
  660. package/src/runtime/routes/btw-routes.ts +9 -4
  661. package/src/runtime/routes/channel-route-shared.ts +1 -9
  662. package/src/runtime/routes/client-routes.ts +108 -0
  663. package/src/runtime/routes/conversation-management-routes.ts +4 -1
  664. package/src/runtime/routes/conversation-routes.ts +125 -14
  665. package/src/runtime/routes/credential-prompt-routes.ts +4 -3
  666. package/src/runtime/routes/credential-routes.ts +1 -2
  667. package/src/runtime/routes/desktop-setup-routes.test.ts +9 -18
  668. package/src/runtime/routes/desktop-setup-routes.ts +8 -7
  669. package/src/runtime/routes/documents-routes.ts +51 -0
  670. package/src/runtime/routes/email-routes.ts +3 -7
  671. package/src/runtime/routes/events-routes.ts +75 -54
  672. package/src/runtime/routes/guardian-approval-interception.ts +24 -0
  673. package/src/runtime/routes/identity-routes.ts +1 -5
  674. package/src/runtime/routes/image-generation-routes.ts +8 -14
  675. package/src/runtime/routes/inbound-message-handler.ts +37 -41
  676. package/src/runtime/routes/inbound-stages/backfill-sender-provenance.test.ts +168 -0
  677. package/src/runtime/routes/inbound-stages/backfill-sender-provenance.ts +96 -0
  678. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +39 -10
  679. package/src/runtime/routes/inbound-stages/background-dispatch.ts +9 -9
  680. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +2 -0
  681. package/src/runtime/routes/inference-profile-session-handler.ts +11 -1
  682. package/src/runtime/routes/inference-profiles-routes.ts +9 -0
  683. package/src/runtime/routes/llm-context-normalization.ts +1 -7
  684. package/src/runtime/routes/migration-routes.ts +73 -2
  685. package/src/runtime/routes/notification-routes.ts +10 -0
  686. package/src/runtime/routes/oauth-commands-routes.ts +57 -54
  687. package/src/runtime/routes/oauth-providers.ts +11 -0
  688. package/src/runtime/routes/oauth-request-hints.test.ts +246 -0
  689. package/src/runtime/routes/oauth-request-hints.ts +149 -0
  690. package/src/runtime/routes/plugins-routes.ts +6 -0
  691. package/src/runtime/routes/roadmap-routes.ts +47 -8
  692. package/src/runtime/routes/schedule-routes.ts +2 -0
  693. package/src/runtime/routes/secret-routes.ts +99 -119
  694. package/src/runtime/routes/settings-routes.ts +10 -4
  695. package/src/runtime/routes/watcher-routes.ts +1 -3
  696. package/src/runtime/trust-class.test.ts +7 -6
  697. package/src/runtime/trust-class.ts +9 -17
  698. package/src/schedule/__tests__/worker-control.test.ts +36 -5
  699. package/src/schedule/__tests__/worker-mcp-bootstrap.test.ts +107 -0
  700. package/src/schedule/__tests__/worker-mcp-readiness.test.ts +173 -0
  701. package/src/schedule/__tests__/worker-mcp-tools.test.ts +13 -47
  702. package/src/schedule/run-script.ts +2 -2
  703. package/src/schedule/scheduler.ts +47 -11
  704. package/src/schedule/tool-surface-readiness.ts +65 -0
  705. package/src/schedule/worker-control.ts +15 -5
  706. package/src/schedule/worker-mcp.ts +85 -0
  707. package/src/schedule/worker.ts +9 -31
  708. package/src/security/secure-keys.ts +74 -112
  709. package/src/skills/clawhub.ts +3 -8
  710. package/src/skills/managed-store.ts +1 -5
  711. package/src/stt/types.ts +4 -0
  712. package/src/subagent/notify.ts +54 -34
  713. package/src/subagent/parent-notification.ts +6 -0
  714. package/src/telemetry/__tests__/phone-call-funnel.test.ts +72 -0
  715. package/src/telemetry/phone-call-funnel.ts +144 -0
  716. package/src/tools/__tests__/tool-schema-root-combinator-guard.test.ts +81 -0
  717. package/src/tools/ask-question/ask-question-tool.test.ts +167 -5
  718. package/src/tools/ask-question/ask-question-tool.ts +120 -22
  719. package/src/tools/browser/browser-execution.ts +29 -60
  720. package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +561 -39
  721. package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +435 -39
  722. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +1 -8
  723. package/src/tools/client-os.ts +15 -0
  724. package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
  725. package/src/tools/computer-use/target.ts +42 -0
  726. package/src/tools/document/document-tool.ts +13 -18
  727. package/src/tools/execution-target.ts +14 -16
  728. package/src/tools/host-terminal/host-shell.ts +16 -7
  729. package/src/tools/network/__tests__/web-fetch-tinyfish.test.ts +250 -0
  730. package/src/tools/network/__tests__/web-search.test.ts +203 -0
  731. package/src/tools/network/web-fetch.ts +274 -7
  732. package/src/tools/network/web-search.ts +468 -6
  733. package/src/tools/permission-checker.ts +3 -3
  734. package/src/tools/policy-context.ts +3 -1
  735. package/src/tools/shared/filesystem/file-ops-service.ts +1 -31
  736. package/src/tools/shared/shell-output.test.ts +10 -0
  737. package/src/tools/shared/shell-output.ts +14 -2
  738. package/src/tools/skills/load.ts +2 -1
  739. package/src/tools/skills/sandbox-runner.ts +24 -4
  740. package/src/tools/skills/scaffold-managed.ts +2 -1
  741. package/src/tools/skills/skill-script-runner.ts +7 -0
  742. package/src/tools/skills/skill-tool-factory.ts +15 -1
  743. package/src/tools/terminal/__tests__/safe-env.test.ts +44 -4
  744. package/src/tools/terminal/__tests__/sanitized-bash.test.ts +0 -14
  745. package/src/tools/terminal/safe-env.ts +39 -24
  746. package/src/tools/terminal/sanitized-bash.ts +15 -2
  747. package/src/tools/terminal/shell-launch.test.ts +162 -0
  748. package/src/tools/terminal/shell.test.ts +29 -0
  749. package/src/tools/terminal/shell.ts +15 -7
  750. package/src/tools/tool-approval-handler.ts +5 -1
  751. package/src/tools/tool-types.ts +3 -3
  752. package/src/tools/types.ts +8 -2
  753. package/src/util/__tests__/worker-process-command.test.ts +5 -4
  754. package/src/util/abort-reasons.ts +18 -26
  755. package/src/util/browser-human-verification.ts +14 -0
  756. package/src/util/canonicalize-identity.test.ts +21 -0
  757. package/src/util/canonicalize-identity.ts +16 -0
  758. package/src/util/errors.ts +13 -3
  759. package/src/util/host-process.test.ts +17 -1
  760. package/src/util/host-process.ts +24 -0
  761. package/src/util/provider-error-patterns.ts +3 -0
  762. package/src/util/unicode.ts +29 -0
  763. package/src/util/worker-process.ts +77 -35
  764. package/src/workspace/migrations/157-add-desktop-files-launcher.ts +94 -0
  765. package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +4 -10
  766. package/src/workspace/migrations/__tests__/157-add-desktop-files-launcher.test.ts +113 -0
  767. package/src/workspace/migrations/registry.ts +2 -0
  768. package/src/__tests__/computer-use-window-schema.test.ts +0 -24
  769. package/src/api/events/heartbeat-alert.ts +0 -20
  770. package/src/daemon/message-types/web-activity.ts +0 -65
  771. package/src/desktop/desktop-dependencies.test.ts +0 -131
  772. package/src/tools/computer-use/definitions.ts +0 -607
@@ -15,6 +15,7 @@ import type {
15
15
  AgentEvent,
16
16
  AgentLoopExitReason,
17
17
  CheckpointDecision,
18
+ PreparedModelCall,
18
19
  } from "../agent/loop.js";
19
20
  import { createAssistantMessage } from "../agent/message-types.js";
20
21
  import type { AssistantEvent } from "../api/index.js";
@@ -38,6 +39,7 @@ import {
38
39
  import { getConfig } from "../config/loader.js";
39
40
  import type { LLMCallSite } from "../config/schemas/llm.js";
40
41
  import { isSendUserMessageActiveForTurn } from "../config/send-user-message-gate.js";
42
+ import { desktopAutomationLease } from "../desktop/desktop-automation-lease.js";
41
43
  import { writeRelationshipState } from "../home/relationship-state-writer.js";
42
44
  import type { UserPromptSubmitInputContext } from "../hooks/types.js";
43
45
  import {
@@ -105,6 +107,7 @@ import {
105
107
  type EventHandlerDeps,
106
108
  finalizePendingToolResultRow,
107
109
  resetInjectionLedgersForStrip,
110
+ selectFinalComputerUseScreenshotCandidate,
108
111
  settlePendingPartialFlush,
109
112
  } from "./conversation-agent-loop-handlers.js";
110
113
  import {
@@ -133,6 +136,7 @@ import {
133
136
  } from "./conversation-runtime-assembly.js";
134
137
  import type { CurrentTurnSurface } from "./conversation-surfaces.js";
135
138
  import {
139
+ blockingPendingSurfaceIds,
136
140
  hasBlockingPendingSurface,
137
141
  markSurfaceCompleted,
138
142
  settleRunningTaskProgressSurfaces,
@@ -150,6 +154,7 @@ import {
150
154
  unregisterInflightTurn,
151
155
  } from "./inflight-turn-registry.js";
152
156
  import type { UsageStats } from "./message-protocol.js";
157
+ import { bestEffortModeSessionTracking } from "./mode-session-tracking.js";
153
158
  import {
154
159
  persistReactionRecords,
155
160
  type QueuedReactionRecord,
@@ -289,6 +294,89 @@ function turnEndedAwaitingUser(ctx: Conversation): boolean {
289
294
  );
290
295
  }
291
296
 
297
+ function recordModeSessionStructuralWaits(
298
+ ctx: Conversation,
299
+ turnId: string,
300
+ ): boolean {
301
+ let recorded = false;
302
+ for (const interaction of getPendingInteractionsByConversation(
303
+ ctx.conversationId,
304
+ )) {
305
+ const kind =
306
+ interaction.kind === "acp_confirmation"
307
+ ? "confirmation"
308
+ : interaction.kind;
309
+ if (kind !== "confirmation" && kind !== "question" && kind !== "secret") {
310
+ continue;
311
+ }
312
+ recorded =
313
+ ctx.modeSessions.recordStructuralWait(turnId, {
314
+ kind,
315
+ responseId: interaction.requestId,
316
+ }) || recorded;
317
+ }
318
+ for (const surfaceId of blockingPendingSurfaceIds(ctx)) {
319
+ recorded =
320
+ ctx.modeSessions.recordStructuralWait(turnId, {
321
+ kind: "surface",
322
+ responseId: surfaceId,
323
+ }) || recorded;
324
+ }
325
+ return recorded;
326
+ }
327
+
328
+ function settleModeSessionTurn(
329
+ ctx: Conversation,
330
+ turnId: string,
331
+ fallback: { status: "completed" | "interrupted"; endReason: string },
332
+ ): void {
333
+ try {
334
+ if (!ctx.modeSessions.getTurnOwner(turnId)) {
335
+ ctx.modeSessions.releaseTurn(turnId);
336
+ return;
337
+ }
338
+ if (
339
+ fallback.status === "completed" &&
340
+ recordModeSessionStructuralWaits(ctx, turnId)
341
+ ) {
342
+ ctx.modeSessions.releaseTurn(turnId);
343
+ return;
344
+ }
345
+ if (ctx.modeSessions.keepsSessionOpenAfterTurn(turnId)) {
346
+ ctx.modeSessions.releaseTurn(turnId);
347
+ return;
348
+ }
349
+ const disposition = ctx.modeSessions.getTerminalDisposition(turnId);
350
+ if (disposition) {
351
+ ctx.modeSessions.releaseTurn(turnId, fallback);
352
+ return;
353
+ }
354
+ const finalized = ctx.modeSessions.finalizeTurn({
355
+ turnId,
356
+ status: fallback.status,
357
+ endedAt: Date.now(),
358
+ endReason: fallback.endReason,
359
+ lastActivityAt: Date.now(),
360
+ });
361
+ if (!finalized) {
362
+ ctx.modeSessions.releaseTurn(turnId, fallback);
363
+ }
364
+ } catch (err) {
365
+ log.warn(
366
+ { err, conversationId: ctx.conversationId, turnId },
367
+ "Mode-session turn settlement failed",
368
+ );
369
+ try {
370
+ ctx.modeSessions.releaseTurn(turnId, fallback);
371
+ } catch (releaseErr) {
372
+ log.warn(
373
+ { err: releaseErr, conversationId: ctx.conversationId, turnId },
374
+ "Mode-session turn cleanup failed",
375
+ );
376
+ }
377
+ }
378
+ }
379
+
292
380
  // ── abort watchdog ───────────────────────────────────────────────────
293
381
 
294
382
  /**
@@ -390,12 +478,16 @@ export async function runAgentLoopImpl(
390
478
  */
391
479
  replyDeliveredInAppOnly?: boolean;
392
480
  /**
393
- * LLM call-site identifier threaded into the per-call provider config.
394
- * Adapter callers (heartbeat, filing, scheduler, etc.) pass their own
395
- * call-site id so the resolver picks `llm.callSites.<id>`. When unset,
396
- * the agent loop defaults to `'mainAgent'` for user-initiated turns.
481
+ * Semantic call-site identifier for the turn. It also selects provider
482
+ * configuration unless `inferenceCallSite` is set. When unset, the agent
483
+ * loop defaults to `'mainAgent'` for user-initiated turns.
397
484
  */
398
485
  callSite?: LLMCallSite;
486
+ /**
487
+ * Provider configuration source when it differs from the turn's semantic
488
+ * call site. The semantic call site still controls tools and UI behavior.
489
+ */
490
+ inferenceCallSite?: LLMCallSite;
399
491
  /**
400
492
  * Optional ad-hoc inference-profile override applied to every LLM call
401
493
  * the loop issues. When set, the agent loop sets
@@ -411,6 +503,8 @@ export async function runAgentLoopImpl(
411
503
  * sites. Used when a caller explicitly pins a background run to a profile.
412
504
  */
413
505
  forceOverrideProfile?: boolean;
506
+ /** Observe the first finalized model request without delaying it. */
507
+ onFirstModelCallPrepared?: (prepared: PreparedModelCall) => void;
414
508
  /**
415
509
  * Origin tag of this turn (the conversation's `TitleOrigin`, e.g.
416
510
  * "memory_consolidation"), threaded from `runBackgroundJob`. Exposed on
@@ -470,12 +564,12 @@ export async function runAgentLoopImpl(
470
564
  ctx.currentTurnIsNonInteractive = isNonInteractive;
471
565
 
472
566
  // Default user-initiated turns to the `mainAgent` call site; other invocation
473
- // contexts (heartbeat, filing, analyze, etc.) pass their own `callSite`. The
474
- // provider layer resolves provider/model/maxTokens via `resolveCallSiteConfig`,
475
- // picking up any user overrides under `llm.callSites.<id>` (falling back to
476
- // the shipped call-site defaults when absent). `resolveTurnCallSite` keeps subagent
477
- // conversations on `subagentSpawn` when no call site is supplied.
567
+ // contexts pass their own semantic `callSite`. Provider configuration uses
568
+ // that site unless a caller supplies `inferenceCallSite` separately.
569
+ // `resolveTurnCallSite` keeps subagent conversations on `subagentSpawn` when
570
+ // no semantic call site is supplied.
478
571
  const turnCallSite = resolveTurnCallSite(options?.callSite, ctx);
572
+ const inferenceCallSite = options?.inferenceCallSite ?? turnCallSite;
479
573
  // Expose the turn's call site on the live conversation so the runtime
480
574
  // injection assembly self-resolves it for the turn's plugin contexts. Set
481
575
  // before the prompt sync below: the tool-gated reply section and the tool
@@ -580,7 +674,11 @@ export async function runAgentLoopImpl(
580
674
  isResolvableProvider: dispatchProviderResolvable,
581
675
  };
582
676
  const { config: resolved, profileName } =
583
- resolveCallSiteConfigWithProfile(turnCallSite, config.llm, resolveOpts);
677
+ resolveCallSiteConfigWithProfile(
678
+ inferenceCallSite,
679
+ config.llm,
680
+ resolveOpts,
681
+ );
584
682
  let connectionName = resolved.provider_connection;
585
683
  try {
586
684
  connectionName =
@@ -615,7 +713,7 @@ export async function runAgentLoopImpl(
615
713
 
616
714
  const effectiveContextWindow = resolveEffectiveContextWindow({
617
715
  llm: config.llm,
618
- callSite: turnCallSite,
716
+ callSite: inferenceCallSite,
619
717
  overrideProfile: turnOverrideProfile ?? undefined,
620
718
  forceOverrideProfile,
621
719
  selectionSeed: ctx.conversationId,
@@ -634,7 +732,7 @@ export async function runAgentLoopImpl(
634
732
  };
635
733
 
636
734
  let currentContextWindowConfig = contextWindowConfigFromEffective(
637
- resolveCallSiteConfig(turnCallSite, config.llm, {
735
+ resolveCallSiteConfig(inferenceCallSite, config.llm, {
638
736
  overrideProfile: turnOverrideProfile ?? undefined,
639
737
  forceOverrideProfile,
640
738
  selectionSeed: ctx.conversationId,
@@ -650,13 +748,13 @@ export async function runAgentLoopImpl(
650
748
  if (currentOverrideProfile !== appliedOverrideProfile) {
651
749
  currentEffectiveContextWindow = resolveEffectiveContextWindow({
652
750
  llm: config.llm,
653
- callSite: turnCallSite,
751
+ callSite: inferenceCallSite,
654
752
  overrideProfile: currentOverrideProfile,
655
753
  forceOverrideProfile,
656
754
  selectionSeed: ctx.conversationId,
657
755
  });
658
756
  currentContextWindowConfig = contextWindowConfigFromEffective(
659
- resolveCallSiteConfig(turnCallSite, config.llm, {
757
+ resolveCallSiteConfig(inferenceCallSite, config.llm, {
660
758
  overrideProfile: currentOverrideProfile,
661
759
  forceOverrideProfile,
662
760
  onResolutionFallback: logResolutionFallback,
@@ -675,8 +773,6 @@ export async function runAgentLoopImpl(
675
773
  ctx.currentTurnOverrideProfile = currentOverrideProfile;
676
774
  return currentOverrideProfile;
677
775
  };
678
- const resolveCurrentOverrideProfile = (): string | undefined =>
679
- refreshCurrentProfileState();
680
776
  const resolveCurrentMaxInputTokens = (): number => {
681
777
  refreshCurrentProfileState();
682
778
  return currentEffectiveContextWindow.maxInputTokens;
@@ -702,7 +798,7 @@ export async function runAgentLoopImpl(
702
798
  };
703
799
 
704
800
  // Initial value for `createToolExecutor` to read into
705
- // `ToolContext.overrideProfile`. `resolveCurrentOverrideProfile` refreshes
801
+ // `ToolContext.overrideProfile`. `refreshCurrentProfileState` refreshes
706
802
  // this between model calls so a confirmed profile session opened by a tool
707
803
  // applies to later tool executions and nested subagents in the same turn.
708
804
  ctx.currentTurnOverrideProfile = turnOverrideProfile;
@@ -913,6 +1009,7 @@ export async function runAgentLoopImpl(
913
1009
  if (ctx.pendingReactionRecords?.length) {
914
1010
  ownedReactionRecords.push(...ctx.pendingReactionRecords.splice(0));
915
1011
  }
1012
+ desktopAutomationLease.releaseForConversation(ctx.conversationId);
916
1013
  ctx.abortController = null;
917
1014
  ctx.setProcessing(false);
918
1015
  unregisterInflightTurn(ctx.conversationId, state);
@@ -977,6 +1074,7 @@ export async function runAgentLoopImpl(
977
1074
  publishConversationMessagesChanged(ctx.conversationId);
978
1075
  }
979
1076
  };
1077
+ let eventHandlerDeps: EventHandlerDeps | undefined;
980
1078
 
981
1079
  try {
982
1080
  closeTurnFinalization = beginTurnFinalization(ctx.conversationId);
@@ -1061,13 +1159,19 @@ export async function runAgentLoopImpl(
1061
1159
  if (!markSurfaceCompleted(ctx, surfaceId, "Dismissed")) {
1062
1160
  continue;
1063
1161
  }
1162
+ ctx.pendingSurfaceActions.delete(surfaceId);
1163
+ bestEffortModeSessionTracking("stale surface wait invalidation", () =>
1164
+ ctx.modeSessions.invalidateStructuralWait({
1165
+ kind: "surface",
1166
+ responseId: surfaceId,
1167
+ }),
1168
+ );
1064
1169
  onEvent({
1065
1170
  type: "ui_surface_complete",
1066
1171
  conversationId: ctx.conversationId,
1067
1172
  surfaceId,
1068
1173
  summary: "Dismissed",
1069
1174
  });
1070
- ctx.pendingSurfaceActions.delete(surfaceId);
1071
1175
  }
1072
1176
  }
1073
1177
 
@@ -1302,13 +1406,13 @@ export async function runAgentLoopImpl(
1302
1406
  // a hand-rolled chain would credit profiles the resolver never consulted
1303
1407
  // (e.g. activeProfile on a non-mainAgent turn).
1304
1408
  const effectiveProfileKey =
1305
- selectWinningProfile(turnCallSite, config.llm, {
1409
+ selectWinningProfile(inferenceCallSite, config.llm, {
1306
1410
  ...(turnOverrideProfile != null
1307
1411
  ? { overrideProfile: turnOverrideProfile }
1308
1412
  : {}),
1309
1413
  selectionSeed: ctx.conversationId,
1310
1414
  }).profileName ??
1311
- resolveProfilelessModelKey(turnCallSite, config.llm, {
1415
+ resolveProfilelessModelKey(inferenceCallSite, config.llm, {
1312
1416
  ...(turnOverrideProfile != null
1313
1417
  ? { overrideProfile: turnOverrideProfile }
1314
1418
  : {}),
@@ -1409,6 +1513,7 @@ export async function runAgentLoopImpl(
1409
1513
  latencyTracker,
1410
1514
  errorAttribution: turnErrorAttribution,
1411
1515
  };
1516
+ eventHandlerDeps = deps;
1412
1517
  const eventHandler = (event: AgentEvent): Promise<void> => {
1413
1518
  if (
1414
1519
  event.type === "agent_loop_exit" &&
@@ -1446,7 +1551,10 @@ export async function runAgentLoopImpl(
1446
1551
 
1447
1552
  turnStarted = true;
1448
1553
 
1449
- rlog.info({ callSite: turnCallSite }, "Starting agent loop run");
1554
+ rlog.info(
1555
+ { callSite: turnCallSite, inferenceCallSite },
1556
+ "Starting agent loop run",
1557
+ );
1450
1558
 
1451
1559
  // Trust snapshot the loop forwards to its mid-loop in-place compaction
1452
1560
  // (scoping the compactor's image manifest) and the post-compaction
@@ -1456,6 +1564,18 @@ export async function runAgentLoopImpl(
1456
1564
  // fields self-resolve from its own conversation id.
1457
1565
  const loopTrust = ctx.getTurnOrRestingTrust() ?? FALLBACK_TURN_TRUST;
1458
1566
 
1567
+ const notifyFirstModelCallPrepared = options?.onFirstModelCallPrepared;
1568
+ let firstModelCallPrepared = false;
1569
+ const onModelCallPrepared = notifyFirstModelCallPrepared
1570
+ ? (prepared: PreparedModelCall): void => {
1571
+ if (firstModelCallPrepared) {
1572
+ return;
1573
+ }
1574
+ firstModelCallPrepared = true;
1575
+ notifyFirstModelCallPrepared(prepared);
1576
+ }
1577
+ : undefined;
1578
+
1459
1579
  /**
1460
1580
  * Shared closure: runs the agent loop with the wrapper's turn context and
1461
1581
  * maps the loop's returned checkpoint pause-reason into the wrapper's yield
@@ -1478,12 +1598,14 @@ export async function runAgentLoopImpl(
1478
1598
  requestId: reqId,
1479
1599
  onCheckpoint,
1480
1600
  callSite: turnCallSite,
1601
+ inferenceCallSite,
1481
1602
  suppressAssistantText: sendUserMessageActive,
1482
1603
  supportsDynamicUi: conversationSupportsDynamicUi(ctx),
1483
1604
  trust: loopTrust,
1484
1605
  overrideProfile: turnOverrideProfile,
1485
1606
  ...(forceOverrideProfile ? { forceOverrideProfile: true } : {}),
1486
- resolveOverrideProfile: resolveCurrentOverrideProfile,
1607
+ resolveOverrideProfile: refreshCurrentProfileState,
1608
+ ...(onModelCallPrepared !== undefined ? { onModelCallPrepared } : {}),
1487
1609
  resolveContextWindow,
1488
1610
  compactInPlace,
1489
1611
  isNonInteractive,
@@ -1582,13 +1704,33 @@ export async function runAgentLoopImpl(
1582
1704
  userMessageInterface: capturedTurnInterfaceContext.userMessageInterface,
1583
1705
  assistantMessageInterface:
1584
1706
  capturedTurnInterfaceContext.assistantMessageInterface,
1707
+ modeSession: ctx.modeSessions.getTurnOwner(reqId),
1585
1708
  };
1586
- await finalizePendingToolResultRow(
1709
+ const toolResultRowId = await finalizePendingToolResultRow(
1587
1710
  state,
1588
1711
  ctx.conversationId,
1589
1712
  toolResultMetadata,
1590
1713
  rlog,
1591
1714
  );
1715
+ if (toolResultRowId) {
1716
+ bestEffortModeSessionTracking(
1717
+ "remaining tool result finalization",
1718
+ () => {
1719
+ const toolResultRow = getMessageById(
1720
+ toolResultRowId,
1721
+ ctx.conversationId,
1722
+ );
1723
+ if (toolResultRow) {
1724
+ ctx.modeSessions.trackPersistedRow(
1725
+ reqId,
1726
+ toolResultRowId,
1727
+ toolResultRow.createdAt,
1728
+ { startsDisplayBoundary: false },
1729
+ );
1730
+ }
1731
+ },
1732
+ );
1733
+ }
1592
1734
  }
1593
1735
 
1594
1736
  // Persist the budget_yield_unrecovered notice now that any pending
@@ -1609,6 +1751,7 @@ export async function runAgentLoopImpl(
1609
1751
  userMessageInterface: capturedTurnInterfaceContext.userMessageInterface,
1610
1752
  assistantMessageInterface:
1611
1753
  capturedTurnInterfaceContext.assistantMessageInterface,
1754
+ modeSession: ctx.modeSessions.getTurnOwner(reqId),
1612
1755
  };
1613
1756
  let yieldNoticePersistedId: string | null = null;
1614
1757
  try {
@@ -1619,6 +1762,13 @@ export async function runAgentLoopImpl(
1619
1762
  { metadata: yieldNoticeMetadata },
1620
1763
  );
1621
1764
  yieldNoticePersistedId = yieldRow.id;
1765
+ bestEffortModeSessionTracking("budget yield notice persistence", () =>
1766
+ ctx.modeSessions.trackPersistedRow(
1767
+ reqId,
1768
+ yieldRow.id,
1769
+ yieldRow.createdAt,
1770
+ ),
1771
+ );
1622
1772
  } catch (err) {
1623
1773
  // Non-fatal — a DB hiccup must not escalate a budget-yield exit into
1624
1774
  // a turn-level throw. The live SSE event was already emitted, so the
@@ -1793,6 +1943,7 @@ export async function runAgentLoopImpl(
1793
1943
  messageKind: PROVIDER_ERROR_MESSAGE_KIND,
1794
1944
  providerErrorCode: state.providerErrorCode ?? undefined,
1795
1945
  providerErrorCategory: state.providerErrorCategory ?? undefined,
1946
+ modeSession: ctx.modeSessions.getTurnOwner(reqId),
1796
1947
  };
1797
1948
  // The persisted row re-enters LLM history and is displayed as
1798
1949
  // assistant speech, so the managed-billing categories swap the
@@ -1819,6 +1970,13 @@ export async function runAgentLoopImpl(
1819
1970
  // (or a downstream handler) doesn't try to clean up an id that
1820
1971
  // already corresponds to a finalized row.
1821
1972
  state.lastAssistantMessageId = errorRow.id;
1973
+ bestEffortModeSessionTracking("provider error notice persistence", () =>
1974
+ ctx.modeSessions.trackPersistedRow(
1975
+ reqId,
1976
+ errorRow.id,
1977
+ errorRow.createdAt,
1978
+ ),
1979
+ );
1822
1980
  state.assistantRowAwaitingFinalization = false;
1823
1981
  newMessages.push(errorAssistantMessage);
1824
1982
  // Pipe the just-assigned message id into any orphaned LLM request log
@@ -1895,10 +2053,10 @@ export async function runAgentLoopImpl(
1895
2053
  // contradicts itself. `forceOverrideProfile` floats it above the
1896
2054
  // call-site profile exactly as the fallback dispatch did.
1897
2055
  {
1898
- callSite: turnCallSite,
2056
+ callSite: inferenceCallSite,
1899
2057
  overrideProfile:
1900
2058
  state.exchangeInferenceProfile ??
1901
- resolveCurrentOverrideProfile() ??
2059
+ refreshCurrentProfileState() ??
1902
2060
  null,
1903
2061
  ...(state.exchangeInferenceProfile !== undefined
1904
2062
  ? { forceOverrideProfile: true }
@@ -1949,6 +2107,8 @@ export async function runAgentLoopImpl(
1949
2107
  state.lastAssistantMessageId,
1950
2108
  )
1951
2109
  : state.lastAssistantMessageId;
2110
+ const computerUseScreenshotCandidate =
2111
+ selectFinalComputerUseScreenshotCandidate(state);
1952
2112
  // Resolve attachments (only when not cancelled, this is expensive async I/O)
1953
2113
  const attachmentResult = await resolveAssistantAttachments(
1954
2114
  state.accumulatedDirectives,
@@ -1965,9 +2125,16 @@ export async function runAgentLoopImpl(
1965
2125
  ),
1966
2126
  attachmentTargetMessageId,
1967
2127
  state.toolContentBlockToolNames,
2128
+ computerUseScreenshotCandidate,
1968
2129
  );
1969
2130
  const { assistantAttachments, emittedAttachments } = attachmentResult;
1970
2131
  persistedAttachmentFiles = attachmentResult.persistedFiles;
2132
+ if (
2133
+ attachmentTargetMessageId &&
2134
+ attachmentResult.linkedAttachmentIds.length > 0
2135
+ ) {
2136
+ state.assistantMessageIdsToSync.add(attachmentTargetMessageId);
2137
+ }
1971
2138
 
1972
2139
  ctx.lastAssistantAttachments = assistantAttachments;
1973
2140
  ctx.lastAttachmentWarnings = attachmentResult.directiveWarnings;
@@ -2000,6 +2167,7 @@ export async function runAgentLoopImpl(
2000
2167
  ...(state.lastAssistantMessageId
2001
2168
  ? { messageId: state.lastAssistantMessageId }
2002
2169
  : {}),
2170
+ modeSession: ctx.modeSessions.getTurnOwner(reqId),
2003
2171
  });
2004
2172
  publishLoopMessagesChanged();
2005
2173
  } else {
@@ -2012,6 +2180,7 @@ export async function runAgentLoopImpl(
2012
2180
  onEvent({
2013
2181
  type: "message_complete",
2014
2182
  conversationId: ctx.conversationId,
2183
+ modeSession: ctx.modeSessions.getTurnOwner(reqId),
2015
2184
  ...(emittedAttachments.length > 0
2016
2185
  ? { attachments: emittedAttachments }
2017
2186
  : {}),
@@ -2047,6 +2216,28 @@ export async function runAgentLoopImpl(
2047
2216
  await settlePendingPartialFlush(state, deps);
2048
2217
  await settleTurnContent({ ctx, state, rlog });
2049
2218
 
2219
+ if (yieldedForHandoff) {
2220
+ const nextRequestId = ctx.queue.snapshot()[0]?.requestId;
2221
+ if (nextRequestId) {
2222
+ ctx.modeSessions.transferTurn(reqId, nextRequestId);
2223
+ } else {
2224
+ settleModeSessionTurn(ctx, reqId, {
2225
+ status: "completed",
2226
+ endReason: "handoff_settled",
2227
+ });
2228
+ }
2229
+ } else if (abortController.signal.aborted) {
2230
+ settleModeSessionTurn(ctx, reqId, {
2231
+ status: "interrupted",
2232
+ endReason: "cancelled",
2233
+ });
2234
+ } else {
2235
+ settleModeSessionTurn(ctx, reqId, {
2236
+ status: "completed",
2237
+ endReason: "turn_settled",
2238
+ });
2239
+ }
2240
+
2050
2241
  // Content is settled, so the conversation is free. Release before the
2051
2242
  // deferred tail rather than in the `finally`: the tail's memory indexing is
2052
2243
  // network-bound and unbounded, and holding the lock across it is what makes
@@ -2124,6 +2315,21 @@ export async function runAgentLoopImpl(
2124
2315
  onEvent(buildConversationErrorMessage(ctx.conversationId, classified));
2125
2316
  publishLoopMessagesChanged();
2126
2317
  }
2318
+ try {
2319
+ if (eventHandlerDeps) {
2320
+ await settlePendingPartialFlush(state, eventHandlerDeps);
2321
+ }
2322
+ await settleTurnContent({ ctx, state, rlog });
2323
+ } catch (settleErr) {
2324
+ rlog.warn(
2325
+ { err: settleErr },
2326
+ "Failed to settle interrupted turn content before mode-session finalization",
2327
+ );
2328
+ }
2329
+ settleModeSessionTurn(ctx, reqId, {
2330
+ status: "interrupted",
2331
+ endReason: isUserCancellation(err, errorCtx) ? "cancelled" : "error",
2332
+ });
2127
2333
  } finally {
2128
2334
  // Backstop release for the cancel/error paths, which throw out of the try
2129
2335
  // before the happy path's release runs. Idempotent, so the happy path