@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
@@ -14,6 +14,12 @@ import {
14
14
  bucketEventsByHour,
15
15
  type UsageEventBucketRow,
16
16
  } from "./usage-buckets.js";
17
+ import {
18
+ bucketGroupedUsageEvents,
19
+ displayUsageGroup,
20
+ type UsageGroupedBucketRow,
21
+ type UsageGroupedSeriesBucket,
22
+ } from "./usage-grouped-buckets.js";
17
23
 
18
24
  // ---------------------------------------------------------------------------
19
25
  // Write
@@ -28,6 +34,9 @@ export function recordUsageEvent(
28
34
  id: uuid(),
29
35
  createdAt: Date.now(),
30
36
  ...input,
37
+ callSite: input.callSite ?? null,
38
+ inferenceProfile: input.inferenceProfile ?? null,
39
+ inferenceProfileSource: input.inferenceProfileSource ?? null,
31
40
  estimatedCostUsd: pricing.estimatedCostUsd,
32
41
  pricingStatus: pricing.pricingStatus,
33
42
  };
@@ -39,6 +48,9 @@ export function recordUsageEvent(
39
48
  runId: event.runId,
40
49
  requestId: event.requestId,
41
50
  actor: event.actor,
51
+ callSite: event.callSite,
52
+ inferenceProfile: event.inferenceProfile,
53
+ inferenceProfileSource: event.inferenceProfileSource,
42
54
  provider: event.provider,
43
55
  model: event.model,
44
56
  inputTokens: event.inputTokens,
@@ -66,6 +78,9 @@ function rowToUsageEvent(row: {
66
78
  runId: string | null;
67
79
  requestId: string | null;
68
80
  actor: string;
81
+ callSite: string | null;
82
+ inferenceProfile: string | null;
83
+ inferenceProfileSource: string | null;
69
84
  provider: string;
70
85
  model: string;
71
86
  inputTokens: number;
@@ -82,6 +97,10 @@ function rowToUsageEvent(row: {
82
97
  runId: row.runId,
83
98
  requestId: row.requestId,
84
99
  actor: row.actor as UsageEvent["actor"],
100
+ callSite: row.callSite as UsageEvent["callSite"],
101
+ inferenceProfile: row.inferenceProfile,
102
+ inferenceProfileSource:
103
+ row.inferenceProfileSource as UsageEvent["inferenceProfileSource"],
85
104
  provider: row.provider,
86
105
  model: row.model,
87
106
  inputTokens: row.inputTokens,
@@ -183,17 +202,23 @@ export interface UsageDayBucket {
183
202
  eventCount: number;
184
203
  }
185
204
 
186
- /** A grouped breakdown row (by actor, provider, or model). */
205
+ /** A grouped breakdown row. */
187
206
  export interface UsageGroupBreakdown {
207
+ /** Display label for the group. */
188
208
  group: string;
189
209
  /**
190
210
  * Stable identifier for the group. Populated with the conversation id when
191
211
  * `groupBy === "conversation"` (and `null` for that mode's "Other" bucket,
192
212
  * which aggregates events with no conversation id). For all other group-bys
193
- * (`actor`, `provider`, `model`) this is always `null` — the raw grouping
194
- * column is already exposed via `group`.
213
+ * this is always `null`.
195
214
  */
196
215
  groupId: string | null;
216
+ /**
217
+ * Raw stored grouping value for dimensions whose display label may differ
218
+ * from storage (`call_site`, `inference_profile`). Omitted for legacy
219
+ * dimensions where `group` is already the raw value.
220
+ */
221
+ groupKey?: string | null;
197
222
  /** Direct input tokens only; cache traffic is reported separately below. */
198
223
  totalInputTokens: number;
199
224
  totalOutputTokens: number;
@@ -216,9 +241,8 @@ interface TotalsRow {
216
241
  unpriced_event_count: number;
217
242
  }
218
243
 
219
-
220
244
  interface GroupRow {
221
- group_key: string;
245
+ group_key: string | null;
222
246
  group_id: string | null;
223
247
  total_input_tokens: number;
224
248
  total_output_tokens: number;
@@ -274,6 +298,7 @@ function fetchRawBucketRows(range: UsageTimeRange): UsageEventBucketRow[] {
274
298
  llm_call_count
275
299
  FROM llm_usage_events
276
300
  WHERE created_at >= ?1 AND created_at <= ?2
301
+ ORDER BY created_at ASC
277
302
  `,
278
303
  range.from,
279
304
  range.to,
@@ -326,7 +351,64 @@ export function getUsageHourBuckets(
326
351
  return bucketEventsByHour(rows, range, tz, options);
327
352
  }
328
353
 
329
- type GroupByDimension = "actor" | "provider" | "model" | "conversation";
354
+ export const USAGE_GROUP_BY_DIMENSIONS = [
355
+ "actor",
356
+ "provider",
357
+ "model",
358
+ "conversation",
359
+ "call_site",
360
+ "inference_profile",
361
+ ] as const;
362
+
363
+ export type GroupByDimension = (typeof USAGE_GROUP_BY_DIMENSIONS)[number];
364
+
365
+ export const USAGE_SERIES_GROUP_BY_DIMENSIONS = [
366
+ "actor",
367
+ "provider",
368
+ "model",
369
+ "call_site",
370
+ "inference_profile",
371
+ ] as const satisfies readonly GroupByDimension[];
372
+
373
+ const GROUP_BY_COLUMNS: Record<
374
+ Exclude<GroupByDimension, "conversation">,
375
+ string
376
+ > = {
377
+ actor: "actor",
378
+ provider: "provider",
379
+ model: "model",
380
+ call_site: "call_site",
381
+ inference_profile: "inference_profile",
382
+ };
383
+
384
+ const ALLOWED_DIMENSIONS = new Set<string>(USAGE_GROUP_BY_DIMENSIONS);
385
+
386
+ function assertGroupByDimension(
387
+ groupBy: string,
388
+ ): asserts groupBy is GroupByDimension {
389
+ if (!ALLOWED_DIMENSIONS.has(groupBy)) {
390
+ throw new Error(`Invalid groupBy dimension: ${groupBy}`);
391
+ }
392
+ }
393
+
394
+ function mapGroupRow(
395
+ row: GroupRow,
396
+ groupBy: GroupByDimension,
397
+ ): UsageGroupBreakdown {
398
+ const includeGroupKey =
399
+ groupBy === "call_site" || groupBy === "inference_profile";
400
+ return {
401
+ group: displayUsageGroup(groupBy, row.group_key),
402
+ groupId: row.group_id,
403
+ ...(includeGroupKey ? { groupKey: row.group_key } : {}),
404
+ totalInputTokens: row.total_input_tokens,
405
+ totalOutputTokens: row.total_output_tokens,
406
+ totalCacheCreationTokens: row.total_cache_creation_tokens,
407
+ totalCacheReadTokens: row.total_cache_read_tokens,
408
+ totalEstimatedCostUsd: row.total_estimated_cost_usd ?? 0,
409
+ eventCount: row.event_count,
410
+ };
411
+ }
330
412
 
331
413
  /**
332
414
  * Return grouped breakdowns across the given time range, ordered by total
@@ -337,15 +419,7 @@ export function getUsageGroupBreakdown(
337
419
  groupBy: GroupByDimension,
338
420
  ): UsageGroupBreakdown[] {
339
421
  // Runtime allowlist — defense-in-depth against SQL injection via type assertions.
340
- const ALLOWED_DIMENSIONS = new Set<string>([
341
- "actor",
342
- "provider",
343
- "model",
344
- "conversation",
345
- ]);
346
- if (!ALLOWED_DIMENSIONS.has(groupBy)) {
347
- throw new Error(`Invalid groupBy dimension: ${groupBy}`);
348
- }
422
+ assertGroupByDimension(groupBy);
349
423
 
350
424
  // Conversation grouping requires a JOIN with conversations to resolve titles.
351
425
  if (groupBy === "conversation") {
@@ -372,22 +446,10 @@ export function getUsageGroupBreakdown(
372
446
  range.from,
373
447
  range.to,
374
448
  );
375
- return rows.map((r) => ({
376
- group: r.group_key,
377
- // `GROUP BY e.conversation_id` makes `e.conversation_id` unambiguous
378
- // inside each group — it is the seeded conversation id for real rows
379
- // and `null` for the "Other" bucket (events with no conversation).
380
- groupId: r.group_id,
381
- totalInputTokens: r.total_input_tokens,
382
- totalOutputTokens: r.total_output_tokens,
383
- totalCacheCreationTokens: r.total_cache_creation_tokens,
384
- totalCacheReadTokens: r.total_cache_read_tokens,
385
- totalEstimatedCostUsd: r.total_estimated_cost_usd ?? 0,
386
- eventCount: r.event_count,
387
- }));
449
+ return rows.map((row) => mapGroupRow(row, groupBy));
388
450
  }
389
451
 
390
- const column = groupBy;
452
+ const column = GROUP_BY_COLUMNS[groupBy];
391
453
  const rows = rawAll<GroupRow>(
392
454
  /*sql*/ `
393
455
  SELECT
@@ -407,18 +469,42 @@ export function getUsageGroupBreakdown(
407
469
  range.from,
408
470
  range.to,
409
471
  );
410
- return rows.map((r) => ({
411
- group: r.group_key,
412
- // Non-conversation group-bys (actor/provider/model) don't have a
413
- // separate stable id — the grouping column itself is the identifier
414
- // and is already exposed via `group`. The SELECT projects
415
- // `NULL AS group_id` so the runtime shape matches `GroupRow`.
416
- groupId: r.group_id,
417
- totalInputTokens: r.total_input_tokens,
418
- totalOutputTokens: r.total_output_tokens,
419
- totalCacheCreationTokens: r.total_cache_creation_tokens,
420
- totalCacheReadTokens: r.total_cache_read_tokens,
421
- totalEstimatedCostUsd: r.total_estimated_cost_usd ?? 0,
422
- eventCount: r.event_count,
423
- }));
472
+ return rows.map((row) => mapGroupRow(row, groupBy));
473
+ }
474
+
475
+ export function getUsageGroupedSeries(
476
+ range: UsageTimeRange,
477
+ groupBy: GroupByDimension,
478
+ granularity: UsageGranularity,
479
+ tz: string = "UTC",
480
+ options: UsageBucketOptions = {},
481
+ ): UsageGroupedSeriesBucket[] {
482
+ assertGroupByDimension(groupBy);
483
+ if (groupBy === "conversation") {
484
+ throw new Error("Grouped usage series does not support conversation");
485
+ }
486
+
487
+ const column = GROUP_BY_COLUMNS[groupBy];
488
+ const rows = rawAll<UsageGroupedBucketRow>(
489
+ /*sql*/ `
490
+ SELECT
491
+ created_at,
492
+ input_tokens,
493
+ output_tokens,
494
+ estimated_cost_usd,
495
+ llm_call_count,
496
+ ${column} AS group_key
497
+ FROM llm_usage_events
498
+ WHERE created_at >= ?1 AND created_at <= ?2
499
+ ORDER BY created_at ASC
500
+ `,
501
+ range.from,
502
+ range.to,
503
+ );
504
+
505
+ return bucketGroupedUsageEvents(rows, range, tz, {
506
+ ...options,
507
+ granularity,
508
+ groupBy,
509
+ });
424
510
  }
@@ -0,0 +1,115 @@
1
+ import { and, desc, eq, inArray, isNull } from "drizzle-orm";
2
+ import { v4 as uuid } from "uuid";
3
+
4
+ import { getDb } from "./db-connection.js";
5
+ import { memoryV2ActivationLogs } from "./schema.js";
6
+
7
+ export interface MemoryV2ConceptRowRecord {
8
+ slug: string;
9
+ finalActivation: number;
10
+ ownActivation: number;
11
+ priorActivation: number;
12
+ simUser: number;
13
+ simAssistant: number;
14
+ simNow: number;
15
+ spreadContribution: number;
16
+ source: "prior_state" | "ann_top50" | "both";
17
+ status: "in_context" | "injected" | "not_injected";
18
+ }
19
+
20
+ export interface MemoryV2SkillRowRecord {
21
+ id: string;
22
+ activation: number;
23
+ simUser: number;
24
+ simAssistant: number;
25
+ simNow: number;
26
+ status: "injected" | "not_injected";
27
+ }
28
+
29
+ export interface MemoryV2ConfigSnapshot {
30
+ d: number;
31
+ c_user: number;
32
+ c_assistant: number;
33
+ c_now: number;
34
+ k: number;
35
+ hops: number;
36
+ top_k: number;
37
+ top_k_skills: number;
38
+ epsilon: number;
39
+ }
40
+
41
+ export interface RecordMemoryV2ActivationLogParams {
42
+ conversationId: string;
43
+ turn: number;
44
+ mode: "context-load" | "per-turn";
45
+ concepts: MemoryV2ConceptRowRecord[];
46
+ skills: MemoryV2SkillRowRecord[];
47
+ config: MemoryV2ConfigSnapshot;
48
+ }
49
+
50
+ export function recordMemoryV2ActivationLog(
51
+ params: RecordMemoryV2ActivationLogParams,
52
+ ): void {
53
+ const db = getDb();
54
+ db.insert(memoryV2ActivationLogs)
55
+ .values({
56
+ id: uuid(),
57
+ conversationId: params.conversationId,
58
+ messageId: null,
59
+ turn: params.turn,
60
+ mode: params.mode,
61
+ conceptsJson: JSON.stringify(params.concepts),
62
+ skillsJson: JSON.stringify(params.skills),
63
+ configJson: JSON.stringify(params.config),
64
+ createdAt: Date.now(),
65
+ })
66
+ .run();
67
+ }
68
+
69
+ export function backfillMemoryV2ActivationMessageId(
70
+ conversationId: string,
71
+ messageId: string,
72
+ ): void {
73
+ const db = getDb();
74
+ db.update(memoryV2ActivationLogs)
75
+ .set({ messageId })
76
+ .where(
77
+ and(
78
+ eq(memoryV2ActivationLogs.conversationId, conversationId),
79
+ isNull(memoryV2ActivationLogs.messageId),
80
+ ),
81
+ )
82
+ .run();
83
+ }
84
+
85
+ export interface MemoryV2ActivationLog {
86
+ conversationId: string;
87
+ turn: number;
88
+ mode: "context-load" | "per-turn";
89
+ concepts: MemoryV2ConceptRowRecord[];
90
+ skills: MemoryV2SkillRowRecord[];
91
+ config: MemoryV2ConfigSnapshot;
92
+ }
93
+
94
+ export function getMemoryV2ActivationLogByMessageIds(
95
+ messageIds: string[],
96
+ ): MemoryV2ActivationLog | null {
97
+ if (messageIds.length === 0) return null;
98
+ const db = getDb();
99
+ const rows = db
100
+ .select()
101
+ .from(memoryV2ActivationLogs)
102
+ .where(inArray(memoryV2ActivationLogs.messageId, messageIds))
103
+ .orderBy(desc(memoryV2ActivationLogs.createdAt))
104
+ .all();
105
+ if (rows.length === 0) return null;
106
+ const row = rows[0]!;
107
+ return {
108
+ conversationId: row.conversationId,
109
+ turn: row.turn,
110
+ mode: row.mode as "context-load" | "per-turn",
111
+ concepts: JSON.parse(row.conceptsJson) as MemoryV2ConceptRowRecord[],
112
+ skills: JSON.parse(row.skillsJson) as MemoryV2SkillRowRecord[],
113
+ config: JSON.parse(row.configJson) as MemoryV2ConfigSnapshot,
114
+ };
115
+ }
@@ -0,0 +1,54 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+ import { withCrashRecovery } from "./validate-migration-state.js";
4
+
5
+ const CHECKPOINT_KEY = "migration_document_conversations_v1";
6
+
7
+ /**
8
+ * Create the document_conversations junction table.
9
+ *
10
+ * Tracks which conversations each document is associated with. A document may
11
+ * appear in multiple conversations (e.g. opened from search, linked by the
12
+ * assistant, etc.), so the relationship is many-to-many.
13
+ *
14
+ * The FK on surface_id cascades deletes from documents — when a document is
15
+ * removed, all its conversation associations are cleaned up automatically.
16
+ *
17
+ * There is intentionally NO FK to the conversations table. Conversation IDs may
18
+ * be synthetic or pre-resolved UUIDs that don't yet exist in the conversations
19
+ * table at insertion time. This means orphaned rows can accumulate when
20
+ * conversations are deleted. This is acceptable — the rows are tiny (two strings
21
+ * + timestamp) and the composite PK prevents unbounded growth per document. If
22
+ * cleanup becomes a concern, add a periodic sweep or hook into the conversation
23
+ * deletion path in memory/job-handlers/cleanup.ts.
24
+ *
25
+ * The migration also backfills from the existing documents.conversation_id column
26
+ * so that pre-existing document–conversation relationships are preserved.
27
+ */
28
+ export function migrateCreateDocumentConversations(database: DrizzleDb): void {
29
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
30
+ const raw = getSqliteFrom(database);
31
+
32
+ raw.exec(/*sql*/ `
33
+ CREATE TABLE IF NOT EXISTS document_conversations (
34
+ surface_id TEXT NOT NULL,
35
+ conversation_id TEXT NOT NULL,
36
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000),
37
+ PRIMARY KEY (surface_id, conversation_id),
38
+ FOREIGN KEY (surface_id) REFERENCES documents(surface_id) ON DELETE CASCADE
39
+ )
40
+ `);
41
+
42
+ raw.exec(/*sql*/ `
43
+ CREATE INDEX IF NOT EXISTS idx_doc_conv_conversation_id
44
+ ON document_conversations(conversation_id)
45
+ `);
46
+
47
+ // Backfill: seed junction table from existing documents.conversation_id
48
+ raw.exec(/*sql*/ `
49
+ INSERT OR IGNORE INTO document_conversations (surface_id, conversation_id, created_at)
50
+ SELECT surface_id, conversation_id, created_at
51
+ FROM documents
52
+ `);
53
+ });
54
+ }
@@ -0,0 +1,55 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+ import { withCrashRecovery } from "./validate-migration-state.js";
4
+
5
+ const CHECKPOINT_KEY = "migration_memory_v2_activation_logs_v1";
6
+
7
+ /**
8
+ * Create the memory_v2_activation_logs table for per-turn v2 activation
9
+ * telemetry.
10
+ *
11
+ * Each row captures one activation pass keyed by (conversation, turn, mode):
12
+ * - mode is "context-load" (initial conversation hydration) or "per-turn"
13
+ * (each subsequent agent turn).
14
+ * - concepts_json / skills_json hold the structured activation outputs.
15
+ * - config_json captures the resolved config snapshot used for the pass so
16
+ * the inspector can reproduce activation conditions.
17
+ *
18
+ * Indexes mirror the access patterns used by the inspector tab: lookup by
19
+ * message_id, by conversation_id, and ordering by created_at.
20
+ */
21
+ export function migrateMemoryV2ActivationLogs(database: DrizzleDb): void {
22
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
23
+ const raw = getSqliteFrom(database);
24
+ raw.exec(/*sql*/ `
25
+ CREATE TABLE IF NOT EXISTS memory_v2_activation_logs (
26
+ id TEXT PRIMARY KEY,
27
+ conversation_id TEXT NOT NULL,
28
+ message_id TEXT,
29
+ turn INTEGER NOT NULL,
30
+ mode TEXT NOT NULL,
31
+ concepts_json TEXT NOT NULL,
32
+ skills_json TEXT NOT NULL,
33
+ config_json TEXT NOT NULL,
34
+ created_at INTEGER NOT NULL
35
+ )
36
+ `);
37
+ raw.exec(/*sql*/ `
38
+ CREATE INDEX IF NOT EXISTS idx_memory_v2_activation_logs_message_id
39
+ ON memory_v2_activation_logs (message_id)
40
+ `);
41
+ raw.exec(/*sql*/ `
42
+ CREATE INDEX IF NOT EXISTS idx_memory_v2_activation_logs_conversation_id
43
+ ON memory_v2_activation_logs (conversation_id)
44
+ `);
45
+ raw.exec(/*sql*/ `
46
+ CREATE INDEX IF NOT EXISTS idx_memory_v2_activation_logs_created_at
47
+ ON memory_v2_activation_logs (created_at)
48
+ `);
49
+ });
50
+ }
51
+
52
+ export function downMemoryV2ActivationLogs(database: DrizzleDb): void {
53
+ const raw = getSqliteFrom(database);
54
+ raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_v2_activation_logs`);
55
+ }
@@ -0,0 +1,31 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+ import { tableHasColumn } from "./schema-introspection.js";
4
+
5
+ /**
6
+ * Add stable attribution identifiers to the local LLM usage ledger.
7
+ *
8
+ * Existing rows remain valid with NULL attribution. Provider/model continue to
9
+ * represent the resolved provider/model used for the request.
10
+ */
11
+ export function migrateLlmUsageAttribution(database: DrizzleDb): void {
12
+ const raw = getSqliteFrom(database);
13
+
14
+ if (!tableHasColumn(database, "llm_usage_events", "call_site")) {
15
+ raw.exec(/*sql*/ `ALTER TABLE llm_usage_events ADD COLUMN call_site TEXT`);
16
+ }
17
+
18
+ if (!tableHasColumn(database, "llm_usage_events", "inference_profile")) {
19
+ raw.exec(
20
+ /*sql*/ `ALTER TABLE llm_usage_events ADD COLUMN inference_profile TEXT`,
21
+ );
22
+ }
23
+
24
+ if (
25
+ !tableHasColumn(database, "llm_usage_events", "inference_profile_source")
26
+ ) {
27
+ raw.exec(
28
+ /*sql*/ `ALTER TABLE llm_usage_events ADD COLUMN inference_profile_source TEXT`,
29
+ );
30
+ }
31
+ }
@@ -0,0 +1,44 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { tableHasColumn } from "./schema-introspection.js";
3
+ import { withCrashRecovery } from "./validate-migration-state.js";
4
+
5
+ const CHECKPOINT_KEY = "migration_slack_compaction_watermark_v1";
6
+
7
+ const COLUMNS = [
8
+ {
9
+ name: "slack_context_compaction_watermark_ts",
10
+ definition: "slack_context_compaction_watermark_ts TEXT",
11
+ },
12
+ {
13
+ name: "slack_context_compaction_watermark_at",
14
+ definition: "slack_context_compaction_watermark_at INTEGER",
15
+ },
16
+ ] as const;
17
+
18
+ /**
19
+ * Add Slack-specific compaction state to conversations.
20
+ *
21
+ * The existing context_compacted_message_count remains the generic DB-row
22
+ * compaction boundary. Slack threads need a source timestamp watermark because
23
+ * late thread mentions can arrive with historical Slack ts values independent
24
+ * of local insertion order.
25
+ */
26
+ export function migrateSlackCompactionWatermark(database: DrizzleDb): void {
27
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
28
+ for (const column of COLUMNS) {
29
+ if (tableHasColumn(database, "conversations", column.name)) {
30
+ continue;
31
+ }
32
+ database.run(`ALTER TABLE conversations ADD COLUMN ${column.definition}`);
33
+ }
34
+ });
35
+ }
36
+
37
+ export function downSlackCompactionWatermark(database: DrizzleDb): void {
38
+ for (const column of COLUMNS) {
39
+ if (!tableHasColumn(database, "conversations", column.name)) {
40
+ continue;
41
+ }
42
+ database.run(`ALTER TABLE conversations DROP COLUMN ${column.name}`);
43
+ }
44
+ }
@@ -0,0 +1,26 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { tableHasColumn } from "./schema-introspection.js";
3
+ import { withCrashRecovery } from "./validate-migration-state.js";
4
+
5
+ const CHECKPOINT_KEY = "migration_tool_invocations_matched_trust_rule_id_v1";
6
+
7
+ /**
8
+ * Add matched_trust_rule_id column to tool_invocations for audit and rule editor UI.
9
+ */
10
+ export function migrateToolInvocationsMatchedRuleId(database: DrizzleDb): void {
11
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
12
+ if (tableHasColumn(database, "tool_invocations", "matched_trust_rule_id")) {
13
+ return;
14
+ }
15
+ database.run(
16
+ `ALTER TABLE tool_invocations ADD COLUMN matched_trust_rule_id TEXT`,
17
+ );
18
+ });
19
+ }
20
+
21
+ export function downToolInvocationsMatchedRuleId(database: DrizzleDb): void {
22
+ if (!tableHasColumn(database, "tool_invocations", "matched_trust_rule_id")) {
23
+ return;
24
+ }
25
+ database.run(`ALTER TABLE tool_invocations DROP COLUMN matched_trust_rule_id`);
26
+ }