@vellumai/assistant 0.4.26 → 0.4.29

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 (1301) hide show
  1. package/.env.example +2 -2
  2. package/AGENTS.md +5 -0
  3. package/ARCHITECTURE.md +169 -69
  4. package/Dockerfile +1 -1
  5. package/README.md +111 -112
  6. package/bun.lock +0 -3
  7. package/docs/architecture/integrations.md +0 -1
  8. package/docs/architecture/memory.md +100 -63
  9. package/docs/error-handling.md +71 -0
  10. package/docs/runbook-trusted-contacts.md +10 -9
  11. package/docs/trusted-contact-access.md +48 -46
  12. package/package.json +3 -3
  13. package/scripts/compare-benchmarks.sh +12 -5
  14. package/scripts/ipc/check-swift-decoder-drift.ts +3 -0
  15. package/scripts/test.sh +89 -5
  16. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +46 -0
  17. package/src/__tests__/access-request-decision.test.ts +0 -1
  18. package/src/__tests__/account-registry.test.ts +1 -1
  19. package/src/__tests__/actor-token-service.test.ts +36 -23
  20. package/src/__tests__/agent-loop-thinking.test.ts +29 -13
  21. package/src/__tests__/agent-loop.test.ts +2 -1
  22. package/src/__tests__/app-builder-tool-scripts.test.ts +1 -1
  23. package/src/__tests__/approval-routes-http.test.ts +2 -2
  24. package/src/__tests__/asset-materialize-tool.test.ts +7 -7
  25. package/src/__tests__/asset-search-tool.test.ts +7 -7
  26. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  27. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +217 -0
  28. package/src/__tests__/call-controller.test.ts +99 -69
  29. package/src/__tests__/call-start-guardian-guard.test.ts +1 -1
  30. package/src/__tests__/channel-approval-routes.test.ts +113 -70
  31. package/src/__tests__/channel-guardian.test.ts +173 -282
  32. package/src/__tests__/channel-readiness-service.test.ts +6 -2
  33. package/src/__tests__/channel-reply-delivery.test.ts +2 -2
  34. package/src/__tests__/channel-retry-sweep.test.ts +14 -14
  35. package/src/__tests__/checker.test.ts +12 -31
  36. package/src/__tests__/claude-code-tool-profiles.test.ts +1 -1
  37. package/src/__tests__/commit-message-enrichment-service.test.ts +67 -59
  38. package/src/__tests__/compaction.benchmark.test.ts +6 -2
  39. package/src/__tests__/computer-use-tools.test.ts +1 -1
  40. package/src/__tests__/config-schema.test.ts +66 -7
  41. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -29
  42. package/src/__tests__/contacts-tools.test.ts +63 -2
  43. package/src/__tests__/context-overflow-approval.test.ts +141 -0
  44. package/src/__tests__/context-overflow-policy.test.ts +171 -0
  45. package/src/__tests__/context-overflow-reducer.test.ts +533 -0
  46. package/src/__tests__/context-window-manager.test.ts +97 -0
  47. package/src/__tests__/conversation-attention-telegram.test.ts +38 -46
  48. package/src/__tests__/conversation-pairing.test.ts +2 -2
  49. package/src/__tests__/conversation-routes-guardian-reply.test.ts +214 -10
  50. package/src/__tests__/conversation-routes.test.ts +4 -7
  51. package/src/__tests__/credential-broker-browser-fill.test.ts +13 -2
  52. package/src/__tests__/credential-security-e2e.test.ts +1 -1
  53. package/src/__tests__/credential-security-invariants.test.ts +1 -1
  54. package/src/__tests__/credential-vault-unit.test.ts +1 -1
  55. package/src/__tests__/credential-vault.test.ts +11 -8
  56. package/src/__tests__/daemon-lifecycle.test.ts +2 -2
  57. package/src/__tests__/daemon-server-session-init.test.ts +6 -6
  58. package/src/__tests__/delete-managed-skill-tool.test.ts +1 -1
  59. package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -2
  60. package/src/__tests__/emit-signal-routing-intent.test.ts +4 -0
  61. package/src/__tests__/encrypted-store.test.ts +10 -7
  62. package/src/__tests__/ephemeral-permissions.test.ts +3 -3
  63. package/src/__tests__/file-edit-tool.test.ts +1 -1
  64. package/src/__tests__/file-read-tool.test.ts +1 -1
  65. package/src/__tests__/file-write-tool.test.ts +1 -1
  66. package/src/__tests__/fixtures/credential-security-fixtures.ts +87 -64
  67. package/src/__tests__/fixtures/media-reuse-fixtures.ts +37 -31
  68. package/src/__tests__/fixtures/mock-signup-server.ts +171 -115
  69. package/src/__tests__/fixtures/proxy-fixtures.ts +39 -39
  70. package/src/__tests__/followup-tools.test.ts +1 -1
  71. package/src/__tests__/gateway-only-guard.test.ts +3 -0
  72. package/src/__tests__/guardian-actions-endpoint.test.ts +543 -1
  73. package/src/__tests__/guardian-control-plane-policy.test.ts +15 -15
  74. package/src/__tests__/guardian-dispatch.test.ts +79 -1
  75. package/src/__tests__/guardian-grant-minting.test.ts +14 -14
  76. package/src/__tests__/guardian-outbound-http.test.ts +1 -2
  77. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -41
  78. package/src/__tests__/guardian-routing-invariants.test.ts +2 -5
  79. package/src/__tests__/guardian-routing-state.test.ts +36 -52
  80. package/src/__tests__/guardian-verification-intent-routing.test.ts +4 -6
  81. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +2 -2
  82. package/src/__tests__/handle-user-message-secret-resume.test.ts +39 -1
  83. package/src/__tests__/handlers-cu-observation-blob.test.ts +21 -10
  84. package/src/__tests__/handlers-telegram-config.test.ts +14 -14
  85. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +23 -2
  86. package/src/__tests__/headless-browser-interactions.test.ts +1 -1
  87. package/src/__tests__/headless-browser-navigate.test.ts +1 -1
  88. package/src/__tests__/headless-browser-read-tools.test.ts +1 -1
  89. package/src/__tests__/headless-browser-snapshot.test.ts +1 -1
  90. package/src/__tests__/heartbeat-service.test.ts +45 -2
  91. package/src/__tests__/host-file-edit-tool.test.ts +1 -1
  92. package/src/__tests__/host-file-read-tool.test.ts +1 -1
  93. package/src/__tests__/host-file-write-tool.test.ts +1 -1
  94. package/src/__tests__/host-shell-tool.test.ts +1 -1
  95. package/src/__tests__/inbound-invite-redemption.test.ts +16 -18
  96. package/src/__tests__/ingress-reconcile.test.ts +2 -2
  97. package/src/__tests__/ingress-routes-http.test.ts +2 -1
  98. package/src/__tests__/integrations-cli.test.ts +256 -0
  99. package/src/__tests__/intent-routing.test.ts +4 -5
  100. package/src/__tests__/invite-redemption-service.test.ts +4 -3
  101. package/src/__tests__/ipc-snapshot.test.ts +28 -0
  102. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -1
  103. package/src/__tests__/mcp-cli.test.ts +136 -57
  104. package/src/__tests__/mcp-client-auth.test.ts +95 -0
  105. package/src/__tests__/media-generate-image.test.ts +2 -2
  106. package/src/__tests__/media-reuse-story.e2e.test.ts +8 -8
  107. package/src/__tests__/memory-regressions.test.ts +6 -6
  108. package/src/__tests__/messaging-send-tool.test.ts +1 -1
  109. package/src/__tests__/migration-cross-version-compatibility.test.ts +1855 -0
  110. package/src/__tests__/migration-export-http.test.ts +540 -0
  111. package/src/__tests__/migration-import-commit-http.test.ts +823 -0
  112. package/src/__tests__/migration-import-preflight-http.test.ts +755 -0
  113. package/src/__tests__/migration-parity-persistence.test.ts +1854 -0
  114. package/src/__tests__/migration-transport.test.ts +904 -0
  115. package/src/__tests__/migration-validate-http.test.ts +698 -0
  116. package/src/__tests__/migration-wizard.test.ts +1289 -0
  117. package/src/__tests__/non-member-access-request.test.ts +17 -17
  118. package/src/__tests__/notification-decision-strategy.test.ts +110 -2
  119. package/src/__tests__/notification-deep-link.test.ts +18 -0
  120. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  121. package/src/__tests__/oauth2-gateway-transport.test.ts +1 -1
  122. package/src/__tests__/playbook-execution.test.ts +1 -1
  123. package/src/__tests__/playbook-tools.test.ts +1 -1
  124. package/src/__tests__/provider-streaming.benchmark.test.ts +3 -1
  125. package/src/__tests__/proxy-approval-callback.test.ts +1 -1
  126. package/src/__tests__/qdrant-manager.test.ts +40 -11
  127. package/src/__tests__/rebind-secrets-screen.test.ts +839 -0
  128. package/src/__tests__/recording-handler.test.ts +2 -2
  129. package/src/__tests__/recording-intent-handler.test.ts +3 -3
  130. package/src/__tests__/recording-state-machine.test.ts +2 -2
  131. package/src/__tests__/relay-server.test.ts +506 -227
  132. package/src/__tests__/reminder-store.test.ts +8 -0
  133. package/src/__tests__/reminder.test.ts +8 -0
  134. package/src/__tests__/{resolve-guardian-trust-class.test.ts → resolve-trust-class.test.ts} +11 -17
  135. package/src/__tests__/scaffold-managed-skill-tool.test.ts +1 -1
  136. package/src/__tests__/schedule-tools.test.ts +1 -1
  137. package/src/__tests__/script-proxy-certs.test.ts +1 -1
  138. package/src/__tests__/script-proxy-connect-tunnel.test.ts +2 -3
  139. package/src/__tests__/script-proxy-decision-trace.test.ts +2 -2
  140. package/src/__tests__/script-proxy-http-forwarder.test.ts +1 -1
  141. package/src/__tests__/script-proxy-injection-runtime.test.ts +5 -5
  142. package/src/__tests__/script-proxy-mitm-handler.test.ts +4 -4
  143. package/src/__tests__/script-proxy-policy-runtime.test.ts +2 -2
  144. package/src/__tests__/script-proxy-policy.test.ts +2 -2
  145. package/src/__tests__/script-proxy-session-manager.test.ts +4 -7
  146. package/src/__tests__/script-proxy-session-runtime.test.ts +1 -6
  147. package/src/__tests__/secret-onetime-send.test.ts +4 -4
  148. package/src/__tests__/secret-scanner-executor.test.ts +2 -2
  149. package/src/__tests__/send-endpoint-busy.test.ts +11 -9
  150. package/src/__tests__/send-notification-tool.test.ts +2 -2
  151. package/src/__tests__/session-abort-tool-results.test.ts +17 -2
  152. package/src/__tests__/session-agent-loop.test.ts +456 -35
  153. package/src/__tests__/session-confirmation-signals.test.ts +3 -2
  154. package/src/__tests__/session-conflict-gate.test.ts +20 -3
  155. package/src/__tests__/session-init.benchmark.test.ts +2 -2
  156. package/src/__tests__/session-load-history-repair.test.ts +7 -7
  157. package/src/__tests__/session-pre-run-repair.test.ts +17 -2
  158. package/src/__tests__/session-profile-injection.test.ts +20 -3
  159. package/src/__tests__/session-provider-retry-repair.test.ts +86 -6
  160. package/src/__tests__/session-queue.test.ts +33 -18
  161. package/src/__tests__/session-runtime-assembly.test.ts +147 -1
  162. package/src/__tests__/session-runtime-workspace.test.ts +40 -0
  163. package/src/__tests__/session-slash-known.test.ts +21 -3
  164. package/src/__tests__/session-slash-queue.test.ts +17 -2
  165. package/src/__tests__/session-slash-unknown.test.ts +17 -2
  166. package/src/__tests__/session-surfaces-deselection.test.ts +208 -0
  167. package/src/__tests__/session-workspace-cache-state.test.ts +2 -2
  168. package/src/__tests__/session-workspace-injection.test.ts +17 -2
  169. package/src/__tests__/session-workspace-tool-tracking.test.ts +17 -2
  170. package/src/__tests__/shell-credential-ref.test.ts +1 -1
  171. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  172. package/src/__tests__/skill-load-feature-flag.test.ts +1 -1
  173. package/src/__tests__/skill-load-tool.test.ts +1 -1
  174. package/src/__tests__/skill-script-runner-host.test.ts +1 -1
  175. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -1
  176. package/src/__tests__/skill-script-runner.test.ts +1 -1
  177. package/src/__tests__/skill-tool-factory.test.ts +1 -1
  178. package/src/__tests__/slack-skill.test.ts +3 -2
  179. package/src/__tests__/subagent-tools.test.ts +3 -3
  180. package/src/__tests__/swarm-recursion.test.ts +1 -1
  181. package/src/__tests__/swarm-session-integration.test.ts +1 -1
  182. package/src/__tests__/swarm-tool.test.ts +1 -1
  183. package/src/__tests__/task-management-tools.test.ts +1 -1
  184. package/src/__tests__/task-tools.test.ts +1 -1
  185. package/src/__tests__/terminal-tools.test.ts +1 -1
  186. package/src/__tests__/test-support/browser-skill-harness.ts +39 -27
  187. package/src/__tests__/test-support/computer-use-skill-harness.ts +14 -14
  188. package/src/__tests__/tool-approval-handler.test.ts +15 -15
  189. package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -1
  190. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
  191. package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
  192. package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
  193. package/src/__tests__/tool-executor.test.ts +23 -182
  194. package/src/__tests__/tool-grant-request-escalation.test.ts +11 -11
  195. package/src/__tests__/tool-permission-simulate-handler.test.ts +4 -4
  196. package/src/__tests__/transfer-progress-screen.test.ts +1180 -0
  197. package/src/__tests__/trust-context-guards.test.ts +25 -29
  198. package/src/__tests__/trusted-contact-approval-notifier.test.ts +23 -21
  199. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +37 -40
  200. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +29 -25
  201. package/src/__tests__/trusted-contact-multichannel.test.ts +25 -24
  202. package/src/__tests__/trusted-contact-verification.test.ts +63 -77
  203. package/src/__tests__/turn-commit.test.ts +18 -18
  204. package/src/__tests__/twilio-provider.test.ts +7 -7
  205. package/src/__tests__/validation-results-screen.test.ts +1107 -0
  206. package/src/__tests__/view-image-tool.test.ts +1 -1
  207. package/src/__tests__/voice-invite-redemption.test.ts +3 -2
  208. package/src/__tests__/voice-scoped-grant-consumer.test.ts +12 -12
  209. package/src/__tests__/voice-session-bridge.test.ts +24 -24
  210. package/src/agent/attachments.ts +3 -1
  211. package/src/agent/loop.ts +13 -13
  212. package/src/agent/message-types.ts +13 -7
  213. package/src/amazon/cart.ts +59 -32
  214. package/src/amazon/checkout.ts +25 -14
  215. package/src/amazon/client.ts +68 -48
  216. package/src/amazon/product-details.ts +3 -3
  217. package/src/amazon/request-extractor.ts +46 -31
  218. package/src/amazon/search.ts +6 -4
  219. package/src/amazon/session.ts +33 -24
  220. package/src/approvals/AGENTS.md +26 -0
  221. package/src/approvals/approval-primitive.ts +87 -64
  222. package/src/approvals/guardian-decision-primitive.ts +172 -81
  223. package/src/approvals/guardian-request-resolvers.ts +262 -155
  224. package/src/autonomy/autonomy-resolver.ts +7 -5
  225. package/src/autonomy/autonomy-store.ts +34 -19
  226. package/src/autonomy/disposition-mapper.ts +5 -5
  227. package/src/autonomy/index.ts +6 -6
  228. package/src/autonomy/types.ts +7 -3
  229. package/src/browser-extension-relay/client.ts +50 -19
  230. package/src/browser-extension-relay/protocol.ts +11 -11
  231. package/src/browser-extension-relay/server.ts +45 -20
  232. package/src/bundler/app-bundler.ts +75 -50
  233. package/src/bundler/bundle-scanner.ts +145 -41
  234. package/src/bundler/bundle-signer.ts +16 -14
  235. package/src/bundler/signature-verifier.ts +36 -33
  236. package/src/calls/call-constants.ts +10 -3
  237. package/src/calls/call-controller.ts +473 -214
  238. package/src/calls/call-conversation-messages.ts +25 -15
  239. package/src/calls/call-domain.ts +401 -148
  240. package/src/calls/call-pointer-message-composer.ts +26 -21
  241. package/src/calls/call-pointer-messages.ts +52 -28
  242. package/src/calls/call-recovery.ts +53 -37
  243. package/src/calls/call-state-machine.ts +37 -7
  244. package/src/calls/call-state.ts +35 -13
  245. package/src/calls/call-store.ts +165 -77
  246. package/src/calls/elevenlabs-client.ts +39 -20
  247. package/src/calls/guardian-action-sweep.ts +42 -24
  248. package/src/calls/guardian-dispatch.ts +79 -56
  249. package/src/calls/guardian-question-copy.ts +28 -23
  250. package/src/calls/relay-server.ts +1121 -532
  251. package/src/calls/speaker-identification.ts +21 -15
  252. package/src/calls/twilio-config.ts +34 -17
  253. package/src/calls/twilio-provider.ts +108 -55
  254. package/src/calls/twilio-rest.ts +212 -100
  255. package/src/calls/twilio-routes.ts +165 -92
  256. package/src/calls/types.ts +55 -7
  257. package/src/calls/voice-quality.ts +6 -4
  258. package/src/calls/voice-session-bridge.ts +181 -133
  259. package/src/channels/config.ts +17 -13
  260. package/src/channels/types.ts +38 -10
  261. package/src/cli/amazon.ts +333 -227
  262. package/src/cli/config-commands.ts +236 -146
  263. package/src/cli/core-commands.ts +403 -329
  264. package/src/cli/email-guardrails.ts +38 -19
  265. package/src/cli/email.ts +207 -153
  266. package/src/cli/influencer.ts +58 -56
  267. package/src/cli/integrations.ts +362 -0
  268. package/src/cli/ipc-client.ts +24 -19
  269. package/src/cli/map.ts +176 -129
  270. package/src/cli/mcp.ts +260 -152
  271. package/src/cli/sequence.ts +165 -107
  272. package/src/cli/twitter.ts +302 -218
  273. package/src/cli.ts +418 -279
  274. package/src/commands/cc-command-registry.ts +52 -27
  275. package/src/config/agent-schema.ts +217 -134
  276. package/src/config/assistant-feature-flags.ts +23 -18
  277. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +19 -0
  278. package/src/config/bundled-skills/app-builder/tools/app-create.ts +7 -4
  279. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +6 -3
  280. package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +7 -4
  281. package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +6 -3
  282. package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +6 -3
  283. package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +7 -4
  284. package/src/config/bundled-skills/app-builder/tools/app-list.ts +6 -3
  285. package/src/config/bundled-skills/app-builder/tools/app-query.ts +6 -3
  286. package/src/config/bundled-skills/app-builder/tools/app-update.ts +6 -3
  287. package/src/config/bundled-skills/browser/tools/browser-click.ts +5 -2
  288. package/src/config/bundled-skills/browser/tools/browser-close.ts +5 -2
  289. package/src/config/bundled-skills/browser/tools/browser-extract.ts +5 -2
  290. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +5 -2
  291. package/src/config/bundled-skills/browser/tools/browser-hover.ts +5 -2
  292. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +5 -2
  293. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +5 -2
  294. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +5 -2
  295. package/src/config/bundled-skills/browser/tools/browser-scroll.ts +5 -2
  296. package/src/config/bundled-skills/browser/tools/browser-select-option.ts +5 -2
  297. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +5 -2
  298. package/src/config/bundled-skills/browser/tools/browser-type.ts +5 -2
  299. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +13 -6
  300. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +5 -2
  301. package/src/config/bundled-skills/claude-code/TOOLS.json +4 -0
  302. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +5 -2
  303. package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
  304. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +6 -3
  305. package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +6 -3
  306. package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +10 -3
  307. package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +6 -3
  308. package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +6 -3
  309. package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +6 -3
  310. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +10 -3
  311. package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +6 -3
  312. package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +10 -3
  313. package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +10 -3
  314. package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +6 -3
  315. package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +6 -3
  316. package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +6 -3
  317. package/src/config/bundled-skills/configure-settings/SKILL.md +28 -14
  318. package/src/config/bundled-skills/contacts/SKILL.md +446 -15
  319. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +99 -20
  320. package/src/config/bundled-skills/contacts/tools/contact-search.ts +74 -17
  321. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +89 -26
  322. package/src/config/bundled-skills/document/tools/document-create.ts +5 -2
  323. package/src/config/bundled-skills/document/tools/document-update.ts +5 -2
  324. package/src/config/bundled-skills/doordash/doordash-cli.ts +17 -7
  325. package/src/config/bundled-skills/email-setup/SKILL.md +9 -9
  326. package/src/config/bundled-skills/followups/tools/followup-create.ts +5 -2
  327. package/src/config/bundled-skills/followups/tools/followup-list.ts +5 -2
  328. package/src/config/bundled-skills/followups/tools/followup-resolve.ts +5 -2
  329. package/src/config/bundled-skills/google-calendar/calendar-client.ts +44 -32
  330. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +11 -5
  331. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +13 -7
  332. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +11 -5
  333. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +13 -7
  334. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +28 -12
  335. package/src/config/bundled-skills/google-calendar/tools/shared.ts +6 -4
  336. package/src/config/bundled-skills/google-calendar/types.ts +3 -3
  337. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +46 -24
  338. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +36 -19
  339. package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +60 -35
  340. package/src/config/bundled-skills/mcp-setup/SKILL.md +75 -0
  341. package/src/config/bundled-skills/media-processing/SKILL.md +55 -15
  342. package/src/config/bundled-skills/media-processing/TOOLS.json +20 -2
  343. package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +12 -10
  344. package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +34 -19
  345. package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +82 -66
  346. package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +148 -0
  347. package/src/config/bundled-skills/media-processing/services/concurrency-pool.ts +1 -1
  348. package/src/config/bundled-skills/media-processing/services/cost-tracker.ts +8 -3
  349. package/src/config/bundled-skills/media-processing/services/gemini-map.ts +117 -53
  350. package/src/config/bundled-skills/media-processing/services/gemini-video.ts +273 -0
  351. package/src/config/bundled-skills/media-processing/services/preprocess.ts +185 -97
  352. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +32 -27
  353. package/src/config/bundled-skills/media-processing/services/reduce.ts +101 -24
  354. package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +121 -55
  355. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +58 -24
  356. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +177 -91
  357. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +98 -70
  358. package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +59 -19
  359. package/src/config/bundled-skills/media-processing/tools/media-status.ts +26 -10
  360. package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +29 -14
  361. package/src/config/bundled-skills/messaging/SKILL.md +7 -5
  362. package/src/config/bundled-skills/messaging/TOOLS.json +7 -7
  363. package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +31 -13
  364. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +16 -10
  365. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +18 -9
  366. package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +23 -16
  367. package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +28 -12
  368. package/src/config/bundled-skills/messaging/tools/gmail-filters.ts +41 -21
  369. package/src/config/bundled-skills/messaging/tools/gmail-follow-up.ts +44 -23
  370. package/src/config/bundled-skills/messaging/tools/gmail-forward.ts +73 -33
  371. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +15 -9
  372. package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +22 -14
  373. package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +99 -50
  374. package/src/config/bundled-skills/messaging/tools/gmail-send-draft.ts +14 -8
  375. package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +63 -44
  376. package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +90 -46
  377. package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +43 -22
  378. package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +15 -9
  379. package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +51 -22
  380. package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +62 -26
  381. package/src/config/bundled-skills/messaging/tools/gmail-vacation.ts +34 -19
  382. package/src/config/bundled-skills/messaging/tools/google-contacts.ts +32 -16
  383. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +10 -4
  384. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +91 -47
  385. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +21 -9
  386. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +9 -3
  387. package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +30 -17
  388. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +10 -4
  389. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +14 -6
  390. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +16 -5
  391. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +63 -36
  392. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +10 -4
  393. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +30 -12
  394. package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +48 -29
  395. package/src/config/bundled-skills/messaging/tools/scan-result-store.ts +20 -6
  396. package/src/config/bundled-skills/messaging/tools/send-notification.ts +1 -1
  397. package/src/config/bundled-skills/messaging/tools/sequence-analytics.ts +59 -22
  398. package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +13 -7
  399. package/src/config/bundled-skills/messaging/tools/sequence-create.ts +27 -12
  400. package/src/config/bundled-skills/messaging/tools/sequence-delete.ts +14 -6
  401. package/src/config/bundled-skills/messaging/tools/sequence-enroll.ts +30 -11
  402. package/src/config/bundled-skills/messaging/tools/sequence-enrollment-list.ts +16 -8
  403. package/src/config/bundled-skills/messaging/tools/sequence-get.ts +31 -13
  404. package/src/config/bundled-skills/messaging/tools/sequence-import.ts +38 -22
  405. package/src/config/bundled-skills/messaging/tools/sequence-list.ts +16 -7
  406. package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +29 -10
  407. package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +16 -8
  408. package/src/config/bundled-skills/messaging/tools/sequence-update.ts +35 -16
  409. package/src/config/bundled-skills/messaging/tools/shared.ts +26 -12
  410. package/src/config/bundled-skills/notifications/tools/send-notification.ts +69 -34
  411. package/src/config/bundled-skills/notifications/tools/shared.ts +1 -1
  412. package/src/config/bundled-skills/phone-calls/SKILL.md +46 -48
  413. package/src/config/bundled-skills/phone-calls/tools/call-end.ts +1 -1
  414. package/src/config/bundled-skills/phone-calls/tools/call-start.ts +1 -1
  415. package/src/config/bundled-skills/phone-calls/tools/call-status.ts +1 -1
  416. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +91 -51
  417. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +30 -16
  418. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +66 -27
  419. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +89 -42
  420. package/src/config/bundled-skills/public-ingress/SKILL.md +26 -19
  421. package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +5 -2
  422. package/src/config/bundled-skills/reminder/tools/reminder-create.ts +5 -2
  423. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +5 -2
  424. package/src/config/bundled-skills/schedule/tools/schedule-create.ts +5 -2
  425. package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +5 -2
  426. package/src/config/bundled-skills/schedule/tools/schedule-list.ts +5 -2
  427. package/src/config/bundled-skills/schedule/tools/schedule-update.ts +5 -2
  428. package/src/config/bundled-skills/screen-recording/SKILL.md +11 -3
  429. package/src/config/bundled-skills/self-upgrade/SKILL.md +9 -8
  430. package/src/config/bundled-skills/slack/TOOLS.json +33 -15
  431. package/src/config/bundled-skills/slack/tools/shared.ts +7 -5
  432. package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +11 -5
  433. package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +11 -5
  434. package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +46 -16
  435. package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +11 -5
  436. package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +28 -0
  437. package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +12 -6
  438. package/src/config/bundled-skills/sms-setup/SKILL.md +5 -8
  439. package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +5 -2
  440. package/src/config/bundled-skills/subagent/tools/subagent-message.ts +5 -2
  441. package/src/config/bundled-skills/subagent/tools/subagent-read.ts +5 -2
  442. package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +5 -2
  443. package/src/config/bundled-skills/subagent/tools/subagent-status.ts +5 -2
  444. package/src/config/bundled-skills/tasks/tools/task-delete.ts +5 -2
  445. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +5 -2
  446. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +5 -2
  447. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +5 -2
  448. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +5 -2
  449. package/src/config/bundled-skills/tasks/tools/task-list.ts +5 -2
  450. package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +5 -2
  451. package/src/config/bundled-skills/tasks/tools/task-run.ts +5 -2
  452. package/src/config/bundled-skills/tasks/tools/task-save.ts +5 -2
  453. package/src/config/bundled-skills/telegram-setup/SKILL.md +7 -8
  454. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +232 -127
  455. package/src/config/bundled-skills/twilio-setup/SKILL.md +7 -12
  456. package/src/config/bundled-skills/twitter/SKILL.md +19 -2
  457. package/src/config/bundled-skills/voice-setup/SKILL.md +5 -5
  458. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +5 -2
  459. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +5 -2
  460. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +5 -2
  461. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +5 -2
  462. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +5 -2
  463. package/src/config/bundled-skills/weather/tools/get-weather.ts +5 -2
  464. package/src/config/calls-schema.ts +108 -63
  465. package/src/config/computer-use-prompt.ts +7 -7
  466. package/src/config/core-schema.ts +239 -155
  467. package/src/config/defaults.ts +2 -2
  468. package/src/config/elevenlabs-schema.ts +15 -15
  469. package/src/config/env-registry.ts +33 -33
  470. package/src/config/feature-flag-registry.json +31 -7
  471. package/src/config/loader.ts +118 -58
  472. package/src/config/mcp-schema.ts +29 -15
  473. package/src/config/memory-schema.ts +434 -229
  474. package/src/config/notifications-schema.ts +4 -4
  475. package/src/config/sandbox-schema.ts +2 -2
  476. package/src/config/schema.ts +12 -2
  477. package/src/config/skill-state.ts +27 -15
  478. package/src/config/skills-schema.ts +72 -23
  479. package/src/config/skills.ts +303 -143
  480. package/src/config/system-prompt.ts +25 -6
  481. package/src/config/types.ts +1 -1
  482. package/src/config/update-bulletin-format.ts +3 -3
  483. package/src/config/update-bulletin-state.ts +15 -6
  484. package/src/config/update-bulletin-template-path.ts +8 -4
  485. package/src/config/update-bulletin.ts +33 -14
  486. package/src/config/user-reference.ts +8 -8
  487. package/src/contacts/contact-events.ts +21 -0
  488. package/src/contacts/contact-store.ts +622 -100
  489. package/src/contacts/contacts-write.ts +287 -0
  490. package/src/contacts/index.ts +13 -4
  491. package/src/contacts/startup-migration.ts +21 -0
  492. package/src/contacts/types.ts +47 -2
  493. package/src/context/token-estimator.ts +54 -31
  494. package/src/context/tool-result-truncation.ts +41 -7
  495. package/src/context/window-manager.ts +225 -120
  496. package/src/daemon/approval-generators.ts +83 -55
  497. package/src/daemon/approved-devices-store.ts +33 -20
  498. package/src/daemon/assistant-attachments.ts +134 -98
  499. package/src/daemon/auth-manager.ts +17 -15
  500. package/src/daemon/classifier.ts +117 -46
  501. package/src/daemon/computer-use-session.ts +316 -187
  502. package/src/daemon/config-watcher.ts +91 -44
  503. package/src/daemon/connection-policy.ts +18 -10
  504. package/src/daemon/context-overflow-approval.ts +48 -0
  505. package/src/daemon/context-overflow-policy.ts +50 -0
  506. package/src/daemon/context-overflow-reducer.ts +300 -0
  507. package/src/daemon/daemon-control.ts +79 -51
  508. package/src/daemon/date-context.ts +119 -69
  509. package/src/daemon/dictation-profile-store.ts +94 -48
  510. package/src/daemon/dictation-text-processing.ts +33 -12
  511. package/src/daemon/doordash-steps.ts +92 -49
  512. package/src/daemon/guardian-action-generators.ts +62 -46
  513. package/src/daemon/guardian-verification-intent.ts +31 -18
  514. package/src/daemon/handlers/apps.ts +257 -111
  515. package/src/daemon/handlers/avatar.ts +20 -15
  516. package/src/daemon/handlers/computer-use.ts +82 -39
  517. package/src/daemon/handlers/config-channels.ts +146 -69
  518. package/src/daemon/handlers/config-heartbeat.ts +114 -59
  519. package/src/daemon/handlers/config-inbox.ts +277 -106
  520. package/src/daemon/handlers/config-ingress.ts +127 -55
  521. package/src/daemon/handlers/config-integrations.ts +145 -88
  522. package/src/daemon/handlers/config-model.ts +58 -22
  523. package/src/daemon/handlers/config-platform.ts +40 -16
  524. package/src/daemon/handlers/config-scheduling.ts +109 -48
  525. package/src/daemon/handlers/config-slack-channel.ts +67 -35
  526. package/src/daemon/handlers/config-slack.ts +21 -20
  527. package/src/daemon/handlers/config-telegram.ts +100 -70
  528. package/src/daemon/handlers/config-tools.ts +103 -55
  529. package/src/daemon/handlers/config-trust.ts +50 -20
  530. package/src/daemon/handlers/config.ts +72 -24
  531. package/src/daemon/handlers/contacts.ts +163 -0
  532. package/src/daemon/handlers/diagnostics.ts +90 -48
  533. package/src/daemon/handlers/documents.ts +74 -46
  534. package/src/daemon/handlers/guardian-actions.ts +118 -71
  535. package/src/daemon/handlers/home-base.ts +19 -16
  536. package/src/daemon/handlers/identity.ts +65 -45
  537. package/src/daemon/handlers/index.ts +78 -54
  538. package/src/daemon/handlers/misc.ts +664 -234
  539. package/src/daemon/handlers/navigate-settings.ts +14 -11
  540. package/src/daemon/handlers/oauth-connect.ts +48 -35
  541. package/src/daemon/handlers/open-bundle-handler.ts +31 -24
  542. package/src/daemon/handlers/pairing.ts +51 -25
  543. package/src/daemon/handlers/publish.ts +55 -33
  544. package/src/daemon/handlers/recording.ts +378 -162
  545. package/src/daemon/handlers/sessions.ts +923 -423
  546. package/src/daemon/handlers/shared.ts +202 -117
  547. package/src/daemon/handlers/signing.ts +25 -6
  548. package/src/daemon/handlers/subagents.ts +117 -56
  549. package/src/daemon/handlers/twitter-auth.ts +70 -49
  550. package/src/daemon/handlers/work-items.ts +264 -112
  551. package/src/daemon/handlers/workspace-files.ts +27 -20
  552. package/src/daemon/handlers.ts +2 -2
  553. package/src/daemon/history-repair.ts +16 -15
  554. package/src/daemon/identity-helpers.ts +4 -4
  555. package/src/daemon/install-cli-launchers.ts +33 -22
  556. package/src/daemon/ipc-blob-store.ts +38 -24
  557. package/src/daemon/ipc-contract/apps.ts +61 -49
  558. package/src/daemon/ipc-contract/computer-use.ts +47 -37
  559. package/src/daemon/ipc-contract/contacts.ts +69 -0
  560. package/src/daemon/ipc-contract/diagnostics.ts +14 -14
  561. package/src/daemon/ipc-contract/documents.ts +8 -8
  562. package/src/daemon/ipc-contract/guardian-actions.ts +4 -4
  563. package/src/daemon/ipc-contract/inbox.ts +16 -16
  564. package/src/daemon/ipc-contract/integrations.ts +57 -44
  565. package/src/daemon/ipc-contract/memory.ts +3 -5
  566. package/src/daemon/ipc-contract/messages.ts +95 -69
  567. package/src/daemon/ipc-contract/notifications.ts +10 -6
  568. package/src/daemon/ipc-contract/pairing.ts +8 -8
  569. package/src/daemon/ipc-contract/schedules.ts +20 -20
  570. package/src/daemon/ipc-contract/sessions.ts +88 -57
  571. package/src/daemon/ipc-contract/settings.ts +12 -7
  572. package/src/daemon/ipc-contract/shared.ts +9 -7
  573. package/src/daemon/ipc-contract/skills.ts +46 -26
  574. package/src/daemon/ipc-contract/subagents.ts +9 -9
  575. package/src/daemon/ipc-contract/trust.ts +11 -11
  576. package/src/daemon/ipc-contract/work-items.ts +33 -28
  577. package/src/daemon/ipc-contract/workspace.ts +28 -21
  578. package/src/daemon/ipc-contract-inventory.json +8 -0
  579. package/src/daemon/ipc-contract-inventory.ts +29 -26
  580. package/src/daemon/ipc-contract.ts +111 -44
  581. package/src/daemon/ipc-handler.ts +27 -19
  582. package/src/daemon/ipc-protocol.ts +22 -12
  583. package/src/daemon/ipc-validate.ts +91 -46
  584. package/src/daemon/lifecycle.ts +25 -1
  585. package/src/daemon/main.ts +10 -8
  586. package/src/daemon/media-visibility-policy.ts +3 -1
  587. package/src/daemon/pairing-store.ts +72 -40
  588. package/src/daemon/providers-setup.ts +35 -25
  589. package/src/daemon/recording-executor.ts +37 -30
  590. package/src/daemon/recording-intent-fallback.ts +58 -28
  591. package/src/daemon/recording-intent.ts +71 -61
  592. package/src/daemon/ride-shotgun-handler.ts +201 -121
  593. package/src/daemon/seed-files.ts +28 -17
  594. package/src/daemon/server.ts +23 -14
  595. package/src/daemon/session-agent-loop-handlers.ts +261 -135
  596. package/src/daemon/session-agent-loop.ts +795 -253
  597. package/src/daemon/session-attachments.ts +104 -39
  598. package/src/daemon/session-conflict-gate.ts +72 -28
  599. package/src/daemon/session-dynamic-profile.ts +36 -22
  600. package/src/daemon/session-error.ts +50 -45
  601. package/src/daemon/session-evictor.ts +17 -10
  602. package/src/daemon/session-history.ts +201 -89
  603. package/src/daemon/session-lifecycle.ts +79 -42
  604. package/src/daemon/session-media-retry.ts +89 -41
  605. package/src/daemon/session-memory.ts +77 -55
  606. package/src/daemon/session-messaging.ts +261 -111
  607. package/src/daemon/session-notifiers.ts +57 -45
  608. package/src/daemon/session-process.ts +370 -154
  609. package/src/daemon/session-queue-manager.ts +30 -13
  610. package/src/daemon/session-runtime-assembly.ts +61 -15
  611. package/src/daemon/session-skill-tools.ts +84 -36
  612. package/src/daemon/session-slash.ts +178 -113
  613. package/src/daemon/session-surfaces.ts +498 -211
  614. package/src/daemon/session-tool-setup.ts +22 -17
  615. package/src/daemon/session-usage.ts +26 -13
  616. package/src/daemon/session-workspace.ts +7 -4
  617. package/src/daemon/session.ts +18 -19
  618. package/src/daemon/shutdown-handlers.ts +36 -33
  619. package/src/daemon/tls-certs.ts +90 -57
  620. package/src/daemon/tool-side-effects.ts +97 -65
  621. package/src/daemon/trace-emitter.ts +8 -7
  622. package/src/daemon/video-thumbnail.ts +55 -25
  623. package/src/daemon/watch-handler.ts +164 -86
  624. package/src/email/provider.ts +1 -1
  625. package/src/email/providers/agentmail.ts +87 -45
  626. package/src/email/providers/index.ts +19 -14
  627. package/src/email/service.ts +52 -24
  628. package/src/email/types.ts +2 -2
  629. package/src/errors.ts +1 -1
  630. package/src/events/bus.ts +30 -10
  631. package/src/events/domain-events.ts +19 -13
  632. package/src/events/index.ts +6 -6
  633. package/src/events/tool-audit-listener.ts +34 -20
  634. package/src/events/tool-domain-event-publisher.ts +22 -20
  635. package/src/events/tool-metrics-listener.ts +26 -21
  636. package/src/events/tool-notification-listener.ts +5 -5
  637. package/src/events/tool-profiling-listener.ts +33 -23
  638. package/src/events/tool-trace-listener.ts +70 -46
  639. package/src/export/formatter.ts +38 -32
  640. package/src/followups/followup-store.ts +43 -36
  641. package/src/followups/index.ts +2 -2
  642. package/src/followups/types.ts +1 -1
  643. package/src/gallery/default-gallery.ts +37 -34
  644. package/src/gallery/gallery-manifest.ts +9 -9
  645. package/src/heartbeat/heartbeat-service.ts +59 -37
  646. package/src/home-base/app-link-store.ts +14 -12
  647. package/src/home-base/bootstrap.ts +14 -8
  648. package/src/home-base/prebuilt/seed.ts +35 -26
  649. package/src/home-base/prebuilt-home-base-updater.ts +14 -8
  650. package/src/hooks/cli.ts +56 -43
  651. package/src/hooks/config.ts +27 -14
  652. package/src/hooks/discovery.ts +53 -33
  653. package/src/hooks/manager.ts +50 -26
  654. package/src/hooks/runner.ts +35 -29
  655. package/src/hooks/templates.ts +38 -15
  656. package/src/hooks/types.ts +13 -13
  657. package/src/inbound/platform-callback-registration.ts +21 -15
  658. package/src/inbound/public-ingress-urls.ts +9 -6
  659. package/src/index.ts +20 -19
  660. package/src/influencer/client.ts +269 -108
  661. package/src/instrument.ts +3 -1
  662. package/src/logfire.ts +64 -39
  663. package/src/mcp/client.ts +107 -55
  664. package/src/mcp/manager.ts +45 -18
  665. package/src/mcp/mcp-oauth-provider.ts +114 -62
  666. package/src/media/gemini-image-service.ts +28 -21
  667. package/src/memory/account-store.ts +16 -9
  668. package/src/memory/admin.ts +87 -57
  669. package/src/memory/app-git-service.ts +77 -47
  670. package/src/memory/app-store.ts +151 -77
  671. package/src/memory/attachments-store.ts +123 -53
  672. package/src/memory/canonical-guardian-store.ts +190 -48
  673. package/src/memory/channel-delivery-store.ts +5 -5
  674. package/src/memory/channel-guardian-store.ts +31 -16
  675. package/src/memory/checkpoints.ts +14 -7
  676. package/src/memory/clarification-resolver.ts +219 -104
  677. package/src/memory/conflict-intent.ts +74 -23
  678. package/src/memory/conflict-policy.ts +20 -7
  679. package/src/memory/conflict-store.ts +144 -94
  680. package/src/memory/contradiction-checker.ts +257 -132
  681. package/src/memory/conversation-attention-store.ts +72 -32
  682. package/src/memory/conversation-bootstrap.ts +28 -0
  683. package/src/memory/conversation-crud.ts +12 -5
  684. package/src/memory/conversation-display-order-migration.ts +7 -7
  685. package/src/memory/conversation-key-store.ts +18 -13
  686. package/src/memory/conversation-queries.ts +130 -52
  687. package/src/memory/conversation-store.ts +43 -26
  688. package/src/memory/conversation-title-service.ts +89 -66
  689. package/src/memory/db-init.ts +90 -2
  690. package/src/memory/db.ts +10 -3
  691. package/src/memory/delivery-channels.ts +12 -6
  692. package/src/memory/delivery-crud.ts +26 -12
  693. package/src/memory/delivery-status.ts +19 -16
  694. package/src/memory/embedding-backend.ts +205 -77
  695. package/src/memory/embedding-gemini.ts +23 -10
  696. package/src/memory/embedding-local.ts +89 -44
  697. package/src/memory/embedding-ollama.ts +25 -13
  698. package/src/memory/embedding-openai.ts +20 -11
  699. package/src/memory/embedding-runtime-manager.ts +163 -90
  700. package/src/memory/entity-extractor.ts +185 -123
  701. package/src/memory/external-conversation-store.ts +30 -12
  702. package/src/memory/fingerprint.ts +2 -2
  703. package/src/memory/fts-reconciler.ts +57 -28
  704. package/src/memory/guardian-action-store.ts +162 -100
  705. package/src/memory/guardian-approvals.ts +63 -129
  706. package/src/memory/guardian-rate-limits.ts +20 -9
  707. package/src/memory/guardian-verification.ts +82 -35
  708. package/src/memory/indexer.ts +96 -55
  709. package/src/memory/ingress-invite-store.ts +28 -169
  710. package/src/memory/items-extractor.ts +313 -157
  711. package/src/memory/job-handlers/backfill.ts +116 -63
  712. package/src/memory/job-handlers/cleanup.ts +64 -41
  713. package/src/memory/job-handlers/conflict.ts +90 -49
  714. package/src/memory/job-handlers/embedding.ts +32 -17
  715. package/src/memory/job-handlers/extraction.ts +58 -33
  716. package/src/memory/job-handlers/index-maintenance.ts +31 -17
  717. package/src/memory/job-handlers/media-processing.ts +65 -24
  718. package/src/memory/job-handlers/summarization.ts +186 -128
  719. package/src/memory/job-utils.ts +100 -57
  720. package/src/memory/jobs-store.ts +235 -142
  721. package/src/memory/jobs-worker.ts +167 -83
  722. package/src/memory/llm-request-log-store.ts +13 -11
  723. package/src/memory/llm-usage-store.ts +35 -26
  724. package/src/memory/media-store.ts +151 -44
  725. package/src/memory/message-content.ts +28 -18
  726. package/src/memory/migrations/001-job-deferrals.ts +11 -5
  727. package/src/memory/migrations/002-tool-invocations-fk.ts +14 -6
  728. package/src/memory/migrations/003-memory-fts-backfill.ts +11 -5
  729. package/src/memory/migrations/004-entity-relation-dedup.ts +17 -11
  730. package/src/memory/migrations/005-fingerprint-scope-unique.ts +36 -21
  731. package/src/memory/migrations/006-scope-salted-fingerprints.ts +35 -20
  732. package/src/memory/migrations/007-assistant-id-to-self.ts +40 -27
  733. package/src/memory/migrations/008-remove-assistant-id-columns.ts +58 -36
  734. package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +36 -22
  735. package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +21 -11
  736. package/src/memory/migrations/011-call-sessions-provider-sid-dedup.ts +30 -15
  737. package/src/memory/migrations/012-call-sessions-add-initiated-from.ts +4 -2
  738. package/src/memory/migrations/013-guardian-action-tables.ts +29 -11
  739. package/src/memory/migrations/014-backfill-inbox-thread-state.ts +35 -21
  740. package/src/memory/migrations/015-drop-active-search-index.ts +17 -11
  741. package/src/memory/migrations/016-memory-segments-indexes.ts +7 -3
  742. package/src/memory/migrations/017-memory-items-indexes.ts +4 -2
  743. package/src/memory/migrations/018-remaining-table-indexes.ts +13 -5
  744. package/src/memory/migrations/019-notification-tables-schema-migration.ts +34 -20
  745. package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +87 -53
  746. package/src/memory/migrations/021-conversation-status-indexes.ts +7 -3
  747. package/src/memory/migrations/022-add-origin-interface.ts +4 -2
  748. package/src/memory/migrations/023-memory-item-sources-indexes.ts +4 -2
  749. package/src/memory/migrations/024-embedding-vector-blob.ts +34 -18
  750. package/src/memory/migrations/025-messages-fts-backfill.ts +11 -5
  751. package/src/memory/migrations/026-guardian-verification-sessions.ts +80 -14
  752. package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +42 -26
  753. package/src/memory/migrations/027-notification-delivery-pairing-columns.ts +22 -8
  754. package/src/memory/migrations/027a-guardian-bootstrap-token.ts +11 -3
  755. package/src/memory/migrations/028-call-session-mode.ts +13 -3
  756. package/src/memory/migrations/028-notification-delivery-client-ack.ts +22 -8
  757. package/src/memory/migrations/029-channel-inbound-delivered-segments.ts +7 -3
  758. package/src/memory/migrations/030-guardian-action-followup.ts +46 -8
  759. package/src/memory/migrations/030-guardian-verification-purpose.ts +4 -2
  760. package/src/memory/migrations/031-conversations-thread-type-index.ts +4 -2
  761. package/src/memory/migrations/032-guardian-delivery-conversation-index.ts +4 -2
  762. package/src/memory/migrations/032-notification-delivery-thread-decision.ts +22 -8
  763. package/src/memory/migrations/033-scoped-approval-grants.ts +1 -1
  764. package/src/memory/migrations/034-guardian-action-tool-metadata.ts +15 -3
  765. package/src/memory/migrations/035-guardian-action-supersession.ts +15 -3
  766. package/src/memory/migrations/036-normalize-phone-identities.ts +101 -87
  767. package/src/memory/migrations/037-voice-invite-columns.ts +22 -4
  768. package/src/memory/migrations/038-actor-token-records.ts +5 -9
  769. package/src/memory/migrations/039-actor-refresh-token-records.ts +7 -13
  770. package/src/memory/migrations/100-core-tables.ts +1 -1
  771. package/src/memory/migrations/101-watchers-and-logs.ts +1 -1
  772. package/src/memory/migrations/103-complex-migrations.ts +9 -9
  773. package/src/memory/migrations/104-core-indexes.ts +188 -64
  774. package/src/memory/migrations/105-contacts-and-triage.ts +28 -10
  775. package/src/memory/migrations/106-call-sessions.ts +58 -16
  776. package/src/memory/migrations/107-followups.ts +16 -6
  777. package/src/memory/migrations/108-tasks-and-work-items.ts +43 -11
  778. package/src/memory/migrations/109-external-conversation-bindings.ts +11 -5
  779. package/src/memory/migrations/110-channel-guardian.ts +48 -10
  780. package/src/memory/migrations/111-media-assets.ts +52 -18
  781. package/src/memory/migrations/112-assistant-inbox.ts +32 -12
  782. package/src/memory/migrations/113-late-migrations.ts +12 -12
  783. package/src/memory/migrations/114-notifications.ts +28 -12
  784. package/src/memory/migrations/115-sequences.ts +10 -4
  785. package/src/memory/migrations/116-messages-fts.ts +1 -1
  786. package/src/memory/migrations/117-conversation-attention.ts +16 -6
  787. package/src/memory/migrations/118-reminder-routing-intent.ts +7 -3
  788. package/src/memory/migrations/119-schema-indexes-and-columns.ts +35 -15
  789. package/src/memory/migrations/120-fk-cascade-rebuilds.ts +36 -17
  790. package/src/memory/migrations/121-canonical-guardian-requests.ts +25 -9
  791. package/src/memory/migrations/122-canonical-guardian-requester-chat-id.ts +11 -3
  792. package/src/memory/migrations/123-canonical-guardian-deliveries-destination-index.ts +4 -2
  793. package/src/memory/migrations/124-voice-invite-display-metadata.ts +15 -3
  794. package/src/memory/migrations/125-guardian-principal-id-columns.ts +22 -4
  795. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +174 -126
  796. package/src/memory/migrations/127-guardian-principal-id-not-null.ts +58 -42
  797. package/src/memory/migrations/128-contacts-role-principal.ts +26 -0
  798. package/src/memory/migrations/129-contact-channels-access-fields.ts +105 -0
  799. package/src/memory/migrations/130-contact-channels-type-ext-chat-id-index.ts +15 -0
  800. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +134 -0
  801. package/src/memory/migrations/132-contacts-assistant-id.ts +21 -0
  802. package/src/memory/migrations/index.ts +82 -73
  803. package/src/memory/migrations/registry.ts +53 -37
  804. package/src/memory/migrations/validate-migration-state.ts +73 -46
  805. package/src/memory/profile-compiler.ts +58 -24
  806. package/src/memory/published-pages-store.ts +12 -16
  807. package/src/memory/qdrant-circuit-breaker.ts +28 -20
  808. package/src/memory/qdrant-client.ts +99 -63
  809. package/src/memory/qdrant-manager.ts +89 -57
  810. package/src/memory/query-builder.ts +9 -7
  811. package/src/memory/raw-query.ts +63 -14
  812. package/src/memory/recall-cache.ts +15 -8
  813. package/src/memory/retrieval-budget.ts +0 -1
  814. package/src/memory/retriever.ts +385 -192
  815. package/src/memory/schema-migration.ts +1 -1
  816. package/src/memory/schema.ts +44 -56
  817. package/src/memory/scoped-approval-grants.ts +99 -45
  818. package/src/memory/search/entity.ts +102 -40
  819. package/src/memory/search/formatting.ts +70 -52
  820. package/src/memory/search/lexical.ts +82 -43
  821. package/src/memory/search/ranking.ts +103 -39
  822. package/src/memory/search/semantic.ts +59 -35
  823. package/src/memory/search/types.ts +8 -8
  824. package/src/memory/segmenter.ts +20 -12
  825. package/src/memory/shared-app-links-store.ts +21 -16
  826. package/src/memory/task-memory-cleanup.ts +18 -8
  827. package/src/memory/tool-usage-store.ts +27 -19
  828. package/src/memory/validation.ts +4 -2
  829. package/src/messaging/activity-analyzer.ts +7 -7
  830. package/src/messaging/draft-store.ts +13 -10
  831. package/src/messaging/email-classifier.ts +73 -37
  832. package/src/messaging/index.ts +3 -3
  833. package/src/messaging/outreach-classifier.ts +76 -38
  834. package/src/messaging/provider-types.ts +2 -4
  835. package/src/messaging/provider.ts +37 -8
  836. package/src/messaging/providers/gmail/adapter.ts +183 -66
  837. package/src/messaging/providers/gmail/client.ts +3 -1
  838. package/src/messaging/providers/gmail/mime-builder.ts +21 -19
  839. package/src/messaging/providers/gmail/people-client.ts +22 -9
  840. package/src/messaging/providers/gmail/types.ts +6 -6
  841. package/src/messaging/providers/slack/adapter.ts +93 -43
  842. package/src/messaging/providers/slack/client.ts +100 -41
  843. package/src/messaging/providers/slack/types.ts +6 -0
  844. package/src/messaging/providers/sms/adapter.ts +76 -40
  845. package/src/messaging/providers/sms/client.ts +4 -4
  846. package/src/messaging/providers/telegram-bot/adapter.ts +52 -30
  847. package/src/messaging/providers/telegram-bot/client.ts +7 -7
  848. package/src/messaging/providers/whatsapp/adapter.ts +58 -31
  849. package/src/messaging/providers/whatsapp/client.ts +4 -4
  850. package/src/messaging/registry.ts +9 -5
  851. package/src/messaging/style-analyzer.ts +69 -39
  852. package/src/messaging/thread-summarizer.ts +101 -53
  853. package/src/messaging/triage-engine.ts +111 -82
  854. package/src/messaging/types.ts +10 -10
  855. package/src/migrations/config-merge.ts +18 -10
  856. package/src/migrations/data-layout.ts +35 -22
  857. package/src/migrations/data-merge.ts +17 -7
  858. package/src/migrations/hooks-merge.ts +43 -16
  859. package/src/migrations/index.ts +6 -6
  860. package/src/migrations/log.ts +9 -5
  861. package/src/migrations/skills-merge.ts +17 -7
  862. package/src/migrations/workspace-layout.ts +39 -25
  863. package/src/notifications/AGENTS.md +5 -0
  864. package/src/notifications/adapters/macos.ts +21 -14
  865. package/src/notifications/adapters/sms.ts +28 -15
  866. package/src/notifications/adapters/telegram.ts +24 -15
  867. package/src/notifications/broadcaster.ts +108 -52
  868. package/src/notifications/conversation-pairing.ts +64 -29
  869. package/src/notifications/copy-composer.ts +165 -95
  870. package/src/notifications/decision-engine.ts +353 -147
  871. package/src/notifications/decisions-store.ts +26 -10
  872. package/src/notifications/deliveries-store.ts +23 -13
  873. package/src/notifications/destination-resolver.ts +42 -24
  874. package/src/notifications/deterministic-checks.ts +78 -27
  875. package/src/notifications/emit-signal.ts +83 -45
  876. package/src/notifications/events-store.ts +13 -7
  877. package/src/notifications/guardian-question-mode.ts +125 -75
  878. package/src/notifications/preference-extractor.ts +85 -53
  879. package/src/notifications/preference-summary.ts +31 -18
  880. package/src/notifications/preferences-store.ts +29 -18
  881. package/src/notifications/runtime-dispatch.ts +22 -12
  882. package/src/notifications/signal.ts +4 -4
  883. package/src/notifications/thread-candidates.ts +59 -23
  884. package/src/notifications/thread-seed-composer.ts +45 -27
  885. package/src/notifications/types.ts +19 -10
  886. package/src/oauth/connect-orchestrator.ts +105 -54
  887. package/src/oauth/connect-types.ts +3 -3
  888. package/src/oauth/provider-profiles.ts +80 -59
  889. package/src/oauth/scope-policy.ts +5 -2
  890. package/src/oauth/token-persistence.ts +58 -24
  891. package/src/outbound-proxy/certs.ts +284 -0
  892. package/src/outbound-proxy/config.ts +94 -0
  893. package/src/outbound-proxy/connect-tunnel.ts +84 -0
  894. package/src/outbound-proxy/health.ts +62 -0
  895. package/src/outbound-proxy/host-pattern-match.ts +67 -0
  896. package/src/outbound-proxy/http-forwarder.ts +162 -0
  897. package/src/outbound-proxy/index.ts +80 -0
  898. package/src/outbound-proxy/logging.ts +193 -0
  899. package/src/outbound-proxy/mitm-handler.ts +292 -0
  900. package/src/outbound-proxy/policy.ts +172 -0
  901. package/src/outbound-proxy/router.ts +64 -0
  902. package/src/outbound-proxy/server.ts +145 -0
  903. package/src/outbound-proxy/types.ts +150 -0
  904. package/src/permissions/checker.ts +481 -189
  905. package/src/permissions/defaults.ts +135 -108
  906. package/src/permissions/prompter.ts +53 -27
  907. package/src/permissions/secret-prompter.ts +21 -15
  908. package/src/permissions/shell-identity.ts +47 -16
  909. package/src/permissions/trust-store.ts +185 -73
  910. package/src/permissions/types.ts +22 -12
  911. package/src/permissions/workspace-policy.ts +47 -38
  912. package/src/playbooks/index.ts +10 -2
  913. package/src/playbooks/playbook-compiler.ts +30 -24
  914. package/src/playbooks/types.ts +11 -8
  915. package/src/providers/anthropic/client.ts +325 -168
  916. package/src/providers/failover.ts +57 -22
  917. package/src/providers/fireworks/client.ts +9 -5
  918. package/src/providers/gemini/client.ts +61 -39
  919. package/src/providers/model-intents.ts +40 -33
  920. package/src/providers/ollama/client.ts +7 -7
  921. package/src/providers/openai/client.ts +106 -68
  922. package/src/providers/openrouter/client.ts +9 -5
  923. package/src/providers/provider-send-message.ts +59 -27
  924. package/src/providers/ratelimit.ts +25 -8
  925. package/src/providers/registry.ts +86 -38
  926. package/src/providers/retry.ts +84 -36
  927. package/src/providers/stream-timeout.ts +5 -3
  928. package/src/providers/types.ts +7 -6
  929. package/src/runtime/AGENTS.md +42 -0
  930. package/src/runtime/access-request-helper.ts +118 -68
  931. package/src/runtime/actor-refresh-token-store.ts +21 -16
  932. package/src/runtime/actor-token-store.ts +25 -18
  933. package/src/runtime/actor-trust-resolver.ts +183 -80
  934. package/src/runtime/approval-conversation-turn.ts +39 -26
  935. package/src/runtime/approval-message-composer.ts +116 -84
  936. package/src/runtime/assistant-event-hub.ts +25 -6
  937. package/src/runtime/assistant-event.ts +4 -4
  938. package/src/runtime/assistant-scope.ts +1 -1
  939. package/src/runtime/auth/__tests__/guard-tests.test.ts +36 -14
  940. package/src/runtime/auth/context.ts +8 -7
  941. package/src/runtime/auth/credential-service.ts +60 -38
  942. package/src/runtime/auth/external-assistant-id.ts +16 -8
  943. package/src/runtime/auth/index.ts +23 -16
  944. package/src/runtime/auth/route-policy.ts +170 -104
  945. package/src/runtime/auth/scopes.ts +22 -29
  946. package/src/runtime/auth/subject.ts +19 -13
  947. package/src/runtime/auth/token-service.ts +3 -3
  948. package/src/runtime/auth/types.ts +23 -23
  949. package/src/runtime/channel-approval-parser.ts +37 -14
  950. package/src/runtime/channel-approval-types.ts +12 -4
  951. package/src/runtime/channel-approvals.ts +41 -23
  952. package/src/runtime/channel-guardian-service.ts +144 -103
  953. package/src/runtime/channel-invite-transport.ts +4 -2
  954. package/src/runtime/channel-invite-transports/telegram.ts +16 -10
  955. package/src/runtime/channel-invite-transports/voice.ts +7 -7
  956. package/src/runtime/channel-readiness-service.ts +139 -90
  957. package/src/runtime/channel-readiness-types.ts +4 -2
  958. package/src/runtime/channel-reply-delivery.ts +21 -11
  959. package/src/runtime/channel-retry-sweep.ts +111 -62
  960. package/src/runtime/confirmation-request-guardian-bridge.ts +73 -54
  961. package/src/runtime/gateway-client.ts +86 -53
  962. package/src/runtime/guardian-action-conversation-turn.ts +34 -18
  963. package/src/runtime/guardian-action-followup-executor.ts +115 -45
  964. package/src/runtime/guardian-action-grant-minter.ts +40 -24
  965. package/src/runtime/guardian-action-message-composer.ts +105 -84
  966. package/src/runtime/guardian-decision-types.ts +28 -13
  967. package/src/runtime/guardian-outbound-actions.ts +9 -0
  968. package/src/runtime/guardian-reply-router.ts +274 -145
  969. package/src/runtime/guardian-vellum-migration.ts +38 -24
  970. package/src/runtime/guardian-verification-templates.ts +8 -11
  971. package/src/runtime/http-router.ts +175 -0
  972. package/src/runtime/http-server.ts +931 -669
  973. package/src/runtime/http-types.ts +2 -2
  974. package/src/runtime/ingress-service.ts +182 -89
  975. package/src/runtime/invite-redemption-service.ts +211 -134
  976. package/src/runtime/invite-redemption-templates.ts +18 -11
  977. package/src/runtime/local-actor-identity.ts +73 -55
  978. package/src/runtime/middleware/auth.ts +25 -14
  979. package/src/runtime/middleware/error-handler.ts +15 -11
  980. package/src/runtime/middleware/rate-limiter.ts +23 -17
  981. package/src/runtime/middleware/request-logger.ts +4 -4
  982. package/src/runtime/middleware/twilio-validation.ts +29 -20
  983. package/src/runtime/migrations/migration-transport.ts +575 -0
  984. package/src/runtime/migrations/migration-wizard.ts +715 -0
  985. package/src/runtime/migrations/rebind-secrets-screen.ts +351 -0
  986. package/src/runtime/migrations/transfer-progress-screen.ts +321 -0
  987. package/src/runtime/migrations/validation-results-screen.ts +467 -0
  988. package/src/runtime/migrations/vbundle-builder.ts +295 -0
  989. package/src/runtime/migrations/vbundle-import-analyzer.ts +212 -0
  990. package/src/runtime/migrations/vbundle-importer.ts +339 -0
  991. package/src/runtime/migrations/vbundle-validator.ts +356 -0
  992. package/src/runtime/pending-interactions.ts +16 -7
  993. package/src/runtime/routes/access-request-decision.ts +73 -52
  994. package/src/runtime/routes/app-routes.ts +56 -38
  995. package/src/runtime/routes/approval-routes.ts +165 -74
  996. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +930 -0
  997. package/src/runtime/routes/approval-strategies/guardian-legacy-fallback-strategy.ts +82 -0
  998. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +151 -0
  999. package/src/runtime/routes/attachment-routes.ts +59 -48
  1000. package/src/runtime/routes/brain-graph-routes.ts +85 -69
  1001. package/src/runtime/routes/call-routes.ts +79 -38
  1002. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +10 -10
  1003. package/src/runtime/routes/channel-delivery-routes.ts +19 -14
  1004. package/src/runtime/routes/channel-guardian-routes.ts +3 -3
  1005. package/src/runtime/routes/channel-inbound-routes.ts +2 -2
  1006. package/src/runtime/routes/channel-readiness-routes.ts +12 -6
  1007. package/src/runtime/routes/channel-route-shared.ts +33 -25
  1008. package/src/runtime/routes/channel-routes.ts +4 -6
  1009. package/src/runtime/routes/contact-routes.ts +205 -16
  1010. package/src/runtime/routes/conversation-attention-routes.ts +57 -28
  1011. package/src/runtime/routes/conversation-routes.ts +321 -174
  1012. package/src/runtime/routes/debug-routes.ts +14 -10
  1013. package/src/runtime/routes/events-routes.ts +90 -57
  1014. package/src/runtime/routes/global-search-routes.ts +266 -0
  1015. package/src/runtime/routes/guardian-action-routes.ts +147 -56
  1016. package/src/runtime/routes/guardian-approval-interception.ts +255 -880
  1017. package/src/runtime/routes/guardian-approval-prompt.ts +40 -24
  1018. package/src/runtime/routes/guardian-approval-reply-helpers.ts +135 -0
  1019. package/src/runtime/routes/guardian-bootstrap-routes.ts +55 -36
  1020. package/src/runtime/routes/guardian-expiry-sweep.ts +63 -37
  1021. package/src/runtime/routes/guardian-refresh-routes.ts +40 -19
  1022. package/src/runtime/routes/identity-routes.ts +71 -42
  1023. package/src/runtime/routes/inbound-conversation.ts +17 -11
  1024. package/src/runtime/routes/inbound-message-handler.ts +278 -1460
  1025. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +658 -0
  1026. package/src/runtime/routes/inbound-stages/background-dispatch.ts +492 -0
  1027. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +214 -0
  1028. package/src/runtime/routes/inbound-stages/edit-intercept.ts +116 -0
  1029. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +167 -0
  1030. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +185 -0
  1031. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +132 -0
  1032. package/src/runtime/routes/inbound-stages/verification-intercept.ts +340 -0
  1033. package/src/runtime/routes/ingress-routes.ts +34 -23
  1034. package/src/runtime/routes/integration-routes.ts +60 -21
  1035. package/src/runtime/routes/migration-routes.ts +434 -0
  1036. package/src/runtime/routes/pairing-routes.ts +157 -79
  1037. package/src/runtime/routes/secret-routes.ts +6 -2
  1038. package/src/runtime/routes/twilio-routes.ts +443 -249
  1039. package/src/runtime/tool-grant-request-helper.ts +36 -27
  1040. package/src/runtime/{guardian-context-resolver.ts → trust-context-resolver.ts} +29 -41
  1041. package/src/schedule/integration-status.ts +44 -9
  1042. package/src/schedule/recurrence-engine.ts +47 -24
  1043. package/src/schedule/recurrence-types.ts +12 -7
  1044. package/src/schedule/schedule-store.ts +166 -83
  1045. package/src/schedule/scheduler.ts +26 -22
  1046. package/src/security/encrypted-store.ts +68 -38
  1047. package/src/security/keychain.ts +183 -120
  1048. package/src/security/oauth-callback-registry.ts +3 -3
  1049. package/src/security/oauth2.ts +226 -138
  1050. package/src/security/redaction.ts +24 -24
  1051. package/src/security/secret-allowlist.ts +46 -21
  1052. package/src/security/secret-ingress.ts +15 -7
  1053. package/src/security/secret-scanner.ts +193 -104
  1054. package/src/security/secure-keys.ts +9 -3
  1055. package/src/security/token-manager.ts +99 -40
  1056. package/src/security/tool-approval-digest.ts +3 -3
  1057. package/src/sequence/analytics.ts +52 -27
  1058. package/src/sequence/engine.ts +135 -72
  1059. package/src/sequence/guardrails.ts +32 -20
  1060. package/src/sequence/importer.ts +75 -37
  1061. package/src/sequence/reply-matcher.ts +36 -18
  1062. package/src/sequence/store.ts +137 -75
  1063. package/src/sequence/types.ts +30 -16
  1064. package/src/services/published-app-updater.ts +26 -16
  1065. package/src/services/vercel-deploy.ts +19 -15
  1066. package/src/skills/active-skill-tools.ts +3 -3
  1067. package/src/skills/clawhub.ts +178 -90
  1068. package/src/skills/include-graph.ts +24 -17
  1069. package/src/skills/managed-store.ts +89 -42
  1070. package/src/skills/path-classifier.ts +10 -10
  1071. package/src/skills/remote-skill-policy.ts +31 -22
  1072. package/src/skills/slash-commands.ts +36 -30
  1073. package/src/skills/tool-manifest.ts +60 -31
  1074. package/src/skills/version-hash.ts +25 -15
  1075. package/src/slack/slack-webhook.ts +19 -15
  1076. package/src/subagent/index.ts +4 -8
  1077. package/src/subagent/manager.ts +119 -69
  1078. package/src/subagent/types.ts +9 -12
  1079. package/src/swarm/backend-claude-code.ts +124 -45
  1080. package/src/swarm/checkpoint.ts +36 -16
  1081. package/src/swarm/graph-utils.ts +1 -3
  1082. package/src/swarm/index.ts +38 -19
  1083. package/src/swarm/limits.ts +13 -4
  1084. package/src/swarm/orchestrator.ts +108 -57
  1085. package/src/swarm/plan-validator.ts +23 -17
  1086. package/src/swarm/router-planner.ts +51 -22
  1087. package/src/swarm/router-prompts.ts +4 -1
  1088. package/src/swarm/synthesizer.ts +26 -18
  1089. package/src/swarm/types.ts +14 -4
  1090. package/src/swarm/worker-backend.ts +36 -26
  1091. package/src/swarm/worker-prompts.ts +13 -9
  1092. package/src/swarm/worker-runner.ts +40 -34
  1093. package/src/tasks/candidate-store.ts +14 -6
  1094. package/src/tasks/ephemeral-permissions.ts +9 -5
  1095. package/src/tasks/task-compiler.ts +41 -38
  1096. package/src/tasks/task-runner.ts +54 -26
  1097. package/src/tasks/task-scheduler.ts +1 -1
  1098. package/src/tasks/task-store.ts +20 -7
  1099. package/src/tasks/tool-sanitizer.ts +3 -3
  1100. package/src/tools/apps/definitions.ts +23 -15
  1101. package/src/tools/apps/executors.ts +118 -37
  1102. package/src/tools/apps/open-proxy.ts +5 -5
  1103. package/src/tools/apps/registry.ts +2 -2
  1104. package/src/tools/assets/materialize.ts +59 -41
  1105. package/src/tools/assets/search.ts +86 -48
  1106. package/src/tools/browser/api-map.ts +52 -36
  1107. package/src/tools/browser/auth-cache.ts +21 -18
  1108. package/src/tools/browser/auth-detector.ts +43 -28
  1109. package/src/tools/browser/auto-navigate.ts +149 -68
  1110. package/src/tools/browser/browser-execution.ts +9 -3
  1111. package/src/tools/browser/headless-browser.ts +287 -150
  1112. package/src/tools/browser/jit-auth.ts +37 -21
  1113. package/src/tools/browser/network-recorder.ts +138 -56
  1114. package/src/tools/browser/recording-store.ts +22 -15
  1115. package/src/tools/browser/runtime-check.ts +8 -5
  1116. package/src/tools/browser/x-auto-navigate.ts +88 -47
  1117. package/src/tools/calls/call-end.ts +9 -6
  1118. package/src/tools/calls/call-start.ts +30 -20
  1119. package/src/tools/calls/call-status.ts +8 -5
  1120. package/src/tools/claude-code/claude-code.ts +301 -165
  1121. package/src/tools/computer-use/definitions.ts +159 -130
  1122. package/src/tools/computer-use/registry.ts +2 -2
  1123. package/src/tools/computer-use/request-computer-control.ts +21 -13
  1124. package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
  1125. package/src/tools/credentials/account-registry.ts +52 -35
  1126. package/src/tools/credentials/broker-types.ts +1 -1
  1127. package/src/tools/credentials/broker.ts +97 -55
  1128. package/src/tools/credentials/domain-policy.ts +5 -2
  1129. package/src/tools/credentials/host-pattern-match.ts +15 -8
  1130. package/src/tools/credentials/metadata-store.ts +93 -43
  1131. package/src/tools/credentials/policy-types.ts +5 -2
  1132. package/src/tools/credentials/policy-validate.ts +21 -14
  1133. package/src/tools/credentials/post-connect-hooks.ts +18 -7
  1134. package/src/tools/credentials/resolve.ts +11 -10
  1135. package/src/tools/credentials/selection.ts +30 -25
  1136. package/src/tools/credentials/tool-policy.ts +5 -2
  1137. package/src/tools/credentials/vault.ts +452 -183
  1138. package/src/tools/document/document-tool.ts +23 -17
  1139. package/src/tools/document/editor-template.ts +12 -7
  1140. package/src/tools/execution-target.ts +13 -10
  1141. package/src/tools/execution-timeout.ts +6 -5
  1142. package/src/tools/executor.ts +141 -74
  1143. package/src/tools/filesystem/edit.ts +82 -45
  1144. package/src/tools/filesystem/fuzzy-match.ts +70 -32
  1145. package/src/tools/filesystem/read.ts +46 -28
  1146. package/src/tools/filesystem/view-image.ts +86 -42
  1147. package/src/tools/filesystem/write.ts +53 -32
  1148. package/src/tools/followups/followup_create.ts +43 -17
  1149. package/src/tools/followups/followup_list.ts +28 -13
  1150. package/src/tools/followups/followup_resolve.ts +9 -6
  1151. package/src/tools/guardian-control-plane-policy.ts +15 -14
  1152. package/src/tools/host-filesystem/edit.ts +77 -42
  1153. package/src/tools/host-filesystem/read.ts +52 -33
  1154. package/src/tools/host-filesystem/write.ts +50 -29
  1155. package/src/tools/host-terminal/host-shell.ts +97 -61
  1156. package/src/tools/mcp/mcp-tool-factory.ts +21 -14
  1157. package/src/tools/memory/definitions.ts +60 -28
  1158. package/src/tools/memory/handlers.ts +149 -77
  1159. package/src/tools/memory/register.ts +39 -16
  1160. package/src/tools/network/__tests__/web-search.test.ts +236 -177
  1161. package/src/tools/network/domain-normalize.ts +13 -9
  1162. package/src/tools/network/script-proxy/__tests__/logging.test.ts +193 -123
  1163. package/src/tools/network/script-proxy/__tests__/policy.test.ts +225 -127
  1164. package/src/tools/network/script-proxy/index.ts +1 -17
  1165. package/src/tools/network/script-proxy/session-manager.ts +151 -84
  1166. package/src/tools/network/url-safety.ts +56 -34
  1167. package/src/tools/network/web-fetch.ts +273 -155
  1168. package/src/tools/network/web-search.ts +166 -81
  1169. package/src/tools/permission-checker.ts +6 -25
  1170. package/src/tools/policy-context.ts +8 -5
  1171. package/src/tools/registry.ts +73 -46
  1172. package/src/tools/reminder/reminder-store.ts +65 -44
  1173. package/src/tools/reminder/reminder.ts +76 -35
  1174. package/src/tools/schedule/create.ts +44 -21
  1175. package/src/tools/schedule/delete.ts +8 -5
  1176. package/src/tools/schedule/list.ts +39 -19
  1177. package/src/tools/schedule/update.ts +49 -26
  1178. package/src/tools/secret-detection-handler.ts +130 -49
  1179. package/src/tools/sensitive-output-placeholders.ts +15 -8
  1180. package/src/tools/shared/filesystem/edit-engine.ts +45 -14
  1181. package/src/tools/shared/filesystem/errors.ts +18 -18
  1182. package/src/tools/shared/filesystem/file-ops-service.ts +59 -32
  1183. package/src/tools/shared/filesystem/format-diff.ts +21 -11
  1184. package/src/tools/shared/filesystem/path-policy.ts +17 -13
  1185. package/src/tools/shared/filesystem/size-guard.ts +8 -4
  1186. package/src/tools/shared/filesystem/types.ts +2 -2
  1187. package/src/tools/shared/shell-output.ts +4 -3
  1188. package/src/tools/side-effects.ts +36 -28
  1189. package/src/tools/skills/delete-managed.ts +30 -17
  1190. package/src/tools/skills/load.ts +88 -46
  1191. package/src/tools/skills/sandbox-runner.ts +62 -46
  1192. package/src/tools/skills/scaffold-managed.ts +98 -48
  1193. package/src/tools/skills/script-contract.ts +5 -2
  1194. package/src/tools/skills/skill-script-runner.ts +29 -13
  1195. package/src/tools/skills/skill-tool-factory.ts +20 -10
  1196. package/src/tools/subagent/abort.ts +10 -4
  1197. package/src/tools/subagent/message.ts +14 -8
  1198. package/src/tools/subagent/read.ts +20 -11
  1199. package/src/tools/subagent/spawn.ts +14 -6
  1200. package/src/tools/subagent/status.ts +7 -4
  1201. package/src/tools/swarm/delegate.ts +75 -49
  1202. package/src/tools/system/avatar-generator.ts +46 -33
  1203. package/src/tools/system/navigate-settings.ts +29 -19
  1204. package/src/tools/system/open-system-settings.ts +30 -20
  1205. package/src/tools/system/request-permission.ts +59 -44
  1206. package/src/tools/system/version.ts +27 -16
  1207. package/src/tools/system/voice-config.ts +116 -53
  1208. package/src/tools/tasks/index.ts +8 -8
  1209. package/src/tools/tasks/task-delete.ts +61 -22
  1210. package/src/tools/tasks/task-list.ts +23 -11
  1211. package/src/tools/tasks/task-run.ts +41 -16
  1212. package/src/tools/tasks/task-save.ts +27 -10
  1213. package/src/tools/tasks/work-item-enqueue.ts +114 -48
  1214. package/src/tools/tasks/work-item-list.ts +20 -10
  1215. package/src/tools/tasks/work-item-remove.ts +49 -15
  1216. package/src/tools/tasks/work-item-run.ts +34 -13
  1217. package/src/tools/tasks/work-item-update.ts +84 -31
  1218. package/src/tools/terminal/backends/native.ts +64 -35
  1219. package/src/tools/terminal/backends/types.ts +6 -2
  1220. package/src/tools/terminal/parser.ts +200 -125
  1221. package/src/tools/terminal/safe-env.ts +27 -21
  1222. package/src/tools/terminal/sandbox-diagnostics.ts +31 -13
  1223. package/src/tools/terminal/sandbox.ts +10 -6
  1224. package/src/tools/terminal/shell.ts +124 -68
  1225. package/src/tools/tool-approval-handler.ts +193 -138
  1226. package/src/tools/types.ts +43 -23
  1227. package/src/tools/ui-surface/definitions.ts +124 -89
  1228. package/src/tools/ui-surface/registry.ts +2 -2
  1229. package/src/tools/watch/screen-watch.ts +50 -32
  1230. package/src/tools/watch/watch-state.ts +41 -15
  1231. package/src/tools/watcher/create.ts +37 -15
  1232. package/src/tools/watcher/delete.ts +9 -6
  1233. package/src/tools/watcher/digest.ts +10 -6
  1234. package/src/tools/watcher/list.ts +37 -14
  1235. package/src/tools/watcher/update.ts +33 -18
  1236. package/src/tools/weather/service.ts +331 -174
  1237. package/src/twitter/client.ts +261 -138
  1238. package/src/twitter/oauth-client.ts +17 -13
  1239. package/src/twitter/router.ts +51 -23
  1240. package/src/twitter/session.ts +27 -18
  1241. package/src/types/qrcode.d.ts +6 -3
  1242. package/src/usage/actors.ts +16 -16
  1243. package/src/usage/types.ts +3 -3
  1244. package/src/util/bundled-asset.ts +10 -6
  1245. package/src/util/canonicalize-identity.ts +11 -4
  1246. package/src/util/clipboard.ts +7 -7
  1247. package/src/util/content-id.ts +3 -3
  1248. package/src/util/debounce.ts +3 -2
  1249. package/src/util/diff.ts +55 -33
  1250. package/src/util/errors.ts +26 -26
  1251. package/src/util/fs.ts +8 -2
  1252. package/src/util/log-redact.ts +12 -12
  1253. package/src/util/logger.ts +112 -51
  1254. package/src/util/network-info.ts +13 -5
  1255. package/src/util/object.ts +4 -2
  1256. package/src/util/phone.ts +4 -4
  1257. package/src/util/platform.ts +80 -58
  1258. package/src/util/pricing.ts +49 -31
  1259. package/src/util/retry.ts +18 -7
  1260. package/src/util/row-mapper.ts +7 -4
  1261. package/src/util/silently.ts +7 -4
  1262. package/src/util/spawn.ts +48 -0
  1263. package/src/util/spinner.ts +9 -7
  1264. package/src/util/time.ts +16 -3
  1265. package/src/util/truncate.ts +1 -1
  1266. package/src/util/voice-code.ts +6 -4
  1267. package/src/util/xml.ts +5 -1
  1268. package/src/version.ts +12 -8
  1269. package/src/watcher/engine.ts +71 -44
  1270. package/src/watcher/provider-registry.ts +1 -1
  1271. package/src/watcher/providers/github.ts +40 -23
  1272. package/src/watcher/providers/gmail.ts +59 -38
  1273. package/src/watcher/providers/google-calendar.ts +62 -48
  1274. package/src/watcher/providers/linear.ts +219 -150
  1275. package/src/watcher/providers/slack.ts +93 -27
  1276. package/src/watcher/watcher-store.ts +75 -55
  1277. package/src/work-items/work-item-runner.ts +62 -29
  1278. package/src/work-items/work-item-store.ts +137 -47
  1279. package/src/workspace/commit-message-enrichment-service.ts +65 -25
  1280. package/src/workspace/commit-message-provider.ts +14 -12
  1281. package/src/workspace/git-service.ts +355 -239
  1282. package/src/workspace/heartbeat-service.ts +74 -37
  1283. package/src/workspace/provider-commit-message-generator.ts +95 -70
  1284. package/src/workspace/top-level-renderer.ts +10 -8
  1285. package/src/workspace/top-level-scanner.ts +9 -3
  1286. package/src/workspace/turn-commit.ts +63 -36
  1287. package/src/__tests__/ingress-member-store.test.ts +0 -294
  1288. package/src/__tests__/script-proxy-router.test.ts +0 -215
  1289. package/src/config/bundled-skills/trusted-contacts/SKILL.md +0 -372
  1290. package/src/memory/guardian-bindings.ts +0 -158
  1291. package/src/memory/ingress-member-store.ts +0 -352
  1292. package/src/tools/network/script-proxy/__tests__/router.test.ts +0 -77
  1293. package/src/tools/network/script-proxy/certs.ts +0 -7
  1294. package/src/tools/network/script-proxy/connect-tunnel.ts +0 -1
  1295. package/src/tools/network/script-proxy/http-forwarder.ts +0 -2
  1296. package/src/tools/network/script-proxy/logging.ts +0 -12
  1297. package/src/tools/network/script-proxy/mitm-handler.ts +0 -2
  1298. package/src/tools/network/script-proxy/policy.ts +0 -4
  1299. package/src/tools/network/script-proxy/router.ts +0 -2
  1300. package/src/tools/network/script-proxy/server.ts +0 -5
  1301. package/src/tools/network/script-proxy/types.ts +0 -19
@@ -7,69 +7,116 @@
7
7
  * runAgentLoop method here via the AgentLoopSessionContext interface.
8
8
  */
9
9
 
10
- import { v4 as uuid } from 'uuid';
11
-
12
- import type { AgentEvent,AgentLoop, CheckpointDecision } from '../agent/loop.js';
13
- import { createAssistantMessage } from '../agent/message-types.js';
14
- import type { ChannelId, InterfaceId, TurnChannelContext, TurnInterfaceContext } from '../channels/types.js';
15
- import { getConfig } from '../config/loader.js';
16
- import type { ContextWindowManager } from '../context/window-manager.js';
17
- import type { ToolProfiler } from '../events/tool-profiling-listener.js';
18
- import { getHookManager } from '../hooks/manager.js';
19
- import { commitAppTurnChanges } from '../memory/app-git-service.js';
20
- import { getApp, listAppFiles } from '../memory/app-store.js';
21
- import * as conversationStore from '../memory/conversation-store.js';
22
- import { getConversationOriginChannel, getConversationOriginInterface, provenanceFromGuardianContext } from '../memory/conversation-store.js';
23
- import { isReplaceableTitle, queueGenerateConversationTitle, queueRegenerateConversationTitle, UNTITLED_FALLBACK } from '../memory/conversation-title-service.js';
24
- import { stripMemoryRecallMessages } from '../memory/retriever.js';
25
- import type { PermissionPrompter } from '../permissions/prompter.js';
26
- import type { ContentBlock,Message } from '../providers/types.js';
27
- import type { Provider } from '../providers/types.js';
28
- import { resolveActorTrust } from '../runtime/actor-trust-resolver.js';
29
- import { DAEMON_INTERNAL_ASSISTANT_ID } from '../runtime/assistant-scope.js';
30
- import type { UsageActor } from '../usage/actors.js';
31
- import { getLogger } from '../util/logger.js';
32
- import { truncate } from '../util/truncate.js';
33
- import { getWorkspaceGitService } from '../workspace/git-service.js';
34
- import { commitTurnChanges } from '../workspace/turn-commit.js';
10
+ import { v4 as uuid } from "uuid";
11
+
12
+ import type {
13
+ AgentEvent,
14
+ AgentLoop,
15
+ CheckpointDecision,
16
+ } from "../agent/loop.js";
17
+ import { createAssistantMessage } from "../agent/message-types.js";
18
+ import type {
19
+ ChannelId,
20
+ InterfaceId,
21
+ TurnChannelContext,
22
+ TurnInterfaceContext,
23
+ } from "../channels/types.js";
24
+ import { getConfig } from "../config/loader.js";
25
+ import { estimatePromptTokens } from "../context/token-estimator.js";
26
+ import type { ContextWindowManager } from "../context/window-manager.js";
27
+ import type { ToolProfiler } from "../events/tool-profiling-listener.js";
28
+ import { getHookManager } from "../hooks/manager.js";
29
+ import { commitAppTurnChanges } from "../memory/app-git-service.js";
30
+ import { getApp, listAppFiles } from "../memory/app-store.js";
31
+ import * as conversationStore from "../memory/conversation-store.js";
32
+ import {
33
+ getConversationOriginChannel,
34
+ getConversationOriginInterface,
35
+ provenanceFromTrustContext,
36
+ } from "../memory/conversation-store.js";
37
+ import {
38
+ isReplaceableTitle,
39
+ queueGenerateConversationTitle,
40
+ queueRegenerateConversationTitle,
41
+ UNTITLED_FALLBACK,
42
+ } from "../memory/conversation-title-service.js";
43
+ import { stripMemoryRecallMessages } from "../memory/retriever.js";
44
+ import type { PermissionPrompter } from "../permissions/prompter.js";
45
+ import type { ContentBlock, Message } from "../providers/types.js";
46
+ import type { Provider } from "../providers/types.js";
47
+ import { resolveActorTrust } from "../runtime/actor-trust-resolver.js";
48
+ import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
49
+ import type { UsageActor } from "../usage/actors.js";
50
+ import { getLogger } from "../util/logger.js";
51
+ import { truncate } from "../util/truncate.js";
52
+ import { getWorkspaceGitService } from "../workspace/git-service.js";
53
+ import { commitTurnChanges } from "../workspace/turn-commit.js";
35
54
  import {
36
55
  type AssistantAttachmentDraft,
37
56
  cleanAssistantContent,
38
- } from './assistant-attachments.js';
39
- import { buildTemporalContext, extractUserTimeZoneFromDynamicProfile } from './date-context.js';
40
- import { deepRepairHistory,repairHistory } from './history-repair.js';
41
- import type { DynamicPageSurfaceData,ServerMessage, SurfaceData, SurfaceType, UsageStats } from './ipc-protocol.js';
57
+ } from "./assistant-attachments.js";
58
+ import { requestCompressionApproval } from "./context-overflow-approval.js";
59
+ import { resolveOverflowAction } from "./context-overflow-policy.js";
60
+ import {
61
+ createInitialReducerState,
62
+ reduceContextOverflow,
63
+ type ReducerState,
64
+ } from "./context-overflow-reducer.js";
65
+ import {
66
+ buildTemporalContext,
67
+ extractUserTimeZoneFromDynamicProfile,
68
+ } from "./date-context.js";
69
+ import { deepRepairHistory, repairHistory } from "./history-repair.js";
70
+ import type {
71
+ DynamicPageSurfaceData,
72
+ ServerMessage,
73
+ SurfaceData,
74
+ SurfaceType,
75
+ UsageStats,
76
+ } from "./ipc-protocol.js";
42
77
  import {
43
78
  createEventHandlerState,
44
79
  dispatchAgentEvent,
45
80
  type EventHandlerDeps,
46
- } from './session-agent-loop-handlers.js';
81
+ } from "./session-agent-loop-handlers.js";
47
82
  import {
48
83
  approveHostAttachmentRead,
49
84
  formatAttachmentWarnings,
50
85
  resolveAssistantAttachments,
51
- } from './session-attachments.js';
52
- import type { ConflictGate } from './session-conflict-gate.js';
53
- import { stripDynamicProfileMessages } from './session-dynamic-profile.js';
54
- import { buildSessionErrorMessage,classifySessionError, isUserCancellation } from './session-error.js';
55
- import { consolidateAssistantMessages } from './session-history.js';
56
- import { raceWithTimeout,stripMediaPayloadsForRetry } from './session-media-retry.js';
57
- import { prepareMemoryContext } from './session-memory.js';
58
- import type { MessageQueue } from './session-queue-manager.js';
59
- import type { QueueDrainReason } from './session-queue-manager.js';
60
- import type { ActiveSurfaceContext, ChannelCapabilities, ChannelTurnContextParams, GuardianRuntimeContext, InboundActorContext, InterfaceTurnContextParams } from './session-runtime-assembly.js';
86
+ } from "./session-attachments.js";
87
+ import type { ConflictGate } from "./session-conflict-gate.js";
88
+ import { stripDynamicProfileMessages } from "./session-dynamic-profile.js";
89
+ import {
90
+ buildSessionErrorMessage,
91
+ classifySessionError,
92
+ isUserCancellation,
93
+ } from "./session-error.js";
94
+ import { consolidateAssistantMessages } from "./session-history.js";
95
+ import { raceWithTimeout } from "./session-media-retry.js";
96
+ import { prepareMemoryContext } from "./session-memory.js";
97
+ import type { MessageQueue } from "./session-queue-manager.js";
98
+ import type { QueueDrainReason } from "./session-queue-manager.js";
99
+ import type {
100
+ ActiveSurfaceContext,
101
+ ChannelCapabilities,
102
+ ChannelTurnContextParams,
103
+ InboundActorContext,
104
+ InjectionMode,
105
+ InterfaceTurnContextParams,
106
+ TrustContext,
107
+ } from "./session-runtime-assembly.js";
61
108
  import {
62
109
  applyRuntimeInjections,
63
- inboundActorContextFromGuardian,
64
110
  inboundActorContextFromTrust,
111
+ inboundActorContextFromTrustContext,
65
112
  stripInjectedContext,
66
- } from './session-runtime-assembly.js';
67
- import type { SkillProjectionCache } from './session-skill-tools.js';
68
- import { resolveGuardianTrustClass } from './session-tool-setup.js';
69
- import { recordUsage } from './session-usage.js';
70
- import type { TraceEmitter } from './trace-emitter.js';
113
+ } from "./session-runtime-assembly.js";
114
+ import type { SkillProjectionCache } from "./session-skill-tools.js";
115
+ import { resolveTrustClass } from "./session-tool-setup.js";
116
+ import { recordUsage } from "./session-usage.js";
117
+ import type { TraceEmitter } from "./trace-emitter.js";
71
118
 
72
- const log = getLogger('session-agent-loop');
119
+ const log = getLogger("session-agent-loop");
73
120
 
74
121
  type GitServiceInitializer = {
75
122
  ensureInitialized(): Promise<void>;
@@ -97,17 +144,27 @@ export interface AgentLoopSessionContext {
97
144
 
98
145
  currentActiveSurfaceId?: string;
99
146
  currentPage?: string;
100
- readonly surfaceState: Map<string, { surfaceType: SurfaceType; data: SurfaceData; title?: string }>;
147
+ readonly surfaceState: Map<
148
+ string,
149
+ { surfaceType: SurfaceType; data: SurfaceData; title?: string }
150
+ >;
101
151
  pendingSurfaceActions: Map<string, { surfaceType: SurfaceType }>;
102
152
  surfaceActionRequestIds: Set<string>;
103
- currentTurnSurfaces: Array<{ surfaceId: string; surfaceType: SurfaceType; title?: string; data: SurfaceData; actions?: Array<{ id: string; label: string; style?: string }>; display?: string }>;
153
+ currentTurnSurfaces: Array<{
154
+ surfaceId: string;
155
+ surfaceType: SurfaceType;
156
+ title?: string;
157
+ data: SurfaceData;
158
+ actions?: Array<{ id: string; label: string; style?: string }>;
159
+ display?: string;
160
+ }>;
104
161
 
105
162
  workingDir: string;
106
163
  workspaceTopLevelContext: string | null;
107
164
  workspaceTopLevelDirty: boolean;
108
165
  channelCapabilities?: ChannelCapabilities;
109
166
  commandIntent?: { type: string; payload?: string; languageCode?: string };
110
- guardianContext?: GuardianRuntimeContext;
167
+ trustContext?: TrustContext;
111
168
  assistantId?: string;
112
169
  voiceCallControlPrompt?: string;
113
170
 
@@ -133,13 +190,37 @@ export interface AgentLoopSessionContext {
133
190
  readonly queue: MessageQueue;
134
191
 
135
192
  emitActivityState(
136
- phase: 'idle' | 'thinking' | 'streaming' | 'tool_running' | 'awaiting_confirmation',
137
- reason: 'message_dequeued' | 'thinking_delta' | 'first_text_delta' | 'tool_use_start' | 'tool_result_received' | 'confirmation_requested' | 'confirmation_resolved' | 'message_complete' | 'generation_cancelled' | 'error_terminal',
138
- anchor?: 'assistant_turn' | 'user_turn' | 'global',
193
+ phase:
194
+ | "idle"
195
+ | "thinking"
196
+ | "streaming"
197
+ | "tool_running"
198
+ | "awaiting_confirmation",
199
+ reason:
200
+ | "message_dequeued"
201
+ | "thinking_delta"
202
+ | "first_text_delta"
203
+ | "tool_use_start"
204
+ | "tool_result_received"
205
+ | "confirmation_requested"
206
+ | "confirmation_resolved"
207
+ | "message_complete"
208
+ | "generation_cancelled"
209
+ | "error_terminal",
210
+ anchor?: "assistant_turn" | "user_turn" | "global",
139
211
  requestId?: string,
140
212
  statusText?: string,
141
213
  ): void;
142
- emitConfirmationStateChanged(params: import('./ipc-contract/messages.js').ConfirmationStateChanged extends { type: infer _ } ? Omit<import('./ipc-contract/messages.js').ConfirmationStateChanged, 'type'> : never): void;
214
+ emitConfirmationStateChanged(
215
+ params: import("./ipc-contract/messages.js").ConfirmationStateChanged extends {
216
+ type: infer _;
217
+ }
218
+ ? Omit<
219
+ import("./ipc-contract/messages.js").ConfirmationStateChanged,
220
+ "type"
221
+ >
222
+ : never,
223
+ ): void;
143
224
 
144
225
  getWorkspaceGitService?: (workspaceDir: string) => GitServiceInitializer;
145
226
  commitTurnChanges?: typeof commitTurnChanges;
@@ -161,14 +242,22 @@ export async function runAgentLoopImpl(
161
242
  content: string,
162
243
  userMessageId: string,
163
244
  onEvent: (msg: ServerMessage) => void,
164
- options?: { skipPreMessageRollback?: boolean; isInteractive?: boolean; isUserMessage?: boolean; titleText?: string },
245
+ options?: {
246
+ skipPreMessageRollback?: boolean;
247
+ isInteractive?: boolean;
248
+ isUserMessage?: boolean;
249
+ titleText?: string;
250
+ },
165
251
  ): Promise<void> {
166
252
  if (!ctx.abortController) {
167
- throw new Error('runAgentLoop called without prior persistUserMessage');
253
+ throw new Error("runAgentLoop called without prior persistUserMessage");
168
254
  }
169
255
  const abortController = ctx.abortController;
170
256
  const reqId = ctx.currentRequestId ?? uuid();
171
- const rlog = log.child({ conversationId: ctx.conversationId, requestId: reqId });
257
+ const rlog = log.child({
258
+ conversationId: ctx.conversationId,
259
+ requestId: reqId,
260
+ });
172
261
  let yieldedForHandoff = false;
173
262
 
174
263
  // Capture the turn channel context *before* any awaits so a second
@@ -179,8 +268,12 @@ export async function runAgentLoopImpl(
179
268
  const live = ctx.getTurnChannelContext();
180
269
  if (live) return live;
181
270
  const origin = getConversationOriginChannel(ctx.conversationId);
182
- if (origin) return { userMessageChannel: origin, assistantMessageChannel: origin };
183
- return { userMessageChannel: 'vellum' as ChannelId, assistantMessageChannel: 'vellum' as ChannelId };
271
+ if (origin)
272
+ return { userMessageChannel: origin, assistantMessageChannel: origin };
273
+ return {
274
+ userMessageChannel: "vellum" as ChannelId,
275
+ assistantMessageChannel: "vellum" as ChannelId,
276
+ };
184
277
  })();
185
278
 
186
279
  // Capture interface context with the same anti-race snapshot pattern.
@@ -191,10 +284,14 @@ export async function runAgentLoopImpl(
191
284
  const live = ctx.getTurnInterfaceContext();
192
285
  if (live) return live;
193
286
  const origin = getConversationOriginInterface(ctx.conversationId);
194
- if (origin) return { userMessageInterface: origin, assistantMessageInterface: origin };
287
+ if (origin)
288
+ return {
289
+ userMessageInterface: origin,
290
+ assistantMessageInterface: origin,
291
+ };
195
292
  return {
196
- userMessageInterface: 'vellum' as InterfaceId,
197
- assistantMessageInterface: 'vellum' as InterfaceId,
293
+ userMessageInterface: "vellum" as InterfaceId,
294
+ assistantMessageInterface: "vellum" as InterfaceId,
198
295
  };
199
296
  })();
200
297
 
@@ -203,11 +300,12 @@ export async function runAgentLoopImpl(
203
300
 
204
301
  // Ensure workspace git repo is initialized before any tools run.
205
302
  try {
206
- const getWorkspaceGitServiceFn = ctx.getWorkspaceGitService ?? getWorkspaceGitService;
303
+ const getWorkspaceGitServiceFn =
304
+ ctx.getWorkspaceGitService ?? getWorkspaceGitService;
207
305
  const gitService = getWorkspaceGitServiceFn(ctx.workingDir);
208
306
  await gitService.ensureInitialized();
209
307
  } catch (err) {
210
- rlog.warn({ err }, 'Failed to initialize workspace git repo (non-fatal)');
308
+ rlog.warn({ err }, "Failed to initialize workspace git repo (non-fatal)");
211
309
  }
212
310
 
213
311
  ctx.profiler.startRequest();
@@ -221,20 +319,20 @@ export async function runAgentLoopImpl(
221
319
  // Placed inside try so the finally block still runs if onEvent throws.
222
320
  if (options?.isUserMessage && !ctx.surfaceActionRequestIds.has(reqId)) {
223
321
  for (const [surfaceId, entry] of ctx.pendingSurfaceActions) {
224
- if (entry.surfaceType === 'dynamic_page') continue;
322
+ if (entry.surfaceType === "dynamic_page") continue;
225
323
  onEvent({
226
- type: 'ui_surface_complete',
324
+ type: "ui_surface_complete",
227
325
  sessionId: ctx.conversationId,
228
326
  surfaceId,
229
- summary: 'Dismissed',
327
+ summary: "Dismissed",
230
328
  });
231
329
  ctx.pendingSurfaceActions.delete(surfaceId);
232
330
  }
233
331
  }
234
332
 
235
- const preMessageResult = await getHookManager().trigger('pre-message', {
333
+ const preMessageResult = await getHookManager().trigger("pre-message", {
236
334
  sessionId: ctx.conversationId,
237
- messagePreview: truncate(content, 200, ''),
335
+ messagePreview: truncate(content, 200, ""),
238
336
  });
239
337
 
240
338
  if (preMessageResult.blocked) {
@@ -244,11 +342,24 @@ export async function runAgentLoopImpl(
244
342
  }
245
343
  // Replace loading placeholder so the thread isn't stuck as "Generating title..."
246
344
  const currentConv = conversationStore.getConversation(ctx.conversationId);
247
- if (isReplaceableTitle(currentConv?.title ?? null) && currentConv?.title !== UNTITLED_FALLBACK) {
248
- conversationStore.updateConversationTitle(ctx.conversationId, UNTITLED_FALLBACK);
249
- onEvent({ type: 'session_title_updated', sessionId: ctx.conversationId, title: UNTITLED_FALLBACK });
345
+ if (
346
+ isReplaceableTitle(currentConv?.title ?? null) &&
347
+ currentConv?.title !== UNTITLED_FALLBACK
348
+ ) {
349
+ conversationStore.updateConversationTitle(
350
+ ctx.conversationId,
351
+ UNTITLED_FALLBACK,
352
+ );
353
+ onEvent({
354
+ type: "session_title_updated",
355
+ sessionId: ctx.conversationId,
356
+ title: UNTITLED_FALLBACK,
357
+ });
250
358
  }
251
- onEvent({ type: 'error', message: `Message blocked by hook "${preMessageResult.blockedBy}"` });
359
+ onEvent({
360
+ type: "error",
361
+ message: `Message blocked by hook "${preMessageResult.blockedBy}"`,
362
+ });
252
363
  return;
253
364
  }
254
365
 
@@ -260,7 +371,11 @@ export async function runAgentLoopImpl(
260
371
  // cancels the response, since the user message is already persisted.
261
372
  // Deferred via setTimeout so the main agent loop LLM call enqueues
262
373
  // first, avoiding rate-limit slot contention on strict configs.
263
- if (isReplaceableTitle(conversationStore.getConversation(ctx.conversationId)?.title ?? null)) {
374
+ if (
375
+ isReplaceableTitle(
376
+ conversationStore.getConversation(ctx.conversationId)?.title ?? null,
377
+ )
378
+ ) {
264
379
  setTimeout(() => {
265
380
  queueGenerateConversationTitle({
266
381
  conversationId: ctx.conversationId,
@@ -268,7 +383,7 @@ export async function runAgentLoopImpl(
268
383
  userMessage: options?.titleText ?? content,
269
384
  onTitleUpdated: (title) => {
270
385
  onEvent({
271
- type: 'session_title_updated',
386
+ type: "session_title_updated",
272
387
  sessionId: ctx.conversationId,
273
388
  title,
274
389
  });
@@ -294,7 +409,7 @@ export async function runAgentLoopImpl(
294
409
  ctx.contextCompactedMessageCount,
295
410
  );
296
411
  onEvent({
297
- type: 'context_compacted',
412
+ type: "context_compacted",
298
413
  previousEstimatedInputTokens: compacted.previousEstimatedInputTokens,
299
414
  estimatedInputTokens: compacted.estimatedInputTokens,
300
415
  maxInputTokens: compacted.maxInputTokens,
@@ -305,7 +420,15 @@ export async function runAgentLoopImpl(
305
420
  summaryOutputTokens: compacted.summaryOutputTokens,
306
421
  summaryModel: compacted.summaryModel,
307
422
  });
308
- emitUsage(ctx, compacted.summaryInputTokens, compacted.summaryOutputTokens, compacted.summaryModel, onEvent, 'context_compactor', reqId);
423
+ emitUsage(
424
+ ctx,
425
+ compacted.summaryInputTokens,
426
+ compacted.summaryOutputTokens,
427
+ compacted.summaryModel,
428
+ onEvent,
429
+ "context_compactor",
430
+ reqId,
431
+ );
309
432
  }
310
433
 
311
434
  const state = createEventHandlerState();
@@ -320,8 +443,9 @@ export async function runAgentLoopImpl(
320
443
  conflictGate: ctx.conflictGate,
321
444
  scopeId: ctx.memoryPolicy.scopeId,
322
445
  includeDefaultFallback: ctx.memoryPolicy.includeDefaultFallback,
323
- guardianTrustClass: resolveGuardianTrustClass(ctx.guardianContext),
324
- isInteractive: options?.isInteractive ?? (!ctx.hasNoClient && !ctx.headlessLock),
446
+ trustClass: resolveTrustClass(ctx.trustContext),
447
+ isInteractive:
448
+ options?.isInteractive ?? (!ctx.hasNoClient && !ctx.headlessLock),
325
449
  },
326
450
  content,
327
451
  userMessageId,
@@ -331,42 +455,55 @@ export async function runAgentLoopImpl(
331
455
 
332
456
  if (memoryResult.conflictClarification) {
333
457
  const loopChannelMeta = {
334
- ...provenanceFromGuardianContext(ctx.guardianContext),
458
+ ...provenanceFromTrustContext(ctx.trustContext),
335
459
  userMessageChannel: capturedTurnChannelContext.userMessageChannel,
336
- assistantMessageChannel: capturedTurnChannelContext.assistantMessageChannel,
460
+ assistantMessageChannel:
461
+ capturedTurnChannelContext.assistantMessageChannel,
337
462
  userMessageInterface: capturedTurnInterfaceContext.userMessageInterface,
338
- assistantMessageInterface: capturedTurnInterfaceContext.assistantMessageInterface,
463
+ assistantMessageInterface:
464
+ capturedTurnInterfaceContext.assistantMessageInterface,
339
465
  };
340
- const assistantMessage = createAssistantMessage(memoryResult.conflictClarification);
466
+ const assistantMessage = createAssistantMessage(
467
+ memoryResult.conflictClarification,
468
+ );
341
469
  await conversationStore.addMessage(
342
470
  ctx.conversationId,
343
- 'assistant',
471
+ "assistant",
344
472
  JSON.stringify(assistantMessage.content),
345
473
  loopChannelMeta,
346
474
  );
347
475
  ctx.messages.push(assistantMessage);
348
476
  onEvent({
349
- type: 'assistant_text_delta',
477
+ type: "assistant_text_delta",
350
478
  text: memoryResult.conflictClarification,
351
479
  sessionId: ctx.conversationId,
352
480
  });
353
- ctx.traceEmitter.emit('message_complete', 'Conflict clarification requested (relevant)', {
354
- requestId: reqId,
355
- status: 'info',
356
- attributes: { conflictGate: 'relevant' },
357
- });
358
- onEvent({ type: 'message_complete', sessionId: ctx.conversationId });
481
+ ctx.traceEmitter.emit(
482
+ "message_complete",
483
+ "Conflict clarification requested (relevant)",
484
+ {
485
+ requestId: reqId,
486
+ status: "info",
487
+ attributes: { conflictGate: "relevant" },
488
+ },
489
+ );
490
+ onEvent({ type: "message_complete", sessionId: ctx.conversationId });
359
491
  return;
360
492
  }
361
493
 
362
- const { recall, dynamicProfile, softConflictInstruction, recallInjectionStrategy } = memoryResult;
494
+ const {
495
+ recall,
496
+ dynamicProfile,
497
+ softConflictInstruction,
498
+ recallInjectionStrategy,
499
+ } = memoryResult;
363
500
  runMessages = memoryResult.runMessages;
364
501
 
365
502
  // Build active surface context
366
503
  let activeSurface: ActiveSurfaceContext | null = null;
367
504
  if (ctx.currentActiveSurfaceId) {
368
505
  const stored = ctx.surfaceState.get(ctx.currentActiveSurfaceId);
369
- if (stored && stored.surfaceType === 'dynamic_page') {
506
+ if (stored && stored.surfaceType === "dynamic_page") {
370
507
  const data = stored.data as DynamicPageSurfaceData;
371
508
  activeSurface = {
372
509
  surfaceId: ctx.currentActiveSurfaceId,
@@ -394,7 +531,9 @@ export async function runAgentLoopImpl(
394
531
  // Absolute "now" is always anchored to assistant host clock, while local
395
532
  // date semantics prefer configured user timezone, then profile memory.
396
533
  const hostTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
397
- const userTimeZone = extractUserTimeZoneFromDynamicProfile(dynamicProfile.text);
534
+ const userTimeZone = extractUserTimeZoneFromDynamicProfile(
535
+ dynamicProfile.text,
536
+ );
398
537
  const configuredUserTimeZone = getConfig().ui.userTimezone ?? null;
399
538
  const temporalContext = buildTemporalContext({
400
539
  hostTimeZone,
@@ -407,12 +546,16 @@ export async function runAgentLoopImpl(
407
546
  // message, even if a newer message from a different channel arrived since.
408
547
  const channelTurnContext: ChannelTurnContextParams = {
409
548
  turnContext: capturedTurnChannelContext,
410
- conversationOriginChannel: getConversationOriginChannel(ctx.conversationId),
549
+ conversationOriginChannel: getConversationOriginChannel(
550
+ ctx.conversationId,
551
+ ),
411
552
  };
412
553
 
413
554
  const interfaceTurnContext: InterfaceTurnContextParams = {
414
555
  turnContext: capturedTurnInterfaceContext,
415
- conversationOriginInterface: getConversationOriginInterface(ctx.conversationId),
556
+ conversationOriginInterface: getConversationOriginInterface(
557
+ ctx.conversationId,
558
+ ),
416
559
  };
417
560
 
418
561
  // Resolve the inbound actor context for the model's <inbound_actor_context>
@@ -421,8 +564,8 @@ export async function runAgentLoopImpl(
421
564
  // are fresh for this turn. The session runtime context remains the source
422
565
  // for policy gating; this block is model-facing grounding metadata.
423
566
  let resolvedInboundActorContext: InboundActorContext | null = null;
424
- if (ctx.guardianContext) {
425
- const gc = ctx.guardianContext;
567
+ if (ctx.trustContext) {
568
+ const gc = ctx.trustContext;
426
569
  if (gc.requesterExternalUserId && gc.requesterChatId) {
427
570
  const actorTrust = resolveActorTrust({
428
571
  assistantId: ctx.assistantId ?? DAEMON_INTERNAL_ASSISTANT_ID,
@@ -433,12 +576,15 @@ export async function runAgentLoopImpl(
433
576
  });
434
577
  resolvedInboundActorContext = inboundActorContextFromTrust(actorTrust);
435
578
  } else {
436
- resolvedInboundActorContext = inboundActorContextFromGuardian(gc);
579
+ resolvedInboundActorContext = inboundActorContextFromTrustContext(gc);
437
580
  }
438
581
  }
439
582
 
440
- const isInteractiveResolved = options?.isInteractive ?? (!ctx.hasNoClient && !ctx.headlessLock);
441
- runMessages = applyRuntimeInjections(runMessages, {
583
+ const isInteractiveResolved =
584
+ options?.isInteractive ?? (!ctx.hasNoClient && !ctx.headlessLock);
585
+
586
+ // Shared injection options — reused whenever we need to re-inject after reduction.
587
+ const injectionOpts = {
442
588
  softConflictInstruction,
443
589
  activeSurface,
444
590
  workspaceTopLevelContext: ctx.workspaceTopLevelContext,
@@ -450,13 +596,124 @@ export async function runAgentLoopImpl(
450
596
  temporalContext,
451
597
  voiceCallControlPrompt: ctx.voiceCallControlPrompt ?? null,
452
598
  isNonInteractive: !isInteractiveResolved,
599
+ } as const;
600
+
601
+ let currentInjectionMode: InjectionMode = "full";
602
+
603
+ runMessages = applyRuntimeInjections(runMessages, {
604
+ ...injectionOpts,
605
+ mode: currentInjectionMode,
453
606
  });
454
607
 
608
+ // ── Preflight budget evaluation ──────────────────────────────
609
+ // After runtime injections are applied, estimate the prompt token count
610
+ // and proactively invoke the reducer if already above budget. This avoids
611
+ // a wasted provider round-trip that would just fail with context_too_large.
612
+ const config = getConfig();
613
+ const overflowRecovery = config.contextWindow.overflowRecovery;
614
+ const providerMaxTokens = config.contextWindow.maxInputTokens;
615
+ const safetyMargin = overflowRecovery.safetyMarginRatio;
616
+ const preflightBudget = Math.floor(providerMaxTokens * (1 - safetyMargin));
617
+ let reducerState: ReducerState | undefined;
618
+
619
+ const preflightTokens = estimatePromptTokens(
620
+ runMessages,
621
+ ctx.systemPrompt,
622
+ { providerName: ctx.provider.name },
623
+ );
624
+
625
+ if (overflowRecovery.enabled && preflightTokens > preflightBudget) {
626
+ rlog.warn(
627
+ {
628
+ phase: "preflight",
629
+ estimatedTokens: preflightTokens,
630
+ budget: preflightBudget,
631
+ },
632
+ "Preflight budget exceeded — running overflow reducer before provider call",
633
+ );
634
+
635
+ reducerState = createInitialReducerState();
636
+ let preflightAttempts = 0;
637
+
638
+ while (
639
+ preflightAttempts < overflowRecovery.maxAttempts &&
640
+ !reducerState.exhausted
641
+ ) {
642
+ preflightAttempts++;
643
+ const step = await reduceContextOverflow(
644
+ ctx.messages,
645
+ {
646
+ providerName: ctx.provider.name,
647
+ systemPrompt: ctx.systemPrompt,
648
+ contextWindow: config.contextWindow,
649
+ targetTokens: preflightBudget,
650
+ },
651
+ reducerState,
652
+ (msgs, signal, opts) =>
653
+ ctx.contextWindowManager.maybeCompact(msgs, signal!, opts),
654
+ abortController.signal,
655
+ );
656
+
657
+ reducerState = step.state;
658
+ ctx.messages = step.messages;
659
+ currentInjectionMode = step.state.injectionMode;
660
+
661
+ if (step.compactionResult?.compacted) {
662
+ ctx.contextCompactedMessageCount +=
663
+ step.compactionResult.compactedPersistedMessages;
664
+ ctx.contextCompactedAt = Date.now();
665
+ conversationStore.updateConversationContextWindow(
666
+ ctx.conversationId,
667
+ step.compactionResult.summaryText,
668
+ ctx.contextCompactedMessageCount,
669
+ );
670
+ onEvent({
671
+ type: "context_compacted",
672
+ previousEstimatedInputTokens:
673
+ step.compactionResult.previousEstimatedInputTokens,
674
+ estimatedInputTokens: step.compactionResult.estimatedInputTokens,
675
+ maxInputTokens: step.compactionResult.maxInputTokens,
676
+ thresholdTokens: step.compactionResult.thresholdTokens,
677
+ compactedMessages: step.compactionResult.compactedMessages,
678
+ summaryCalls: step.compactionResult.summaryCalls,
679
+ summaryInputTokens: step.compactionResult.summaryInputTokens,
680
+ summaryOutputTokens: step.compactionResult.summaryOutputTokens,
681
+ summaryModel: step.compactionResult.summaryModel,
682
+ });
683
+ emitUsage(
684
+ ctx,
685
+ step.compactionResult.summaryInputTokens,
686
+ step.compactionResult.summaryOutputTokens,
687
+ step.compactionResult.summaryModel,
688
+ onEvent,
689
+ "context_compactor",
690
+ reqId,
691
+ );
692
+ }
693
+
694
+ // Re-inject with potentially downgraded injection mode
695
+ runMessages = applyRuntimeInjections(ctx.messages, {
696
+ ...injectionOpts,
697
+ mode: currentInjectionMode,
698
+ });
699
+
700
+ if (step.estimatedTokens <= preflightBudget) break;
701
+ }
702
+ }
703
+
455
704
  // Pre-run repair
456
705
  let preRepairMessages = runMessages;
457
706
  const preRunRepair = repairHistory(runMessages);
458
- if (preRunRepair.stats.assistantToolResultsMigrated > 0 || preRunRepair.stats.missingToolResultsInserted > 0 || preRunRepair.stats.orphanToolResultsDowngraded > 0 || preRunRepair.stats.consecutiveSameRoleMerged > 0) {
459
- rlog.warn({ phase: 'pre_run', ...preRunRepair.stats }, 'Repaired runtime history before provider call');
707
+ if (
708
+ preRunRepair.stats.assistantToolResultsMigrated > 0 ||
709
+ preRunRepair.stats.missingToolResultsInserted > 0 ||
710
+ preRunRepair.stats.orphanToolResultsDowngraded > 0 ||
711
+ preRunRepair.stats.consecutiveSameRoleMerged > 0
712
+ ) {
713
+ rlog.warn(
714
+ { phase: "pre_run", ...preRunRepair.stats },
715
+ "Repaired runtime history before provider call",
716
+ );
460
717
  runMessages = preRunRepair.messages;
461
718
  }
462
719
 
@@ -476,25 +733,29 @@ export async function runAgentLoopImpl(
476
733
  turnChannelContext: capturedTurnChannelContext,
477
734
  turnInterfaceContext: capturedTurnInterfaceContext,
478
735
  };
479
- const eventHandler = (event: AgentEvent) => dispatchAgentEvent(state, deps, event);
736
+ const eventHandler = (event: AgentEvent) =>
737
+ dispatchAgentEvent(state, deps, event);
480
738
 
481
739
  const onCheckpoint = (): CheckpointDecision => {
482
740
  const turnTools = state.currentTurnToolNames;
483
741
  state.currentTurnToolNames = [];
484
742
 
485
743
  if (ctx.canHandoffAtCheckpoint()) {
486
- const inBrowserFlow = turnTools.length > 0
487
- && turnTools.every(n => n.startsWith('browser_'));
744
+ const inBrowserFlow =
745
+ turnTools.length > 0 &&
746
+ turnTools.every((n) => n.startsWith("browser_"));
488
747
  if (!inBrowserFlow) {
489
748
  yieldedForHandoff = true;
490
- return 'yield';
749
+ return "yield";
491
750
  }
492
751
  }
493
- return 'continue';
752
+ return "continue";
494
753
  };
495
754
 
496
755
  turnStarted = true;
497
756
 
757
+ let denyCompressionMessage: Message | null = null;
758
+
498
759
  let updatedHistory = await ctx.agentLoop.run(
499
760
  runMessages,
500
761
  eventHandler,
@@ -504,8 +765,14 @@ export async function runAgentLoopImpl(
504
765
  );
505
766
 
506
767
  // One-shot ordering error retry
507
- if (state.orderingErrorDetected && updatedHistory.length === preRunHistoryLength) {
508
- rlog.warn({ phase: 'retry' }, 'Provider ordering error detected, attempting one-shot deep-repair retry');
768
+ if (
769
+ state.orderingErrorDetected &&
770
+ updatedHistory.length === preRunHistoryLength
771
+ ) {
772
+ rlog.warn(
773
+ { phase: "retry" },
774
+ "Provider ordering error detected, attempting one-shot deep-repair retry",
775
+ );
509
776
  const retryRepair = deepRepairHistory(runMessages);
510
777
  runMessages = retryRepair.messages;
511
778
  preRepairMessages = retryRepair.messages;
@@ -522,53 +789,98 @@ export async function runAgentLoopImpl(
522
789
  );
523
790
 
524
791
  if (state.orderingErrorDetected) {
525
- rlog.error({ phase: 'retry' }, 'Deep-repair retry also failed with ordering error. Consider starting a new conversation if this persists.');
792
+ rlog.error(
793
+ { phase: "retry" },
794
+ "Deep-repair retry also failed with ordering error. Consider starting a new conversation if this persists.",
795
+ );
526
796
  }
527
797
  }
528
798
 
529
- // One-shot context-too-large recovery
530
- if (state.contextTooLargeDetected && updatedHistory.length === preRunHistoryLength) {
531
- rlog.warn({ phase: 'retry' }, 'Context too large — attempting forced compaction and retry');
532
- const emergencyCompact = await ctx.contextWindowManager.maybeCompact(
533
- ctx.messages,
534
- abortController.signal,
535
- { lastCompactedAt: ctx.contextCompactedAt ?? undefined, force: true },
536
- );
537
- if (emergencyCompact.compacted) {
538
- ctx.messages = emergencyCompact.messages;
539
- ctx.contextCompactedMessageCount += emergencyCompact.compactedPersistedMessages;
540
- ctx.contextCompactedAt = Date.now();
541
- conversationStore.updateConversationContextWindow(
542
- ctx.conversationId,
543
- emergencyCompact.summaryText,
544
- ctx.contextCompactedMessageCount,
799
+ // ── Bounded context overflow convergence loop ──────────────────
800
+ // When the provider rejects with context-too-large, iterate through
801
+ // reducer tiers (forced compaction, tool-result truncation, media
802
+ // stubbing, injection downgrade) with optional approval gating for
803
+ // interactive latest-turn compression.
804
+ if (
805
+ state.contextTooLargeDetected &&
806
+ updatedHistory.length === preRunHistoryLength
807
+ ) {
808
+ if (!reducerState) {
809
+ reducerState = createInitialReducerState();
810
+ }
811
+
812
+ let convergenceAttempts = 0;
813
+ const maxAttempts = overflowRecovery.maxAttempts;
814
+
815
+ while (
816
+ state.contextTooLargeDetected &&
817
+ convergenceAttempts < maxAttempts &&
818
+ !reducerState.exhausted
819
+ ) {
820
+ convergenceAttempts++;
821
+ rlog.warn(
822
+ {
823
+ phase: "convergence",
824
+ attempt: convergenceAttempts,
825
+ appliedTiers: reducerState.appliedTiers,
826
+ },
827
+ "Context too large — applying next reducer tier",
545
828
  );
546
- onEvent({
547
- type: 'context_compacted',
548
- previousEstimatedInputTokens: emergencyCompact.previousEstimatedInputTokens,
549
- estimatedInputTokens: emergencyCompact.estimatedInputTokens,
550
- maxInputTokens: emergencyCompact.maxInputTokens,
551
- thresholdTokens: emergencyCompact.thresholdTokens,
552
- compactedMessages: emergencyCompact.compactedMessages,
553
- summaryCalls: emergencyCompact.summaryCalls,
554
- summaryInputTokens: emergencyCompact.summaryInputTokens,
555
- summaryOutputTokens: emergencyCompact.summaryOutputTokens,
556
- summaryModel: emergencyCompact.summaryModel,
557
- });
558
- emitUsage(ctx, emergencyCompact.summaryInputTokens, emergencyCompact.summaryOutputTokens, emergencyCompact.summaryModel, onEvent, 'context_compactor', reqId);
829
+
830
+ const step = await reduceContextOverflow(
831
+ ctx.messages,
832
+ {
833
+ providerName: ctx.provider.name,
834
+ systemPrompt: ctx.systemPrompt,
835
+ contextWindow: config.contextWindow,
836
+ targetTokens: preflightBudget,
837
+ },
838
+ reducerState,
839
+ (msgs, signal, opts) =>
840
+ ctx.contextWindowManager.maybeCompact(msgs, signal!, opts),
841
+ abortController.signal,
842
+ );
843
+
844
+ reducerState = step.state;
845
+ ctx.messages = step.messages;
846
+ currentInjectionMode = step.state.injectionMode;
847
+
848
+ if (step.compactionResult?.compacted) {
849
+ ctx.contextCompactedMessageCount +=
850
+ step.compactionResult.compactedPersistedMessages;
851
+ ctx.contextCompactedAt = Date.now();
852
+ conversationStore.updateConversationContextWindow(
853
+ ctx.conversationId,
854
+ step.compactionResult.summaryText,
855
+ ctx.contextCompactedMessageCount,
856
+ );
857
+ onEvent({
858
+ type: "context_compacted",
859
+ previousEstimatedInputTokens:
860
+ step.compactionResult.previousEstimatedInputTokens,
861
+ estimatedInputTokens: step.compactionResult.estimatedInputTokens,
862
+ maxInputTokens: step.compactionResult.maxInputTokens,
863
+ thresholdTokens: step.compactionResult.thresholdTokens,
864
+ compactedMessages: step.compactionResult.compactedMessages,
865
+ summaryCalls: step.compactionResult.summaryCalls,
866
+ summaryInputTokens: step.compactionResult.summaryInputTokens,
867
+ summaryOutputTokens: step.compactionResult.summaryOutputTokens,
868
+ summaryModel: step.compactionResult.summaryModel,
869
+ });
870
+ emitUsage(
871
+ ctx,
872
+ step.compactionResult.summaryInputTokens,
873
+ step.compactionResult.summaryOutputTokens,
874
+ step.compactionResult.summaryModel,
875
+ onEvent,
876
+ "context_compactor",
877
+ reqId,
878
+ );
879
+ }
559
880
 
560
881
  runMessages = applyRuntimeInjections(ctx.messages, {
561
- softConflictInstruction,
562
- activeSurface,
563
- workspaceTopLevelContext: ctx.workspaceTopLevelContext,
564
- channelCapabilities: ctx.channelCapabilities ?? null,
565
- channelCommandContext: ctx.commandIntent ?? null,
566
- channelTurnContext,
567
- interfaceTurnContext,
568
- inboundActorContext: resolvedInboundActorContext,
569
- temporalContext,
570
- voiceCallControlPrompt: ctx.voiceCallControlPrompt ?? null,
571
- isNonInteractive: !isInteractiveResolved,
882
+ ...injectionOpts,
883
+ mode: currentInjectionMode,
572
884
  });
573
885
  preRepairMessages = runMessages;
574
886
  preRunHistoryLength = runMessages.length;
@@ -583,30 +895,164 @@ export async function runAgentLoopImpl(
583
895
  );
584
896
  }
585
897
 
898
+ // All reducer tiers exhausted but provider still rejects —
899
+ // consult the overflow policy for latest-turn compression.
586
900
  if (state.contextTooLargeDetected) {
587
- const mediaTrimmed = stripMediaPayloadsForRetry(ctx.messages);
588
- if (mediaTrimmed.modified) {
589
- rlog.warn(
901
+ const action = resolveOverflowAction({
902
+ overflowRecovery,
903
+ isInteractive: isInteractiveResolved,
904
+ });
905
+
906
+ if (action === "request_user_approval") {
907
+ const approval = await requestCompressionApproval(ctx.prompter, {
908
+ signal: abortController.signal,
909
+ });
910
+
911
+ if (approval.approved) {
912
+ // User approved — force emergency compaction with aggressive settings
913
+ const emergencyCompact =
914
+ await ctx.contextWindowManager.maybeCompact(
915
+ ctx.messages,
916
+ abortController.signal,
917
+ {
918
+ lastCompactedAt: ctx.contextCompactedAt ?? undefined,
919
+ force: true,
920
+ minKeepRecentUserTurns: 0,
921
+ targetInputTokensOverride: preflightBudget,
922
+ },
923
+ );
924
+ if (emergencyCompact.compacted) {
925
+ ctx.messages = emergencyCompact.messages;
926
+ ctx.contextCompactedMessageCount +=
927
+ emergencyCompact.compactedPersistedMessages;
928
+ ctx.contextCompactedAt = Date.now();
929
+ conversationStore.updateConversationContextWindow(
930
+ ctx.conversationId,
931
+ emergencyCompact.summaryText,
932
+ ctx.contextCompactedMessageCount,
933
+ );
934
+ onEvent({
935
+ type: "context_compacted",
936
+ previousEstimatedInputTokens:
937
+ emergencyCompact.previousEstimatedInputTokens,
938
+ estimatedInputTokens: emergencyCompact.estimatedInputTokens,
939
+ maxInputTokens: emergencyCompact.maxInputTokens,
940
+ thresholdTokens: emergencyCompact.thresholdTokens,
941
+ compactedMessages: emergencyCompact.compactedMessages,
942
+ summaryCalls: emergencyCompact.summaryCalls,
943
+ summaryInputTokens: emergencyCompact.summaryInputTokens,
944
+ summaryOutputTokens: emergencyCompact.summaryOutputTokens,
945
+ summaryModel: emergencyCompact.summaryModel,
946
+ });
947
+ emitUsage(
948
+ ctx,
949
+ emergencyCompact.summaryInputTokens,
950
+ emergencyCompact.summaryOutputTokens,
951
+ emergencyCompact.summaryModel,
952
+ onEvent,
953
+ "context_compactor",
954
+ reqId,
955
+ );
956
+ }
957
+
958
+ runMessages = applyRuntimeInjections(ctx.messages, {
959
+ ...injectionOpts,
960
+ mode: currentInjectionMode,
961
+ });
962
+ preRepairMessages = runMessages;
963
+ preRunHistoryLength = runMessages.length;
964
+ state.contextTooLargeDetected = false;
965
+
966
+ updatedHistory = await ctx.agentLoop.run(
967
+ runMessages,
968
+ eventHandler,
969
+ abortController.signal,
970
+ reqId,
971
+ onCheckpoint,
972
+ );
973
+ } else {
974
+ // User denied compression — emit a graceful assistant explanation
975
+ // instead of a session_error, and end the turn cleanly.
976
+ state.contextTooLargeDetected = false;
977
+ const denyText =
978
+ "The conversation has grown too long for the model to process, " +
979
+ "and compression was declined. Please start a new conversation " +
980
+ "or manually shorten the thread to continue.";
981
+ const loopChannelMeta = {
982
+ ...provenanceFromTrustContext(ctx.trustContext),
983
+ userMessageChannel: capturedTurnChannelContext.userMessageChannel,
984
+ assistantMessageChannel:
985
+ capturedTurnChannelContext.assistantMessageChannel,
986
+ userMessageInterface:
987
+ capturedTurnInterfaceContext.userMessageInterface,
988
+ assistantMessageInterface:
989
+ capturedTurnInterfaceContext.assistantMessageInterface,
990
+ };
991
+ const denyMessage = createAssistantMessage(denyText);
992
+ await conversationStore.addMessage(
993
+ ctx.conversationId,
994
+ "assistant",
995
+ JSON.stringify(denyMessage.content),
996
+ loopChannelMeta,
997
+ );
998
+ denyCompressionMessage = denyMessage;
999
+ onEvent({
1000
+ type: "assistant_text_delta",
1001
+ text: denyText,
1002
+ sessionId: ctx.conversationId,
1003
+ });
1004
+ // Prevent the final error fallback from firing
1005
+ state.providerErrorUserMessage = null;
1006
+ }
1007
+ } else if (action === "auto_compress_latest_turn") {
1008
+ // Non-interactive — auto-compress without asking
1009
+ const emergencyCompact = await ctx.contextWindowManager.maybeCompact(
1010
+ ctx.messages,
1011
+ abortController.signal,
590
1012
  {
591
- phase: 'retry',
592
- replacedBlocks: mediaTrimmed.replacedBlocks,
593
- latestUserIndex: mediaTrimmed.latestUserIndex,
1013
+ lastCompactedAt: ctx.contextCompactedAt ?? undefined,
1014
+ force: true,
1015
+ minKeepRecentUserTurns: 0,
1016
+ targetInputTokensOverride: preflightBudget,
594
1017
  },
595
- 'Context still too large — retrying with older media payloads trimmed',
596
1018
  );
597
- ctx.messages = mediaTrimmed.messages;
1019
+ if (emergencyCompact.compacted) {
1020
+ ctx.messages = emergencyCompact.messages;
1021
+ ctx.contextCompactedMessageCount +=
1022
+ emergencyCompact.compactedPersistedMessages;
1023
+ ctx.contextCompactedAt = Date.now();
1024
+ conversationStore.updateConversationContextWindow(
1025
+ ctx.conversationId,
1026
+ emergencyCompact.summaryText,
1027
+ ctx.contextCompactedMessageCount,
1028
+ );
1029
+ onEvent({
1030
+ type: "context_compacted",
1031
+ previousEstimatedInputTokens:
1032
+ emergencyCompact.previousEstimatedInputTokens,
1033
+ estimatedInputTokens: emergencyCompact.estimatedInputTokens,
1034
+ maxInputTokens: emergencyCompact.maxInputTokens,
1035
+ thresholdTokens: emergencyCompact.thresholdTokens,
1036
+ compactedMessages: emergencyCompact.compactedMessages,
1037
+ summaryCalls: emergencyCompact.summaryCalls,
1038
+ summaryInputTokens: emergencyCompact.summaryInputTokens,
1039
+ summaryOutputTokens: emergencyCompact.summaryOutputTokens,
1040
+ summaryModel: emergencyCompact.summaryModel,
1041
+ });
1042
+ emitUsage(
1043
+ ctx,
1044
+ emergencyCompact.summaryInputTokens,
1045
+ emergencyCompact.summaryOutputTokens,
1046
+ emergencyCompact.summaryModel,
1047
+ onEvent,
1048
+ "context_compactor",
1049
+ reqId,
1050
+ );
1051
+ }
1052
+
598
1053
  runMessages = applyRuntimeInjections(ctx.messages, {
599
- softConflictInstruction,
600
- activeSurface,
601
- workspaceTopLevelContext: ctx.workspaceTopLevelContext,
602
- channelCapabilities: ctx.channelCapabilities ?? null,
603
- channelCommandContext: ctx.commandIntent ?? null,
604
- channelTurnContext,
605
- interfaceTurnContext,
606
- inboundActorContext: resolvedInboundActorContext,
607
- temporalContext,
608
- voiceCallControlPrompt: ctx.voiceCallControlPrompt ?? null,
609
- isNonInteractive: !isInteractiveResolved,
1054
+ ...injectionOpts,
1055
+ mode: currentInjectionMode,
610
1056
  });
611
1057
  preRepairMessages = runMessages;
612
1058
  preRunHistoryLength = runMessages.length;
@@ -620,38 +1066,50 @@ export async function runAgentLoopImpl(
620
1066
  onCheckpoint,
621
1067
  );
622
1068
  }
1069
+ // action === "fail_gracefully" falls through to the final error below
623
1070
  }
624
1071
 
1072
+ // Final fallback: all recovery paths exhausted
625
1073
  if (state.contextTooLargeDetected) {
626
1074
  const classified = classifySessionError(
627
- new Error('context_length_exceeded'),
628
- { phase: 'agent_loop' },
1075
+ new Error("context_length_exceeded"),
1076
+ { phase: "agent_loop" },
629
1077
  );
630
1078
  onEvent(buildSessionErrorMessage(ctx.conversationId, classified));
631
1079
  }
632
1080
  } else if (state.contextTooLargeDetected) {
633
1081
  // Progress was made (updatedHistory grew), so the retry path above was
634
1082
  // skipped. Surface the error so clients are not left with a silent failure.
635
- rlog.warn({ phase: 'post_run' }, 'Context too large after progress — surfacing error without retry');
1083
+ rlog.warn(
1084
+ { phase: "post_run" },
1085
+ "Context too large after progress — surfacing error without retry",
1086
+ );
636
1087
  const classified = classifySessionError(
637
- new Error('context_length_exceeded'),
638
- { phase: 'agent_loop' },
1088
+ new Error("context_length_exceeded"),
1089
+ { phase: "agent_loop" },
639
1090
  );
640
1091
  onEvent(buildSessionErrorMessage(ctx.conversationId, classified));
641
1092
  state.providerErrorUserMessage = classified.userMessage;
642
1093
  }
643
1094
 
644
1095
  if (state.deferredOrderingError) {
645
- const classified = classifySessionError(new Error(state.deferredOrderingError), { phase: 'agent_loop' });
1096
+ const classified = classifySessionError(
1097
+ new Error(state.deferredOrderingError),
1098
+ { phase: "agent_loop" },
1099
+ );
646
1100
  onEvent(buildSessionErrorMessage(ctx.conversationId, classified));
647
1101
  }
648
1102
 
649
1103
  // Reconcile synthesized cancellation tool_results
650
1104
  for (let i = preRunHistoryLength; i < updatedHistory.length; i++) {
651
1105
  const msg = updatedHistory[i];
652
- if (msg.role === 'user') {
1106
+ if (msg.role === "user") {
653
1107
  for (const block of msg.content) {
654
- if (block.type === 'tool_result' && !state.pendingToolResults.has(block.tool_use_id) && !state.persistedToolUseIds.has(block.tool_use_id)) {
1108
+ if (
1109
+ block.type === "tool_result" &&
1110
+ !state.pendingToolResults.has(block.tool_use_id) &&
1111
+ !state.persistedToolUseIds.has(block.tool_use_id)
1112
+ ) {
655
1113
  state.pendingToolResults.set(block.tool_use_id, {
656
1114
  content: block.content,
657
1115
  isError: block.is_error ?? false,
@@ -663,25 +1121,29 @@ export async function runAgentLoopImpl(
663
1121
 
664
1122
  // Flush remaining tool results
665
1123
  if (state.pendingToolResults.size > 0) {
666
- const toolResultBlocks = Array.from(state.pendingToolResults.entries()).map(
667
- ([toolUseId, result]) => ({
668
- type: 'tool_result',
669
- tool_use_id: toolUseId,
670
- content: result.content,
671
- is_error: result.isError,
672
- ...(result.contentBlocks ? { contentBlocks: result.contentBlocks } : {}),
673
- }),
674
- );
1124
+ const toolResultBlocks = Array.from(
1125
+ state.pendingToolResults.entries(),
1126
+ ).map(([toolUseId, result]) => ({
1127
+ type: "tool_result",
1128
+ tool_use_id: toolUseId,
1129
+ content: result.content,
1130
+ is_error: result.isError,
1131
+ ...(result.contentBlocks
1132
+ ? { contentBlocks: result.contentBlocks }
1133
+ : {}),
1134
+ }));
675
1135
  const toolResultMetadata = {
676
- ...provenanceFromGuardianContext(ctx.guardianContext),
1136
+ ...provenanceFromTrustContext(ctx.trustContext),
677
1137
  userMessageChannel: capturedTurnChannelContext.userMessageChannel,
678
- assistantMessageChannel: capturedTurnChannelContext.assistantMessageChannel,
1138
+ assistantMessageChannel:
1139
+ capturedTurnChannelContext.assistantMessageChannel,
679
1140
  userMessageInterface: capturedTurnInterfaceContext.userMessageInterface,
680
- assistantMessageInterface: capturedTurnInterfaceContext.assistantMessageInterface,
1141
+ assistantMessageInterface:
1142
+ capturedTurnInterfaceContext.assistantMessageInterface,
681
1143
  };
682
1144
  await conversationStore.addMessage(
683
1145
  ctx.conversationId,
684
- 'user',
1146
+ "user",
685
1147
  JSON.stringify(toolResultBlocks),
686
1148
  toolResultMetadata,
687
1149
  );
@@ -690,31 +1152,46 @@ export async function runAgentLoopImpl(
690
1152
 
691
1153
  // Reconstruct history
692
1154
  const newMessages = updatedHistory.slice(preRunHistoryLength).map((msg) => {
693
- if (msg.role !== 'assistant') return msg;
1155
+ if (msg.role !== "assistant") return msg;
694
1156
  const { cleanedContent } = cleanAssistantContent(msg.content);
695
1157
  const cleanedBlocks = cleanedContent as ContentBlock[];
696
1158
  return { ...msg, content: cleanedBlocks };
697
1159
  });
698
1160
 
699
- const hasAssistantResponse = newMessages.some((msg) => msg.role === 'assistant');
700
- if (!hasAssistantResponse && state.providerErrorUserMessage && !abortController.signal.aborted && !yieldedForHandoff) {
1161
+ if (denyCompressionMessage) {
1162
+ newMessages.push(denyCompressionMessage);
1163
+ }
1164
+
1165
+ const hasAssistantResponse = newMessages.some(
1166
+ (msg) => msg.role === "assistant",
1167
+ );
1168
+ if (
1169
+ !hasAssistantResponse &&
1170
+ state.providerErrorUserMessage &&
1171
+ !abortController.signal.aborted &&
1172
+ !yieldedForHandoff
1173
+ ) {
701
1174
  const errChannelMeta = {
702
- ...provenanceFromGuardianContext(ctx.guardianContext),
1175
+ ...provenanceFromTrustContext(ctx.trustContext),
703
1176
  userMessageChannel: capturedTurnChannelContext.userMessageChannel,
704
- assistantMessageChannel: capturedTurnChannelContext.assistantMessageChannel,
1177
+ assistantMessageChannel:
1178
+ capturedTurnChannelContext.assistantMessageChannel,
705
1179
  userMessageInterface: capturedTurnInterfaceContext.userMessageInterface,
706
- assistantMessageInterface: capturedTurnInterfaceContext.assistantMessageInterface,
1180
+ assistantMessageInterface:
1181
+ capturedTurnInterfaceContext.assistantMessageInterface,
707
1182
  };
708
- const errorAssistantMessage = createAssistantMessage(state.providerErrorUserMessage);
1183
+ const errorAssistantMessage = createAssistantMessage(
1184
+ state.providerErrorUserMessage,
1185
+ );
709
1186
  await conversationStore.addMessage(
710
1187
  ctx.conversationId,
711
- 'assistant',
1188
+ "assistant",
712
1189
  JSON.stringify(errorAssistantMessage.content),
713
1190
  errChannelMeta,
714
1191
  );
715
1192
  newMessages.push(errorAssistantMessage);
716
1193
  onEvent({
717
- type: 'assistant_text_delta',
1194
+ type: "assistant_text_delta",
718
1195
  text: state.providerErrorUserMessage,
719
1196
  sessionId: ctx.conversationId,
720
1197
  });
@@ -722,13 +1199,27 @@ export async function runAgentLoopImpl(
722
1199
 
723
1200
  const restoredHistory = [...preRepairMessages, ...newMessages];
724
1201
  ctx.messages = stripInjectedContext(restoredHistory, {
725
- stripRecall: (msgs) => stripMemoryRecallMessages(msgs, recall.injectedText, recallInjectionStrategy),
726
- stripDynamicProfile: (msgs) => stripDynamicProfileMessages(msgs, dynamicProfile.text),
1202
+ stripRecall: (msgs) =>
1203
+ stripMemoryRecallMessages(
1204
+ msgs,
1205
+ recall.injectedText,
1206
+ recallInjectionStrategy,
1207
+ ),
1208
+ stripDynamicProfile: (msgs) =>
1209
+ stripDynamicProfileMessages(msgs, dynamicProfile.text),
727
1210
  });
728
1211
 
729
- emitUsage(ctx, state.exchangeInputTokens, state.exchangeOutputTokens, state.model, onEvent, 'main_agent', reqId);
1212
+ emitUsage(
1213
+ ctx,
1214
+ state.exchangeInputTokens,
1215
+ state.exchangeOutputTokens,
1216
+ state.model,
1217
+ onEvent,
1218
+ "main_agent",
1219
+ reqId,
1220
+ );
730
1221
 
731
- void getHookManager().trigger('post-message', {
1222
+ void getHookManager().trigger("post-message", {
732
1223
  sessionId: ctx.conversationId,
733
1224
  });
734
1225
 
@@ -738,7 +1229,14 @@ export async function runAgentLoopImpl(
738
1229
  state.accumulatedToolContentBlocks,
739
1230
  state.directiveWarnings,
740
1231
  ctx.workingDir,
741
- async (filePath) => approveHostAttachmentRead(filePath, ctx.workingDir, ctx.prompter, ctx.conversationId, ctx.hasNoClient),
1232
+ async (filePath) =>
1233
+ approveHostAttachmentRead(
1234
+ filePath,
1235
+ ctx.workingDir,
1236
+ ctx.prompter,
1237
+ ctx.conversationId,
1238
+ ctx.hasNoClient,
1239
+ ),
742
1240
  state.lastAssistantMessageId,
743
1241
  );
744
1242
  const { assistantAttachments, emittedAttachments } = attachmentResult;
@@ -746,55 +1244,74 @@ export async function runAgentLoopImpl(
746
1244
  ctx.lastAssistantAttachments = assistantAttachments;
747
1245
  ctx.lastAttachmentWarnings = attachmentResult.directiveWarnings;
748
1246
 
749
- const warningText = formatAttachmentWarnings(attachmentResult.directiveWarnings);
1247
+ const warningText = formatAttachmentWarnings(
1248
+ attachmentResult.directiveWarnings,
1249
+ );
750
1250
  if (warningText) {
751
- onEvent({ type: 'assistant_text_delta', text: warningText, sessionId: ctx.conversationId });
1251
+ onEvent({
1252
+ type: "assistant_text_delta",
1253
+ text: warningText,
1254
+ sessionId: ctx.conversationId,
1255
+ });
752
1256
  }
753
1257
 
754
1258
  // Emit completion event
755
1259
  if (yieldedForHandoff) {
756
- ctx.traceEmitter.emit('generation_handoff', 'Handing off to next queued message', {
757
- requestId: reqId,
758
- status: 'info',
759
- attributes: { queuedCount: ctx.getQueueDepth() },
760
- });
1260
+ ctx.traceEmitter.emit(
1261
+ "generation_handoff",
1262
+ "Handing off to next queued message",
1263
+ {
1264
+ requestId: reqId,
1265
+ status: "info",
1266
+ attributes: { queuedCount: ctx.getQueueDepth() },
1267
+ },
1268
+ );
761
1269
  onEvent({
762
- type: 'generation_handoff',
1270
+ type: "generation_handoff",
763
1271
  sessionId: ctx.conversationId,
764
1272
  requestId: reqId,
765
1273
  queuedCount: ctx.getQueueDepth(),
766
- ...(emittedAttachments.length > 0 ? { attachments: emittedAttachments } : {}),
1274
+ ...(emittedAttachments.length > 0
1275
+ ? { attachments: emittedAttachments }
1276
+ : {}),
767
1277
  });
768
1278
  } else if (abortController.signal.aborted) {
769
- ctx.emitActivityState('idle', 'generation_cancelled', 'global', reqId);
770
- ctx.traceEmitter.emit('generation_cancelled', 'Generation cancelled by user', {
771
- requestId: reqId,
772
- status: 'warning',
773
- });
774
- onEvent({ type: 'generation_cancelled', sessionId: ctx.conversationId });
1279
+ ctx.emitActivityState("idle", "generation_cancelled", "global", reqId);
1280
+ ctx.traceEmitter.emit(
1281
+ "generation_cancelled",
1282
+ "Generation cancelled by user",
1283
+ {
1284
+ requestId: reqId,
1285
+ status: "warning",
1286
+ },
1287
+ );
1288
+ onEvent({ type: "generation_cancelled", sessionId: ctx.conversationId });
775
1289
  } else {
776
- ctx.emitActivityState('idle', 'message_complete', 'global', reqId);
777
- ctx.traceEmitter.emit('message_complete', 'Message processing complete', {
1290
+ ctx.emitActivityState("idle", "message_complete", "global", reqId);
1291
+ ctx.traceEmitter.emit("message_complete", "Message processing complete", {
778
1292
  requestId: reqId,
779
- status: 'success',
1293
+ status: "success",
780
1294
  });
781
1295
  onEvent({
782
- type: 'message_complete',
1296
+ type: "message_complete",
783
1297
  sessionId: ctx.conversationId,
784
- ...(emittedAttachments.length > 0 ? { attachments: emittedAttachments } : {}),
1298
+ ...(emittedAttachments.length > 0
1299
+ ? { attachments: emittedAttachments }
1300
+ : {}),
785
1301
  });
786
1302
  }
787
1303
 
788
1304
  // Second title pass: after 3 completed turns, re-generate the title
789
1305
  // using the last 3 messages for better context. Only fires when the
790
1306
  // current title was auto-generated (isAutoTitle = 1).
791
- if (ctx.turnCount === 2) { // turnCount is 0-indexed, incremented in finally; 2 = about to become 3rd turn
1307
+ if (ctx.turnCount === 2) {
1308
+ // turnCount is 0-indexed, incremented in finally; 2 = about to become 3rd turn
792
1309
  queueRegenerateConversationTitle({
793
1310
  conversationId: ctx.conversationId,
794
1311
  provider: ctx.provider,
795
1312
  onTitleUpdated: (title) => {
796
1313
  onEvent({
797
- type: 'session_title_updated',
1314
+ type: "session_title_updated",
798
1315
  sessionId: ctx.conversationId,
799
1316
  title,
800
1317
  });
@@ -803,30 +1320,37 @@ export async function runAgentLoopImpl(
803
1320
  });
804
1321
  }
805
1322
  } catch (err) {
806
- const errorCtx = { phase: 'agent_loop' as const, aborted: abortController.signal.aborted };
1323
+ const errorCtx = {
1324
+ phase: "agent_loop" as const,
1325
+ aborted: abortController.signal.aborted,
1326
+ };
807
1327
  if (isUserCancellation(err, errorCtx)) {
808
- ctx.emitActivityState('idle', 'generation_cancelled', 'global', reqId);
809
- rlog.info('Generation cancelled by user');
810
- ctx.traceEmitter.emit('generation_cancelled', 'Generation cancelled by user', {
811
- requestId: reqId,
812
- status: 'warning',
813
- });
814
- onEvent({ type: 'generation_cancelled', sessionId: ctx.conversationId });
1328
+ ctx.emitActivityState("idle", "generation_cancelled", "global", reqId);
1329
+ rlog.info("Generation cancelled by user");
1330
+ ctx.traceEmitter.emit(
1331
+ "generation_cancelled",
1332
+ "Generation cancelled by user",
1333
+ {
1334
+ requestId: reqId,
1335
+ status: "warning",
1336
+ },
1337
+ );
1338
+ onEvent({ type: "generation_cancelled", sessionId: ctx.conversationId });
815
1339
  } else {
816
- ctx.emitActivityState('idle', 'error_terminal', 'global', reqId);
1340
+ ctx.emitActivityState("idle", "error_terminal", "global", reqId);
817
1341
  const message = err instanceof Error ? err.message : String(err);
818
- const errorClass = err instanceof Error ? err.constructor.name : 'Error';
819
- rlog.error({ err }, 'Session processing error');
820
- ctx.traceEmitter.emit('request_error', truncate(message, 200, ''), {
1342
+ const errorClass = err instanceof Error ? err.constructor.name : "Error";
1343
+ rlog.error({ err }, "Session processing error");
1344
+ ctx.traceEmitter.emit("request_error", truncate(message, 200, ""), {
821
1345
  requestId: reqId,
822
- status: 'error',
823
- attributes: { errorClass, message: truncate(message, 500, '') },
1346
+ status: "error",
1347
+ attributes: { errorClass, message: truncate(message, 500, "") },
824
1348
  });
825
1349
  const classified = classifySessionError(err, errorCtx);
826
- onEvent({ type: 'error', message: classified.userMessage });
1350
+ onEvent({ type: "error", message: classified.userMessage });
827
1351
  onEvent(buildSessionErrorMessage(ctx.conversationId, classified));
828
- void getHookManager().trigger('on-error', {
829
- error: err instanceof Error ? err.name : 'Error',
1352
+ void getHookManager().trigger("on-error", {
1353
+ error: err instanceof Error ? err.name : "Error",
830
1354
  message,
831
1355
  stack: err instanceof Error ? err.stack : undefined,
832
1356
  sessionId: ctx.conversationId,
@@ -840,15 +1364,21 @@ export async function runAgentLoopImpl(
840
1364
  const deadlineMs = Date.now() + maxWait;
841
1365
  const commitTurnChangesFn = ctx.commitTurnChanges ?? commitTurnChanges;
842
1366
  const commitPromise = commitTurnChangesFn(
843
- ctx.workingDir, ctx.conversationId, ctx.turnCount,
1367
+ ctx.workingDir,
1368
+ ctx.conversationId,
1369
+ ctx.turnCount,
844
1370
  undefined,
845
1371
  deadlineMs,
846
1372
  );
847
1373
  const outcome = await raceWithTimeout(commitPromise, maxWait);
848
- if (outcome === 'timed_out') {
1374
+ if (outcome === "timed_out") {
849
1375
  rlog.warn(
850
- { turnNumber: ctx.turnCount, maxWaitMs: maxWait, conversationId: ctx.conversationId },
851
- 'Turn-boundary commit timed out — continuing without waiting (commit still runs in background)',
1376
+ {
1377
+ turnNumber: ctx.turnCount,
1378
+ maxWaitMs: maxWait,
1379
+ conversationId: ctx.conversationId,
1380
+ },
1381
+ "Turn-boundary commit timed out — continuing without waiting (commit still runs in background)",
852
1382
  );
853
1383
  }
854
1384
 
@@ -860,7 +1390,7 @@ export async function runAgentLoopImpl(
860
1390
 
861
1391
  ctx.abortController = null;
862
1392
  ctx.processing = false;
863
- ctx.surfaceActionRequestIds.delete(ctx.currentRequestId ?? '');
1393
+ ctx.surfaceActionRequestIds.delete(ctx.currentRequestId ?? "");
864
1394
  ctx.currentRequestId = undefined;
865
1395
  ctx.currentActiveSurfaceId = undefined;
866
1396
  ctx.allowedToolNames = undefined;
@@ -873,14 +1403,17 @@ export async function runAgentLoopImpl(
873
1403
  consolidateAssistantMessages(ctx.conversationId, userMessageId);
874
1404
  }
875
1405
 
876
- ctx.drainQueue(yieldedForHandoff ? 'checkpoint_handoff' : 'loop_complete');
1406
+ ctx.drainQueue(yieldedForHandoff ? "checkpoint_handoff" : "loop_complete");
877
1407
  }
878
1408
  }
879
1409
 
880
1410
  // ── Helper ───────────────────────────────────────────────────────────
881
1411
 
882
1412
  function emitUsage(
883
- ctx: Pick<AgentLoopSessionContext, 'conversationId' | 'provider' | 'usageStats'>,
1413
+ ctx: Pick<
1414
+ AgentLoopSessionContext,
1415
+ "conversationId" | "provider" | "usageStats"
1416
+ >,
884
1417
  inputTokens: number,
885
1418
  outputTokens: number,
886
1419
  model: string,
@@ -889,7 +1422,16 @@ function emitUsage(
889
1422
  requestId: string | null = null,
890
1423
  ): void {
891
1424
  recordUsage(
892
- { conversationId: ctx.conversationId, providerName: ctx.provider.name, usageStats: ctx.usageStats },
893
- inputTokens, outputTokens, model, onEvent, actor, requestId,
1425
+ {
1426
+ conversationId: ctx.conversationId,
1427
+ providerName: ctx.provider.name,
1428
+ usageStats: ctx.usageStats,
1429
+ },
1430
+ inputTokens,
1431
+ outputTokens,
1432
+ model,
1433
+ onEvent,
1434
+ actor,
1435
+ requestId,
894
1436
  );
895
1437
  }