@vellumai/assistant 0.7.0 → 0.7.1

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 (666) hide show
  1. package/ARCHITECTURE.md +6 -7
  2. package/Dockerfile +1 -0
  3. package/README.md +2 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
  5. package/bun.lock +3 -0
  6. package/docs/architecture/security.md +18 -16
  7. package/knip.json +1 -0
  8. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
  9. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
  10. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
  11. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
  12. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
  13. package/node_modules/@vellumai/slack-text/bun.lock +24 -0
  14. package/node_modules/@vellumai/slack-text/package.json +18 -0
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
  16. package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
  17. package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
  18. package/openapi.yaml +294 -107
  19. package/package.json +4 -2
  20. package/scripts/generate-openapi.ts +16 -111
  21. package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
  22. package/src/__tests__/anthropic-provider.test.ts +56 -13
  23. package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
  24. package/src/__tests__/app-conversation-ids.test.ts +151 -0
  25. package/src/__tests__/approval-cascade.test.ts +0 -15
  26. package/src/__tests__/approval-routes-http.test.ts +6 -17
  27. package/src/__tests__/assistant-event-hub.test.ts +126 -77
  28. package/src/__tests__/assistant-event.test.ts +0 -5
  29. package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
  31. package/src/__tests__/background-shell-host-bash.test.ts +34 -43
  32. package/src/__tests__/call-controller.test.ts +1 -1
  33. package/src/__tests__/call-site-routing-provider.test.ts +193 -0
  34. package/src/__tests__/channel-approval-routes.test.ts +10 -296
  35. package/src/__tests__/channel-approvals.test.ts +25 -17
  36. package/src/__tests__/channel-guardian.test.ts +100 -146
  37. package/src/__tests__/checker.test.ts +20 -34
  38. package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/config-schema.test.ts +6 -48
  41. package/src/__tests__/config-watcher.test.ts +12 -0
  42. package/src/__tests__/connection-policy.test.ts +1 -52
  43. package/src/__tests__/contacts-write.test.ts +2 -64
  44. package/src/__tests__/context-image-dimensions.test.ts +1 -1
  45. package/src/__tests__/context-search-memory-source.test.ts +120 -1
  46. package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
  47. package/src/__tests__/context-search-pkb-source.test.ts +49 -0
  48. package/src/__tests__/context-search-workspace-source.test.ts +9 -22
  49. package/src/__tests__/context-window-manager.test.ts +46 -0
  50. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
  51. package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
  52. package/src/__tests__/conversation-agent-loop.test.ts +980 -13
  53. package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
  54. package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
  55. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
  56. package/src/__tests__/conversation-history-web-search.test.ts +4 -3
  57. package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
  58. package/src/__tests__/conversation-lifecycle.test.ts +4 -4
  59. package/src/__tests__/conversation-process-callsite.test.ts +79 -2
  60. package/src/__tests__/conversation-queue.test.ts +3 -8
  61. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
  62. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
  63. package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
  64. package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
  65. package/src/__tests__/conversation-slash-commands.test.ts +24 -4
  66. package/src/__tests__/conversation-slash-queue.test.ts +2 -0
  67. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  68. package/src/__tests__/conversation-starter-routes.test.ts +79 -2
  69. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
  70. package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
  71. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
  72. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
  73. package/src/__tests__/conversation-usage.test.ts +253 -3
  74. package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
  75. package/src/__tests__/credential-health-service.test.ts +68 -0
  76. package/src/__tests__/credential-security-e2e.test.ts +4 -3
  77. package/src/__tests__/credential-security-invariants.test.ts +1 -5
  78. package/src/__tests__/credential-token-resolver.test.ts +180 -0
  79. package/src/__tests__/cu-unified-flow.test.ts +33 -16
  80. package/src/__tests__/daemon-assistant-events.test.ts +34 -21
  81. package/src/__tests__/daemon-credential-client.test.ts +4 -1
  82. package/src/__tests__/db-connection-isolation.test.ts +125 -0
  83. package/src/__tests__/db-migration-rollback.test.ts +101 -0
  84. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
  85. package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
  86. package/src/__tests__/document-conversations.test.ts +332 -0
  87. package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
  88. package/src/__tests__/emit-event-signal.test.ts +4 -6
  89. package/src/__tests__/events-client-registration.test.ts +193 -49
  90. package/src/__tests__/filing-service.test.ts +58 -7
  91. package/src/__tests__/first-greeting.test.ts +156 -150
  92. package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
  93. package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
  94. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  95. package/src/__tests__/guardian-dispatch.test.ts +1 -1
  96. package/src/__tests__/guardian-grant-minting.test.ts +7 -2
  97. package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
  98. package/src/__tests__/guardian-routing-state.test.ts +1 -1
  99. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
  100. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
  101. package/src/__tests__/headless-browser-mode.test.ts +4 -9
  102. package/src/__tests__/headless-browser-navigate.test.ts +21 -20
  103. package/src/__tests__/heartbeat-service.test.ts +289 -7
  104. package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
  105. package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
  106. package/src/__tests__/host-bash-proxy.test.ts +46 -122
  107. package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
  108. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
  109. package/src/__tests__/host-browser-proxy.test.ts +111 -185
  110. package/src/__tests__/host-browser-routes.test.ts +45 -75
  111. package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
  112. package/src/__tests__/host-cu-proxy.test.ts +56 -111
  113. package/src/__tests__/host-file-proxy.test.ts +44 -98
  114. package/src/__tests__/host-file-read-tool.test.ts +42 -21
  115. package/src/__tests__/host-shell-tool.test.ts +33 -68
  116. package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
  117. package/src/__tests__/host-transfer-proxy.test.ts +43 -53
  118. package/src/__tests__/http-user-message-parity.test.ts +0 -6
  119. package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
  120. package/src/__tests__/injector-chain.test.ts +10 -5
  121. package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
  122. package/src/__tests__/inline-command-runner.test.ts +0 -66
  123. package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
  124. package/src/__tests__/install-skill-routing.test.ts +1 -13
  125. package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
  126. package/src/__tests__/llm-catalog-parity.test.ts +90 -0
  127. package/src/__tests__/llm-context-resolution.test.ts +180 -0
  128. package/src/__tests__/llm-resolver.test.ts +80 -12
  129. package/src/__tests__/llm-usage-store.test.ts +269 -4
  130. package/src/__tests__/log-export-routes.test.ts +89 -0
  131. package/src/__tests__/managed-profile-guard.test.ts +225 -0
  132. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
  133. package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
  134. package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
  135. package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
  136. package/src/__tests__/migration-export-http.test.ts +33 -26
  137. package/src/__tests__/migration-export-streaming.test.ts +18 -10
  138. package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
  139. package/src/__tests__/migration-import-commit-http.test.ts +66 -21
  140. package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
  141. package/src/__tests__/migration-import-from-url.test.ts +20 -6
  142. package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
  143. package/src/__tests__/migration-parity-persistence.test.ts +62 -25
  144. package/src/__tests__/migration-transport.test.ts +115 -23
  145. package/src/__tests__/migration-validate-http.test.ts +105 -80
  146. package/src/__tests__/migration-wizard.test.ts +133 -27
  147. package/src/__tests__/non-member-access-request.test.ts +1 -1
  148. package/src/__tests__/notification-guardian-path.test.ts +1 -1
  149. package/src/__tests__/oauth-store.test.ts +19 -0
  150. package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
  151. package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
  152. package/src/__tests__/pricing.test.ts +68 -4
  153. package/src/__tests__/process-message-background-slack.test.ts +331 -0
  154. package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
  155. package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
  156. package/src/__tests__/provider-usage-tracking.test.ts +208 -0
  157. package/src/__tests__/reaction-persistence.test.ts +9 -6
  158. package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
  159. package/src/__tests__/recording-handler.test.ts +64 -81
  160. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
  161. package/src/__tests__/relay-server.test.ts +18 -13
  162. package/src/__tests__/require-fresh-approval.test.ts +13 -22
  163. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  164. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  165. package/src/__tests__/runtime-events-sse.test.ts +3 -12
  166. package/src/__tests__/search-skills-unified.test.ts +9 -15
  167. package/src/__tests__/secret-ingress-cli.test.ts +2 -5
  168. package/src/__tests__/secret-ingress-http.test.ts +0 -4
  169. package/src/__tests__/secret-onetime-send.test.ts +4 -2
  170. package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
  171. package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
  172. package/src/__tests__/secret-response-routing.test.ts +29 -15
  173. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
  174. package/src/__tests__/secret-scanner.test.ts +2 -545
  175. package/src/__tests__/send-endpoint-busy.test.ts +9 -24
  176. package/src/__tests__/settings-routes.test.ts +1 -1
  177. package/src/__tests__/shell-credential-ref.test.ts +0 -8
  178. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
  179. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
  180. package/src/__tests__/skill-tool-factory.test.ts +97 -0
  181. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
  182. package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
  183. package/src/__tests__/slack-inbound-verification.test.ts +1 -62
  184. package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
  185. package/src/__tests__/subagent-manager-notify.test.ts +70 -70
  186. package/src/__tests__/subagent-notify-parent.test.ts +80 -83
  187. package/src/__tests__/system-prompt.test.ts +115 -13
  188. package/src/__tests__/terminal-tools.test.ts +0 -89
  189. package/src/__tests__/thread-backfill.test.ts +945 -31
  190. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
  191. package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
  192. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
  193. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
  194. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
  195. package/src/__tests__/tool-executor.test.ts +12 -19
  196. package/src/__tests__/tool-metrics-listener.test.ts +0 -35
  197. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  198. package/src/__tests__/tool-trace-listener.test.ts +0 -17
  199. package/src/__tests__/transfer-progress-screen.test.ts +63 -26
  200. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
  201. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
  202. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  203. package/src/__tests__/tts-catalog-parity.test.ts +16 -5
  204. package/src/__tests__/usage-attribution.test.ts +247 -0
  205. package/src/__tests__/usage-cli.test.ts +143 -0
  206. package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
  207. package/src/__tests__/usage-routes.test.ts +150 -0
  208. package/src/__tests__/validation-results-screen.test.ts +39 -16
  209. package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
  210. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
  211. package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
  212. package/src/__tests__/voice-session-bridge.test.ts +5 -5
  213. package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
  214. package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
  215. package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
  216. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
  217. package/src/acp/index.ts +0 -15
  218. package/src/acp/session-manager.ts +37 -34
  219. package/src/agent/loop.ts +16 -1
  220. package/src/approvals/AGENTS.md +4 -0
  221. package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
  222. package/src/approvals/guardian-request-resolvers.ts +10 -2
  223. package/src/backup/__tests__/backup-worker.test.ts +36 -8
  224. package/src/backup/__tests__/paths.test.ts +2 -2
  225. package/src/backup/__tests__/restore.test.ts +45 -28
  226. package/src/backup/backup-worker.ts +36 -2
  227. package/src/backup/paths.ts +9 -6
  228. package/src/browser-session/events.ts +0 -9
  229. package/src/calls/call-store.ts +1 -34
  230. package/src/calls/guardian-question-copy.ts +0 -108
  231. package/src/calls/relay-server.ts +0 -24
  232. package/src/calls/twilio-rest.ts +0 -38
  233. package/src/calls/twilio-routes.ts +1 -1
  234. package/src/calls/voice-session-bridge.ts +7 -38
  235. package/src/channels/types.ts +1 -36
  236. package/src/cli/commands/__tests__/cache.test.ts +152 -5
  237. package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
  238. package/src/cli/commands/__tests__/trust.test.ts +21 -387
  239. package/src/cli/commands/backup.ts +4 -4
  240. package/src/cli/commands/cache-fs.ts +8 -0
  241. package/src/cli/commands/cache.ts +153 -82
  242. package/src/cli/commands/clients.ts +63 -5
  243. package/src/cli/commands/completions.ts +3 -3
  244. package/src/cli/commands/contacts.ts +231 -76
  245. package/src/cli/commands/keys.ts +4 -1
  246. package/src/cli/commands/memory-v2.ts +24 -52
  247. package/src/cli/commands/oauth/shared.ts +2 -29
  248. package/src/cli/commands/pending.ts +102 -0
  249. package/src/cli/commands/skills.ts +77 -35
  250. package/src/cli/commands/trust.ts +70 -430
  251. package/src/cli/commands/usage.ts +25 -16
  252. package/src/cli/lib/daemon-credential-client.ts +14 -0
  253. package/src/cli/program.ts +2 -0
  254. package/src/cli.ts +0 -21
  255. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  256. package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
  257. package/src/config/env-registry.ts +12 -2
  258. package/src/config/env.ts +3 -14
  259. package/src/config/feature-flag-registry.json +30 -30
  260. package/src/config/llm-callsite-catalog.ts +12 -0
  261. package/src/config/llm-context-resolution.ts +80 -0
  262. package/src/config/llm-resolver.ts +58 -22
  263. package/src/config/loader.ts +3 -3
  264. package/src/config/schema.ts +2 -158
  265. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
  266. package/src/config/schemas/call-site-catalog.ts +271 -0
  267. package/src/config/schemas/calls.ts +5 -5
  268. package/src/config/schemas/inference.ts +1 -1
  269. package/src/config/schemas/ingress.ts +1 -1
  270. package/src/config/schemas/llm.ts +31 -3
  271. package/src/config/schemas/memory-retrieval.ts +2 -2
  272. package/src/config/schemas/memory-v2.ts +9 -0
  273. package/src/config/schemas/security.ts +1 -42
  274. package/src/config/schemas/services.ts +6 -6
  275. package/src/config/schemas/skills.ts +5 -5
  276. package/src/config/schemas/tts.ts +1 -1
  277. package/src/config/seed-inference-profiles.ts +117 -0
  278. package/src/config/skills.ts +0 -90
  279. package/src/config/types.ts +3 -6
  280. package/src/contacts/contact-store.ts +0 -17
  281. package/src/contacts/contacts-write.ts +1 -105
  282. package/src/context/window-manager.ts +44 -5
  283. package/src/credential-execution/process-manager.ts +34 -10
  284. package/src/credential-health/credential-health-service.ts +21 -16
  285. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
  286. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
  287. package/src/daemon/connection-policy.ts +1 -26
  288. package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
  289. package/src/daemon/conversation-agent-loop.ts +277 -36
  290. package/src/daemon/conversation-history.ts +8 -8
  291. package/src/daemon/conversation-launch.ts +20 -135
  292. package/src/daemon/conversation-lifecycle.ts +1 -1
  293. package/src/daemon/conversation-messaging.ts +1 -0
  294. package/src/daemon/conversation-process.ts +83 -163
  295. package/src/daemon/conversation-runtime-assembly.ts +219 -76
  296. package/src/daemon/conversation-slash.ts +47 -5
  297. package/src/daemon/conversation-store.ts +7 -31
  298. package/src/daemon/conversation-surfaces.ts +22 -28
  299. package/src/daemon/conversation-tool-setup.ts +3 -33
  300. package/src/daemon/conversation-usage.ts +36 -0
  301. package/src/daemon/conversation.ts +117 -233
  302. package/src/daemon/daemon-control.ts +3 -71
  303. package/src/daemon/daemon-skill-host.ts +8 -11
  304. package/src/daemon/dictation-profile-store.ts +2 -26
  305. package/src/daemon/first-greeting.ts +44 -156
  306. package/src/daemon/handlers/config-channels.ts +12 -12
  307. package/src/daemon/handlers/config-ingress.ts +4 -165
  308. package/src/daemon/handlers/config-model.ts +1 -1
  309. package/src/daemon/handlers/config-voice.ts +0 -42
  310. package/src/daemon/handlers/conversations.ts +11 -190
  311. package/src/daemon/handlers/recording.ts +26 -158
  312. package/src/daemon/handlers/shared.ts +23 -71
  313. package/src/daemon/handlers/skills.ts +42 -93
  314. package/src/daemon/host-bash-proxy.ts +67 -45
  315. package/src/daemon/host-browser-proxy.ts +65 -27
  316. package/src/daemon/host-cu-proxy.ts +40 -39
  317. package/src/daemon/host-file-proxy.ts +58 -37
  318. package/src/daemon/host-transfer-proxy.ts +84 -46
  319. package/src/daemon/lifecycle.ts +49 -15
  320. package/src/daemon/message-types/conversations.ts +7 -0
  321. package/src/daemon/message-types/host-bash.ts +1 -0
  322. package/src/daemon/message-types/host-cu.ts +1 -0
  323. package/src/daemon/message-types/host-file.ts +1 -0
  324. package/src/daemon/message-types/host-transfer.ts +1 -0
  325. package/src/daemon/message-types/messages.ts +10 -9
  326. package/src/daemon/message-types/workspace.ts +1 -1
  327. package/src/daemon/process-message.ts +102 -239
  328. package/src/daemon/server.ts +13 -462
  329. package/src/daemon/shutdown-handlers.ts +2 -2
  330. package/src/daemon/tool-side-effects.ts +125 -107
  331. package/src/daemon/trust-context.ts +13 -0
  332. package/src/daemon/wake-target-adapter.ts +4 -9
  333. package/src/events/domain-events.ts +0 -8
  334. package/src/events/tool-audit-listener.ts +3 -1
  335. package/src/events/tool-domain-event-publisher.ts +0 -10
  336. package/src/events/tool-metrics-listener.ts +0 -17
  337. package/src/events/tool-trace-listener.ts +0 -14
  338. package/src/filing/filing-service.ts +13 -1
  339. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
  340. package/src/heartbeat/heartbeat-service.ts +23 -5
  341. package/src/home/__tests__/feed-writer.test.ts +0 -4
  342. package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
  343. package/src/home/feed-writer.ts +1 -2
  344. package/src/home/relationship-state-writer.ts +16 -3
  345. package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
  346. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
  347. package/src/ipc/assistant-server.ts +3 -10
  348. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
  349. package/src/ipc/routes/route-adapter.ts +1 -1
  350. package/src/ipc/routes/trust-rules.test.ts +0 -95
  351. package/src/ipc/skill-ipc-types.ts +41 -0
  352. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
  353. package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
  354. package/src/ipc/skill-routes/events.ts +12 -23
  355. package/src/ipc/skill-routes/identity.ts +4 -17
  356. package/src/ipc/skill-routes/index.ts +1 -1
  357. package/src/ipc/skill-server.ts +6 -39
  358. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
  359. package/src/live-voice/protocol.ts +4 -13
  360. package/src/mcp/manager.ts +0 -5
  361. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
  362. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
  363. package/src/memory/app-git-service.ts +0 -32
  364. package/src/memory/app-store.ts +154 -0
  365. package/src/memory/attachments-store.ts +6 -0
  366. package/src/memory/context-search/sources/memory-v2.ts +578 -0
  367. package/src/memory/context-search/sources/memory.ts +5 -0
  368. package/src/memory/context-search/sources/pkb.ts +10 -1
  369. package/src/memory/context-search/sources/workspace.ts +3 -2
  370. package/src/memory/conversation-crud.ts +29 -4
  371. package/src/memory/conversation-disk-view.ts +1 -5
  372. package/src/memory/conversation-starter-checkpoints.ts +63 -0
  373. package/src/memory/db-connection.ts +62 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +3 -21
  376. package/src/memory/embedding-gemini.ts +0 -2
  377. package/src/memory/embedding-local.ts +6 -6
  378. package/src/memory/embedding-ollama.ts +6 -6
  379. package/src/memory/embedding-openai.ts +6 -6
  380. package/src/memory/embedding-types.ts +21 -0
  381. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
  382. package/src/memory/graph/conversation-graph-memory.ts +35 -13
  383. package/src/memory/graph/injection.test.ts +2 -2
  384. package/src/memory/graph/injection.ts +1 -1
  385. package/src/memory/guardian-action-store.ts +0 -83
  386. package/src/memory/guardian-approvals.ts +0 -48
  387. package/src/memory/indexer.ts +1 -15
  388. package/src/memory/job-handlers/conversation-starters.ts +36 -53
  389. package/src/memory/job-utils.ts +0 -6
  390. package/src/memory/jobs-store.ts +0 -1
  391. package/src/memory/jobs-worker.ts +2 -16
  392. package/src/memory/llm-request-log-store.ts +0 -41
  393. package/src/memory/llm-usage-store.ts +129 -43
  394. package/src/memory/memory-v2-activation-log-store.ts +115 -0
  395. package/src/memory/migrations/233-document-conversations.ts +54 -0
  396. package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
  397. package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
  398. package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
  399. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
  400. package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
  401. package/src/memory/migrations/index.ts +14 -0
  402. package/src/memory/migrations/registry.ts +24 -0
  403. package/src/memory/raw-query.ts +2 -68
  404. package/src/memory/schema/conversations.ts +7 -0
  405. package/src/memory/schema/infrastructure.ts +25 -0
  406. package/src/memory/search/semantic.ts +5 -16
  407. package/src/memory/tool-usage-store.ts +2 -0
  408. package/src/memory/usage-buckets.ts +40 -1
  409. package/src/memory/usage-grouped-buckets.ts +127 -0
  410. package/src/memory/v2/__tests__/activation.test.ts +289 -90
  411. package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
  412. package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
  413. package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
  414. package/src/memory/v2/__tests__/injection.test.ts +384 -15
  415. package/src/memory/v2/__tests__/migration.test.ts +64 -36
  416. package/src/memory/v2/__tests__/page-store.test.ts +191 -8
  417. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
  418. package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
  419. package/src/memory/v2/__tests__/static-context.test.ts +153 -0
  420. package/src/memory/v2/activation.ts +168 -97
  421. package/src/memory/v2/backfill-jobs.ts +15 -100
  422. package/src/memory/v2/consolidation-job.ts +14 -12
  423. package/src/memory/v2/edge-index.ts +191 -0
  424. package/src/memory/v2/injection.ts +182 -58
  425. package/src/memory/v2/migration.ts +57 -64
  426. package/src/memory/v2/now-text.ts +2 -3
  427. package/src/memory/v2/page-store.ts +168 -31
  428. package/src/memory/v2/prompts/consolidation.ts +118 -42
  429. package/src/memory/v2/prompts/sweep.ts +3 -3
  430. package/src/memory/v2/skill-store.ts +55 -7
  431. package/src/memory/v2/static-context.ts +62 -0
  432. package/src/memory/v2/types.ts +10 -20
  433. package/src/memory/validation.ts +0 -11
  434. package/src/messaging/draft-store.ts +0 -6
  435. package/src/messaging/provider-types.ts +8 -0
  436. package/src/messaging/provider.ts +7 -0
  437. package/src/messaging/providers/gmail/client.ts +1 -121
  438. package/src/messaging/providers/outlook/client.ts +0 -73
  439. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
  440. package/src/messaging/providers/slack/adapter.ts +122 -21
  441. package/src/messaging/providers/slack/backfill.test.ts +95 -6
  442. package/src/messaging/providers/slack/backfill.ts +89 -11
  443. package/src/messaging/providers/slack/client.ts +10 -124
  444. package/src/messaging/providers/slack/message-metadata.ts +12 -2
  445. package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
  446. package/src/messaging/providers/slack/render-transcript.ts +126 -25
  447. package/src/messaging/providers/slack/types.ts +1 -0
  448. package/src/oauth/connection-resolver.test.ts +8 -0
  449. package/src/oauth/connection-resolver.ts +8 -16
  450. package/src/oauth/credential-token-resolver.ts +97 -0
  451. package/src/oauth/manual-token-connection.ts +30 -34
  452. package/src/oauth/oauth-store.ts +6 -4
  453. package/src/outbound-proxy/certs.ts +0 -7
  454. package/src/outbound-proxy/config.ts +0 -74
  455. package/src/outbound-proxy/health.ts +0 -44
  456. package/src/outbound-proxy/index.ts +0 -22
  457. package/src/permissions/approval-provenance.test.ts +184 -0
  458. package/src/permissions/approval-provenance.ts +70 -0
  459. package/src/permissions/checker.ts +4 -1
  460. package/src/permissions/gateway-threshold-reader.ts +4 -1
  461. package/src/permissions/prompter.ts +9 -2
  462. package/src/permissions/secret-prompter.ts +21 -48
  463. package/src/permissions/types.ts +33 -0
  464. package/src/permissions/workspace-policy.ts +0 -5
  465. package/src/platform/sync-identity.ts +0 -8
  466. package/src/plugins/defaults/injectors.ts +69 -2
  467. package/src/plugins/defaults/overflow-reduce.ts +3 -2
  468. package/src/plugins/types.ts +8 -0
  469. package/src/prompts/system-prompt.ts +34 -70
  470. package/src/prompts/templates/BOOTSTRAP.md +52 -6
  471. package/src/prompts/update-bulletin-job.ts +2 -0
  472. package/src/providers/__tests__/retry-callsite.test.ts +138 -1
  473. package/src/providers/anthropic/client.ts +72 -33
  474. package/src/providers/call-site-routing.ts +42 -3
  475. package/src/providers/gemini/client.ts +18 -2
  476. package/src/providers/managed-proxy/context.ts +0 -5
  477. package/src/providers/model-catalog.ts +105 -19
  478. package/src/providers/openai/chat-completions-provider.ts +6 -0
  479. package/src/providers/openai/responses-provider.ts +7 -1
  480. package/src/providers/provider-send-message.ts +45 -2
  481. package/src/providers/ratelimit.ts +7 -2
  482. package/src/providers/registry.ts +14 -9
  483. package/src/providers/retry.ts +96 -8
  484. package/src/providers/types.ts +13 -0
  485. package/src/providers/usage-tracking.ts +96 -0
  486. package/src/runtime/AGENTS.md +10 -6
  487. package/src/runtime/__tests__/agent-wake.test.ts +89 -0
  488. package/src/runtime/agent-wake.ts +39 -2
  489. package/src/runtime/assistant-event-hub.ts +541 -45
  490. package/src/runtime/assistant-event.ts +1 -6
  491. package/src/runtime/auth/context.ts +0 -9
  492. package/src/runtime/auth/middleware.ts +1 -1
  493. package/src/runtime/auth/route-policy.ts +11 -9
  494. package/src/runtime/auth/token-service.ts +0 -11
  495. package/src/runtime/channel-approvals.ts +6 -2
  496. package/src/runtime/channel-verification-service.ts +3 -5
  497. package/src/runtime/http-errors.ts +0 -34
  498. package/src/runtime/http-router.ts +6 -3
  499. package/src/runtime/http-server.ts +22 -82
  500. package/src/runtime/http-types.ts +5 -0
  501. package/src/runtime/interactive-ui.ts +0 -1
  502. package/src/runtime/middleware/auth.ts +0 -20
  503. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
  504. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
  505. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
  506. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
  507. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
  508. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
  509. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
  510. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
  511. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
  512. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
  513. package/src/runtime/migrations/migration-transport.ts +46 -13
  514. package/src/runtime/migrations/migration-wizard.ts +2 -2
  515. package/src/runtime/migrations/origin-mode.ts +40 -0
  516. package/src/runtime/migrations/vbundle-builder.ts +133 -79
  517. package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
  518. package/src/runtime/migrations/vbundle-importer.ts +7 -7
  519. package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
  520. package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
  521. package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
  522. package/src/runtime/migrations/vbundle-validator.ts +214 -41
  523. package/src/runtime/pending-interactions.ts +13 -4
  524. package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
  525. package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
  526. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
  527. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
  528. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
  529. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
  530. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
  531. package/src/runtime/routes/acp-routes.test.ts +0 -3
  532. package/src/runtime/routes/acp-routes.ts +3 -7
  533. package/src/runtime/routes/app-management-routes.ts +18 -9
  534. package/src/runtime/routes/approval-routes.ts +55 -14
  535. package/src/runtime/routes/avatar-routes.ts +3 -5
  536. package/src/runtime/routes/browser-routes.ts +1 -15
  537. package/src/runtime/routes/channel-guardian-routes.ts +1 -5
  538. package/src/runtime/routes/channel-readiness-routes.ts +3 -7
  539. package/src/runtime/routes/channel-route-shared.ts +2 -28
  540. package/src/runtime/routes/client-routes.ts +45 -12
  541. package/src/runtime/routes/consolidation-routes.ts +115 -0
  542. package/src/runtime/routes/conversation-list-routes.ts +12 -29
  543. package/src/runtime/routes/conversation-management-routes.ts +14 -51
  544. package/src/runtime/routes/conversation-query-routes.ts +120 -8
  545. package/src/runtime/routes/conversation-routes.ts +44 -528
  546. package/src/runtime/routes/conversation-starter-routes.ts +19 -40
  547. package/src/runtime/routes/documents-routes.ts +53 -18
  548. package/src/runtime/routes/events-routes.ts +59 -91
  549. package/src/runtime/routes/filing-routes.ts +18 -1
  550. package/src/runtime/routes/guardian-action-routes.ts +4 -9
  551. package/src/runtime/routes/host-bash-routes.ts +3 -2
  552. package/src/runtime/routes/host-browser-routes.ts +9 -33
  553. package/src/runtime/routes/host-cu-routes.ts +6 -1
  554. package/src/runtime/routes/host-file-routes.ts +3 -2
  555. package/src/runtime/routes/host-transfer-routes.ts +11 -15
  556. package/src/runtime/routes/identity-routes.ts +78 -6
  557. package/src/runtime/routes/inbound-message-handler.ts +580 -137
  558. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
  559. package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
  560. package/src/runtime/routes/index.ts +4 -0
  561. package/src/runtime/routes/integrations/slack/channel.ts +0 -24
  562. package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
  563. package/src/runtime/routes/memory-v2-routes.ts +10 -15
  564. package/src/runtime/routes/migration-routes.ts +188 -31
  565. package/src/runtime/routes/playground/guard.ts +1 -1
  566. package/src/runtime/routes/playground/index.ts +0 -2
  567. package/src/runtime/routes/recording-routes.ts +4 -24
  568. package/src/runtime/routes/rename-conversation-routes.ts +2 -6
  569. package/src/runtime/routes/schedule-routes.ts +3 -6
  570. package/src/runtime/routes/secret-routes.ts +87 -18
  571. package/src/runtime/routes/settings-routes.ts +29 -28
  572. package/src/runtime/routes/skills-routes.ts +12 -31
  573. package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
  574. package/src/runtime/routes/task-routes.ts +6 -6
  575. package/src/runtime/routes/trust-rules-routes.ts +3 -94
  576. package/src/runtime/routes/types.ts +4 -4
  577. package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
  578. package/src/runtime/routes/usage-routes.ts +87 -10
  579. package/src/runtime/routes/user-routes.ts +17 -31
  580. package/src/runtime/routes/work-items-routes.ts +1 -4
  581. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
  582. package/src/runtime/services/analyze-conversation.ts +7 -17
  583. package/src/runtime/services/conversation-serializer.ts +2 -4
  584. package/src/runtime/verification-outbound-actions.ts +1 -1
  585. package/src/runtime/verification-rate-limiter.ts +1 -1
  586. package/src/schedule/schedule-store.ts +0 -16
  587. package/src/security/secret-scanner.ts +14 -547
  588. package/src/security/secure-keys.ts +31 -11
  589. package/src/security/token-manager.ts +7 -3
  590. package/src/signals/cancel.ts +16 -25
  591. package/src/signals/conversation-undo.ts +2 -27
  592. package/src/signals/emit-event.ts +1 -2
  593. package/src/signals/user-message.ts +108 -22
  594. package/src/skills/catalog-install.ts +1 -0
  595. package/src/skills/clawhub.ts +2 -2
  596. package/src/skills/inline-command-runner.ts +1 -7
  597. package/src/subagent/manager.ts +67 -84
  598. package/src/tasks/task-store.ts +1 -28
  599. package/src/telemetry/types.ts +6 -0
  600. package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
  601. package/src/telemetry/usage-telemetry-reporter.ts +3 -5
  602. package/src/tools/acp/spawn.test.ts +1 -2
  603. package/src/tools/acp/steer.test.ts +1 -2
  604. package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
  605. package/src/tools/browser/browser-execution.ts +31 -147
  606. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
  607. package/src/tools/browser/cdp-client/factory.ts +48 -76
  608. package/src/tools/browser/cdp-client/index.ts +1 -14
  609. package/src/tools/executor.ts +44 -31
  610. package/src/tools/host-filesystem/edit.ts +3 -2
  611. package/src/tools/host-filesystem/read.ts +3 -2
  612. package/src/tools/host-filesystem/transfer.test.ts +45 -42
  613. package/src/tools/host-filesystem/transfer.ts +4 -3
  614. package/src/tools/host-filesystem/write.ts +3 -2
  615. package/src/tools/host-terminal/host-shell.ts +4 -3
  616. package/src/tools/network/script-proxy/index.ts +1 -10
  617. package/src/tools/permission-checker.ts +66 -1
  618. package/src/tools/skills/sandbox-runner.ts +1 -6
  619. package/src/tools/skills/skill-tool-factory.ts +32 -0
  620. package/src/tools/terminal/safe-env.ts +1 -0
  621. package/src/tools/terminal/shell.ts +2 -78
  622. package/src/tools/types.ts +12 -39
  623. package/src/tts/__tests__/provider-catalog.test.ts +2 -2
  624. package/src/tts/provider-catalog.ts +1 -1
  625. package/src/usage/actors.ts +2 -1
  626. package/src/usage/attribution.ts +185 -0
  627. package/src/usage/pricing.ts +166 -0
  628. package/src/usage/types.ts +14 -0
  629. package/src/util/json.ts +13 -0
  630. package/src/util/logger.ts +3 -3
  631. package/src/util/pricing.ts +50 -3
  632. package/src/work-items/work-item-runner.ts +15 -42
  633. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
  634. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
  635. package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
  636. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
  637. package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
  638. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
  639. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
  640. package/src/workspace/migrations/registry.ts +8 -0
  641. package/src/workspace/provider-commit-message-generator.ts +3 -3
  642. package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
  643. package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
  644. package/src/__tests__/secret-detection-handler.test.ts +0 -67
  645. package/src/__tests__/secret-scanner-executor.test.ts +0 -450
  646. package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
  647. package/src/__tests__/terminal-sandbox.test.ts +0 -374
  648. package/src/__tests__/tool-notification-listener.test.ts +0 -65
  649. package/src/context/__tests__/microcompact.test.ts +0 -805
  650. package/src/context/microcompact.ts +0 -443
  651. package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
  652. package/src/events/tool-notification-listener.ts +0 -17
  653. package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
  654. package/src/memory/v2/__tests__/edges.test.ts +0 -435
  655. package/src/memory/v2/edges.ts +0 -217
  656. package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
  657. package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
  658. package/src/runtime/__tests__/client-registry.test.ts +0 -271
  659. package/src/runtime/chrome-extension-registry.ts +0 -368
  660. package/src/runtime/client-registry.ts +0 -254
  661. package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
  662. package/src/tools/secret-detection-handler.ts +0 -269
  663. package/src/tools/terminal/backends/native.ts +0 -327
  664. package/src/tools/terminal/backends/types.ts +0 -37
  665. package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
  666. package/src/tools/terminal/sandbox.ts +0 -40
@@ -25,8 +25,13 @@ import type {
25
25
  TurnInterfaceContext,
26
26
  } from "../channels/types.js";
27
27
  import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
28
+ import {
29
+ contextWindowConfigFromEffective,
30
+ resolveEffectiveContextWindow,
31
+ } from "../config/llm-context-resolution.js";
28
32
  import { getConfig } from "../config/loader.js";
29
33
  import type { LLMCallSite } from "../config/schemas/llm.js";
34
+ import type { ContextWindowConfig } from "../config/types.js";
30
35
  import {
31
36
  derefToolResultReReads,
32
37
  postTurnTruncateToolResults,
@@ -57,6 +62,7 @@ import {
57
62
  getMessageById,
58
63
  provenanceFromTrustContext,
59
64
  updateConversationContextWindow,
65
+ updateConversationSlackContextWatermark,
60
66
  } from "../memory/conversation-crud.js";
61
67
  import { getResolvedConversationDirPath } from "../memory/conversation-directories.js";
62
68
  import { syncMessageToDisk } from "../memory/conversation-disk-view.js";
@@ -68,6 +74,7 @@ import type { ConversationGraphMemory } from "../memory/graph/conversation-graph
68
74
  import { recordMemoryRecallLog } from "../memory/memory-recall-log-store.js";
69
75
  import { PKB_WORKSPACE_SCOPE } from "../memory/pkb/types.js";
70
76
  import type { QdrantSparseVector } from "../memory/qdrant-client.js";
77
+ import { readMemoryV2StaticContent } from "../memory/v2/static-context.js";
71
78
  import type { PermissionPrompter } from "../permissions/prompter.js";
72
79
  import { defaultCompactionTerminal } from "../plugins/defaults/compaction.js";
73
80
  import { defaultHistoryRepairTerminal } from "../plugins/defaults/history-repair.js";
@@ -155,10 +162,12 @@ import {
155
162
  buildUnifiedTurnContextBlock,
156
163
  findLastInjectedNowContent,
157
164
  getPkbAutoInjectList,
165
+ getSlackCompactionWatermarkForPrefix,
158
166
  inboundActorContextFromTrust,
159
167
  inboundActorContextFromTrustContext,
160
168
  loadSlackActiveThreadFocusBlock,
161
- loadSlackChronologicalMessages,
169
+ loadSlackChronologicalContext,
170
+ type SlackChronologicalContext,
162
171
  stripInjectionsForCompaction,
163
172
  } from "./conversation-runtime-assembly.js";
164
173
  import type { SkillProjectionCache } from "./conversation-skill-tools.js";
@@ -484,6 +493,7 @@ export interface AgentLoopConversationContext {
484
493
  assistantId?: string;
485
494
  voiceCallControlPrompt?: string;
486
495
  transportHints?: string[];
496
+ slackRuntimeContextNotice?: string;
487
497
 
488
498
  readonly coreToolNames: Set<string>;
489
499
  allowedToolNames?: Set<string>;
@@ -640,6 +650,22 @@ export async function runAgentLoopImpl(
640
650
  options?.overrideProfile ??
641
651
  getConversationOverrideProfileFromRow(turnStartConversation);
642
652
 
653
+ const config = getConfig();
654
+ const effectiveContextWindow = resolveEffectiveContextWindow({
655
+ llm: config.llm,
656
+ callSite: turnCallSite,
657
+ overrideProfile: turnOverrideProfile ?? undefined,
658
+ });
659
+ const turnContextWindowConfig = contextWindowConfigFromEffective(
660
+ config.llm.default.contextWindow,
661
+ effectiveContextWindow,
662
+ );
663
+ (
664
+ ctx.contextWindowManager as ContextWindowManager & {
665
+ updateConfig?: (config: ContextWindowConfig) => void;
666
+ }
667
+ ).updateConfig?.(turnContextWindowConfig);
668
+
643
669
  // Snapshot for `createToolExecutor` to read into `ToolContext.overrideProfile`
644
670
  // — see field doc on `AgentLoopConversationContext` for why the tool needs
645
671
  // it (nested subagent spawns can't recover the override from a row read).
@@ -776,8 +802,138 @@ export async function runAgentLoopImpl(
776
802
  const isFirstMessage = ctx.messages.length === 1;
777
803
  let shouldInjectWorkspace = isFirstMessage;
778
804
  let compactedThisTurn = false;
805
+ let slackCompactedThisTurn = false;
806
+ const isSlackConversation = ctx.channelCapabilities?.channel === "slack";
807
+ let currentSlackContextSummary =
808
+ turnStartConversation?.contextSummary ?? null;
809
+ let currentSlackContextCompactedMessageCount =
810
+ turnStartConversation?.contextCompactedMessageCount ?? 0;
811
+ let currentSlackContextCompactionWatermarkTs =
812
+ turnStartConversation?.slackContextCompactionWatermarkTs ?? null;
813
+ const loadCurrentSlackChronologicalContext =
814
+ (): SlackChronologicalContext | null => {
815
+ if (!isSlackConversation) return null;
816
+ return loadSlackChronologicalContext(
817
+ ctx.conversationId,
818
+ ctx.channelCapabilities!,
819
+ {
820
+ trustClass: ctx.trustContext?.trustClass,
821
+ contextSummary: currentSlackContextSummary,
822
+ contextCompactedMessageCount:
823
+ currentSlackContextCompactedMessageCount,
824
+ slackContextCompactionWatermarkTs:
825
+ currentSlackContextCompactionWatermarkTs,
826
+ },
827
+ );
828
+ };
829
+ let slackChronologicalContext: SlackChronologicalContext | null =
830
+ loadCurrentSlackChronologicalContext();
831
+ const messagesForStartOfTurnCompaction =
832
+ slackChronologicalContext?.messages ?? ctx.messages;
833
+ const getSlackProvenanceContextForCompactionBasis = (
834
+ messages: Message[],
835
+ compactedMessages: number,
836
+ ): SlackChronologicalContext | null => {
837
+ if (!isSlackConversation || compactedMessages <= 0) return null;
838
+ const context = slackChronologicalContext;
839
+ if (!context) return null;
840
+ if (messages !== context.messages) return null;
841
+ const end = context.compactableStartIndex + compactedMessages;
842
+ if (
843
+ end <= context.compactableStartIndex ||
844
+ end > context.renderedMessages.length ||
845
+ context.renderedMessages.length !== context.messages.length
846
+ ) {
847
+ return null;
848
+ }
849
+ return context;
850
+ };
851
+ const projectSlackProvenanceAfterCompaction = (
852
+ context: SlackChronologicalContext | null,
853
+ compactedBasis: Message[] | undefined,
854
+ result: Awaited<ReturnType<typeof ctx.contextWindowManager.maybeCompact>>,
855
+ ): SlackChronologicalContext | null => {
856
+ if (
857
+ !isSlackConversation ||
858
+ !context ||
859
+ !compactedBasis ||
860
+ compactedBasis !== context.messages ||
861
+ result.compactedMessages <= 0 ||
862
+ result.messages.length === 0 ||
863
+ context.renderedMessages.length !== context.messages.length
864
+ ) {
865
+ return null;
866
+ }
779
867
 
780
- const compactCheck = ctx.contextWindowManager.shouldCompact(ctx.messages);
868
+ const keptStart =
869
+ context.compactableStartIndex + result.compactedMessages;
870
+ if (keptStart > context.renderedMessages.length) {
871
+ return null;
872
+ }
873
+
874
+ const retainedRenderedMessages =
875
+ context.renderedMessages.slice(keptStart);
876
+ const retainedResultMessages = result.messages.slice(1);
877
+ if (retainedResultMessages.length !== retainedRenderedMessages.length) {
878
+ return null;
879
+ }
880
+ for (let index = 0; index < retainedResultMessages.length; index++) {
881
+ if (
882
+ retainedResultMessages[index] !==
883
+ retainedRenderedMessages[index]!.message
884
+ ) {
885
+ return null;
886
+ }
887
+ }
888
+
889
+ return {
890
+ renderedMessages: [
891
+ {
892
+ message: result.messages[0]!,
893
+ sourceChannelTs: null,
894
+ },
895
+ ...retainedRenderedMessages,
896
+ ],
897
+ messages: result.messages,
898
+ compactableStartIndex: 1,
899
+ };
900
+ };
901
+ const applySuccessfulCompaction = (
902
+ result: Awaited<ReturnType<typeof ctx.contextWindowManager.maybeCompact>>,
903
+ compactedBasis?: Message[],
904
+ ) => {
905
+ const provenanceContext = compactedBasis
906
+ ? getSlackProvenanceContextForCompactionBasis(
907
+ compactedBasis,
908
+ result.compactedMessages,
909
+ )
910
+ : null;
911
+ const slackWatermarkTs = getSlackCompactionWatermarkForPrefix(
912
+ provenanceContext,
913
+ result.compactedMessages,
914
+ );
915
+ applyCompactionResult(ctx, result, onEvent, reqId, {
916
+ slackContextCompactionWatermarkTs: slackWatermarkTs,
917
+ });
918
+ currentSlackContextSummary = result.summaryText;
919
+ currentSlackContextCompactedMessageCount =
920
+ ctx.contextCompactedMessageCount;
921
+ if (slackWatermarkTs) {
922
+ currentSlackContextCompactionWatermarkTs = slackWatermarkTs;
923
+ }
924
+ if (isSlackConversation) {
925
+ slackCompactedThisTurn = true;
926
+ }
927
+ slackChronologicalContext = projectSlackProvenanceAfterCompaction(
928
+ provenanceContext,
929
+ compactedBasis,
930
+ result,
931
+ );
932
+ };
933
+
934
+ const compactCheck = ctx.contextWindowManager.shouldCompact(
935
+ messagesForStartOfTurnCompaction,
936
+ );
781
937
  // Skip auto-compaction while the circuit breaker is open. Force paths
782
938
  // and user-initiated /compact bypass this check.
783
939
  const autoCompactAllowed = !(await isCompactionCircuitOpen(ctx));
@@ -789,6 +945,13 @@ export async function runAgentLoopImpl(
789
945
  reqId,
790
946
  );
791
947
  }
948
+ const compactionOptions = {
949
+ lastCompactedAt: ctx.contextCompactedAt ?? undefined,
950
+ precomputedEstimate: compactCheck.estimatedTokens,
951
+ conversationOriginChannel:
952
+ getConversationOriginChannel(ctx.conversationId) ?? undefined,
953
+ overrideProfile: turnOverrideProfile ?? null,
954
+ };
792
955
  let compacted: Awaited<
793
956
  ReturnType<typeof ctx.contextWindowManager.maybeCompact>
794
957
  > | null = null;
@@ -800,14 +963,9 @@ export async function runAgentLoopImpl(
800
963
  (args) =>
801
964
  defaultCompactionTerminal(args, buildPluginTurnContext(ctx, reqId)),
802
965
  {
803
- messages: ctx.messages,
966
+ messages: messagesForStartOfTurnCompaction,
804
967
  signal: abortController.signal,
805
- options: {
806
- lastCompactedAt: ctx.contextCompactedAt ?? undefined,
807
- precomputedEstimate: compactCheck.estimatedTokens,
808
- conversationOriginChannel:
809
- getConversationOriginChannel(ctx.conversationId) ?? undefined,
810
- },
968
+ options: compactionOptions,
811
969
  },
812
970
  buildPluginTurnContext(ctx, reqId),
813
971
  DEFAULT_TIMEOUTS.compaction,
@@ -841,7 +999,7 @@ export async function runAgentLoopImpl(
841
999
  await trackCompactionOutcome(ctx, compacted.summaryFailed, onEvent);
842
1000
  }
843
1001
  if (compacted?.compacted) {
844
- applyCompactionResult(ctx, compacted, onEvent, reqId);
1002
+ applySuccessfulCompaction(compacted, messagesForStartOfTurnCompaction);
845
1003
  shouldInjectWorkspace = true;
846
1004
  if (compacted.compactedPersistedMessages > 0) {
847
1005
  compactedThisTurn = true;
@@ -1170,6 +1328,15 @@ export async function runAgentLoopImpl(
1170
1328
  const pkbContext = shouldInjectNowAndPkb ? currentPkbContent : null;
1171
1329
  const pkbActive = currentPkbContent !== null;
1172
1330
 
1331
+ // V2 static memory block (essentials/threads/recent/buffer). Same
1332
+ // first-turn / post-compaction cadence as PKB — `readMemoryV2StaticContent`
1333
+ // self-gates on the v2 flag + config, returning null when v2 is off.
1334
+ // Skip the file reads entirely on non-injection turns.
1335
+ const currentMemoryV2Static = shouldInjectNowAndPkb
1336
+ ? readMemoryV2StaticContent()
1337
+ : null;
1338
+ const memoryV2Static = currentMemoryV2Static;
1339
+
1173
1340
  // PKB relevance-hint inputs. Resolved once per turn and reused across
1174
1341
  // re-injections so post-compaction rebuilds pick up fresh hints against
1175
1342
  // the updated conversation history.
@@ -1198,14 +1365,25 @@ export async function runAgentLoopImpl(
1198
1365
  // model sees one channel-wide view instead of the gateway's per-turn
1199
1366
  // hints. DMs render as a flat sequence (no thread tags), channels
1200
1367
  // include sibling threads.
1201
- const isSlackConversation = ctx.channelCapabilities?.channel === "slack";
1202
- const slackChronologicalMessages = isSlackConversation
1203
- ? loadSlackChronologicalMessages(
1204
- ctx.conversationId,
1205
- ctx.channelCapabilities!,
1206
- { trustClass: ctx.trustContext?.trustClass },
1207
- )
1208
- : null;
1368
+ const slackConversationForInjection = isSlackConversation
1369
+ ? (getConversation(ctx.conversationId) ?? turnStartConversation)
1370
+ : turnStartConversation;
1371
+ if (isSlackConversation && !slackCompactedThisTurn) {
1372
+ slackChronologicalContext ??= loadSlackChronologicalContext(
1373
+ ctx.conversationId,
1374
+ ctx.channelCapabilities!,
1375
+ {
1376
+ trustClass: ctx.trustContext?.trustClass,
1377
+ contextSummary: slackConversationForInjection?.contextSummary,
1378
+ contextCompactedMessageCount:
1379
+ slackConversationForInjection?.contextCompactedMessageCount,
1380
+ slackContextCompactionWatermarkTs:
1381
+ slackConversationForInjection?.slackContextCompactionWatermarkTs,
1382
+ },
1383
+ );
1384
+ }
1385
+ const slackChronologicalMessages =
1386
+ slackChronologicalContext?.messages ?? null;
1209
1387
 
1210
1388
  // Active-thread focus block: when the inbound user message belongs to
1211
1389
  // a Slack thread, append a non-persisted `<active_thread>` tail block
@@ -1218,7 +1396,13 @@ export async function runAgentLoopImpl(
1218
1396
  ? loadSlackActiveThreadFocusBlock(
1219
1397
  ctx.conversationId,
1220
1398
  ctx.channelCapabilities!,
1221
- { trustClass: ctx.trustContext?.trustClass },
1399
+ {
1400
+ trustClass: ctx.trustContext?.trustClass,
1401
+ contextCompactedMessageCount:
1402
+ slackConversationForInjection?.contextCompactedMessageCount,
1403
+ slackContextCompactionWatermarkTs:
1404
+ slackConversationForInjection?.slackContextCompactionWatermarkTs,
1405
+ },
1222
1406
  )
1223
1407
  : null;
1224
1408
 
@@ -1248,9 +1432,11 @@ export async function runAgentLoopImpl(
1248
1432
  pkbAutoInjectList,
1249
1433
  pkbRoot,
1250
1434
  pkbWorkingDir: pkbActive ? ctx.workingDir : undefined,
1435
+ memoryV2Static,
1251
1436
  nowScratchpad,
1252
1437
  voiceCallControlPrompt: ctx.voiceCallControlPrompt ?? null,
1253
1438
  transportHints: ctx.transportHints ?? null,
1439
+ slackRuntimeContextNotice: ctx.slackRuntimeContextNotice ?? null,
1254
1440
  isNonInteractive: !isInteractiveResolved,
1255
1441
  subagentStatusBlock,
1256
1442
  slackChronologicalMessages,
@@ -1329,9 +1515,8 @@ export async function runAgentLoopImpl(
1329
1515
  // After runtime injections are applied, estimate the prompt token count
1330
1516
  // and proactively invoke the reducer if already above budget. This avoids
1331
1517
  // a wasted provider round-trip that would just fail with context_too_large.
1332
- const config = getConfig();
1333
- const overflowRecovery = config.llm.default.contextWindow.overflowRecovery;
1334
- const providerMaxTokens = config.llm.default.contextWindow.maxInputTokens;
1518
+ const overflowRecovery = effectiveContextWindow.overflowRecovery;
1519
+ const providerMaxTokens = effectiveContextWindow.maxInputTokens;
1335
1520
  // Widen safety margin for large conversations where estimation error
1336
1521
  // compounds across many messages with tool results.
1337
1522
  const baseSafetyMargin = overflowRecovery.safetyMarginRatio;
@@ -1408,12 +1593,14 @@ export async function runAgentLoopImpl(
1408
1593
  // injection reassembly, token re-estimation). Registered plugins that
1409
1594
  // wrap the `overflowReduce` slot see each iteration through their own
1410
1595
  // middleware `next` callback.
1596
+ const messagesForPreflightOverflowReduction =
1597
+ slackChronologicalContext?.messages ?? ctx.messages;
1411
1598
  const overflowArgs: OverflowReduceArgs = {
1412
- messages: ctx.messages,
1599
+ messages: messagesForPreflightOverflowReduction,
1413
1600
  runMessages,
1414
1601
  systemPrompt: ctx.systemPrompt,
1415
1602
  providerName: estimationProviderName,
1416
- contextWindow: config.llm.default.contextWindow,
1603
+ contextWindow: turnContextWindowConfig,
1417
1604
  preflightBudget,
1418
1605
  toolTokenBudget,
1419
1606
  maxAttempts: overflowRecovery.maxAttempts,
@@ -1444,7 +1631,10 @@ export async function runAgentLoopImpl(
1444
1631
  {
1445
1632
  messages: msgs,
1446
1633
  signal,
1447
- options: opts,
1634
+ options: {
1635
+ ...(opts ?? {}),
1636
+ overrideProfile: turnOverrideProfile ?? null,
1637
+ },
1448
1638
  },
1449
1639
  buildPluginTurnContext(ctx, reqId),
1450
1640
  DEFAULT_TIMEOUTS.compaction,
@@ -1486,7 +1676,7 @@ export async function runAgentLoopImpl(
1486
1676
  reqId,
1487
1677
  );
1488
1678
  },
1489
- onCompactionResult: async (result) => {
1679
+ onCompactionResult: async (result, compactedBasis) => {
1490
1680
  // Track circuit-breaker state whenever the reducer invoked
1491
1681
  // compaction. The reducer's forced_compaction tier uses
1492
1682
  // force:true, so it bypasses the open-circuit check, but we
@@ -1500,7 +1690,7 @@ export async function runAgentLoopImpl(
1500
1690
  await trackCompactionOutcome(ctx, result.summaryFailed, onEvent);
1501
1691
  }
1502
1692
  if (result.compacted) {
1503
- applyCompactionResult(ctx, result, onEvent, reqId);
1693
+ applySuccessfulCompaction(result, compactedBasis);
1504
1694
  shouldInjectWorkspace = true;
1505
1695
  }
1506
1696
  },
@@ -1528,6 +1718,7 @@ export async function runAgentLoopImpl(
1528
1718
  const injection = await applyRuntimeInjections(reducedMessages, {
1529
1719
  ...injectionOpts,
1530
1720
  ...(stepCompacted && { pkbContext: currentPkbContent }),
1721
+ ...(stepCompacted && { memoryV2Static: currentMemoryV2Static }),
1531
1722
  ...(stepCompacted && { nowScratchpad: currentNowContent }),
1532
1723
  workspaceTopLevelContext: shouldInjectWorkspace
1533
1724
  ? ctx.workspaceTopLevelContext
@@ -1725,6 +1916,7 @@ export async function runAgentLoopImpl(
1725
1916
  turnCallSite,
1726
1917
  loopTurnCtx,
1727
1918
  turnOverrideProfile,
1919
+ effectiveContextWindow.maxInputTokens,
1728
1920
  );
1729
1921
 
1730
1922
  rlog.info(
@@ -1791,6 +1983,7 @@ export async function runAgentLoopImpl(
1791
1983
  targetInputTokensOverride: preflightBudget,
1792
1984
  conversationOriginChannel:
1793
1985
  getConversationOriginChannel(ctx.conversationId) ?? undefined,
1986
+ overrideProfile: turnOverrideProfile ?? null,
1794
1987
  },
1795
1988
  },
1796
1989
  buildPluginTurnContext(ctx, reqId),
@@ -1826,7 +2019,7 @@ export async function runAgentLoopImpl(
1826
2019
  );
1827
2020
  }
1828
2021
  if (midLoopCompact.compacted) {
1829
- applyCompactionResult(ctx, midLoopCompact, onEvent, reqId);
2022
+ applySuccessfulCompaction(midLoopCompact, rawHistory);
1830
2023
  reducerCompacted = true;
1831
2024
  shouldInjectWorkspace = true;
1832
2025
  }
@@ -1838,6 +2031,7 @@ export async function runAgentLoopImpl(
1838
2031
  const injection = await applyRuntimeInjections(ctx.messages, {
1839
2032
  ...injectionOpts,
1840
2033
  pkbContext: currentPkbContent,
2034
+ memoryV2Static: currentMemoryV2Static,
1841
2035
  nowScratchpad: currentNowContent,
1842
2036
  workspaceTopLevelContext: shouldInjectWorkspace
1843
2037
  ? ctx.workspaceTopLevelContext
@@ -1875,6 +2069,7 @@ export async function runAgentLoopImpl(
1875
2069
  turnCallSite,
1876
2070
  loopTurnCtx,
1877
2071
  turnOverrideProfile,
2072
+ effectiveContextWindow.maxInputTokens,
1878
2073
  );
1879
2074
  }
1880
2075
 
@@ -1931,6 +2126,7 @@ export async function runAgentLoopImpl(
1931
2126
  turnCallSite,
1932
2127
  loopTurnCtx,
1933
2128
  turnOverrideProfile,
2129
+ effectiveContextWindow.maxInputTokens,
1934
2130
  );
1935
2131
 
1936
2132
  if (state.orderingErrorDetected) {
@@ -2036,18 +2232,22 @@ export async function runAgentLoopImpl(
2036
2232
  "assistant_turn",
2037
2233
  reqId,
2038
2234
  );
2235
+ const convergenceCompactionBasis = ctx.messages;
2039
2236
  const step = await reduceContextOverflow(
2040
- ctx.messages,
2237
+ convergenceCompactionBasis,
2041
2238
  {
2042
2239
  providerName: estimationProviderName,
2043
2240
  systemPrompt: ctx.systemPrompt,
2044
- contextWindow: config.llm.default.contextWindow,
2241
+ contextWindow: turnContextWindowConfig,
2045
2242
  targetTokens: correctedTarget,
2046
2243
  toolTokenBudget,
2047
2244
  },
2048
2245
  reducerState,
2049
2246
  (msgs, signal, opts) =>
2050
- ctx.contextWindowManager.maybeCompact(msgs, signal!, opts),
2247
+ ctx.contextWindowManager.maybeCompact(msgs, signal!, {
2248
+ ...(opts ?? {}),
2249
+ overrideProfile: turnOverrideProfile ?? null,
2250
+ }),
2051
2251
  abortController.signal,
2052
2252
  );
2053
2253
 
@@ -2071,7 +2271,10 @@ export async function runAgentLoopImpl(
2071
2271
  }
2072
2272
 
2073
2273
  if (step.compactionResult?.compacted) {
2074
- applyCompactionResult(ctx, step.compactionResult, onEvent, reqId);
2274
+ applySuccessfulCompaction(
2275
+ step.compactionResult,
2276
+ convergenceCompactionBasis,
2277
+ );
2075
2278
  shouldInjectWorkspace = true;
2076
2279
  reducerCompacted = true;
2077
2280
  }
@@ -2082,6 +2285,7 @@ export async function runAgentLoopImpl(
2082
2285
  const injection = await applyRuntimeInjections(ctx.messages, {
2083
2286
  ...injectionOpts,
2084
2287
  pkbContext: currentPkbContent,
2288
+ memoryV2Static: convergenceStripped ? currentMemoryV2Static : null,
2085
2289
  nowScratchpad: convergenceStripped ? currentNowContent : null,
2086
2290
  workspaceTopLevelContext: shouldInjectWorkspace
2087
2291
  ? ctx.workspaceTopLevelContext
@@ -2118,6 +2322,7 @@ export async function runAgentLoopImpl(
2118
2322
  turnCallSite,
2119
2323
  loopTurnCtx,
2120
2324
  turnOverrideProfile,
2325
+ effectiveContextWindow.maxInputTokens,
2121
2326
  );
2122
2327
 
2123
2328
  // If the rerun still yields at checkpoint, the turn is still
@@ -2195,6 +2400,7 @@ export async function runAgentLoopImpl(
2195
2400
  force: true,
2196
2401
  minKeepRecentUserTurns: 0,
2197
2402
  targetInputTokensOverride: correctedTarget,
2403
+ overrideProfile: turnOverrideProfile ?? null,
2198
2404
  },
2199
2405
  },
2200
2406
  buildPluginTurnContext(ctx, reqId),
@@ -2231,7 +2437,7 @@ export async function runAgentLoopImpl(
2231
2437
  );
2232
2438
  }
2233
2439
  if (emergencyCompact?.compacted) {
2234
- applyCompactionResult(ctx, emergencyCompact, onEvent, reqId);
2440
+ applySuccessfulCompaction(emergencyCompact, ctx.messages);
2235
2441
  reducerCompacted = true;
2236
2442
  shouldInjectWorkspace = true;
2237
2443
  }
@@ -2241,6 +2447,7 @@ export async function runAgentLoopImpl(
2241
2447
  const injection = await applyRuntimeInjections(ctx.messages, {
2242
2448
  ...injectionOpts,
2243
2449
  pkbContext: currentPkbContent,
2450
+ memoryV2Static: convergenceStripped ? currentMemoryV2Static : null,
2244
2451
  nowScratchpad: convergenceStripped ? currentNowContent : null,
2245
2452
  workspaceTopLevelContext: shouldInjectWorkspace
2246
2453
  ? ctx.workspaceTopLevelContext
@@ -2276,6 +2483,7 @@ export async function runAgentLoopImpl(
2276
2483
  turnCallSite,
2277
2484
  loopTurnCtx,
2278
2485
  turnOverrideProfile,
2486
+ effectiveContextWindow.maxInputTokens,
2279
2487
  );
2280
2488
  }
2281
2489
  // action === "fail_gracefully" falls through to the final error below
@@ -2462,7 +2670,11 @@ export async function runAgentLoopImpl(
2462
2670
  state.exchangeLlmCallCount,
2463
2671
  {
2464
2672
  tokens: state.lastCallInputTokens,
2465
- maxTokens: config.llm.default.contextWindow.maxInputTokens,
2673
+ maxTokens: effectiveContextWindow.maxInputTokens,
2674
+ },
2675
+ {
2676
+ callSite: turnCallSite,
2677
+ overrideProfile: turnOverrideProfile ?? null,
2466
2678
  },
2467
2679
  );
2468
2680
 
@@ -2718,7 +2930,12 @@ export async function runAgentLoopImpl(
2718
2930
  errorCode: classified.code,
2719
2931
  },
2720
2932
  });
2721
- onEvent({ type: "error", message: classified.userMessage });
2933
+ onEvent({
2934
+ type: "error",
2935
+ conversationId: ctx.conversationId,
2936
+ code: classified.code,
2937
+ message: classified.userMessage,
2938
+ });
2722
2939
  onEvent(buildConversationErrorMessage(ctx.conversationId, classified));
2723
2940
  }
2724
2941
  } finally {
@@ -2769,6 +2986,7 @@ export async function runAgentLoopImpl(
2769
2986
  ctx.allowedToolNames = undefined;
2770
2987
  ctx.preactivatedSkillIds = undefined;
2771
2988
  ctx.currentTurnOverrideProfile = undefined;
2989
+ ctx.slackRuntimeContextNotice = undefined;
2772
2990
  // Channel command intents (e.g. Telegram /start) are single-turn metadata.
2773
2991
  // Clear at turn end so they never leak into subsequent unrelated messages.
2774
2992
  ctx.commandIntent = undefined;
@@ -2809,6 +3027,10 @@ function emitUsage(
2809
3027
  providerName?: string,
2810
3028
  llmCallCount = 1,
2811
3029
  contextWindow?: { tokens: number; maxTokens: number },
3030
+ attribution?: {
3031
+ callSite: LLMCallSite | null;
3032
+ overrideProfile?: string | null;
3033
+ },
2812
3034
  ): void {
2813
3035
  recordUsage(
2814
3036
  {
@@ -2827,6 +3049,7 @@ function emitUsage(
2827
3049
  rawResponse,
2828
3050
  llmCallCount,
2829
3051
  contextWindow,
3052
+ attribution,
2830
3053
  );
2831
3054
  }
2832
3055
 
@@ -2877,19 +3100,32 @@ export function applyCompactionResult(
2877
3100
  summaryCacheCreationInputTokens?: number;
2878
3101
  summaryCacheReadInputTokens?: number;
2879
3102
  summaryRawResponses?: unknown[];
3103
+ summaryCallSite?: LLMCallSite;
3104
+ summaryOverrideProfile?: string | null;
2880
3105
  },
2881
3106
  onEvent: (msg: ServerMessage) => void,
2882
3107
  reqId: string | null,
3108
+ options: {
3109
+ slackContextCompactionWatermarkTs?: string | null;
3110
+ } = {},
2883
3111
  ): void {
2884
3112
  ctx.messages = result.messages;
2885
3113
  ctx.contextCompactedMessageCount += result.compactedPersistedMessages;
2886
- ctx.contextCompactedAt = Date.now();
3114
+ const compactedAt = Date.now();
3115
+ ctx.contextCompactedAt = compactedAt;
2887
3116
  ctx.graphMemory.onCompacted(result.compactedPersistedMessages);
2888
3117
  updateConversationContextWindow(
2889
3118
  ctx.conversationId,
2890
3119
  result.summaryText,
2891
3120
  ctx.contextCompactedMessageCount,
2892
3121
  );
3122
+ if (options.slackContextCompactionWatermarkTs) {
3123
+ updateConversationSlackContextWatermark(
3124
+ ctx.conversationId,
3125
+ options.slackContextCompactionWatermarkTs,
3126
+ compactedAt,
3127
+ );
3128
+ }
2893
3129
  enqueueAutoAnalysisOnCompaction(
2894
3130
  ctx.conversationId,
2895
3131
  ctx.trustContext?.trustClass,
@@ -2924,6 +3160,11 @@ export function applyCompactionResult(
2924
3160
  collapseRawResponses(result.summaryRawResponses),
2925
3161
  undefined /* providerName */,
2926
3162
  1 /* llmCallCount */,
3163
+ undefined /* contextWindow */,
3164
+ {
3165
+ callSite: result.summaryCallSite ?? null,
3166
+ overrideProfile: result.summaryOverrideProfile ?? null,
3167
+ },
2927
3168
  );
2928
3169
  }
2929
3170
 
@@ -350,6 +350,7 @@ export function consolidateAssistantMessages(
350
350
  export interface HistoryConversationContext {
351
351
  readonly conversationId: string;
352
352
  readonly traceEmitter: TraceEmitter;
353
+ /** @internal */ sendToClient: (msg: ServerMessage) => void;
353
354
  messages: Message[];
354
355
  processing: boolean;
355
356
  abortController: AbortController | null;
@@ -357,7 +358,7 @@ export interface HistoryConversationContext {
357
358
  runAgentLoop(
358
359
  content: string,
359
360
  userMessageId: string,
360
- onEvent: (msg: ServerMessage) => void,
361
+ onEvent?: (msg: ServerMessage) => void,
361
362
  options?: {
362
363
  isUserMessage?: boolean;
363
364
  titleText?: string;
@@ -414,11 +415,10 @@ export function undo(conversation: HistoryConversationContext): number {
414
415
  */
415
416
  export async function regenerate(
416
417
  conversation: HistoryConversationContext,
417
- onEvent: (msg: ServerMessage) => void,
418
418
  requestId?: string,
419
419
  ): Promise<void> {
420
420
  if (conversation.processing) {
421
- onEvent({ type: "error", message: "Cannot regenerate while processing" });
421
+ conversation.sendToClient({ type: "error", conversationId: conversation.conversationId, message: "Cannot regenerate while processing" });
422
422
  if (requestId) {
423
423
  conversation.traceEmitter.emit(
424
424
  "request_error",
@@ -437,7 +437,7 @@ export async function regenerate(
437
437
  // assistant's exchange that we want to regenerate.
438
438
  const lastUserIdx = findLastUndoableUserMessageIndex(conversation.messages);
439
439
  if (lastUserIdx === -1) {
440
- onEvent({ type: "error", message: "No messages to regenerate" });
440
+ conversation.sendToClient({ type: "error", conversationId: conversation.conversationId, message: "No messages to regenerate" });
441
441
  if (requestId) {
442
442
  conversation.traceEmitter.emit(
443
443
  "request_error",
@@ -454,7 +454,7 @@ export async function regenerate(
454
454
 
455
455
  // There must be at least one message after the user message (the assistant reply).
456
456
  if (lastUserIdx >= conversation.messages.length - 1) {
457
- onEvent({ type: "error", message: "No assistant response to regenerate" });
457
+ conversation.sendToClient({ type: "error", conversationId: conversation.conversationId, message: "No assistant response to regenerate" });
458
458
  if (requestId) {
459
459
  conversation.traceEmitter.emit(
460
460
  "request_error",
@@ -497,7 +497,7 @@ export async function regenerate(
497
497
  }
498
498
 
499
499
  if (dbUserMsgIdx === -1) {
500
- onEvent({ type: "error", message: "No user message found in DB" });
500
+ conversation.sendToClient({ type: "error", conversationId: conversation.conversationId, message: "No user message found in DB" });
501
501
  if (requestId) {
502
502
  conversation.traceEmitter.emit(
503
503
  "request_error",
@@ -546,7 +546,7 @@ export async function regenerate(
546
546
  .join("");
547
547
 
548
548
  // Notify client that the old response has been removed.
549
- onEvent({
549
+ conversation.sendToClient({
550
550
  type: "undo_complete",
551
551
  removedCount: messagesToDelete.length,
552
552
  conversationId: conversation.conversationId,
@@ -572,7 +572,7 @@ export async function regenerate(
572
572
  // not await the agent loop. Emit a structured trace event so the
573
573
  // observability contract is preserved on those paths too.
574
574
  void conversation
575
- .runAgentLoop(content, existingUserMessageId, onEvent, {
575
+ .runAgentLoop(content, existingUserMessageId, undefined, {
576
576
  isUserMessage: true,
577
577
  })
578
578
  .catch((err) => {