@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
@@ -12,7 +12,6 @@ describe("AssistantEvent shape", () => {
12
12
  test("accepts a minimal valid event", () => {
13
13
  const event: AssistantEvent = {
14
14
  id: "evt_001",
15
- assistantId: "ast_123",
16
15
  emittedAt: "2026-02-18T21:20:00.000Z",
17
16
  message: {
18
17
  type: "assistant_text_delta",
@@ -22,7 +21,6 @@ describe("AssistantEvent shape", () => {
22
21
  };
23
22
 
24
23
  expect(event.id).toBe("evt_001");
25
- expect(event.assistantId).toBe("ast_123");
26
24
  expect(event.conversationId).toBeUndefined();
27
25
  expect(event.emittedAt).toBe("2026-02-18T21:20:00.000Z");
28
26
  expect(event.message.type).toBe("assistant_text_delta");
@@ -31,7 +29,6 @@ describe("AssistantEvent shape", () => {
31
29
  test("accepts a full event with conversationId", () => {
32
30
  const event: AssistantEvent = {
33
31
  id: "evt_002",
34
- assistantId: "ast_123",
35
32
  conversationId: "conv_456",
36
33
  emittedAt: "2026-02-18T21:20:00.000Z",
37
34
  message: {
@@ -50,7 +47,6 @@ describe("AssistantEvent shape", () => {
50
47
  describe("formatSseFrame", () => {
51
48
  const baseEvent: AssistantEvent = {
52
49
  id: "evt_003",
53
- assistantId: "ast_abc",
54
50
  conversationId: "sess_xyz",
55
51
  emittedAt: "2026-02-18T00:00:00.000Z",
56
52
  message: {
@@ -80,7 +76,6 @@ describe("formatSseFrame", () => {
80
76
  ) as AssistantEvent;
81
77
 
82
78
  expect(parsed.id).toBe(baseEvent.id);
83
- expect(parsed.assistantId).toBe(baseEvent.assistantId);
84
79
  expect(parsed.conversationId).toBe(baseEvent.conversationId);
85
80
  expect(parsed.emittedAt).toBe(baseEvent.emittedAt);
86
81
  expect(parsed.message.type).toBe("assistant_text_delta");
@@ -32,9 +32,7 @@ mock.module("../config/loader.js", () => ({
32
32
  import { getDb } from "../memory/db-connection.js";
33
33
  import { initializeDb } from "../memory/db-init.js";
34
34
  import { AssistantEventHub } from "../runtime/assistant-event-hub.js";
35
- import {
36
- ServiceUnavailableError,
37
- } from "../runtime/routes/errors.js";
35
+ import { ServiceUnavailableError } from "../runtime/routes/errors.js";
38
36
  import { handleSubscribeAssistantEvents } from "../runtime/routes/events-routes.js";
39
37
 
40
38
  initializeDb();
@@ -54,14 +52,18 @@ describe("AssistantEventHub — subscriber cap", () => {
54
52
  const hub = new AssistantEventHub({ maxSubscribers: 1 });
55
53
  const evicted: string[] = [];
56
54
 
57
- const sub1 = hub.subscribe({ assistantId: "ast_1" }, () => {}, {
55
+ const sub1 = hub.subscribe({
56
+ type: "process",
57
+ callback: () => {},
58
58
  onEvict: () => evicted.push("sub1"),
59
59
  });
60
60
  expect(hub.subscriberCount()).toBe(1);
61
61
  expect(sub1.active).toBe(true);
62
62
 
63
63
  // Adding sub2 evicts sub1 to make room.
64
- const sub2 = hub.subscribe({ assistantId: "ast_1" }, () => {}, {
64
+ const sub2 = hub.subscribe({
65
+ type: "process",
66
+ callback: () => {},
65
67
  onEvict: () => evicted.push("sub2"),
66
68
  });
67
69
 
@@ -77,15 +79,21 @@ describe("AssistantEventHub — subscriber cap", () => {
77
79
  const hub = new AssistantEventHub({ maxSubscribers: 2 });
78
80
  const evicted: number[] = [];
79
81
 
80
- const sub1 = hub.subscribe({ assistantId: "ast_1" }, () => {}, {
82
+ const sub1 = hub.subscribe({
83
+ type: "process",
84
+ callback: () => {},
81
85
  onEvict: () => evicted.push(1),
82
86
  });
83
- const sub2 = hub.subscribe({ assistantId: "ast_1" }, () => {}, {
87
+ const sub2 = hub.subscribe({
88
+ type: "process",
89
+ callback: () => {},
84
90
  onEvict: () => evicted.push(2),
85
91
  });
86
92
 
87
93
  // 3rd subscriber evicts oldest (sub1)
88
- const sub3 = hub.subscribe({ assistantId: "ast_1" }, () => {}, {
94
+ const sub3 = hub.subscribe({
95
+ type: "process",
96
+ callback: () => {},
89
97
  onEvict: () => evicted.push(3),
90
98
  });
91
99
  expect(evicted).toEqual([1]);
@@ -93,7 +101,9 @@ describe("AssistantEventHub — subscriber cap", () => {
93
101
  expect(sub2.active).toBe(true);
94
102
 
95
103
  // 4th subscriber evicts next oldest (sub2)
96
- const sub4 = hub.subscribe({ assistantId: "ast_1" }, () => {}, {
104
+ const sub4 = hub.subscribe({
105
+ type: "process",
106
+ callback: () => {},
97
107
  onEvict: () => evicted.push(4),
98
108
  });
99
109
  expect(evicted).toEqual([1, 2]);
@@ -107,19 +117,28 @@ describe("AssistantEventHub — subscriber cap", () => {
107
117
 
108
118
  test("maxSubscribers: 0 throws RangeError (nothing to evict)", () => {
109
119
  const hub = new AssistantEventHub({ maxSubscribers: 0 });
110
- expect(() => hub.subscribe({ assistantId: "ast_1" }, () => {})).toThrow(
111
- RangeError,
112
- );
120
+ expect(() =>
121
+ hub.subscribe({
122
+ type: "process",
123
+ callback: () => {},
124
+ }),
125
+ ).toThrow(RangeError);
113
126
  });
114
127
 
115
128
  test("subscribe succeeds after disposal frees a slot", () => {
116
129
  const hub = new AssistantEventHub({ maxSubscribers: 1 });
117
- const sub = hub.subscribe({ assistantId: "ast_1" }, () => {});
130
+ const sub = hub.subscribe({
131
+ type: "process",
132
+ callback: () => {},
133
+ });
118
134
  sub.dispose();
119
135
 
120
136
  // Should not throw now that the slot is free.
121
137
  expect(() =>
122
- hub.subscribe({ assistantId: "ast_1" }, () => {}),
138
+ hub.subscribe({
139
+ type: "process",
140
+ callback: () => {},
141
+ }),
123
142
  ).not.toThrow();
124
143
  });
125
144
 
@@ -127,7 +146,10 @@ describe("AssistantEventHub — subscriber cap", () => {
127
146
  const hub = new AssistantEventHub();
128
147
  const N = 50;
129
148
  const subs = Array.from({ length: N }, () =>
130
- hub.subscribe({ assistantId: "ast_1" }, () => {}),
149
+ hub.subscribe({
150
+ type: "process",
151
+ callback: () => {},
152
+ }),
131
153
  );
132
154
  expect(hub.subscriberCount()).toBe(N);
133
155
  subs.forEach((s) => s.dispose());
@@ -98,32 +98,3 @@ describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
98
98
  ).toBe(true);
99
99
  });
100
100
  });
101
-
102
- // ---------------------------------------------------------------------------
103
- // compaction-v2 flag (opt-in): ensures registry-declared defaultEnabled=false
104
- // is honored and that an explicit override can flip it on. Guards the rollout
105
- // gate for the boundary-message-based compaction pipeline introduced in
106
- // later PRs.
107
- // ---------------------------------------------------------------------------
108
-
109
- describe("compaction-v2 flag", () => {
110
- test("defaults to false (disabled) when no override is set", () => {
111
- const config = {} as any;
112
-
113
- expect(isAssistantFeatureFlagEnabled("compaction-v2", config)).toBe(false);
114
- });
115
-
116
- test("returns true when explicitly overridden to true", () => {
117
- _setOverridesForTesting({ "compaction-v2": true });
118
- const config = {} as any;
119
-
120
- expect(isAssistantFeatureFlagEnabled("compaction-v2", config)).toBe(true);
121
- });
122
-
123
- test("returns false when explicitly overridden to false", () => {
124
- _setOverridesForTesting({ "compaction-v2": false });
125
- const config = {} as any;
126
-
127
- expect(isAssistantFeatureFlagEnabled("compaction-v2", config)).toBe(false);
128
- });
129
- });
@@ -66,8 +66,6 @@ const mockConfig = {
66
66
  rateLimit: { maxRequestsPerMinute: 0 },
67
67
  secretDetection: {
68
68
  enabled: true,
69
- action: "warn" as const,
70
- entropyThreshold: 4.0,
71
69
  },
72
70
  auditLog: { retentionDays: 0 },
73
71
  };
@@ -90,12 +88,24 @@ mock.module("../util/logger.js", () => ({
90
88
  }),
91
89
  }));
92
90
 
93
- mock.module("../tools/terminal/sandbox.js", () => ({
94
- wrapCommand: (...args: unknown[]) => ({
95
- command: "bash",
96
- args: ["-c", "--", args[0]],
97
- sandboxed: false,
98
- }),
91
+ // Mock HostBashProxy singleton — proxy delegation tests configure this.
92
+ let mockProxyAvailable = false;
93
+ let mockProxyRequestImpl: (
94
+ input: { command: string; working_dir?: string; timeout_seconds?: number; env?: Record<string, string> },
95
+ conversationId: string,
96
+ signal?: AbortSignal,
97
+ ) => Promise<ToolExecutionResult> = () => Promise.resolve({ content: "", isError: false });
98
+
99
+ mock.module("../daemon/host-bash-proxy.js", () => ({
100
+ HostBashProxy: {
101
+ get instance() {
102
+ return {
103
+ isAvailable: () => mockProxyAvailable,
104
+ request: (...args: Parameters<typeof mockProxyRequestImpl>) =>
105
+ mockProxyRequestImpl(...args),
106
+ };
107
+ },
108
+ },
99
109
  }));
100
110
 
101
111
  // ---------------------------------------------------------------------------
@@ -118,7 +128,7 @@ function makeContext(overrides: Partial<ToolContext> = {}): ToolContext {
118
128
  };
119
129
  }
120
130
 
121
- function makeMockProxy(result: ToolExecutionResult) {
131
+ function setupMockProxy(result: ToolExecutionResult) {
122
132
  const requestMock = mock(
123
133
  (
124
134
  _input: {
@@ -132,17 +142,10 @@ function makeMockProxy(result: ToolExecutionResult) {
132
142
  ) => Promise.resolve(result),
133
143
  );
134
144
 
135
- return {
136
- proxy: {
137
- isAvailable: () => true,
138
- request: requestMock,
139
- updateSender: () => {},
140
- dispose: () => {},
141
- resolve: () => {},
142
- hasPendingRequest: () => false,
143
- },
144
- requestMock,
145
- };
145
+ mockProxyAvailable = true;
146
+ mockProxyRequestImpl = requestMock;
147
+
148
+ return requestMock;
146
149
  }
147
150
 
148
151
  // ---------------------------------------------------------------------------
@@ -158,10 +161,13 @@ beforeEach(() => {
158
161
  mockIsBackgroundToolLimitReached.mockClear();
159
162
  mockIsBackgroundToolLimitReached.mockReturnValue(false);
160
163
  latestChild = undefined;
164
+ mockProxyAvailable = false;
165
+ mockProxyRequestImpl = () => Promise.resolve({ content: "", isError: false });
161
166
  });
162
167
 
163
168
  afterEach(() => {
164
169
  latestChild = undefined;
170
+ mockProxyAvailable = false;
165
171
  });
166
172
 
167
173
  // ---------------------------------------------------------------------------
@@ -174,10 +180,9 @@ describe("host_bash background mode — proxy path", () => {
174
180
  content: "proxy output",
175
181
  isError: false,
176
182
  };
177
- const { proxy } = makeMockProxy(proxyResult);
183
+ setupMockProxy(proxyResult);
178
184
 
179
185
  const ctx = makeContext({
180
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
181
186
  });
182
187
 
183
188
  const result = await hostShellTool.execute(
@@ -196,10 +201,9 @@ describe("host_bash background mode — proxy path", () => {
196
201
  content: "proxy output",
197
202
  isError: false,
198
203
  };
199
- const { proxy } = makeMockProxy(proxyResult);
204
+ setupMockProxy(proxyResult);
200
205
 
201
206
  const ctx = makeContext({
202
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
203
207
  });
204
208
 
205
209
  await hostShellTool.execute(
@@ -221,10 +225,9 @@ describe("host_bash background mode — proxy path", () => {
221
225
  content: "proxy success output",
222
226
  isError: false,
223
227
  };
224
- const { proxy } = makeMockProxy(proxyResult);
228
+ setupMockProxy(proxyResult);
225
229
 
226
230
  const ctx = makeContext({
227
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
228
231
  });
229
232
 
230
233
  await hostShellTool.execute(
@@ -252,10 +255,9 @@ describe("host_bash background mode — proxy path", () => {
252
255
  content: "command not found",
253
256
  isError: true,
254
257
  };
255
- const { proxy } = makeMockProxy(proxyResult);
258
+ setupMockProxy(proxyResult);
256
259
 
257
260
  const ctx = makeContext({
258
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
259
261
  });
260
262
 
261
263
  await hostShellTool.execute(
@@ -274,21 +276,11 @@ describe("host_bash background mode — proxy path", () => {
274
276
  });
275
277
 
276
278
  test("calls wakeAgentForOpportunity on proxy rejection", async () => {
277
- const requestMock = mock(() =>
278
- Promise.reject(new Error("proxy transport error")),
279
- );
280
-
281
- const proxy = {
282
- isAvailable: () => true,
283
- request: requestMock,
284
- updateSender: () => {},
285
- dispose: () => {},
286
- resolve: () => {},
287
- hasPendingRequest: () => false,
288
- };
279
+ mockProxyAvailable = true;
280
+ mockProxyRequestImpl = () =>
281
+ Promise.reject(new Error("proxy transport error"));
289
282
 
290
283
  const ctx = makeContext({
291
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
292
284
  });
293
285
 
294
286
  await hostShellTool.execute(
@@ -311,10 +303,9 @@ describe("host_bash background mode — proxy path", () => {
311
303
  content: "done",
312
304
  isError: false,
313
305
  };
314
- const { proxy } = makeMockProxy(proxyResult);
306
+ setupMockProxy(proxyResult);
315
307
 
316
308
  const ctx = makeContext({
317
- hostBashProxy: proxy as unknown as ToolContext["hostBashProxy"],
318
309
  });
319
310
 
320
311
  const result = await hostShellTool.execute(
@@ -243,7 +243,6 @@ import {
243
243
  import type { CallTransport } from "../calls/call-transport.js";
244
244
  import { resolveCallTtsProvider } from "../calls/resolve-call-tts-provider.js";
245
245
  import { loadConfig } from "../config/loader.js";
246
- import { createGuardianBinding } from "../contacts/contacts-write.js";
247
246
  import {
248
247
  getCanonicalGuardianRequest,
249
248
  getPendingCanonicalRequestByCallSessionId,
@@ -253,6 +252,7 @@ import { getDb, resetDb } from "../memory/db-connection.js";
253
252
  import { initializeDb } from "../memory/db-init.js";
254
253
  import { resetTestTables } from "../memory/raw-query.js";
255
254
  import { conversations } from "../memory/schema.js";
255
+ import { createGuardianBinding } from "./helpers/create-guardian-binding.js";
256
256
 
257
257
  initializeDb();
258
258
 
@@ -194,6 +194,91 @@ describe("CallSiteRoutingProvider", () => {
194
194
  expect(response.model).toBe("anthropic");
195
195
  });
196
196
 
197
+ test("stamps actualProvider when routing to an alternative provider", async () => {
198
+ setLlmConfig({
199
+ default: { provider: "anthropic", model: "claude-opus-4-7" },
200
+ callSites: {
201
+ memoryRetrieval: { provider: "openai", model: "gpt-5.5" },
202
+ },
203
+ });
204
+
205
+ const defaultProvider = makeProvider("anthropic", () => {});
206
+ const altProvider = makeProvider("openai", () => {});
207
+
208
+ const wrapped = new CallSiteRoutingProvider(defaultProvider, (name) =>
209
+ name === "openai" ? altProvider : undefined,
210
+ );
211
+
212
+ const response = await wrapped.sendMessage(
213
+ DUMMY_MESSAGES,
214
+ undefined,
215
+ undefined,
216
+ { config: { callSite: "memoryRetrieval" } },
217
+ );
218
+
219
+ // actualProvider must reflect the alternative, not the default, so that
220
+ // loop.ts / emitUsage / llm_call_finished log and bill the correct
221
+ // provider (fixes gpt-5.5 showing as "anthropic" with $0 cost).
222
+ expect(response.actualProvider).toBe("openai");
223
+ });
224
+
225
+ test("does not overwrite actualProvider already set by the alternative provider", async () => {
226
+ setLlmConfig({
227
+ default: { provider: "anthropic", model: "claude-opus-4-7" },
228
+ callSites: {
229
+ memoryRetrieval: { provider: "openai", model: "gpt-5.5" },
230
+ },
231
+ });
232
+
233
+ const defaultProvider = makeProvider("anthropic", () => {});
234
+ // Simulate a wrapper provider that sets actualProvider itself
235
+ const altProvider: Provider = {
236
+ name: "openai",
237
+ async sendMessage() {
238
+ return {
239
+ ...makeResponse("openai"),
240
+ actualProvider: "openai-via-proxy",
241
+ };
242
+ },
243
+ };
244
+
245
+ const wrapped = new CallSiteRoutingProvider(defaultProvider, (name) =>
246
+ name === "openai" ? altProvider : undefined,
247
+ );
248
+
249
+ const response = await wrapped.sendMessage(
250
+ DUMMY_MESSAGES,
251
+ undefined,
252
+ undefined,
253
+ { config: { callSite: "memoryRetrieval" } },
254
+ );
255
+
256
+ expect(response.actualProvider).toBe("openai-via-proxy");
257
+ });
258
+
259
+ test("does not set actualProvider when routing to the default provider", async () => {
260
+ setLlmConfig({
261
+ default: { provider: "anthropic", model: "claude-opus-4-7" },
262
+ });
263
+
264
+ const defaultProvider = makeProvider("anthropic", () => {});
265
+
266
+ const wrapped = new CallSiteRoutingProvider(
267
+ defaultProvider,
268
+ () => undefined,
269
+ );
270
+
271
+ const response = await wrapped.sendMessage(
272
+ DUMMY_MESSAGES,
273
+ undefined,
274
+ undefined,
275
+ { config: { callSite: "memoryRetrieval" } },
276
+ );
277
+
278
+ // No alternative was resolved — actualProvider should stay unset.
279
+ expect(response.actualProvider).toBeUndefined();
280
+ });
281
+
197
282
  test("delegates `name` and `tokenEstimationProvider` to the default provider", () => {
198
283
  const defaultProvider: Provider = {
199
284
  name: "anthropic",
@@ -211,4 +296,112 @@ describe("CallSiteRoutingProvider", () => {
211
296
  expect(wrapped.name).toBe("anthropic");
212
297
  expect(wrapped.tokenEstimationProvider).toBe("anthropic");
213
298
  });
299
+
300
+ test("name getter reflects the routed provider during sendMessage and reverts after", async () => {
301
+ // Regression: emitLlmCallStartedIfNeeded fires on the first text_delta,
302
+ // *during* the sendMessage call (before the response completes). It reads
303
+ // provider.name directly — if that's always the default name the trace
304
+ // event says "LLM call to anthropic" even when the call went to openai.
305
+ setLlmConfig({
306
+ default: { provider: "anthropic", model: "claude-opus-4-7" },
307
+ callSites: {
308
+ memoryRetrieval: { provider: "openai", model: "gpt-5.5" },
309
+ },
310
+ });
311
+
312
+ const defaultProvider = makeProvider("anthropic", () => {});
313
+ const namesDuringCall: string[] = [];
314
+
315
+ const altProvider: Provider = {
316
+ name: "openai",
317
+ async sendMessage() {
318
+ // Simulate reading provider.name mid-stream (as handleTextDelta does).
319
+ namesDuringCall.push(wrapped.name);
320
+ return makeResponse("openai");
321
+ },
322
+ };
323
+
324
+ const wrapped = new CallSiteRoutingProvider(defaultProvider, (name) =>
325
+ name === "openai" ? altProvider : undefined,
326
+ );
327
+
328
+ expect(wrapped.name).toBe("anthropic"); // idle → default
329
+ await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
330
+ config: { callSite: "memoryRetrieval" },
331
+ });
332
+ expect(namesDuringCall).toEqual(["openai"]); // mid-call → routed provider
333
+ expect(wrapped.name).toBe("anthropic"); // after call → reverted to default
334
+ });
335
+
336
+ test("concurrent sendMessage calls each see their own provider name (no clobbering)", async () => {
337
+ // Regression: if _routedProviderName were a plain instance field, concurrent
338
+ // calls (e.g. main turn + title-gen both in-flight) would clobber each
339
+ // other. AsyncLocalStorage gives each call its own async-context slot.
340
+ setLlmConfig({
341
+ default: { provider: "anthropic", model: "claude-opus-4-7" },
342
+ callSites: {
343
+ memoryRetrieval: { provider: "openai", model: "gpt-5.5" },
344
+ conversationTitle: { provider: "fireworks", model: "qwen3-235b" },
345
+ },
346
+ });
347
+
348
+ const defaultProvider = makeProvider("anthropic", () => {});
349
+ const nameSeenByOpenAI: string[] = [];
350
+ const nameSeenByFireworks: string[] = [];
351
+
352
+ // Shared resolve handles so we can interleave the two calls:
353
+ // openAI starts → fireworks starts → openAI resolves → fireworks resolves
354
+ let resolveOpenAI!: () => void;
355
+ let resolveFireworks!: () => void;
356
+
357
+ const openAIProvider: Provider = {
358
+ name: "openai",
359
+ async sendMessage() {
360
+ // Yield so fireworks call can start before we complete.
361
+ await new Promise<void>((r) => {
362
+ resolveOpenAI = r;
363
+ });
364
+ nameSeenByOpenAI.push(wrapped.name);
365
+ return makeResponse("openai");
366
+ },
367
+ };
368
+
369
+ const fireworksProvider: Provider = {
370
+ name: "fireworks",
371
+ async sendMessage() {
372
+ await new Promise<void>((r) => {
373
+ resolveFireworks = r;
374
+ });
375
+ nameSeenByFireworks.push(wrapped.name);
376
+ return makeResponse("fireworks");
377
+ },
378
+ };
379
+
380
+ const wrapped = new CallSiteRoutingProvider(defaultProvider, (name) => {
381
+ if (name === "openai") return openAIProvider;
382
+ if (name === "fireworks") return fireworksProvider;
383
+ return undefined;
384
+ });
385
+
386
+ // Start both calls concurrently (do not await yet).
387
+ const callA = wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
388
+ config: { callSite: "memoryRetrieval" }, // → openai
389
+ });
390
+ const callB = wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
391
+ config: { callSite: "conversationTitle" }, // → fireworks
392
+ });
393
+
394
+ // Let both reach their suspension point, then resolve in order.
395
+ await Promise.resolve(); // flush microtasks so both calls are in-flight
396
+ resolveOpenAI();
397
+ resolveFireworks();
398
+
399
+ await Promise.all([callA, callB]);
400
+
401
+ // Each call must have seen its own provider, not the other's.
402
+ expect(nameSeenByOpenAI).toEqual(["openai"]);
403
+ expect(nameSeenByFireworks).toEqual(["fireworks"]);
404
+ // And the idle name reverts to the default.
405
+ expect(wrapped.name).toBe("anthropic");
406
+ });
214
407
  });